-
Notifications
You must be signed in to change notification settings - Fork 0
Brain Cloud Sync
Federation makes separate brains readable across projects. Brain Cloud Sync makes one brain collaborative across a team. The move is deliberately minimal: when you turn cloud sync on, dreamcontext syncs the whole project — your code, .claude/, and the brain nested under _dream_context/ — to the project's own GitHub origin on the current branch, and git becomes the sync transport. Nothing else changes: the brain is still plain markdown and JSON, edited by the same CLI and dashboard, read by the same snapshot. Git is a transport, not a new database. Because .claude/ and _dream_context/ already live in the code repo, they travel together — there is no separate brain repo and no symlink layer to maintain.
full-repo (cloud sync on) makes the whole project folder the synced unit, pushed to its own origin on the current branch. in-tree (cloud sync off) commits the brain inside the code repo on sleep and never auto-pushes — it is the safe default, because committing local checkpoints is harmless where pushing to a shared remote is a decision. The scrub gate (below) runs in both. full-repo also refuses on a detached HEAD and force-writes the machine-local brain excludes into the project-root .gitignore before every whole-project stage, so git add -A never leaks the sync lock or secrets.
Every dreamcontext sleep done runs fetch → merge → commit → push against the project's origin, and a session-start background pull (non-blocking, detached) keeps you current on the way in. A sync failure never fails the sleep — consolidation is the primary job and the push is best-effort on top of it. A manual dreamcontext brain sync does the same cycle on demand, and the /dream-sync skill drives the agent half of a conflicted merge.
A plain git merge is wrong for markdown-plus-frontmatter task and knowledge files — two people editing the same task's changelog is a routine, resolvable event, not a conflict to abort on. So the merge is split. Deterministic files resolve themselves: JSON (changelog, releases, config, taxonomy) and task status/changelog merge by rule (changelog entries union, the furthest status along the lifecycle wins). Prose conflicts defer to an agent: when two people edit the same section of a knowledge or feature file, the sync writes base/ours/theirs snapshots plus a conflict report, aborts back to a clean committed tree, and sets pendingAgentMerge. The /dream-sync skill (or the SessionStart snapshot) surfaces the pending merge; the agent reads the three snapshots, writes the real semantic merge, and hands back through a --resume/--continue loop that re-scrubs and pushes. Real code conflicts go to the human: a conflicting file outside _dream_context/ is left with native git markers for your editor — never semantically merged, never sent to the agent. This agent-on-conflict design was wanted from day zero so the full-sync phase was never a rewrite.
Two security invariants are non-negotiable. First, the token is never embedded in the remote URL — that would persist it in .git/config in plaintext. Every git network call runs through GIT_ASKPASS pointed at a 0600-at-create temp file (the path travels in the environment, the token never does, and the file is unlinked in a finally), with -c credential.helper= disabling any persisted helper. Second, a scrub gate runs before every commit and push — in-tree commits, the whole-project full-repo push, and post-merge results alike. BLOCK-tier hits (a staged ghp_-plus-36-chars token) abort loudly everywhere; WARN-tier hits (absolute local paths) block only in headless pull-only mode, where no human is watching the auto-commit, and stay non-blocking in foreground use. Because full-repo stages the whole project with git add -A, the project-root .gitignore is force-written (gitignore-first) with the machine-local brain state and secrets under _dream_context/ before anything is staged.
Every machine builds its own recall index, embeddings, and caches over the shared brain, all gitignored (.brain-local.json) and rebuilt after each pull, so per-machine derived state never pollutes the repo or breeds merge noise. Personal attribution rides the existing multi-people awareness (the people/ roster and its per-person constitutions, person:<slug> tags, changelog authors) rather than a per-person file namespace, so the brain stays one shared set of files instead of task-alice.md / task-bob.md forks.
The launcher wraps all of this without a terminal: a device-flow GitHub login (with a PAT fallback), a Settings "Cloud sync" toggle that turns whole-project sync on/off (the master switch), a team-updates badge fed by a cache-only endpoint, and a one-click "Resolve with AI" for a deferred prose merge. When the project has no origin, the same panel offers Create new (a fresh private-by-default repo wired as origin) or Connect existing — so a project can go from no remote to synced without dropping to a shell — then lays the gitignore-first excludes and runs the first push. The server routes call the same in-process sync functions the CLI uses — not a shell-out to the CLI — so the desktop and terminal paths share one implementation.
- Why It Exists
- The Problem in Depth
- The Architecture
- The Hook Mechanism
- The Sleep Cycle
- Neuroscience-Inspired Memory
- The Dashboard
- Project task overrides
- Council Debates
- Memory Recall (BM25 over the curated corpus)
- Lab (Insights)
- Automations
- Federation
- Brain Cloud Sync
- Linked Repos
- Obsidian Integration
- CLI Design
- Install & Update
- The Desktop App
- Design Tradeoffs
- What Comes Next