ADR-007 — Shared state has an explicit owner and a frozen mutation window
Every shared structure has one owner, one mutation window, and one freeze point.
Context
ClientManifest is created by build/, then implicitly mutated by dev/, then consumed by render/ — with no documented ownership or mutation contract. Agent and tool registries are similarly shared without defined ownership. This makes it impossible to reason about correctness across module boundaries, and quietly allows races in dev mode.
Decision
Every shared data structure has exactly one owner, one mutation window, and one freeze point. After the freeze, any write throws in strict mode (Object.freeze). When a structure must change (e.g. dev island rebuild), the owner creates a new instance and atomically replaces the reference — never mutating the currently-serving frozen instance. See data ownership for the full table.
Consequences
State transitions are visible in the type system: consumers receive Readonly<ClientManifest>; the freeze is structural, not just documented. Swap-on-change means request handlers always see a consistent snapshot, not a partially-updated manifest. Cost: dev/ must build a full new manifest on each island rebuild rather than patching the old one — acceptable given that manifests are small.