Files
stack/docs/remediation/MISSION.md
T
mos-dt-0andClaude Opus 5 4520d2f672 docs(remediation): promote two first-class principles to the charter; dispatch RM-02 round 3
Mos ruled both open questions and promoted the pattern to the charter.

PRINCIPLE 1 — the anchor must live outside the audited party's authority. You cannot fix "the author
controls X" by deriving X from something the author also controls; deriving only MOVES the control
point. Third independent arrival of one conclusion, each reached while shipping something else and each
from a different direction: the manifest certifying its own tree (D-19), the sandbox evaluating code
that enters before the boundary exists (D-25), and now the registry seam derived from a path the author
also places (D-45). Three impossibility-derivations of the same conclusion is the strongest
architectural evidence this mission has produced, and it is what forces Builds 1-2 rather than making
them a preference.

PRINCIPLE 2 — no universally-quantified check may pass over an empty set. "All registered cases ran" is
vacuously true when there are none. Non-emptiness and anchoring are preconditions asserted before the
quantified check runs, not properties hoped for after. The identical vacuity appeared twice at two
levels — seam=HEAD emptied the commit range, an emptied manifest emptied the registry population — and
the first was fixed as an instance, so it returned one level up. Corollary, same disease: a clause
written for the instance that produced it is not a clause.

Q1 ruled: the merge-base anchor IS in scope for f10-coder in this PR. It is git-computable against
main, which the author does not control, so reordering or splitting within the branch cannot move it —
an existing non-author-controlled reference, no new infrastructure. RM-60's execution boundary is a
sibling under the same principle but a different mechanism (where gate-verify runs, not what the anchor
is) and stays with Mos and Jason. Honesty required in both directions: the merge-base anchors to main,
whose integrity rests on the merge discipline this registry enforces — a bootstrap, sound against an
author who cannot rewrite main and NOT sound against an attacker who can, with that residual bound to
the Builds 1-2 dependency rather than implied.

Q2 ruled: state the empty-set principle as a general clause now, and generalize the D-38/D-40 criteria
the same way — quantify over the population instead of relabeling the originating instances.

Round 3 dispatched to f10-coder: merge-base anchor plus delayed-introduction must-fail; empty-set
precondition as a general clause with an emptied-registry must-fail; generalized clauses bound across
the gate inventory; each red-first. Number.isInteger accepting zero/negative/unsafe pipeline numbers
banked as a non-blocking follow-up.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-08-01 12:08:21 -05:00

28 KiB
Raw Blame History

Mosaic Stack Remediation — Mission Charter

Owner: project orchestrator mos-remediation (Claude, launched in /src/mosaic-stack). Origin: 2026-07-16..31 fleet lifecycle postmortem. Status: EXECUTING (planning complete; RM-01 in flight). HOLD lifted for this workstream by Jason, 2026-07-31 — "begin full mosaic fleet operation on this."

Goal

Convert the 15 accepted postmortem remediation proposals into a working, dogfooded implementation. North star: anything with a deterministic right answer moves OUT of the LLM into a deterministic gate/program; the LLM handles only genuine judgment.

First-class principle — observe the property, not the exit code

No write is done until the requested PROPERTY is observed. A success exit code is not evidence.

Success output is designed to be believed. That is the whole reason the inert-gate class exists and why P-WRAPPER-001's tri-state (verified / written-unverified / failed) is not optional. The failure is not carelessness — a green is engineered to be trusted, so trusting it is the default behaviour of a competent operator, not a lapse.

Promoted to the charter by Mos (2026-07-31) after the orchestrator committed this exact error: a --draft flag was silently dropped by a wrapper fallback that still exited 0, and the PR was reported as a draft on the strength of the exit code rather than an observed draft: true (D-12). Twelve failure instances were banked in that session; three of them were the orchestrator's own. That ratio is the point — the mechanism must catch the mechanic too, or it is not a mechanism.

Operationally: after any write, read back the property you required. Applies to gates, wrappers, PR flags, commit authorship, file installs, and message delivery alike.

First-class principle — pre-registration prevents retrofitting, and nothing else

A pre-registered check set can fail in three distinct ways:

mode the set is… found as
WRONG a check does not test what it claims D-8
INCOMPLETE green while a criterion's requirement is untested D-17
INTERNALLY INCONSISTENT two criteria cannot both hold D-18

Pre-registration protects against exactly one thing: retrofitting a check to fit the implementation it is supposed to judge. It confers neither correctness, nor coverage, nor consistency. "We pre-registered the checks" has been treated as though it settled the question — it settles one of three.

Promoted to the charter by Mos (2026-07-31). All three modes were found on this mission's own first delivery, by the machinery applied to its own work — not by inspection, and not by looking for them.

Enforceable form — RM-02's four clauses. The registry must establish that: (1) each check is right — proven red for its own stated reason before its green counts; (2) the set covers — every criterion bound to a case that actually exercises it; (3) no two criteria conflict — mutual unsatisfiability is a registry defect discoverable by construction; (4) when a criterion's meaning changes, the registry retains original text, restatement, and reason, so evolution stays auditable. A criterion with no case that can fail for its own reason is unregistered in substance, however it reads in the manifest.

Corollary — never ship an integrity claim dressed as a property

A verification artifact that can be forged by whoever it is meant to catch verifies nothing. If a manifest, marker, ledger, or receipt is writable by the same actor whose behaviour it certifies, it certifies the attack. Such an artifact must sit inside the integrity envelope it belongs to, publish atomically, and carry a tamper negative-control observed red — otherwise its integrity is a claim, not a property.

If it cannot be made tamper-evident, say so and reconsider the approach. Laundering foreign content as certified is the only unacceptable outcome; an honest "this cannot be verified" is always available and always preferable.

First-class principle — when a property cannot exist at the layer it was specified

Some required properties are impossible at the layer that asked for them — not hard, impossible. A local check cannot defend against an actor who can rewrite the check itself. When that happens, there are exactly three honest moves, and all three are mandatory:

  1. Implement what the layer can guarantee. Partial protection against the class it was actually born from is worth having.
  2. State the boundary precisely, in BOTH directions. What it does not defend, and beside it what it does. A reader who sees only the negative dismisses the check as worthless; one who sees only the positive over-trusts it. Both together is the honest artifact — either alone misleads.
  3. Record where the real guarantee will come from — as a TRACKED DEPENDENCY, not prose. It must name a task that someone must close. A documented gap with no owner becomes a permanent gap that reads as intentional.

A written-down gap is acceptable engineering. An implied-fixed gap is this mission's core failure in a new costume — a verification artifact that verifies nothing, with a green to prove it.

Promoted to the charter by Mos (2026-07-31) from D-19. Origin: the RM-01 symlink manifest could not be made tamper-evident against a same-UID actor (CWE-345), because the manifest and its marker share one writable tree. The implementing seat escalated rather than relabelling self-authentication as tamper-resistance — the corollary above firing on its first real adversarial test, on the cheapest seat in the loop. Residual risk bound to RM-59 (depends_on: RM-12, RM-21, RM-25), where the choke-point executor and spine verify from outside the worktree's authority.

First-class principle — query for refutation, never for confirmation

A subordinate asked to confirm a hypothesis will agree. Ask it to refute, with evidence.

The bias is induced by the query, not by the answerer's diligence. "The DB flaked — please confirm" and "confirm or refute this, with the log line that proves it" are different instruments, and they return different answers to the same question. The first harvests agreement; only the second can return "you are wrong, and here is why."

This matters most with agent subordinates, which are agreeable by construction: fluent, eager to be useful, and structurally disinclined to tell the dispatcher their premise is false. A confirmation query aimed at one is close to a guaranteed yes — so the discipline cannot rest on the answerer being rigorous. It has to be built into how the question is asked.

Promoted to the charter by Mos (2026-08-01). Origin: the orchestrator hypothesised that a coincident ci-postgres failure caused a CI test failure and asked the implementing seat to confirm or refute it. The seat refuted it with the log (ci-postgres:5432 - accepting connections, migrations completed) and identified the real cause. Reproduction on an identical head then settled it. Had the query been phrased for confirmation, the agreement would have been returned, D-21 would have been re-classified on a false premise, and a banked finding would have been silently corrupted.

Operationally: state your hypothesis explicitly, mark it as yours, ask for evidence that kills it, and say what evidence would change your mind. A hypothesis you cannot describe how to falsify is not yet a hypothesis. Where the answer is consequential, reproduce rather than accept — two independent runs beat one confident report.

First-class principle — the anchor must live outside the audited party's authority

You cannot fix "the author controls X" by deriving X from something the author ALSO controls. Deriving merely moves the control point; it does not remove it.

Promoted to the charter by Mos (2026-08-01) on the THIRD INDEPENDENT ARRIVAL of the same conclusion, each reached while trying to ship something else, each from a different direction:

arrival the audited party controls… found as
manifest the tree that certifies its own generated state (same-UID, CWE-345) D-19
sandbox the code that enters the sandbox, before the boundary exists D-25
registry seam WHEN the tracked path is introduced, hence the derived boundary D-45

Round 1 the value was an author-settable field, so it was derived. Round 2 the derivation depended on when the author introduces the path. Same authority, new costume. Three impossibility-derivations of one conclusion is not a coincidence to note — it is the strongest architectural evidence this mission has produced, and it is precisely what forces Builds 12 rather than making them a preference.

Operationally: anchor to a reference the audited party cannot move. A git merge-base against main is such a reference for a PR author (they own their branch; they do not own main). State the bootstrap in BOTH directions (D-19): that anchor is sound against an author who cannot rewrite main — the threat in scope — and NOT sound against an attacker who can. That residual is what Builds 12 close, and it must be recorded as a tracked dependency, never implied.

First-class principle — no universally-quantified check may pass over an empty set

"All registered cases ran" is VACUOUSLY TRUE when there are no registered cases. Non-emptiness and anchoring are PRECONDITIONS asserted before the quantified check runs — not properties hoped for after it.

Promoted by Mos (2026-08-01) after the identical vacuity appeared twice, at two different levels: activationCommit = HEAD emptied the commit range (D-44), and an emptied manifest — criteria, gates, proseClaims, compatibilityScenarios all [] — emptied the registry population (D-46), each yielding exit 0. The first was fixed as an instance; the principle was never extracted, so it returned one level up.

Delete every gate and every criterion TOGETHER and no remaining reference complains — because every reference went with them. A check that quantifies over a population must actually range over it, and that population must be provably complete and non-empty.

Corollary (same disease): a clause written for the instance that produced it is not a clause. Do not relabel the originating instances as the general clauses — quantify over the population.

First-class principle — redundant observation on evidence-bearing steps

Two observers of the same evidence, disagreeing, catch what neither catches alone. Apply redundancy not only to judgement calls but to evidence gathering itself — the step everyone assumes is mechanical and therefore skips.

Promoted by Mos (2026-08-01) from D-33. A seat scanned a pipeline with -f json and reported 9 steps; the orchestrator scanned the same pipeline in the wrapper's default text mode and reported 8. The default output omits clone. Every "full step scan" that night had been 8-of-9 and was stated as complete in good faith. No verdict changed — but the method was wrong, invisibly, and only the disagreement between two counts surfaced it.

The reason it survived: a summary that resembles an enumeration is more dangerous than one that obviously summarises. A labelled list of named steps with states looks like the artifact, so nobody checks it against the record. Compare D-24 — mergeable was a true answer to a different question; this was a true answer to a smaller one. Neither is a lie; both pass every sniff test.

Operationally: where a step produces evidence a decision rests on, have it produced twice by different means, and treat any divergence as a finding rather than as noise to reconcile. Prefer the machine-readable record over the human-readable rendering — read the artifact, not the summary — and state the counts observed so a divergence is detectable at all.

Decision record (authoritative, immutable)

  • 15/15 proposals decided: 13 accept, 2 modify (P-AUTHORITY-001, P-INBOX-001), 0 reject.
  • Site + annotations.json: jarvis-brain/docs/postmortem-spec/site/ (committed, origin/main).
  • Discussion checkpoint (rich rationale per proposal): jarvis-brain/docs/scratchpads/postmortem/REMEDIATION-DISCUSSION-STATE.md.
  • Postmortem report: mosaicstack/stack PR #107 (merged 88f4ee04).
  • MACP wiring scout (verdict c=STRANDED): MACP-WIRING-SCOUT.md (copied into this dir; TODO discharged). Its findings are sound; its recommended wire-in point is superseded by DECISION-1.

The plan — 15 proposals collapse to 4 builds + hygiene

