Scoping the folder
Shared agent memory works better when it’s curated. A folder holding
node_modules/ and build output costs sync bandwidth, buries the documents that
matter, and gives agents thousands of irrelevant paths to wander into.
One mechanism controls it: .bdriveignore, a gitignore-style rule file at
the mount root. It opts individual paths out, and — as a bdrive-managed block of
“only these folders” rules — it narrows the project to chosen subfolders. Rules
are applied symmetrically: the same filter governs what’s read from disk and
what’s written back to it.
Sync only subfolders
Section titled “Sync only subfolders”A mount is always exactly the folder you name:
bdrive init wiki # ./wiki is the projectIts contents are the project’s contents — no wiki/ prefix on the hub — and
nothing outside it is ever scanned. This is the right shape inside a code
repository: sync wiki/ or docs/ and leave the source tree alone. The agent
gets a knowledge folder; the code stays in git where it belongs.
When the project has to be the enclosing folder — several subfolders belonging
to one project, or agents that work from the repo root — narrow it with
--only:
bdrive init . --only wiki,docsBoth folders join the same project, with one membership and one permission set.
The interactive bdrive init asks the same question.
--only writes ordinary .bdriveignore rules, in a managed block at the top of
the file:
# bdrive scope — only these folders sync (managed by bdrive; change with `bdrive scope add/rm`)/*!/wiki/!/docs/# end bdrive scope/* excludes everything at the mount root; each ! line re-includes one
folder, anchored to that root — so a nested directory that happens to share the
name never syncs. The block goes first because matching is last-match-wins:
ordinary rules below it still apply, which keeps node_modules/ excluded
inside a scoped folder.
There is no separate scope setting to keep in step.
The scope is the team’s
Section titled “The scope is the team’s”Because the rules live in .bdriveignore, and that file syncs, a narrow scope
is the whole team’s scope: every device that syncs the project picks it up.
Narrowing it is a change everyone sees immediately, not a local preference.
(Legacy include lists are the exception — they sit in the never-synced
.bdrive/config.json and apply to one device only.)
Widening is a local decision
Section titled “Widening is a local decision”One direction is deliberately not automatic. A rule a teammate pushes that
widens what syncs — a ! re-include — takes effect on your machine for what
comes down from the hub, but it does not start uploading files off your disk
that your own rules held back. Uploading something that was never shared is a
decision your machine makes, not one a teammate makes for it.
You accept the current rules the moment you author them yourself: bdrive init --only, bdrive scope add / scope rm, or editing .bdriveignore by hand.
Any of those makes the file as it stands your device’s rules, widenings
included.
This matters most in the shape this guide recommends for a repository — bdrive init . --only docs,notes puts the whole repository under the mount, with only
.bdriveignore holding the rest of it back. Without the rule above, one
teammate adding !.env to the shared file would upload every other member’s
local .env on their next sync.
A device joining a project has authored nothing yet, so the project’s rules stand on their own — team-wide scope still works for a new member on day one.
Change the scope later
Section titled “Change the scope later”bdrive scope shows what syncs; scope add / scope rm edit the managed block
— no hand-written negation syntax, and the running daemon applies the change
within seconds:
bdrive scope # what syncs nowbdrive scope add notes # also sync ./notesbdrive scope rm docs # stop syncing ./docsBoth act on an already-narrowed project; on a whole-folder mount scope add
points you at bdrive init . --only <dirs> and scope rm at a plain
.bdriveignore rule.
Removing a folder stops syncing it but deletes nothing — local files stay, and
the hub keeps everything already synced (the same
non-destructive rule as any other
.bdriveignore change). Removing the last entry is refused, because an empty
block means the whole folder syncs; if you want to stop syncing entirely, that’s
bdrive stop.
Check what actually leaves your machine
Section titled “Check what actually leaves your machine”Rules are one thing; their effect is another. bdrive scope --explain walks the
folder and prints every path it found, split into what syncs and what does not:
bdrive scope --explainsynced (4) .bdriveignore docs/architecture.md docs/onboarding.md specs/BEA-24.md
not synced (2,486) .DS_Store .bdrive/ (1 file) .env .git/ (312 files) node_modules/ (2,481 files) scratch/notes.md vendor/acme/ (own project — syncs separately)
4 files sync, 2,486 do not.A directory that is excluded whole collapses to one counted line, so a folder
with node_modules in it prints a handful of lines, not thousands. A nested
mount is labelled rather than called “not synced” — it does sync, through its
own project.
The decisions come from the same walk the sync cycle itself uses, so what this prints cannot drift from what actually leaves. It is a pure read: safe to run while the daemon is running and while you are offline, it takes no lock and makes no network call. Output is sorted and stable, which makes it diffable — the way to prove a rule change did what you meant:
bdrive scope --explain > before.txt# edit .bdriveignorebdrive scope --explain > after.txtdiff before.txt after.txtOne thing it does not answer: whether a path you exclude today is already
on the hub from before the rule existed. Excluding it stops future syncs but
leaves the copy up there — bdrive forget <path> is what takes it off.
Opt files out
Section titled “Opt files out”.bdriveignore sits at the mount root and works like .gitignore:
# commentsnode_modules/*.logbuild/!build/keep.txt/only-at-rootSupported: # comments, *, **, ?, a trailing / for directories, a
leading (or any) / for root-anchoring, and ! to re-include.
It always syncs — even when the scope block excludes everything around it, and
even if a pattern matches it — so every device shares the same rules: one
person excluding *.tmp fixes it for the whole team.
bdrive init seeds a starter one covering node_modules, build directories,
caches, and .env*.
Opting out is non-destructive
Section titled “Opting out is non-destructive”When a pattern starts matching an already-synced file, the file stops syncing but is deleted nowhere. The path is dropped from the local cache without a delete op, so opting out on your machine never removes the file from anyone else’s.
To take something off the hub as well, use bdrive forget <path>: it writes the
rule and removes what already synced from the hub, keeping the local copy on
every device. bdrive sync --prune does the same reconciliation for rules you
added by hand — but it refuses on a scoped project, because “only these
folders” rules exclude everything else the project holds, and pruning them would
strip all of it from the hub for every teammate, not just this device. Name the
specific paths with bdrive forget instead, or widen the rules first.
What never syncs
Section titled “What never syncs”Regardless of configuration:
.gitdirectories — per-file last-writer-wins would corrupt a repository. If git is the content you want synced, you want git, not BearDrive..DS_Store.- The
.bdrive/settings directory — and it holds no credentials; the session token stays in~/.bdrive. - BearDrive’s own temp files (
.bdrive-tmp-*). - Nested mounts — a subdirectory with its own
.bdrive/config.jsonsyncs only through its own project. The parent never scans into it, writes over it, or propagates deletes for it. - Empty directories — not tracked, the same as git.
A note on secrets
Section titled “A note on secrets”.bdriveignore is the mechanism for keeping .env* and key material out, and
the seeded default covers the common cases. But treat it as hygiene, not a
security control: any org member can mint a public link for any synced file.
Secrets belong in a secret manager, not in a folder you hand to agents.
Minting a share link is the one place the hub reads the bytes first: it scans
the first 1 MiB for credential-shaped strings (AWS access key, private key
block, GitHub/Slack/GitLab/OpenAI token) and refuses, naming the rule and the
line but never the matched text. bdrive share --force — or Share anyway
in the web UI — overrides it. Know what that check does not cover: it runs
at the moment you share, and a link serves the file’s latest content
forever, so a key written into an already-shared file is never caught. It is a
last-line backstop, not a reason to sync a folder you wouldn’t otherwise.