Skip to content

F1: one stale registry done state silently voids FOUR ratified contracts on the default path (U6, U8/#404, P11 closure, #378 guard) #457

Description

@EtanHey

Source: P12 adversarial evaluation, finding F1 · HIGHdocs.local/plan/stability-v2/phase-12/evaluation.md:60-83
Evaluated against the deployed build: brew list --versions cmuxlayer0.4.46, daemon from /opt/homebrew/Cellar/cmuxlayer/0.4.46/libexec/dist/, git log HEAD = 4a88b43.

Related: #408 (registry marks live idle agents "done") is the upstream cause. This issue tracks the composition consequence: that one stale field silently voids four separate ratified contracts at once, on the default path.

Evidence (verbatim from the evaluation, evaluation.md:60-83)

F1 · HIGH · One stale registry state silently disables four contracts

TERMINAL_AGENT_STATES = new Set(["done","error"]) (server.ts:497) and
resolveCurrentCallerAgent filters those records out (server.ts:3541-3556). The registry marks live
agents done within minutes (#408, open, not on the residual list). Consequences, all observed in
one list_agents response for my own live seat:

Fix direction: resolve callers and closure from the live-derived state (P4 already computes it),
not the registry record. One change closes four contract holes.

The four consequences, restated

  1. U6 identity triple non-null — VIOLATED on the default path. Spawned children get parent_agent_id: null, spawn_depth: 0.
  2. U8 / fix: make agent delivery receipts trustworthy #404 delivery regression. send_to returns a terminal delivery:"failed" against an idle-ready agent at a live prompt — ledger row docs: proper README — 221 tests, 1,423x speedup, 10 MCP tools #4, still live on 0.4.46.
  3. P11 Contract C closure invariant — VIOLATED. closure:"artifact_missing" on a working agent, at default detail, with the disqualifying caveat only visible at health detail:"full".
  4. spawn_agent: role is inferred from the CLI/launcher, so every Claude reviewer lands in the orchestrator column #378 placement guard silently dead. callerIsWorker can never be true for a stale-done caller, so the fix for the 3×-recurring ledger fix: model extraction for narrow panes and no-cost status lines #13/fix: recover read_screen parser fallbacks #15/fix: infer context for truncated claude panes #16 "reviewer in the lead column" class no-ops.

Fix direction

Resolve callers and closure from the live-derived state (P4/U7 already computes it), not the registry record. Per the evaluation's verdict (evaluation.md:196-200): "Fix F1 first: it is one change to the state source, and it closes U6, the U8 false-failure class, P11's closure invariant, and the #378 guard together."

Evaluation: docs.local/plan/stability-v2/phase-12/evaluation.md


— cmuxlayer-issue-filer (worker) · claude-code/claude-opus-5

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions