# Mosaic Framework Constitution — Synthesis v1 (Chief Architect Ruling) **Status:** Canonical design. Resolves the seven-position debate (`debate/position-*.md`, `debate/rebuttal-*.md`) against the BRIEF (`BRIEF.md`) and the real framework tree at `packages/mosaic/framework/`. This document is the single design of record for the alpha. A PRD derives from it; implementation derives from the PRD. **Author:** Neutral Chief Architect. **Scope:** DQ1–DQ5 of the BRIEF, plus the two release-blockers the debate surfaced outside the DQ frame (LICENSE, hardcoded credential path). --- ## 0. Where the conference actually converged Seven lenses, near-unanimous on the easy 80%. I am banking the consensus as settled and spending the ruling on the contested 20%. **Settled (all or nearly all papers agree — adopted without further debate):** 1. Introduce an explicit **Constitution** layer (framework-owned, immutable law) distinct from persona (SOUL) and operator profile (USER). (every paper) 2. Split content by **ownership × upgrade-fate × residency**, not by topic. (architect §1.2, devex DQ1, aiml DQ1, coder DQ1, contrarian DQ1) 3. **Delete `defaults/SOUL.md`** (the "Jarvis"/"PDA" file). Persona ships only as `templates/SOUL.md.template`, generated at init. `install.sh:232-241` already refuses to seed it. (every paper) 4. **Subtraction before structure:** create the Constitution *by extraction and deletion*, never by addition. A fifth restatement on top of four existing ones yields five disagreeing law files. (contrarian, endorsed in every rebuttal) 5. **A blocking CI grep** for personal data + dead paths is the only durable anti-regression control. (every paper) 6. **"Hooks are the real enforcement; prose is the spec"** — promote the repo's own `prevent-memory-write.sh` lesson (`runtime/claude/RUNTIME.md:30-32`) to Constitution doctrine. (devex DQ4, contrarian DQ5, aiml §1.2, coder, steward, moonshot) 7. **Remove framework-owned files from `PRESERVE_PATHS`** so gate updates reach existing installs. (every paper — this is the literal drift bug) 8. **An enforced resident-token budget**, or the new Constitution re-bloats into the old 155-line `AGENTS.md` within two releases. (aiml DQ5, endorsed by devex, coder, moonshot, contrarian) 9. **Fix the false `defaults/AGENTS.md:11` claim** ("already in your context… do not re-read") — it is provably false on a bare `claude` launch and teaches agents to skip the gates. (coder, contrarian, devex, aiml, moonshot) **Verified live facts (I re-ran the greps, did not trust the papers):** - `tools/_lib/credentials.sh:19` AND `tools/git/detect-platform.sh:89` both default to `$HOME/src/jarvis-brain/credentials.json` — a private path shipped as an executable default. - `mosaic/rails/git/` appears in **12 shipped template files** (all of `templates/agent/` + `projects/*`), while `defaults/AGENTS.md:30` uses `tools/git/` and `install.sh:192-194` actively deletes a stale `rails` symlink. A dozen templates emit a command pointing at a path the installer removes. - **No LICENSE** at monorepo root, `packages/mosaic/framework/`, or as a `package.json` field. **Contested 20% (resolved in the Decision Records, §3):** number of layers; physical-directory split vs flat files; one Constitution *file* vs a `constitution/` *directory*; 3-way merge vs `.local` overlays; YAML front-matter + hash-refusal vs structural enforcement; capability-manifest JSON vs prose table; injection-by-value vs self-load. --- ## 1. The Canonical Layer Model Five **concerns**, collapsed into **four owned layers** plus a non-resident governance spec. The collapse resolves the architect-vs-contrarian layer-count fight: the architect's "Standards" and "Operator Policy" are real *concerns* but do not earn *separate sovereign documents* — Standards is framework law that a deployment tightens via an additive overlay; Operator Policy is a section of USER plus optional `policy/` example files. (Decision D1, D2.) A layer boundary is legitimate **iff** the two sides differ in **owner**, **upgrade-fate**, OR **residency**. This single test (architect §1.2, banked by every rebuttal) does all the work. | # | Layer | Owns | Owner | Upgrade fate | Residency | Canonical deployed path | |---|-------|------|-------|--------------|-----------|--------------------------| | **L0** | **Constitution** | Irreducible non-negotiable law: hard gates, escalation triggers, block-vs-done, mode declaration, precedence rule, the "hooks are the gate" doctrine, the "no operator context in framework PRs" rule | Framework | **Overwritten wholesale every upgrade.** Never in `PRESERVE_PATHS`. User MUST NOT edit. | **Always resident**, byte-budgeted | `~/.config/mosaic/CONSTITUTION.md` | | **L1** | **Standards & Guides** | How to do the work well: secrets/ESO, trunk-based git, image tagging, the E2E procedure, QA matrix, orchestrator protocol, all `guides/*` | Framework (deployment may **tighten** via overlay) | Overwritten; user delta lives in `STANDARDS.local.md` / never edits guides | `STANDARDS.md` resident; `guides/*` on-demand | `~/.config/mosaic/STANDARDS.md`, `~/.config/mosaic/guides/*` | | **L2** | **Persona (SOUL)** | Agent name, tone, role, communication style, persona-scoped principles | User (init-generated) | **Never overwritten.** Generated from template. | Always resident, byte-budgeted | `~/.config/mosaic/SOUL.md` (+ optional `SOUL.local.md`) | | **L3** | **Operator (USER)** | Human name, pronouns, timezone, accessibility/accommodations, comms prefs, projects, **operator policy** (e.g. merge-authority delegation), operator tool paths | User (init-generated) | **Never overwritten.** | Always resident, byte-budgeted | `~/.config/mosaic/USER.md` (+ optional `USER.local.md`, optional `policy/*.md`) | | **L4** | **Project / Runtime mechanism** | Per-repo `AGENTS.md` deltas; harness-specific *mechanism only* (subagent syntax, hook config, MCP wiring, injection tier) | Repo / framework | Project file user-owned; runtime mechanism overwritten | Project loaded in-repo; runtime resident, ~15 lines | `/AGENTS.md`, `~/.config/mosaic/runtime//RUNTIME.md` | | — | **Layer-Model spec** (governance) | The definition of these layers + precedence + "what may live in L0" | Framework maintainers | Source-only, **never deployed** | Not resident | `packages/mosaic/framework/constitution/LAYER-MODEL.md` | `AGENTS.md` (deployed) is **not a layer** — it is the thin **load-order dispatcher + Conditional Guide Loading table** that routes to L0–L4. It is framework-owned and overwritten on upgrade. ### Precedence — typed two-axis, not a flat stack A flat "L0 > L1 > L2 > L3" ordering is a trap (contrarian DQ1, devex DQ1): persona and law are not on the same axis. The governing rule, stated **verbatim in L0**, in one sentence each: > **Safety axis (gates, integrity, destructive actions):** L0 Constitution is supreme. Nothing in > STANDARDS, SOUL, USER, `policy/`, project `AGENTS.md`, runtime, or any injected reminder may relax, > suspend, or contradict a Constitution gate. A lower layer may only make behavior **stricter**, never > more permissive. > > **Taste axis (tone, formatting, verbosity, iconography):** the operator layers (SOUL/USER) win over > generic framework or model defaults. The framework has no legitimate opinion on style. This generalizes the two good instincts already half-present in the tree (`SOUL.md:48`, injected reminders never expand permissions; `SOUL.md:32`, user formatting wins) and makes precedence **total and one-sentence-holdable** rather than scattered across runtime files. (D3.) ### Enforcement strength is ranked, not chosen Resolving the conference's central fault line (injection-by-value vs self-load vs metadata-gate): the three are **not alternatives** — they are a **priority ladder** (aiml §3, devex §3, architect §3, coder, contrarian): ``` mechanical (hook/CI) > resident-by-value (system-prompt injection) > file-read (self-load fallback) ``` 1. **Mechanical first.** Every *checkable* gate becomes a hook or CI check (no-force-merge, green-CI-before-done, no-hardcoded-secrets, no-PII, no-dead-paths, no-unrendered-template-tokens). A hook does not compete for attention or care about injection tier. This *drains* prose out of the resident core, which is the precondition that makes the next tier work. 2. **Resident-by-value second.** The irreducible *non-checkable* gates (the ones governing *when the agent stops* — block-vs-done, escalation, completion-definition) are injected by value at primacy on the strongest channel each harness offers, restated as a ≤5-bullet anchor at the recency position (bottom). 3. **File-read third (fallback).** `AGENTS.md` says: *"If `CONSTITUTION.md` is not already in your context, READ IT NOW."* — conditional, never the false unconditional "already loaded." This is the safety net for harnesses/launches where injection silently failed; it is explicitly the weakest tier, never the primary mechanism. --- ## 2. File-by-File Plan (what content moves where) ### 2a. New files | New file | Content | Source of content | |----------|---------|-------------------| | `~/.config/mosaic/CONSTITUTION.md` (ships as `defaults/CONSTITUTION.md`) | **L0, one flat file, ~70–90 lines.** The 13 hard gates *minus* the operator-policy clause (see below); the 5 escalation triggers; block-vs-done; mode declaration protocol; the one-sentence precedence rule (both axes); the "hooks are the gate" doctrine; the "no operator context in framework PRs" rule; a single pointer line to the guide index. **Gates keep full unambiguous wording; procedure (wrapper paths, flags) moves to L1.** | Extracted from `defaults/AGENTS.md:23-87` | | `packages/mosaic/framework/constitution/LAYER-MODEL.md` | The §1 layer model + precedence + "what may live in L0" governance spec. **Source-only, never deployed, never resident.** | This document | | `packages/mosaic/framework/examples/personas/execution-partner.md` | The sanitized, placeholdered essence of the Jarvis persona (a worked example, copied on request, never auto-loaded) | `defaults/SOUL.md` (sanitized) | | `packages/mosaic/framework/examples/overlays/e2e-loop.json` | The sanitized, placeholdered essence of `jarvis-loop.json` (`~/src/` placeholders) | `runtime/claude/settings-overlays/jarvis-loop.json` | | `packages/mosaic/framework/examples/policy/merge-authority.example.md` | The operator-policy merge-authority decision, as an *example* operator policy a deployment may adopt | `defaults/AGENTS.md:37` ("Policy: Jason, 2026-06-11") | | `LICENSE` (monorepo root) + `packages/mosaic/framework/LICENSE` | MIT license text | new (D8) | | `CONTRIBUTING.md` (framework package) | Layer model, PII/secrets prohibition, the dedup rule, how to add a harness adapter, the re-contamination rule | new (D8) | | `tools/quality/scripts/verify-sanitized.sh` | The blocking CI grep (PII + home paths + dead `rails/` + unrendered tokens) | new (D6) | ### 2b. Files that shrink / change role | File | Change | Why (DQ) | |------|--------|----------| | `defaults/AGENTS.md` | Gut from 155 lines to a **~50-line dispatcher**: load order + Conditional Guide Loading table + the self-bootstrapping "read CONSTITUTION.md if not resident" line. **Zero restated gates.** Remove from `PRESERVE_PATHS`. | DQ1, DQ5 | | `defaults/STANDARDS.md` | Stays L1, but: drop the **"Master/slave model"** framing (line 5); stop re-asserting gates that now live in L0; end with an additive include convention for `STANDARDS.local.md`. Remove from `PRESERVE_PATHS`. | DQ1, DQ3, DQ5 | | `defaults/TOOLS.md` | Delete the `jarvis-brain` MANDATORY rule (line 40). Generic tool index only; operator-specific rules move to the operator's `USER.md`/project `AGENTS.md`. | DQ2 | | `templates/SOUL.md.template` | Already clean and correct. Keep. Ensure every `{{TOKEN}}` has a non-empty default in `mosaic-init` (no placeholder can survive into a resident file). | DQ2 | | `templates/agent/AGENTS.md.template` (+ 11 sibling/project templates) | **Delete the restated Hard-Gates block.** Replace with one line: *"This project is governed by `~/.config/mosaic/CONSTITUTION.md`. Add only project-specific extensions below."* **Fix all `rails/git/` → `tools/git/`.** | DQ4, DQ5 | | `runtime/{claude,codex,pi,opencode}/RUNTIME.md` | Strip restated policy (wrappers-first, mode declaration, caution-doesn't-override-gates). Reduce to **harness mechanism only** + a one-line reference to `CONSTITUTION.md`. | DQ4, DQ5 | | `tools/_lib/credentials.sh:19`, `tools/git/detect-platform.sh:89` | `$HOME/src/jarvis-brain/credentials.json` → `${MOSAIC_CREDENTIALS_FILE:?MOSAIC_CREDENTIALS_FILE must be set}` (fast-fail, consistent with the framework's own `STANDARDS.md:35` ban on `${VAR:-default}` for required values). Document the env var in `USER.md.template` under `## Tool Paths`. | DQ2 (blocker) | | `guides/ORCHESTRATOR.md` (lines 99,111,152), `guides/TOOLS-REFERENCE.md`, `guides/BOOTSTRAP.md` | Replace `jarvis-brain/docs/templates/` with `~/.config/mosaic/templates/` (the canonical install path). | DQ2 | ### 2c. Files deleted / moved out of the shipped package | File | Action | Why | |------|--------|-----| | `defaults/SOUL.md` | **Delete.** Persona is generated at init from the template only. | Primary contamination vector | | `runtime/claude/settings-overlays/jarvis-loop.json` | **Delete**; sanitized essence → `examples/overlays/e2e-loop.json` | Personal project map | | `defaults/AUDIT-2026-02-17-framework-consistency.md` | **Move** to `docs/` at monorepo root (maintainer artifact, not agent context) | Not framework content | --- ## 3. Decision Records Each contested question, resolved with Decision / Rationale / Rejected. ### D1 — Layer count: four owned layers (+ a non-resident spec), not five, not three - **Decision:** L0 Constitution / L1 Standards+Guides / L2 Persona / L3 Operator / L4 Project+Runtime. "Operator Policy" is a section of L3 (USER) plus optional `policy/*.md`, not a fifth sovereign layer. - **Rationale:** The owner×fate×residency test legitimizes splitting law from persona from operator (so the "Policy: Jason, 2026-06-11" clause at `defaults/AGENTS.md:37` *must* leave L0 — different owner, different upgrade-fate). But it does **not** legitimize a standalone `policy/` *layer*: no paper named a failure mode that "USER.md has a `## Operator Policy` section" cannot handle (steward §2b). Three layers (contrarian/coder) under-serves the merge-authority extraction; five (architect) re-creates the very `AGENTS.md`/`STANDARDS.md` overlap that already drifts (contrarian §2c). Four is the count where every boundary passes the test and none is gratuitous. - **Rejected:** Architect's five layers (Standards + Operator-Policy + Deployment as separate sovereigns) — taxonomy inflation; more documents to keep non-duplicative is the disease, not the cure. Contrarian/coder's strict three — loses the operator-policy seam the merge-authority leak proves is needed. ### D2 — One flat `CONSTITUTION.md`, not a `constitution/` deploy directory - **Decision:** L0 deploys as a **single flat file** `~/.config/mosaic/CONSTITUTION.md`. The `constitution/` directory exists **only in the package source**, holding the non-deployed `LAYER-MODEL.md` governance spec. - **Rationale:** A directory of `GATES.md`+`DELIVERY.md`+… multiplies load-order failure points — on a weak-injection harness an agent can load file 1, get pulled into the task, and operate with incomplete gates (coder §3, devex "load-order indirection"). You can anchor a *file* at primacy+recency; you cannot anchor a *directory* (aiml). One file is injected/read whole and is impossible to partially load. The separation-of-concerns the directory camp wants is real but is a *post-alpha evolution target*, triggered only if L0 exceeds its budget. - **Rejected:** Architect/steward/moonshot `constitution/` deploy directory — correct intuition, wrong alpha granularity; reserve for v2. ### D3 — Precedence is structural (placement + overwrite + hooks), not metadata/hash-enforced - **Decision:** Enforce L0 supremacy and immutability through (a) **directory/overwrite mechanics** — L0 is overwritten wholesale every upgrade, so a user edit simply does not survive; (b) **placement** — L0 at primacy, ≤5-bullet anchor at recency, SOUL/USER in the low-attention middle; (c) **hooks/CI** for every checkable gate. No YAML front-matter, no content-hash launch gate. - **Rationale:** Front-matter (`mosaic-layer: 0`, `mosaic-override: forbidden`) spends the single most valuable primacy-position attention slot on key-value pairs whose audience is a bash script, and teaches the model that override-rules are parseable properties — an injection surface (aiml §2.1, steward §2a, coder §2b, devex §2a). Hash-refusal-on-launch is invisible on the exact direct-launch paths where drift happens (it only runs inside `mosaic `), bricks the one user who customized, and false-positives on every mid-upgrade state and CRLF/trailing-newline diff (every rebuttal rejected it). Immutability-by-overwrite needs zero hashes: overwrite *is* the guarantee. - **Rejected:** Moonshot's front-matter + "launcher refuses to start on hash mismatch"; steward's `--check-constitution`-as-error. A **post-hoc advisory** `mosaic doctor` drift *warning* (never a launch block, never on model-visible bytes) is acceptable and kept. ### D4 — Upgrade-safe customization = additive `.local` overlays, not 3-way merge - **Decision:** Framework-owned files (L0, L1 `STANDARDS.md`+`guides/*`, `AGENTS.md`, runtime) are **overwritten wholesale** on upgrade. User customization that must survive lives in **never-touched additive overlays**: `SOUL.local.md`, `USER.local.md`, `STANDARDS.local.md`, optional `policy/*.md`. One overlay mechanism, **owned by the launcher/composer**, resolved *before* injection — not a per-guide variant, not an inert `` comment. `TOOLS.md` (generated then hand-tuned) is the one file that may keep the existing `.bak.` backup-on-regenerate behavior. - **Rationale:** The directory/overwrite split makes 3-way merge **unnecessary** — there is nothing to merge when framework files are clobbered and user deltas are separate (architect §2.2, contrarian §2a). Markdown has no merge semantics: `git merge-file` resolves by line, so a reflowed paragraph produces phantom conflicts, and a half-resolved merge can leave `<<<<<<<` markers **inside the agent's resident identity file** — the same erratic-behavior class as a half-rendered `{{TOKEN}}` (aiml §2.3, moonshot §1). A 3-way merge also needs a `base` that **no current install has** (contrarian §2a) — most fragile exactly at the alpha boundary the BRIEF says must not break. Interactive merge prompts hang headless launches. The three papers that invented *different* overlay schemes (coder per-guide, aiml/devex per-layer, contrarian include-comment) must converge: devex (§2b) correctly rules that **per-layer overlays composed by the launcher** is the only one that does not silently no-op on a pointer harness. - **Rejected:** Architect/devex 3-way `mosaic-reconcile`; moonshot interactive `[Y/n]` auto-merge; contrarian's inert include-comment; coder's per-guide `.local.md` (guides are L1, referenced not forked). Per-layer template-version markers survive **only as a `doctor` advisory signal** ("your SOUL was generated from template v2; v4 ships — review `examples/`"), never as a merge trigger. ### D5 — Cross-harness: single L0 source + capability-resolved adapters + tiered injection + a smoke test - **Decision:** L0 is one canonical text. Adapters carry **mechanism only**. The Constitution speaks in **capability verbs** ("use structured reasoning before planning"); each harness adapter binds the verb to a concrete tool and declares whether absence is a hard stop. For the **alpha**, that binding is a **single markdown table** in the adapter docs (not a JSON manifest). Injection is **tiered and honest about asymmetry**: Tier-1 (system-prompt append: Pi, `mosaic claude`/`codex`) injects L0 by value; Tier-3 (bare `claude`/`codex`/`opencode` pointer) carries the ≤5-bullet irreducible-gate summary **inline** plus the read instruction. A **CI smoke test** launches each harness path and asserts the irreducible gates are present in the effective context — the control that makes "enforced across harnesses" *true* rather than aspirational. - **Rationale:** The four harnesses genuinely do not inject symmetrically (devex §3, verified: `adapters/pi.md:14-16` system-prompt; Claude append-or-pointer with competing harness ``s; Codex/OpenCode instructions-file). "Byte-for-byte everywhere" is an aspiration, not a switch. The capability-verb split kills the **already-live** contradiction — `defaults/AGENTS.md:143` says sequential-thinking MCP is REQUIRED-or-stop, while `adapters/pi.md` says native thinking replaces it (aiml §1.3). But a bespoke `capabilities.json` schema + validator for a four-row, three-axis table is over-engineering at alpha (coder §2c, contrarian §2c): a markdown table conveys the same and catches errors at review time. The JSON manifest is a good v2 evolution once there are 6+ harnesses. - **Rejected:** Devex's `adapters/.capabilities.json` machine-read manifests **for the alpha** (kept as a v2 roadmap item); moonshot's "Pi is the reference harness" (inverts single-source-of- truth — defines abstract law in terms of one runtime's affordances; architect §2.3). Moonshot's `COMPLIANCE.md` harness×gate **matrix as documentation** is kept (good for visibility); machine-read- and-enforced is not. ### D6 — Sanitization: per-layer strategy + a blocking CI gate that closes the *class*, not the tokens - **Decision:** Per-layer, not one global choice (contrarian DQ2): **L0/L1 ship generic-and-complete** (law has no PII once leaks are removed; empty law = no gates = dangerous); **L2/L3 ship as templates only**, generated at init (delete `defaults/SOUL.md`); **examples/ ship the worked Jarvis config** sanitized + placeholdered (`~/src/`), copied on request, never auto-loaded. The blocking CI gate (`verify-sanitized.sh`) fails the build on the **structural class**, not just current tokens: `jarvis|jason|woltje|\bPDA\b`, plus `~/src/` / `/home//` absolute home paths, plus dead `/rails/` tokens, plus unrendered `{{...}}`/`${...}` in resident files — over `defaults/ guides/ templates/ runtime/ adapters/`, excluding `examples/`. - **Rationale:** The contamination reached ~29–55 files because `defaults/README.md:7`'s prose promise has no enforcement; a CI grep is ~15 lines and is the only durable control (every paper). It must close the *class* because the primary author of future framework PRs is an agent running with *some* operator's SOUL/USER in context — a denylist of today's tokens won't catch tomorrow's operator (steward §3, moonshot "biggest risk"). The unrendered-token check closes the half-rendered-template failure class (aiml §2.2): a `SOUL.md` containing `You are **{{AGENT_NAME}}**` makes the model adopt the literal braces. - **Rejected:** Generic-defaults for persona (recreates the bug — "Assistant" becomes the new "Jarvis"; devex DQ2); empty-defaults for persona (terrible first-run); prose-only sanitization (already proven to decay). ### D7 — Resident-token budget: budget the *container* by line count, keep gate *wording* intact - **Decision:** Enforce a **resident line-count ceiling in CI + `mosaic-doctor`** over the always-resident set (`CONSTITUTION.md` + `AGENTS.md` index + `SOUL.md` + `USER.md` + the resident RUNTIME slice). Budget the *container*, not the constitution's clarity. Gates keep full unambiguous wording; *procedure* (wrapper paths, `--purpose` flags) moves to on-demand `E2E-DELIVERY.md`. - **Rationale:** A new top-level `CONSTITUTION.md` is psychologically tempting to fill and will re-bloat to 155 lines within two releases without a mechanical forcing function (aiml "biggest risk," moonshot §1). But moonshot's "exactly 500 words" is asserted, not derived, and is **self-defeating**: gate #13 alone is ~110 words, so a 500-word cap forces *paraphrasing the gates* — paraphrased law is the exact drift vector we are killing (aiml §2.2). Budget the resident *set* by line count (the mechanism several papers converge on); let each gate keep its wording; push procedure to guides. - **Rejected:** Moonshot's "exactly 500 words for CONSTITUTION.md" — right instinct, wrong unit; forces lossy compression of normative text. ### D8 — Two non-DQ release blockers ship in the alpha DoD: LICENSE and the credential path - **Decision:** Add **MIT** `LICENSE` (monorepo root + framework package) + `"license": "MIT"` in `package.json`, on day zero. Fix both hardcoded `$HOME/src/jarvis-brain/credentials.json` defaults to fast-fail env vars. Ship `CONTRIBUTING.md` (with the operator-data-hygiene section) with the alpha, not deferred. - **Rationale:** "Public does not mean licensed" — under Berne, an unlicensed public repo is all-rights-reserved, so every fork/contribution has unclear IP status, and retroactively licensing after the alpha creates ambiguity about the pre-license period (steward, the only paper to surface this; endorsed by architect §1.3, devex §1c). A hardcoded private credential path shipped as an executable default is worse than the persona contamination — it is in the *tooling* layer and it is runnable. MIT maximizes adoption and signals genuine open infrastructure. - **Rejected:** Deferring LICENSE/CONTRIBUTING to "pre-stable" — the alpha will have downstream users; the window to fix legal status cleanly closes at the alpha tag. AGPL/Apache considered; MIT chosen for adoption (revisitable, but pick one now). --- ## 4. Sanitization plan for the public package **Ships generic (PII-free, complete, in the package):** `defaults/CONSTITUTION.md`, `defaults/AGENTS.md` (dispatcher), `defaults/STANDARDS.md`, `defaults/TOOLS.md` (generic index), all `guides/*` (purged), `templates/*` (token-only), `examples/*` (placeholdered worked configs), `runtime/*/RUNTIME.md` (mechanism-only), `adapters/*.md`, `LICENSE`, `CONTRIBUTING.md`. **Generated at `mosaic init` (never in the package, gitignored downstream):** `~/.config/mosaic/SOUL.md`, `USER.md`, `TOOLS.md` (rendered from templates), `*.local.md` overlays, optional `policy/*.md`, per-harness runtime copies. **Deleted / relocated from the shipped tree:** `defaults/SOUL.md` (delete); `runtime/claude/settings-overlays/jarvis-loop.json` (delete → `examples/overlays/`); `defaults/AUDIT-2026-02-17-*.md` (move to monorepo `docs/`). **Mechanical gate (the durable control):** `tools/quality/scripts/verify-sanitized.sh`, wired into `.woodpecker.yml`, blocking. Fails on: operator tokens; absolute home paths (`~/src/`, `/home//`); dead `/rails/` paths; unrendered `{{...}}`/`${...}` in resident files. Excludes `examples/`. Plus a structural-firewall **L0 rule**: *"When proposing a framework PR or capturing a `framework-improvement`/`tooling-gap`, you MUST NOT include content derived from SOUL.md, USER.md, or operator-specific context; if you cannot express it operator-agnostically, it belongs in `policy/` or a project `AGENTS.md`, not the framework."* --- ## 5. Customization + upgrade-safety mechanism **The single sentence a user can now truthfully rely on:** *"Edit `SOUL.md`/`USER.md` and the `*.local.md` overlays freely — upgrades never touch them. Never edit `CONSTITUTION.md`/`STANDARDS.md`/ `guides/*`/`AGENTS.md` — they update automatically every upgrade. Want to change framework behavior? Add a `.local.md` overlay or a `policy/` file (tighten-only)."* **Mechanism:** 1. **Physical seam = ownership.** Framework-owned files are overwritten wholesale (`rsync` without an exclude); user-owned files (`SOUL.md`, `USER.md`, `*.local.md`, `policy/`, `TOOLS.md`, `memory`, `sources`, `credentials`) are the *only* `PRESERVE_PATHS` entries. **Remove `AGENTS.md` and `STANDARDS.md` from `PRESERVE_PATHS`** — this single change makes gate updates reach every existing install (the literal drift bug, contrarian §0/§3). 2. **Additive overlays, launcher-composed.** `mosaic compose-contract ` concatenates, in precedence order, base + `.local` deltas *before* injection, so the model receives one pre-merged blob and never runs a redundant read-merge ritual. (D4.) 3. **One global `FRAMEWORK_VERSION` integer + linear migrations** (the existing `install.sh:160-202` scaffold). No per-layer version matrix — it is a combinatorial test cliff no single maintainer will cover (contrarian, steward §2b). Per-layer template versions survive only as a `doctor` *advisory*. 4. **Migration v2→v3 (backward-compatible, the BRIEF's hard constraint):** - Snapshot `~/.config/mosaic/` → `~/.config/mosaic/.backup-v2/` before touching disk. - Install `CONSTITUTION.md` as a **new** file nothing previously owned (avoids the reclassification catastrophe moonshot §2 flags — we do **not** try to diff/split a user-edited flat `AGENTS.md` into "framework vs user" content). - Install the slimmed `AGENTS.md` dispatcher; remove `AGENTS.md`/`STANDARDS.md` from `PRESERVE_PATHS` going forward. - The agent self-loads L0 from `AGENTS.md` regardless of launcher injection (the self-bootstrap fallback), so even a stale-pointer install gets the gates. 5. **The migration is the biggest risk; gate it with a falsifiable test matrix** (contrarian §3, the *decider*, not a mitigation). Alpha cannot tag until three fixtures pass with **no interactive prompt, no hang**: (1) fresh install; (2) legacy-flat user-edited install — law moves, user files survive; (3) user-tuned-standard install — change survives as `STANDARDS.local.md`, framework `STANDARDS.md` updates. Smallest design that passes all three wins (it does: `rsync` + linear migration + overlays + a 15-line grep — zero new subsystems). 6. **Detection without enforcement:** `mosaic doctor` reports drift/unrendered-tokens/budget-overflow as **advisories** (warn, never block launch). `--check-constitution` is an opt-in diagnostic, not a gate (D3). --- ## 6. Cross-harness strategy (single source of truth + adapters) **Single source:** L0 `CONSTITUTION.md` is the one law text. No harness gets a forked copy; runtime files and project templates **reference** it, never restate it (kills the four-way duplication and the live `rails/`-vs-`tools/` + sequential-thinking-except-Pi contradictions). **Adapter contract (mechanism only):** an `adapters/.md` / `runtime//RUNTIME.md` may specify **only** (a) the injection channel + tier this harness uses, and (b) how L0's **capability verbs** map to concrete tools (subagent syntax, MCP wiring, hook config). The Constitution says *"use structured reasoning before planning"*; the Claude adapter binds it to `mcp:sequential-thinking` (gate=true), the Pi adapter to native thinking (gate=false). For the alpha this binding is a markdown table; JSON manifests are a v2 item once 6+ harnesses exist. **Tiered, honest injection (the four harnesses are not symmetric):** | Harness | Channel | Tier | L0 delivery | |---------|---------|------|-------------| | Pi | `--append-system-prompt` (+ no hook backstop) | 1 | By value at primacy; keep L0 tiny — resident fidelity is Pi's *only* enforcement | | `mosaic claude` / `mosaic codex` | system-prompt append | 1 | By value at primacy + ≤5-bullet recency anchor | | Codex / OpenCode (instructions-file) | written file | 2 | Resident-ish; self-load line as backup | | bare `claude`/`codex`/`opencode` | thin pointer | 3 | Pointer carries the ≤5-bullet gate summary **inline** + "READ CONSTITUTION.md NOW" — never the false "already loaded" | **Mechanical backstop:** every hookable gate is a hook where the harness supports one (`prevent-memory-write.sh` precedent); Codex/OpenCode hook parity is a **tracked gap** in the compliance doc, not a silent inconsistency. A **CI smoke test** asserts the irreducible gates are resident on every harness path — the control that makes the cross-harness claim true. --- ## 7. Alpha Definition of Done (derived, for the PRD) Blocking: MIT LICENSE + `package.json` field; credential-path fast-fail fix; `defaults/SOUL.md` + `jarvis-loop.json` deleted; `rails/`→`tools/` fixed in 12 templates; `verify-sanitized.sh` green and wired to CI; `CONSTITUTION.md` extracted (gates one place, dispatcher `AGENTS.md` self-bootstraps); `AGENTS.md`/`STANDARDS.md` out of `PRESERVE_PATHS`; resident line-count budget enforced; per-layer overlay + compose step; migration v2→v3 passing the 3-fixture matrix with no hang; cross-harness smoke test green; `CONTRIBUTING.md` with operator-hygiene section; tag the alpha. PRD precedes implementation. **Explicitly deferred to post-alpha (v2):** `constitution/` deploy directory; `adapters/.capabilities.json` JSON manifests; 3-way merge reconciliation; per-layer version stamps as a migration driver; DCO CI.