11. Brain wiring: the global user registry is the default source of truth¶
- Status: Accepted
- Date: 2026-07-01
- Deciders: kristof (owner), Claude (orchestrator)
- Relates: ADR-0008, ADR-0009, distribution, issue #14
Context¶
A project → brain mapping decides which brain a working directory reads and writes. The
resolver (packages/core/src/registry.ts, resolveBrainDir) has always supported five layers,
in order: (1) a per-project .commonwealth/brain marker file, (2) a directory that is itself a
brain, (3) the global user registry ~/.commonwealth/registry.json (a prefix → brain map),
(4) the COMMONWEALTH_BRAIN_DIR env var, (5) nothing.
Onboarding, however, wired brains by dropping the layer-1 marker into every synced folder.
That scatters a .commonwealth/ directory into each project — clutter in a solo checkout, and a
marker that does not travel with the machine (it lives in the project, not the user's config).
Layer 3 already existed and is a better home for the default mapping: one global file, nothing
added to the project tree.
Decision¶
- The global user registry is the DEFAULT brain-wiring source of truth. Onboarding writes a
prefix → brainmapping into~/.commonwealth/registry.json(resolver layer 3) for each synced folder, instead of dropping a per-project marker. - The per-project
.commonwealth/brainmarker stays as an optional manual override.core.setBrainMarkerand resolver layer 1 are unchanged; a marker still resolves ahead of a registry mapping (layer 1 > 3) so a human can pin one project explicitly. - Convenience symlinks. Onboarding also drops
~/.commonwealth/brains/<name> → <brainDir>(where<name>is the basename of the brain directory) so a human canls/cdtheir brains. Symlink creation degrades gracefully — a real file/dir at the path is left intact, and unsupported/permission cases (Windows/EPERM/EACCES/ENOSYS) are reported, never thrown. @cmnwlth/coreowns the writes:addRegistryMapping(idempotent add/update, dedupe by expanded prefix),linkBrain(idempotent, non-clobbering symlink), plusdefaultRegistryPathanddefaultBrainsDirhelpers. The CLI'sregisterBrainonboarding step composes them.- No multi-brain-per-project yet. One prefix maps to exactly one brain.
- Brain identity is keyed off
.commonwealth/schema-version, not.commonwealth/config.json. The self-is-brain layer (resolver layer 2) previously identified a brain by the presence of.commonwealth/config.json. But the per-user scope config (ADR-0008) lives at~/.commonwealth/config.json, so walking up from any project under$HOMEmatched the home directory as a brain — shadowing the registry entirely (and only latent on machines that have runinit; CI has no such file, so the bug hid there). Identity now uses the brain-onlyschema-versionscaffold artifact, which the global scope dir never has.
Consequences¶
- One global file wires every project; no per-project
.commonwealth/clutter and the mapping is portable within a user's machine. ~/.commonwealth/brains/gives a human a browsable index of their brains.- Two override paths remain for special cases: the marker (layer 1) and
COMMONWEALTH_BRAIN_DIR(layer 4). - Two files live under
~/.commonwealth/:config.json(per-user scope allow/deny, ADR-0008) andregistry.json(project → brain routing). The README's Configuration section disambiguates them.
Alternatives considered¶
- Per-project marker as the default (the prior behavior) — rejected: it clutters every solo
checkout with a
.commonwealth/dir and the mapping does not live with the user's config. Kept only as an explicit manual override. - Multi-brain-per-project — deferred; not needed yet and it complicates resolution.
Supersedes nothing.