Build Absorbs What it is
1. One choke-point service (mechanical enforcer) MISSION, STATE, AUDIT, WRAPPER, QUEUE Deterministic program every task/data mutation flows through. Wire the stranded @mosaicstack/macp — typed tasks, gate-runner, event ledger, credential binding, tri-state write outcomes. ⚠ Target CORRECTED 2026-07-31 (DECISION-1, Mos): a new production Node TaskExecutor on the live dispatch path (packages/mosaic launch + packages/coord), which Coord/Forge/live-dispatch submit through. NOT mosaic_orchestrator.py::run_single_task — that controller is "enabled": false and references a dispatcher absent from this checkout; wiring it would strand the executor, reproducing this mission's own disease. The Python rail is deleted, not ported. Both planners reached this independently.
2. One durable spine + hot path (storage under everything) PG system-of-record + Redis hot queue (transactional-outbox). Mission/tasks/state-claims/audit-ledger/comms-inbox all land here.
3. Rotation lifecycle (finish the Mission Control Plane) LIFECYCLE, CONTRACT, GUIDE, RECOVERY Coordinator daemon: contract-hash binding, compaction-detected → rotate-not-compact, checkpoint→fresh-session→rehydrate, broker-independent recovery. Deterministic, not an LLM. Reuse packages/coord; existing PRD at docs/mission-control/.
4. Comms service AUTHORITY, INBOX (+ versioning roadmap) Envelope (comms/v1) → sole-path service → PG/Redis → pluggable adapters (tmux→Matrix/Discord/Slack/Telegram). Version the protocol, not participants.
+ Hygiene & proof FLEET, WORKFLOW, CONFORMANCE One roster-owned socket/host + stale GC; allowlist auto-sync; the conformance harness that fault-injects the failure classes and proves builds 14 hold.

Why Builds 12 are necessary — two independent impossibility proofs

The choke-point executor and PG spine are not a design preference. They are forced. Twice during the mission's own first deliveries, work stopped against a security property that cannot exist at the layer that needed it — and both times the only resolution was an authority outside the audited party's control, which is precisely what Builds 12 provide.

the audited party controls… so what fails found as
Artifact integrity the manifest that certifies its own generated tree (same-UID write ⇒ regenerate manifest and marker consistently, CWE-345) tamper-evidence D-19
Execution integrity the code that enters the sandbox (PR-controlled config executes before the boundary exists) isolation D-25

Both reduce to one sentence:

Self-verification by the audited party is not verification.

And to one consequence: the anchor must live outside the audited party's authority. A local check cannot defend against an actor who can rewrite the check; a repo cannot grant a capability to PR-controlled config and simultaneously prevent that config from using it.

An architecture forced by two independent impossibility proofs is stronger evidence than one argued for. Neither proof was sought — both arrived while trying to ship something else, from different directions (a symlink manifest; a CI sandbox), at different layers. RM-59 and RM-60 are the two tracked dependencies this creates, and they are the same dependency in different clothes.

The finding that sets the cost

Built-but-unwired disease. @mosaicstack/macp is stranded (nothing calls it); packages/coord primitives exist; the Mission Control PRD exists; PG + Redis already run in-stack. Three duplicate MACP islands, an orphaned context loader, a fail-open bypass. Work = wire + consolidate + retire, NOT greenfield. "Finish, don't re-spec."

Sequencing (skeleton — adversarial decomposition refines this)

  1. Spine + choke-point service (builds 1+2) — foundation; unlocks MISSION/STATE/AUDIT/WRAPPER/QUEUE at one integration point. (Per DECISION-1, a P0 phase of provable-gate + activation work precedes this; see TASKS.md §3.)
  2. Rotation daemon (build 3) on that spine — the drift fix proper.
  3. Comms service (build 4) — envelope → service → PG/Redis → adapters; retire direct-tmux.
  4. Hygiene + conformance (build 5) — fleet convergence, allowlist sync, dogfood harness.
  • Cross-cutting retirements: flat-file orchestration tracking (hard cutover to DB), the 3 duplicate MACP islands, the silent MOSAIC BYPASS.

Standing directives (Jason, 2026-07-31)

  • Dogfooding: validate EACH fix against the live fleet failure that motivated it. Seed acceptance tests: Pi brick (RECOVERY), scout-bounce (INBOX/FLEET), gate-6 inert + #1019 recursion (QUEUE), identity drift (WRAPPER), auto-sync sweep (WORKFLOW), #1018 stale-consumed (INBOX). The fleet is its own test bed.
  • Orchestration tracking → DB, hard cutover ("rip off the bandaid"), NO flat-file interim. jarvis-brain PDA flat-files untouched. Current flat-file tracking runs as-is/unhardened until DB tracking is real, then one clean replace.
    • QUALIFIED 2026-07-31 (DECISION-2, Mos): the DB spine must NOT be a single-point hard-stop. A broker-independent / degraded mode and a rehearsed rollback artifact are design requirements (P-RECOVERY-001), binding now on RM-12, RM-13, RM-23, RM-36 and RM-53. This supersedes the earlier orchestrator recommendation to pre-commit "no DB ⇒ the fleet stops" — that answer is not on record. Only the specific availability target remains open, queued for Jason; it does not block current work.

