fix(sync): anchor --shared include entries to the mount root (BEA-5) (#56)

`bdrive init --shared wiki` wrote `include: ["wiki/"]`, which compile()
treats as an unanchored gitignore pattern — so any nested directory named
`wiki` synced too. Shared-subfolder mode is what people use to keep private
material out of a project, and it was silently widening the scope: 15 files
under .agents/, .claude/ and .gemini/ leaked into a real project from
.../detector/shared/ dirs.

cleanShared now emits "/wiki/", which fixes both callers (init --shared and
bdrive scope add). config.LoadProject anchors legacy single-segment entries
on read, so the existing mounts are fixed without a re-init — and that also
keeps `bdrive scope rm wiki` working against pre-fix configs, with a
belt-and-braces unanchored candidate key in scopeRemove for any config that
bypasses LoadProject.

Not touched: compile() itself, and no delete op for the already-leaked
remote files (BEA-20 — a delete would unlink teammates' local copies).

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Snow W. Lee (Sungwon)
2026-07-27 18:44:05 +09:00
committed by GitHub
co-authored by Claude Opus 5
parent 46db6507c4
commit 056c883204
10 changed files with 112 additions and 28 deletions
+7 -5
View File
@@ -274,10 +274,12 @@ func chooseScope() ([]string, error) {
return strings.Fields(strings.ReplaceAll(dirs, ",", " ")), nil
}
// cleanShared normalizes --shared entries into include patterns ("wiki/"):
// slashes cleaned, duplicates dropped. Any entry that resolves to the mount
// root or escapes it is an error — a silently-dropped "." would widen the
// scope to the whole folder.
// cleanShared normalizes --shared entries into include patterns ("/wiki/"):
// slashes cleaned, duplicates dropped. The leading slash anchors the pattern
// to the mount root — without it a nested directory of the same name (say
// .claude/skills/x/wiki/) would match and sync too. Any entry that resolves
// to the mount root or escapes it is an error — a silently-dropped "." would
// widen the scope to the whole folder.
func cleanShared(shared []string) ([]string, error) {
var out []string
seen := map[string]bool{}
@@ -288,7 +290,7 @@ func cleanShared(shared []string) ([]string, error) {
}
if !seen[s] {
seen[s] = true
out = append(out, s+"/")
out = append(out, "/"+s+"/")
}
}
return out, nil