docs(design): mosaic framework constitution — expert conference output
Some checks failed
ci/woodpecker/push/ci Pipeline failed
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:
259
docs/design/framework-constitution/debate/rebuttal-coder.md
Normal file
259
docs/design/framework-constitution/debate/rebuttal-coder.md
Normal 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 29–55 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`,
|
||||
~40–80 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.
|
||||
Reference in New Issue
Block a user