Private sync
Keep your global config and every project's private working notes (plans, kb, findings) in a single private git repo — synced across machines and cloud sessions — without ever committing any of it into the (often public) project repos.
This workflow is entirely opt-in — and it is not part of dotagents. init never
touches a project directory, and the two commands this model needs, link-project and
sync-project, are shipped by the private-sync overlay itself (commands and the
logic behind them). Installing the overlay is what makes them exist; a plain dotagents
has no private-sync surface at all.
The idea
Your global config store is a private git repo. Its root is the per-user config;
a projects/<name>/ tree inside it holds each project's private payload. For a
checked-out project, its .agents directory is a symlink into the store (the
project's .gitignore already excludes .agents per the Leakage rule, so the link
never lands in the public repo). <name> defaults to the project's basename, so a
local checkout and a cloud checkout of the same project resolve to the same store
entry.
Commands
dotagents init # base config
dotagents overlays add private-sync --source <overlays-checkout> # commands + kb + hooks
# link-project / sync-project come FROM that overlay -- run `overlays add` first.
python -m dotagents link-project . # symlink this project's .agents into its store
# (an existing real .agents/ is adopted on the
# first link; --copy mirrors it as a real dir
# for no-symlink systems)
python -m dotagents sync-project -m "msg" # git pull --rebase / commit / push the store
python -m dotagents sync-project --remote <url> -m init # one-command bootstrap
Where the store lives and how it reaches other machines are conventions, not requirements: the default store location is configurable, and a store that never leaves the machine is a perfectly valid setup.
Safety behaviors
- A project whose
.agentsis itself a git checkout is never adopted or copied back —link-project/sync-projectskip it (with a message) so a nested repo is never swallowed.link-project --forcebacks the checkout up (git state intact) and links the store instead. - Copy mode (
--copy) makes.agentsa real directory rather than a symlink;sync-projectcopies edits back into the store.
Cloud sessions
The private-sync overlay installs SessionStart / Stop hooks that clone or pull the
private repo and link/sync the project each session — register them in your runner's
settings (a ready-made snippet ships with the overlay).
For a fresh container with no config yet, point the web environment's setup-script field at the self-contained bootstrap shipped in this repo — it fetches the latest each start, so there is nothing to re-paste:
curl -fsSL https://raw.githubusercontent.com/<you>/dotagents/main/tools/cloud-setup.sh \
-o /tmp/dg-cloud-setup.sh && sh /tmp/dg-cloud-setup.sh
Note
Use curl … -o file && sh file, not curl … | sh: with a pipe the setup field's
exit code is sh's (0 on empty stdin), so a failed fetch is silently logged as
success. && propagates the curl failure instead.
The bootstrap authenticates (bypassing a hosted-runner github.com → proxy git
rewrite), clones/pulls the store, installs the CLI, and links the project — driven by
AGENTS_REMOTE / DOTAGENTS_AGENTS_TOKEN / DOTAGENTS_CLI_INSTALL
environment variables (the token is never committed). The full walkthrough ships with
the private-sync overlay.