diff --git a/docs/remediation/BOARD-LEDGER.md b/docs/remediation/BOARD-LEDGER.md new file mode 100644 index 00000000..ffef49da --- /dev/null +++ b/docs/remediation/BOARD-LEDGER.md @@ -0,0 +1,5 @@ + + +### **D-1 / P-ACTIVATION + hygiene — committed `.npmrc` hard-pins `store-dir=/root/.local/share/pnpm/store`.** + +Correct for the CI container (runs as root), fatal for EVERY non-root local checkout: `EACCES` on `/root/.local/share/pnpm/store/v10/server/server.json`. A committed config that only works on one runtime is exactly the activation-skew class. Fix candidate: make store-dir env-overridable, not hardcoded. diff --git a/docs/remediation/BOARD.md b/docs/remediation/BOARD.md index 049d9611..46ee517c 100644 --- a/docs/remediation/BOARD.md +++ b/docs/remediation/BOARD.md @@ -53,37 +53,38 @@ 4. Hygiene + conformance harness Cross-cutting retirements: flat-file tracking, 3 MACP islands, silent MOSAIC BYPASS. -## Dogfood evidence captured this session (live failure classes, not hypotheticals) +## Dogfood evidence — live failure classes, not hypotheticals -- **D-1 / P-ACTIVATION + hygiene — committed `.npmrc` hard-pins `store-dir=/root/.local/share/pnpm/store`.** - Correct for the CI container (runs as root), fatal for EVERY non-root local checkout: `EACCES` on - `/root/.local/share/pnpm/store/v10/server/server.json`. A committed config that only works on one - runtime is exactly the activation-skew class. Fix candidate: make store-dir env-overridable, not hardcoded. -- **D-2 / hygiene — husky `prepare` fails `EPERM` copying into root-owned `.husky/_/`.** Repo working - tree has root-owned dirs (`.husky/`, repo root) under a non-root agent. Worked around with the - intended `HUSKY=0` escape hatch (does NOT disable the existing pre-commit/pre-push hooks). -- **D-3 / P-FLEET-001 — the seats running this mission are UNMANAGED.** `mos-remediation`, `rev-974`, - `planner-opus`, `planner-sol` appear in NO roster (`~/.config/mosaic/fleet/roster.yaml`, `agents/`). - Planners run on socket `default`; the roster declares `mosaic-fleet`. This is the exact - "one roster-owned socket/host + quarantine unmanaged + stale GC" failure P-FLEET-001 indicts — - observed on the remediation mission's own fleet. Prerequisite for INBOX identity-addressing. -- **D-4 / P-LIFECYCLE + hygiene — a dispatched agent silently IGNORED an in-message context reset.** - planner-sol was at 64.3%/372k; the brief asked it to reset first; it began work on dirty context anyway. - Only an out-of-band `/new` driven by the orchestrator guaranteed clean state. Confirms the postmortem - thesis: **instructions are not enforcement.** Reset must be a mechanical pre-dispatch step, not a request. +> Newest first. Oldest entries roll to `BOARD-LEDGER.md` via `board-roll.sh` when this file +> exceeds its 8 KB cap. Keystone detail is duplicated in `TASKS.md` §1a, so rolling loses nothing. -- **D-6 / P-QUEUE-001 — the mandated queue guard returned PASS on an UNKNOWN state, live, today.** - Running the required `ci-queue-wait.sh --purpose push` before pushing produced - `state=unknown ... exit 0` — the exact defect at `ci-queue-wait.sh:282-288` that PR #1023 is parked - on. It also evaluated `branch=main` rather than the branch being pushed. The mission's own required - pre-push gate passed me on an indeterminate result. Third independent live instance of the class. -- **D-5 / P-QUEUE-001 + P-CONFORMANCE-001 — KEYSTONE: an inert gate that erased its own evidence.** - Merged PR #868 (`b79336a8`) shipped a file that FAILS `pnpm format:check` ⇒ the CI format gate did - not block. An unrelated later PR (#872) then reformatted that file via its own `lint-staged`, so - `main` went green again and nobody learned the gate had failed to fire. Verified blob-level under the - repo's own config. **Detection must be per-merge-commit against that commit's own tree** — a "is main - green today" check reports all-clear on this exact defect. Binding on RM-02/RM-55. Full chain in - `TASKS.md` §1a. NOT quiet-patched, by Mos's ruling: patching the symptom destroys the signal. + + +### **D-7 / P-FLEET-001 — stale-GC-on-disk: shared 30G /tmp hit 100% ENOSPC, degrading two seats.** + +~5.2G was session scratch dead 8-9 days (this session's own footprint: 88K). Same missing capability as orphaned-tmux-session GC, applied to disk — not a quota or discipline problem. Resolved manually by Mos (lead coordinator) after independent verification; `/tmp` now 79%. **The gap IS the finding:** the authority to reap exists, the deterministic reaper does not. Folded into RM-50 with explicit requirements (mechanical liveness, age threshold, dry-run, audit event per reap — never a heuristic sweep). Refusing to unilaterally delete another session's scratch was correct doctrine; the fix is a reaper, not braver agents. + +### **D-6 / P-QUEUE-001 — the mandated queue guard returned PASS on an UNKNOWN state, live, today.** + +Running the required `ci-queue-wait.sh --purpose push` before pushing produced `state=unknown ... exit 0` — the exact defect at `ci-queue-wait.sh:282-288` that PR #1023 is parked on. It also evaluated `branch=main` rather than the branch being pushed. The mission's own required pre-push gate passed me on an indeterminate result. Third independent live instance of the class. + +### **D-5 / P-QUEUE-001 + P-CONFORMANCE-001 — KEYSTONE: an inert gate that erased its own evidence.** + +Merged PR #868 (`b79336a8`) shipped a file that FAILS `pnpm format:check` ⇒ the CI format gate did not block. An unrelated later PR (#872) then reformatted that file via its own `lint-staged`, so `main` went green again and nobody learned the gate had failed to fire. Verified blob-level under the repo's own config. **Detection must be per-merge-commit against that commit's own tree** — a "is main green today" check reports all-clear on this exact defect. Binding on RM-02/RM-55. Full chain in `TASKS.md` §1a. NOT quiet-patched, by Mos's ruling: patching the symptom destroys the signal. + +### **D-4 / P-LIFECYCLE + hygiene — a dispatched agent silently IGNORED an in-message context reset.** + +planner-sol was at 64.3%/372k; the brief asked it to reset first; it began work on dirty context anyway. Only an out-of-band `/new` driven by the orchestrator guaranteed clean state. Confirms the postmortem thesis: **instructions are not enforcement.** Reset must be a mechanical pre-dispatch step, not a request. + +### **D-3 / P-FLEET-001 — the seats running this mission are UNMANAGED.** `mos-remediation`, `rev-974`, + +`planner-opus`, `planner-sol` appear in NO roster (`~/.config/mosaic/fleet/roster.yaml`, `agents/`). Planners run on socket `default`; the roster declares `mosaic-fleet`. This is the exact "one roster-owned socket/host + quarantine unmanaged + stale GC" failure P-FLEET-001 indicts — observed on the remediation mission's own fleet. Prerequisite for INBOX identity-addressing. + +### **D-2 / hygiene — husky `prepare` fails `EPERM` copying into root-owned `.husky/_/`.** Repo working + +tree has root-owned dirs (`.husky/`, repo root) under a non-root agent. Worked around with the intended `HUSKY=0` escape hatch (does NOT disable the existing pre-commit/pre-push hooks). + + ## Decisions log diff --git a/docs/remediation/TASKS.md b/docs/remediation/TASKS.md index 4216d6bd..c382c4bc 100644 --- a/docs/remediation/TASKS.md +++ b/docs/remediation/TASKS.md @@ -116,6 +116,27 @@ tmux-session GC. **Added to RM-01 as acceptance criteria:** heavy build artifacts (node_modules, package stores, build output) must land on the main disk in the worktree, never on the shared 30 G `/tmp`. +**Resolution, and the part that is actually the finding.** Mos verified the attribution independently +(mtimes, no process or `lsof` holding either path, no live session maps) and reaped both as lead +coordinator: `/tmp` went to 79%, 6.0 G free. But note _how_ it was resolved — **a human-authority seat +did it by hand, because the authority exists and the reaper does not.** That gap is the finding, not +the disk usage. + +Two doctrine points fall out, both binding on RM-50: + +1. **The fix is not "agents should tidy up."** Asking each seat to clean its own scratch is + `instructions are not enforcement` (D-4) wearing a different hat. A deterministic reaper must own + it — same conclusion the north star reaches for every other class in this mission. +2. **Refusing to unilaterally delete another session's scratch was correct, and the resolution is not + "be braver about deleting."** An agent guessing that someone else's state is garbage is exactly the + unreviewed destructive act the Constitution forbids. The resolution is that _ownership and liveness + become mechanically decidable_, so reaping is a determination rather than a judgement call. + +**Reaper requirements for RM-50:** liveness determined mechanically (process/`lsof`/session-map, not +mtime alone); an age threshold; a dry-run that reports what it would reap and why; and an audit event +per reap. Never a heuristic sweep — that would reintroduce the P-WORKFLOW-001 auto-sync failure in a +more destructive form. + **The self-erasure is the important part.** An inert gate that is masked by unrelated downstream commits produces no lasting artifact, which is precisely why this class survives for months. Detection cannot rely on "is `main` currently red" — it must be per-merge-commit. @@ -237,7 +258,7 @@ spread is itself information, and X1 says we calibrate on real merged PRs. | id | task | src | depends_on | est (S/O) | tier | | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -------------------------- | ---------------- | ------ | -| RM-50 | One roster-owned socket/host; quarantine unmanaged; stale-session GC | O+S | RM-04 | 14K / 150K | sonnet | +| RM-50 | One roster-owned socket/host; quarantine unmanaged; **deterministic reaper for stale sessions AND dead-session disk scratch** (D-7) | O+S+live | RM-04 | 14K / 150K | sonnet | | RM-51 | Auto-sync **allowlist** (never auto-stage unknown paths) + worktree/lease isolation | O+S | RM-02 | 8K / 110K | sonnet | | RM-52 | Retire the Python controller + duplicate MACP islands (3 → 1) | O+S | RM-26, RM-27, RM-25, RM-28 | 14K / 110K | codex | | RM-53 | Flat-file orchestration → DB hard cutover, with rehearsed rollback artifact | O+S | RM-27, RM-30, RM-34, RM-29 | (in S-10) / 200K | opus |