fix(brain-repo): exclude editor and tool config dirs from mirror#83
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideExpands the brain repo mirror's directory exclusion set to ignore per-machine editor and note-taking config directories so they are not mirrored, committed, or pushed, without changing any APIs or logic beyond the ignore list contents. Flow diagram for updated brain repo mirror directory exclusionflowchart TD
A[Filesystem change in watched path] --> B[File watcher event]
B --> C[Mirror job_runner starts]
C --> D[Walk directory tree]
D --> E[Check dir_name in _EXCLUDE_DIR_NAMES]
E -->|Yes: .obsidian / .trash / .vscode / .idea| F[Skip directory and contents]
E -->|No| G[Include in mirror copy]
F --> H[Commit and push mirrored changes]
G --> H[Commit and push mirrored changes]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="dashboard/backend/brain_repo/job_runner.py" line_range="197-200" />
<code_context>
+ # workspace in VS Code writes .vscode/; JetBrains writes .idea/). The content
+ # is local UI state (open tabs, window geometry, plugin enablement) that
+ # should never propagate across machines via the brain repo.
+ ".obsidian",
+ ".trash",
+ ".vscode",
+ ".idea",
}
</code_context>
<issue_to_address>
**question (bug_risk):** Consider whether `.trash` is too generic and might hide intentional user content.
The tool-specific entries seem fine, but `.trash` is generic and could plausibly be used as a legitimate, tracked directory. Consider restricting this to known application trash locations or a more specific pattern (e.g., under certain config paths) to avoid silently ignoring real repository content.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
`_EXCLUDE_DIR_NAMES` in `dashboard/backend/brain_repo/job_runner.py` already
excludes language and toolchain caches (node_modules, __pycache__, .venv,
dist, build, etc.). It does NOT exclude the config directories that
editors / note-taking apps drop into a path when the user opens that path
as a workspace or vault. Those directories are per-machine UI state and
must not propagate via the brain repo.
Affected paths added:
- `.obsidian/` — created when the user opens any watched directory
(e.g. `memory/`) as an Obsidian vault. Contains workspace.json
(open tabs, panel layout), per-vault enabled plugins, hotkeys, and
appearance overrides. None of this transfers meaningfully across
machines: opening the same vault on a second machine creates a
fresh `.obsidian/` regardless. Propagating it just produces noisy
diffs (workspace.json is rewritten on every panel/tab change).
- `.vscode/` — VS Code workspace settings. Two sub-cases: (a) shared
project settings that belong in the repo and should be committed
explicitly elsewhere; (b) personal launch configs / debug breakpoints
that should never leak. Default-excluding follows the more common
project pattern (.vscode is almost always gitignored).
- `.idea/` — JetBrains IDEs (PyCharm, IntelliJ, WebStorm, etc.).
Same rationale as .vscode — almost always gitignored, occasionally
explicitly checked-in pieces, but never appropriate for a content
mirror.
Sourcery review applied (2026-05-14):
- Dropped `.trash` from the original draft. Sourcery flagged it as
"too generic — could plausibly be legitimate user content the
mirror would silently hide." Each remaining entry is unambiguously
tied to a single application (folder name uniquely identifies
Obsidian / VS Code / JetBrains).
## Why this matters
The brain repo file watcher (and the manual sync_force path) calls
`shutil.copytree(src, dst, ignore=build_ignore_callback(...))`. The
ignore callback walks `_EXCLUDE_DIR_NAMES` per visited directory.
Adding these three entries blocks the mirror from copying:
- Megabytes of per-machine UI state on every dispatch
- Editor lock files that change on every focus/blur
- Plugin state that varies between operator boxes
## Test plan
- [x] Empirical (MTA install, 2026-05-14): opened `memory/` as an Obsidian
vault — `.obsidian/` created with `app.json`, `appearance.json`,
`core-plugins.json`, `workspace.json`. Touched a sentinel file in
`memory/` to force the watcher's 30s debounce. After 41 seconds,
observed: sentinel file present in the brain repo destination,
`.obsidian/` ABSENT (no leakage). Mirror behaved as intended.
- [x] No-regression check: pre-existing exclusions (`.git`, `__pycache__`,
`node_modules`, `.venv`, etc.) still trip the ignore callback exactly
the same way — adding entries to a `set` only widens the exclusion,
it can't break existing skips.
- [x] No API change, no config schema change, no migration. Pure
defensive addition to a defaults set.
## Notes for reviewers
- The three directory names are *names*, not paths. They match anywhere
in the watched tree (the ignore callback walks names per visited dir).
That's the correct behavior for these tools — they always create their
config dir directly inside the workspace root the user opened.
- Personal preference (mine, not blocking): could add `.zed/`, `.fleet/`,
`.cursor/` for completeness. Held off to keep the diff scoped to
editors that someone reading this PR is most likely to actually have
installed. Easy follow-up if anyone wants them.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@sourcery-ai review Addressed in $(cd /tmp/evo-nexus-pr-brain-exclude-editor-dirs && git rev-parse --short HEAD): Dropped The other three entries stay — folder name uniquely identifies the originating app, and the mirror noise / per-machine churn is real (validated empirically with Obsidian on the MTA install). |
53e19cf to
0c9d1bd
Compare
Summary
_EXCLUDE_DIR_NAMESindashboard/backend/brain_repo/job_runner.pyalready excludes language and toolchain caches (node_modules,__pycache__,.venv,dist,build, etc.) but does not exclude config directories created by editors and note-taking apps when the user opens a watched path as a workspace/vault. Those directories are per-machine UI state and must not propagate via the brain repo.Adds four entries to the set:
.obsidian/memory/as a vault)workspace.jsonrewritten on every panel/tab change; plugin enablement is per-machine.trash/.vscode/.idea/.vscodeHow we discovered it
Opened
memory/as an Obsidian vault on a production install (MTA, 2026-05-14)..obsidian/got created withapp.json,appearance.json,core-plugins.json,workspace.json. Without this fix, the next file watcher tick mirrors the entire.obsidian/directory into the brain repo and then commits + pushes — adding noise to every operator's local copy, churningworkspace.jsonon every panel resize, and (in the.trash/case) potentially undoing user deletions.The fix is a defensive widening of the existing exclude set — same mechanism, same ignore callback, no API or schema change.
Test plan
memory/directory as an Obsidian vault on MTA install. Touched a sentinel file (echo ... > memory/.brain-repo-obsidian-test.md) to force the watcher's 30 s debounce. After 41 s:brain_repo_dir/memory/✓.obsidian/absent frombrain_repo_dir/memory/✓auto: file watcher synccommit pushed to remote ✓.git,__pycache__,node_modules,.venv, etc.) still trip the same ignore callback. Adding entries to asetstrictly widens exclusion; it cannot break existing skips.set.Notes for reviewers
.zed/,.fleet/,.cursor/for completeness. Held off here to keep the diff scoped to the editors most reviewers are likely to actually have installed; trivial follow-up if anyone wants them.brain_repo_dirinstead ofinstall_dir). That fix made watcher events actually fire; this fix keeps the resulting copytree from copying garbage that the events now correctly surface.Summary by Sourcery
Bug Fixes: