diff --git a/docs/remediation/BOARD.md b/docs/remediation/BOARD.md new file mode 100644 index 00000000..e8e2bcad --- /dev/null +++ b/docs/remediation/BOARD.md @@ -0,0 +1,42 @@ +# mos-remediation — LIVE BOARD (keep < 8 KB) + +**Phase:** PLANNING — adversarial task decomposition. +**Updated:** 2026-07-31 (setup by Mos/mos-claude; handoff to mos-remediation orchestrator). + +## Head + +- Mission charter + 15 decisions + 4-build plan: PERSISTED (`docs/remediation/MISSION.md`). +- HOLD lifted for this workstream (Jason 2026-07-31). Nothing implemented yet — planning first. +- Next action: adversarial decomposition of the 4-build plan into ordered, gated tasks. + +## In-flight + +| Task | Owner | State | +| ----------------------------------- | --------------------------------------------------- | ---------- | +| Adversarial task decomp of the plan | planner-opus (robustness) + planner-sol (pragmatic) | DISPATCHED | +| Orchestrator resume/own the mission | mos-remediation | STARTING | + +## Fleet seats + +- mos-remediation — project orchestrator (Claude, /src/mosaic-stack) — STARTING +- planner-opus — adversarial planner (robustness) — to dispatch +- planner-sol — adversarial planner (pragmatic) — to dispatch +- rev-974 — mosaicstack reviewer identity (id 16, write:repository) — idle, on call +- Mos (mos-claude) — lead coordinator + +## Gate status + +- Delivery gates active: author≠reviewer, diff-blind pre-registered checks, CI-green, merged-PR completion. +- Freeze: LIFTED for this workstream only. + +## Sequencing (from MISSION.md) + +1. Spine + choke-point service (MACP wiring @ mosaic_orchestrator.py::run_single_task) + PG/Redis +2. Rotation daemon (finish Mission Control Plane, reuse packages/coord) +3. Comms service (envelope→service→PG/Redis→adapters) +4. Hygiene + conformance harness + Cross-cutting retirements: flat-file tracking, 3 MACP islands, silent MOSAIC BYPASS. + +## Log + +- 2026-07-31 — Mission set up by Mos post-postmortem (15/15 decided). Orchestrator + adversarial planners being launched. Dogfood posture active. diff --git a/docs/remediation/KICKSTART.md b/docs/remediation/KICKSTART.md new file mode 100644 index 00000000..fa4900f0 --- /dev/null +++ b/docs/remediation/KICKSTART.md @@ -0,0 +1,44 @@ +# mos-remediation — Orchestrator Kickstart / Compaction-Survival Resume + +**You are `mos-remediation`, the project orchestrator for the Mosaic Stack remediation, launched in `/src/mosaic-stack`.** +This file is your fail-closed resume procedure. Read it on EVERY fresh/cleared session and on the FIRST turn +after any compaction. This mission's whole point is that manual compaction-survival is fragile — so follow this +mechanically until Build 3 (rotation) makes it automatic. + +## On resume (do in order, before any orchestration action) + +1. `cd /src/mosaic-stack` and confirm you are on the remediation working branch. +2. Read `docs/remediation/MISSION.md` — the charter (goal, 4 builds, 15 decisions, sequencing, directives). +3. Read `docs/remediation/BOARD.md` — the LIVE state: current phase, in-flight tasks, fleet seat assignments, + gate status. This is your single source of in-flight truth (kept small). +4. Read the discussion checkpoint for full rationale if needed: + `../jarvis-brain/docs/scratchpads/postmortem/REMEDIATION-DISCUSSION-STATE.md` (or the jarvis-brain repo path). +5. **Residency attestation (fail-closed):** restate from the reloaded files — (a) the goal in one line, (b) the + current build/phase, (c) the BOARD head (in-flight tasks + who owns them). If you cannot, HALT and re-read. + Do NOT act on memory alone; a compaction may have dropped context silently. + +## Standing invariants (never violate) + +- **North star:** deterministic-right-answer → code/gate; LLM only for judgment. +- **Delivery gates:** author≠reviewer; PRE-REGISTERED diff-blind checks committed before reading the diff; + CI terminal-green; completion = merged PR + closed issue. rev-974 = the mosaicstack reviewer identity. +- **Dogfooding:** every fix validated against its live seed case (MISSION.md lists them). +- **Tracking → DB** (hard cutover); do NOT re-invest in flat-file tracking. jarvis-brain PDA is off-limits. +- **Git identity:** export `MOSAIC_GIT_IDENTITY=` so wrappers author correctly and survive respawn. + +## After every significant event + +Overwrite stale lines in `BOARD.md`, keep it < 8 KB, commit + push. The board IS your checkpoint until the +DB-backed rotation daemon (Build 3) exists. Persist typed state (phase, tasks, owners, gates) — never the transcript. + +## Fleet + +- Adversarial planners: `planner-opus` (robustness), `planner-sol` (pragmatic) — dispatch for task decomposition; reconcile their oppositional decomps. +- Coders/reviewers: dispatch per roster + delivery gates. Comms: `~/.config/mosaic/tools/tmux/agent-send.sh` + (`-L -s -S : --class `); always pass `-S`. +- Lead coordinator: Mos (`mos-claude`). Escalate only on the Constitution's escalation triggers. + +## Remote control + +On first startup, activate remote control for this session (`/remote-control`) so Jason can reach/drive you while +away. If the command is unavailable in this runtime, report it to Mos and continue — it is not a blocker. diff --git a/docs/remediation/MACP-WIRING-SCOUT.md b/docs/remediation/MACP-WIRING-SCOUT.md new file mode 100644 index 00000000..c3ba49b5 --- /dev/null +++ b/docs/remediation/MACP-WIRING-SCOUT.md @@ -0,0 +1,98 @@ +# MACP wiring investigation + +**Scope:** `/src/mosaic-stack` inspected at HEAD `b79336a8c11e2a4646a47ff8d295a226e0c71404`; read-only. Existing dirty/untracked state was not touched. + +## Verdict + +**(c) STRANDED.** `packages/macp` is exported, unit-tested, and registered as a CLI command group, but no production dispatch/execution code invokes its credential resolver, gate runner, or event emitter. +A separate MACP-named OpenClaw/orchestrator rail exists, but it redefines task/result types and gate/event logic instead of importing `@mosaicstack/macp`; direct `mosaic yolo|claude|codex|opencode|pi` also bypasses it. + +## 1. Production call sites vs tests + +### Production references to `@mosaicstack/macp` + +| Surface | Evidence | Actual use | +| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Unified CLI | `packages/mosaic/src/cli.ts:8,385` | Imports and registers `registerMacpCommand`; no task/gate/event execution. | +| Forge | `packages/forge/src/types.ts:1,17,68,79` | **Type-only** imports of `GateEntry` and `TaskResult`. Pipeline calls an injected abstract executor at `packages/forge/src/pipeline-runner.ts:189-190,299-300`, not MACP. | +| Mosaic package metadata | `packages/mosaic/package.json:36`; `packages/mosaic/src/runtime/update-checker.ts:172` | Dependency/update inventory only. | +| Agent | No match under production `packages/agent/src/**` | No MACP import/call. | +| Coord | No match under production `packages/coord/src/**`; dependency list is only `@mosaicstack/types` at `packages/coord/package.json:25-27` | No MACP import/call. | +| Plugins | No `@mosaicstack/macp` import under `plugins/**` | No package use; the MACP-named plugin is an independent implementation (below). | + +**Repository-wide production call-site search result:** excluding `packages/macp/**`, tests, worktrees, and build output, there are **zero** calls to `runGate`, `runGates`, `emitEvent`, `appendEvent`, or `resolveCredentials`. + +### `packages/macp` implementation is internally connected only + +- Public exports: `packages/macp/src/index.ts:1-48` exports Task/GateEntry/MACPEvent/TaskResult, credential resolution, `runGate(s)`, risk-floor, and event emission. +- Gate runner calls its own event emitter: `packages/macp/src/gate-runner.ts:187-236`. +- Event persistence implementation appends NDJSON to a caller-supplied path: `packages/macp/src/event-emitter.ts:11-27`. +- There is **no exported programmatic `submit` implementation** in `packages/macp/src/index.ts:1-48`; only the CLI placeholder named `submit`. + +### Test-only invocations + +- Gate runner: `packages/macp/__tests__/gate-runner.test.ts:96-242` invokes `runGate/runGates`. +- Event ledger: `packages/macp/__tests__/event-emitter.test.ts:46-133` invokes `appendEvent/emitEvent` against temporary `events.ndjson` files. +- Credential resolver: `packages/macp/__tests__/credential-resolver.test.ts` exercises resolver behavior. +- CLI tests only verify command registration: `packages/macp/src/cli.spec.ts:37-73`; `packages/mosaic/src/cli-smoke.spec.ts:8` imports registration. + +## 2. Gate on the live dispatch path + +### Direct Mosaic runtime launch bypasses MACP + +- Runtime commands dispatch directly to harness launch: `packages/mosaic/src/commands/launch.ts:730-801`. +- Claude/Pi go through the lease broker, then spawn the runtime: `packages/mosaic/src/commands/launch.ts:817-843`. +- Commander wiring sends `mosaic yolo ` and direct runtime commands to `launchRuntime`: `packages/mosaic/src/commands/launch.ts:1102-1157,1165-1167`. +- None of those ranges imports/calls `@mosaicstack/macp`, `runGates`, or `emitEvent`. + +**Result:** a direct `mosaic yolo`, `mosaic claude/codex/opencode/pi`, or underlying exec does not create a typed MACP Task, run the package gate-runner, or append a package MACPEvent. + +### Coord bypasses MACP + +- Coord reads/updates `docs/TASKS.md`: `packages/coord/src/runner.ts:6,306-386`; parser/writer is `packages/coord/src/tasks-file.ts:326-377`. +- Coord launches a child process directly: `packages/coord/src/runner.ts:397-427`. +- Mission state is its own `.mosaic/orchestrator/mission.json`/`next-task.json`: `packages/coord/src/mission.ts:8-12`; `packages/coord/src/runner.ts:15-16,355-384`. + +**Result:** Coord task execution has no MACP Task validation, package gate runner, or event append. + +### Forge bypasses MACP execution + +- Forge defines its own `ForgeTask` and abstract `TaskExecutor`: `packages/forge/src/types.ts:48-80`. +- The production CLI injects a **stub executor** that immediately reports completion with empty gates: `packages/forge/src/cli.ts:13-31,167,185`. + +**Result:** even `mosaic forge run` does not execute MACP gates or persist MACP events. + +### Separate MACP-named rail is not `packages/macp` + +- OpenClaw plugin registers an ACP backend named `macp`: `plugins/macp/src/index.ts:1-18,72-102`. +- It locally redefines `OrchestratorTask`, `TaskResult`, and gate-result shapes instead of importing package types: `plugins/macp/src/macp-runtime.ts:43-77`. +- It appends directly to `.mosaic/orchestrator/tasks.json`, triggers an external controller, and polls `results/.json`: `plugins/macp/src/macp-runtime.ts:290-329,437-483`. +- The controller independently implements `append_event`, `emit_event`, shell execution, gate execution, and results: `packages/mosaic/framework/tools/orchestrator-matrix/controller/mosaic_orchestrator.py:29-91,126-276`. +- Its gate loop runs raw string gates after worker success: `mosaic_orchestrator.py:213-235`; it does not support the package's structured `GateEntry`/AI-review behavior. +- Current checkout disables this controller: `.mosaic/orchestrator/config.json:2` (`"enabled": false`). +- Plugin references `tools/macp/dispatcher/pi_runner.ts` at `plugins/macp/src/macp-runtime.ts:85-91`, but `tools/macp/` does not exist in this checkout. + +**Result:** there is a parallel, optionally enabled MACP-shaped rail, not package integration. It cannot make `packages/macp` the enforced path. + +## 3. Event ledger status + +- Package persistence exists only as a library primitive: `packages/macp/src/event-emitter.ts:11-27` appends JSON lines to an arbitrary `eventsPath`. +- Package event emission is reached only from package `runGates`: `packages/macp/src/gate-runner.ts:204-236`. +- No production caller invokes package `runGates/emitEvent/appendEvent`; therefore no runtime destination path is configured for the package ledger. +- Test-only ledgers use temp paths: `packages/macp/__tests__/event-emitter.test.ts:35-133`; gate tests use temp `events.ndjson`: `packages/macp/__tests__/gate-runner.test.ts:171-242`. +- The separate Python controller writes `.mosaic/orchestrator/events.ndjson`: `mosaic_orchestrator.py:129-133,159-161,219-235`; the Mosaic Framework plugin only **reads** that file for context at `plugins/mosaic-framework/src/index.ts:279-316,430-438`. +- In this checkout, `.mosaic/orchestrator/events.ndjson` is absent and the controller is disabled (`.mosaic/orchestrator/config.json:2`). + +**Conclusion:** `MACPEvent` from `packages/macp` is defined/tested but not emitted or persisted by live production call sites. The similarly shaped Python ledger is a duplicate island. + +## 4. Coord link + +- `packages/coord` has no `@mosaicstack/macp` dependency/import: `packages/coord/package.json:25-27`; no matches in `packages/coord/src/**`. +- Coord's task model is Markdown `docs/TASKS.md` plus mission/session JSON: `packages/coord/src/tasks-file.ts:1-10,257-377`; `packages/coord/src/mission.ts:8-12`; `packages/coord/src/runner.ts:306-427`. +- It does not consume `.mosaic/orchestrator/events.ndjson`, MACP Task, MACPEvent, GateEntry, or TaskResult. + +**Conclusion:** Coord and `packages/macp` are disconnected islands. + +## Shortest wiring gap + +**Single integration point:** replace the duplicated execution/gate/event block in `mosaic_orchestrator.py::run_single_task` (`:126-276`) with one production Node `TaskExecutor` backed by `@mosaicstack/macp` (typed Task validation + `resolveCredentials` + `runGates` + `emitEvent`), and make Coord/Forge/OpenClaw submit through that executor. This queue/controller choke point is where `yolo|acp|exec` worker outcomes can be gated and journaled before completion is recorded. diff --git a/docs/remediation/MISSION.md b/docs/remediation/MISSION.md new file mode 100644 index 00000000..2065267d --- /dev/null +++ b/docs/remediation/MISSION.md @@ -0,0 +1,79 @@ +# 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:** PLANNING (task decomposition). +**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. + +## 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): `/tmp/macp-wiring-investigation.md` (copy into this dir — see TODO). + +## 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`** in at `mosaic_orchestrator.py::run_single_task` — typed tasks, gate-runner, event ledger, credential binding, tri-state write outcomes. | +| **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 1–4 hold. | + +## 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. +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. + +## 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 (non-negotiable):** author≠reviewer, PRE-REGISTERED diff-blind acceptance checks committed + before reading the diff, CI terminal-green, completion = merged PR + closed issue. rev-974 = mosaicstack reviewer. +- **Compaction survival:** see `KICKSTART.md` in this dir — the resume procedure. Persist typed state, not transcript.