docs(design): mosaic framework constitution — expert conference output
Some checks failed
ci/woodpecker/push/ci Pipeline failed

Conference of 7 experts (architect/moonshot/contrarian/coder/aiml/devex/steward)
debated layering, sanitization, upgrade-safety, cross-harness robustness.
Artifacts: BRIEF, 7 positions, 7 rebuttals, synthesis-v1, 3 red-team passes,
canonical DESIGN.md, OPEN-QUESTIONS.md, MISSION.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-15 23:47:49 -05:00
parent d481a74a86
commit c70b217a5c
22 changed files with 5822 additions and 0 deletions

View File

@@ -0,0 +1,259 @@
# Rebuttal — Pragmatic Coder Lens
**Author role:** Pragmatic Coder — cares about implementability, migration cost, and what a
maintainer can actually keep working across releases.
**Responding to:** all seven position papers (architect, aiml, contrarian, devex, moonshot,
steward, and the coder's own opening position).
---
## Part 1 — Strongest ideas from other personas worth keeping
### 1a. The CI grep gate (Contrarian, DevEx, Steward, AIML — universal agreement)
Every other persona proposes a blocking CI check for personal-data tokens. Every one of them is
right. This is the only proposal in the entire debate with zero credible downside. The contamination
reached 2955 files (counts differ slightly by grep pattern) precisely because the existing
`defaults/README.md:7` promise ("no personal data should be committed") is prose with no
enforcement. The CI gate is ~15 lines of shell and it makes the entire sanitization discussion
permanent rather than aspirational.
**Concrete form I'd endorse for alpha DoD (Contrarian's version is the cleanest):**
```bash
grep -rinE 'jarvis|jason|woltje|\bPDA\b|/home/jwoltje|~/src/jarvis|/rails/' \
packages/mosaic/framework/ \
--exclude-dir=examples \
&& { echo "PERSONAL DATA OR STALE PATH IN SHIPPED FRAMEWORK"; exit 1; } || exit 0
```
Note: `/rails/` belongs on this list. The Contrarian and AIML papers both identify the live
`rails/` vs `tools/` path conflict in `templates/agent/AGENTS.md.template` as a correctness
bug that will make agents issue "no such file" errors on `ci-queue-wait.sh`. That is not a
design question — it is a broken template in production and it should be fixed before alpha.
### 1b. The `.local.md` overlay pattern for upgrade-safe user customization (AIML)
The AIML paper proposes `SOUL.local.md` / `USER.local.md` overlays that are always preserved
by upgrade and loaded last-within-layer. This is the best concrete answer to DQ3 of any paper.
The insight: **framework owns the base shape; user owns the delta; the two never share a file.**
It mirrors the `settings.json` / `settings.local.json` split the Claude runtime already uses
(`runtime/claude/RUNTIME.md:47`) — a pattern that already works in the codebase.
The alternative proposals (Architect's 3-way merge, DevEx's `mosaic-reconcile`, Moonshot's
migrations/) are all more complex and require new tooling that must be maintained. The `.local.md`
pattern requires only two lines added to `PRESERVE_PATHS` and two sentences in `AGENTS.md` load
order. It is implementable in an afternoon and never regresses.
### 1c. "Prose rules are advisory; hooks are the gate" elevated to doctrine (DevEx, Contrarian)
DevEx's strongest insight, supported by evidence already in the repo: `runtime/claude/RUNTIME.md:30-32`
explicitly says the `prevent-memory-write.sh` hook exists because "the rule alone proved
insufficient — the hook is the hard gate." That is a framework lesson that should be promoted to
the Constitution itself, not left buried in one runtime file.
The Contrarian frames this well: *prefer mechanical enforcement (hooks/CI) over prose gates wherever
the gate is checkable.* A Constitution that instructs maintainers to convert checkable gates into
hooks is more durable than one that relies on models reading prose carefully.
---
## Part 2 — Weakest or riskiest proposals with concrete failure modes
### 2a. The Architect's five-layer model and 3-way merge engine (attack)
The Architect proposes five distinct layers (Constitution, Standards, Persona, Operator Policy,
Deployment/Runtime) plus a `git merge-file`-style 3-way merge for upgraded user files. The layer
count is intellectually clean but operationally reckless.
**Concrete failure mode:** The 3-way merge requires a "base" — the template version the user's
file was generated from, stamped at init time. That stamp must be stored somewhere, retrieved
during upgrade, and matched against the correct prior template. If any link in that chain breaks
(lost stamp, renamed file, manually-edited header), the merge silently degrades to a clobber or
a conflict that surfaces as noise. Real users will not resolve `SOUL.md.mosaic-merge` conflict
files. They will either ignore them (drift) or delete them and regenerate (losing customization).
The Architect's migration section acknowledges the risk vaguely ("migration test matrix") but
provides no concrete implementation. The existing `run_migrations()` in `install.sh` is already
at 42 lines for two version hops. A 3-way merge adds a class of failure that the current
maintainer cannot reasonably test across all permutations of prior edits.
**The pragmatic counter:** the `.local.md` pattern (see 1b) achieves the same upgrade safety
with zero merge machinery. User adds a section → puts it in `SOUL.local.md` → upgrade never
touches it. No base version needed. No conflict to resolve. The cost is that users must put new
additions in `.local.md` rather than editing `SOUL.md` directly — which is a good habit to
enforce anyway.
**What to keep from the Architect:** the physical separation of `constitution/` (always
overwritten) from user files at root (always preserved) is correct and should be adopted. Only
the 3-way merge engine should be dropped.
### 2b. The Moonshot's YAML front-matter layer markers and content-hash launcher enforcement (attack)
The Moonshot proposes adding `mosaic-layer`, `mosaic-owner`, and `mosaic-override` YAML front
matter to every Constitution file, with the launcher performing content-hash checks and refusing
to start if a layer-0 file has been structurally modified.
**Concrete failure mode 1 — agent context pollution.** YAML front matter in a Markdown file that
agents read as context is not neutral. Models parse it as structured data. A file that starts with:
```yaml
---
mosaic-layer: 0
mosaic-owner: framework
mosaic-override: forbidden
---
```
gives the model explicit machine-readable "layer 0" and "forbidden" signals — which sounds useful
until you realize that an adversarial project file claiming `mosaic-layer: 0` will be treated by
the model with the same weight. The metadata is unverifiable by the model. It only helps the
*launcher* — and only if the launcher actually implements the hash check, which is new tooling
that doesn't exist yet.
**Concrete failure mode 2 — hash check fragility.** A content-hash check on Constitution files
means any legitimate framework upgrade that changes `CONSTITUTION.md` will trigger a hash mismatch
warning on every user's machine until they run `mosaic upgrade`. That is the correct behavior
for a compromised file — but it is indistinguishable from a normal upgrade. Users will learn to
dismiss the warning, rendering the gate meaningless. The Steward proposes `mosaic doctor --check-constitution`
for the same purpose, which is better because it is *opt-in* diagnostic, not a startup blocker.
**What to keep from Moonshot:** the 500-word budget for the resident core is correct and the
Moonshot is the only paper that proposes it as a hard word count (not just a line count). That
discipline should be adopted. The YAML front matter and hash enforcement should not.
### 2c. The DevEx's capability manifest JSON per harness (attack, with nuance)
DevEx proposes `adapters/<h>.capabilities.json` machine-readable manifests that map
abstract capability verbs ("structured_reasoning") to concrete tool bindings per harness. The
goal — removing the four near-duplicate "sequential-thinking required (except Pi)" stanzas — is
correct. The mechanism is over-engineered for alpha.
**Concrete failure mode:** the manifest is a new contract surface. Every new harness must
produce a correct JSON manifest. Every new Constitution capability verb must be added to every
manifest. If a manifest is wrong or stale (the Pi manifest says `"gate": false` for
`structured_reasoning` but the Constitution says it's required), behavior diverges silently. The
four-way prose duplication is bad, but at least it's human-readable and catches errors at review
time. A JSON manifest that no one reads until something breaks is worse.
**The pragmatic counter for alpha:** Delete the duplicate policy text from the four
`runtime/*/RUNTIME.md` files and replace each with a one-line reference: "Policy:
`~/.config/mosaic/CONSTITUTION.md`. Harness-specific mechanics below." Total work: four small
edits. That removes the duplication and the drift risk without creating a new JSON schema to
maintain. The capability manifest is a good idea for a post-alpha v2 — when there are enough
harnesses (say, 6+) that prose management becomes genuinely untenable.
---
## Part 3 — The key disagreement most relevant to this lens: how many files is "one Constitution"?
The single sharpest divergence in the debate is not about *whether* to have a Constitution layer —
all seven papers agree on that. The disagreement is: **should the Constitution be one flat file
or a directory of decomposed files?**
- **Flat file camp (Contrarian, AIML, coder's own opening position):** one `CONSTITUTION.md`,
~4080 lines, containing only the irreducible gates. Everything else stays in existing files.
Advantage: trivially injected into any harness as a single read; trivially line-count enforced;
trivially referenced by path; impossible to partially-load.
- **Directory camp (Architect, Steward, Moonshot, DevEx):** `constitution/` directory with
`GATES.md`, `DELIVERY.md`, `ESCALATION.md`, `SUBAGENT.md`, `GUIDE-INDEX.md`, `COMPLIANCE.md`,
`migrations/`, `schema.json`, etc. Advantage: cleaner separation of concerns within law.
Disadvantage: agents must load multiple files to have the complete law, and the load order
becomes a new point of failure.
### Why the flat file wins for alpha
The Steward's proposed load order is revealing:
```markdown
1. ~/.config/mosaic/constitution/GATES.md
2. ~/.config/mosaic/constitution/DELIVERY.md
3. ~/.config/mosaic/SOUL.md
4. ~/.config/mosaic/USER.md
5. Project-local AGENTS.md
6. Runtime RUNTIME.md
```
Items 1 and 2 are now two separate file reads that must both succeed for the agent to have the
complete law. If an agent on a constrained harness (e.g., direct `claude` launch via
`~/.claude/CLAUDE.md`) processes item 1 and then gets distracted by the task before loading
item 2, it is operating with incomplete gates. The DevEx paper explicitly identifies this as the
"load-order indirection chain breaks silently" risk — and it becomes *worse*, not better, with a
directory of multiple constitution files.
The AIML paper has the clearest statement of the primacy/recency principle: the Constitution
should be **at the very top and anchored at the very bottom** of the injected blob. You cannot
anchor a directory — you can only anchor a file. A single flat `CONSTITUTION.md` can be composed
into position by the launcher; a directory requires the launcher to decide the ordering, which
is a new failure surface.
### Resolution: one flat `CONSTITUTION.md` for alpha; directory structure optional post-alpha
**Concrete proposal:**
1. **Single `CONSTITUTION.md` file**, ~80 lines, placed in `~/.config/mosaic/` root (not a
subdirectory). Content: the 13 hard gates minus the one operator-specific merge-authority
policy (which moves to a `policy/` file per the Architect's correct insight), plus the 5
escalation triggers, block-vs-done, mode declaration protocol, and a one-sentence precedence
rule. Not `constitution/CORE.md`. Not `defaults/CONSTITUTION.md`. Just
`~/.config/mosaic/CONSTITUTION.md` — discoverable, injectable, flat.
2. **`AGENTS.md` becomes the load-order dispatcher and Conditional Guide Loading table only.**
~50 lines. First instruction: "read CONSTITUTION.md (if not already injected by launcher)."
No gates restated. No "Non-Negotiable" section. Upgrade-safe because it is not in
`PRESERVE_PATHS` (it's a framework-owned dispatcher, not user content). The self-bootstrapping
pattern the coder's opening position identified — "if CONSTITUTION.md is not already in context,
read it now" — is the correct defensive pattern and it works equally for system-prompt injection
and direct-launch pointer scenarios.
3. **`PRESERVE_PATHS` in `install.sh:24`** shrinks to: `SOUL.md SOUL.local.md USER.md
USER.local.md TOOLS.md memory sources credentials`. Constitution and AGENTS.md are removed
from the preserve list — they are always overwritten. This single change means gate updates
reach users on every `mosaic upgrade` without manual intervention.
4. **Post-alpha, if the Constitution grows beyond 100 lines**, that is a signal to extract a
`GUIDE-INDEX.md` (the conditional loading table) as the first split. The directory structure
proposed by Architect/Steward/DevEx is the right *evolution target* — not the right alpha
starting point.
**The test for any alpha proposal:** a fresh `mosaic claude` launch and a direct `claude` launch
(using only `~/.claude/CLAUDE.md`) must both result in the agent having the complete law resident
before its first tool call. With one flat `CONSTITUTION.md` and a self-bootstrapping `AGENTS.md`,
both scenarios work. With a `constitution/` directory, the direct launch scenario depends on the
pointer correctly enumerating all files in the directory — a fragile assumption.
---
## Top Contentions (short list for the conference)
1. **Ship one flat `CONSTITUTION.md`, not a directory.** A directory multiplies load-order
failure points. The alpha must work on direct launches where injection is weakest. One file
is injected whole; a directory requires ordered multi-file loading.
2. **Drop 3-way merge; adopt `.local.md` overlays.** The 3-way merge engine (Architect, DevEx)
is unimplementable at alpha quality. The `.local.md` pattern achieves the same outcome with
existing machinery and no new failure modes.
3. **The CI PII grep is mandatory DoD for alpha.** Every paper agrees. It is ~15 lines of shell.
It is the only durable anti-contamination control. Ship it with the alpha or the sanitization
work will re-decay. Include `/rails/` in the denylist — that stale path is a live correctness
bug that breaks agent-issued `ci-queue-wait.sh` commands on 12 templates.
4. **Remove `AGENTS.md` and `STANDARDS.md` from `PRESERVE_PATHS`.** They are framework-owned
dispatchers, not user content. Keeping them preserved means users never receive gate updates —
the exact deployed-vs-source drift the brief identifies as "a real problem today."
5. **Promote "hooks are the real gate" to Constitution doctrine.** The `prevent-memory-write.sh`
lesson (`runtime/claude/RUNTIME.md:30-32`) is the most actionable DevEx insight in the repo.
It belongs in `CONSTITUTION.md` as a design principle so future maintainers write hooks, not
more prose.
6. **Drop the Moonshot's YAML front matter.** Content-hash launcher enforcement is fragile and
trains users to dismiss startup warnings. The Steward's `mosaic doctor --check-constitution`
(opt-in diagnostic) is the right mechanism for the same concern.
7. **Drop the DevEx's per-harness capability JSON manifests for alpha.** The duplication problem
they solve is real, but the fix is simpler: delete the duplicate policy text from the four
`runtime/*/RUNTIME.md` files and replace with a one-line reference to `CONSTITUTION.md`. Four
edits, no new schema surface, done.