The 15 decisions (one-line; full rationale in the checkpoint)

  1. P-ACTIVATION-001 accept — transactional CLI+hooks+broker+version release; block launch on skew, fail-SAFE.
  2. P-AUTHORITY-001 MODIFY — structured authenticated inbox; envelope carries comms-PROTOCOL version; version the protocol not participants; N-version window.
  3. P-LIFECYCLE-001 accept — rotation not recursive compaction; pre-empt at token threshold; enforcer = deterministic coordinator; = finish Mission Control Plane.
  4. P-MISSION-001 accept — bind lanes to mission+task ledger; convention exists, ENFORCEMENT is the gap; mission+tasks → DB spine (hard cutover).
  5. P-QUEUE-001 accept — repair queue transport + exit-asserting non-null-case tests (gate-6 was INERT fleet-wide; #1019 fix recursed the same bug).
  6. P-STATE-001 accept — typed claims (source/confidence/TTL) not prose blob; MACP typed record; integrity fail-closed HMAC; don't fork a 4th island.
  7. P-AUDIT-001 accept — MACPEvent lifecycle ledger; EXTEND enum to lifecycle events; runtime-neutral (executor-emitted); retire duplicate Python ledger.
  8. P-WRAPPER-001 accept — identity derives from seat name + survives respawn; tri-state write outcomes MANDATORY; name safe target metadata.
  9. P-CONTRACT-001 accept — bind session to contract hash; re-anchor on policy-change OR compaction-detected; stale generation loses authority MECHANICALLY.
  10. P-INBOX-001 MODIFY — sole-path comms SERVICE; PG durable SoR + Redis hot queue (outbox, reconciliation sweeper); pluggable adapters; protocol-first, PG-first-then-Redis.
  11. P-RECOVERY-001 accept — broker-independent bootstrap recovery; honest capability labeling; break-glass LOUD+AUDITED+TEMPORARY not silent permanent bypass.
  12. P-GUIDE-001 accept — delete /compact and continue from orchestrator path (keep for ephemeral); removal = substitution (wire rotation trigger).
  13. P-FLEET-001 accept — one roster-owned socket/host; quarantine unmanaged; stale-session GC; prerequisite for INBOX identity-addressing.
  14. P-WORKFLOW-001 accept — auto-sync ALLOWLIST not denylist; worktree/lease isolation for agent docs/source; DB-tracking obviates the flat-file-sweep criterion.
  15. P-CONFORMANCE-001 accept — fleet lifecycle harness on REAL runtime artifacts + fault injection; the 100-rotations-lossless bar is a test; target the DB substrate.

Fleet operating model

  • Project orchestrator mos-remediation (this seat) owns the mission; coordinates under Mos (lead).

  • Adversarial task decomposition: planner-opus (robustness) + planner-sol (pragmatic) each decompose the plan independently; orchestrator reconciles into TASKS.md/DB tasks. Oppositional by design.

  • Delivery gates — REFERENCE, do not restate. The authoritative definitions live at ~/.config/mosaic/fleet/roles.local/merge-gate.md (verdict authority) and ~/.config/mosaic/fleet/roles/validator.md (validator/certificate role). Read them; do not paraphrase them. Restating an authoritative source is lossy every time — see D-26, where a subset restated from memory dropped a security precondition.

    Gate order (the sequence only; the definitions are in the files above):

    1. Independent review, author ≠ reviewer (rev-974 on mosaicstack), with PRE-REGISTERED diff-blind acceptance checks committed before the diff is read
    2. Remediation of findings
    3. CI terminal-green at the exact full-40 head, by full step scan
    4. Merge-gate verdict — GO / NO-GO / HOLD (class merge-gate; "Ultron" is an instance name, display data, never an authority source). Bound to a commit and VOID the instant the head moves. HOLD persists until replaced; a NO-GO answered by an empty commit must be re-issued as NO-GO. Posted durably on the PR under the gate's own minted identity, enumerating its evidence — a bare "GO — gates verified" is non-conforming.
    5. Coordinator merge, head-pinned. The gate never merges; it holds push=False by design.

    The CI queue guard runs but is ZERO-INFORMATION until RM-03 lands (D-23: it returns pass for every possible input). It must not be cited as evidence by any gate, including the coordinator's own merge path.

    Assignment: the coordinator assigns the merge-gate seat; the orchestrator does not. The orchestrator owns getting a PR gate-ready.

  • Compaction survival: see KICKSTART.md in this dir — the resume procedure. Persist typed state, not transcript.