Files
multi-agent-mux/tests/fixtures/issue_5/watcher/manifest.json
T
GodopuandClaude Opus 5 964abc6965 feat(issue-5): shadow watcher that logs would-complete and cannot write
policy.decide is a pure function so the phase-0 scenario fixtures can be fed to
it verbatim. Those seven decisions survived three-reviewer scrutiny, so they are
the contract rather than a fresh set of rules, and the test asserts against
expected_policy.decision directly.

Order inside the policy matters. Transport doubt and staleness invalidate the
evidence itself, so they are answered before anything is inferred from it; a
blocked agent is waiting for a human and can never be completed; attribution
including the execution anchor comes before quiescence, because idle is not
evidence of finishing when a session is reused; and a report must be finalized,
never merely paused, since a debounce is a candidate filter and not an authority.

The shadow runner is never handed the engine, so it has no route to a write.
That is the structural half of P2A-03. The measured half hashes every file under
the registry directory around a full run and asserts it is unchanged, which is a
stronger claim than checking a status field.

Adds the five scenarios P2A-04 requires: a raced double dispatch, a reused
attempt with no anchor, a mid-write report, an unknown status, and a pane
restarted mid-flight. They pass phase 0's own fixture validator, which is what
keeps them honest. The phase-0 test that pinned exactly seven scenarios now
requires the seven to still exist rather than forbidding growth.

Also pins the two phase 1 handoffs as dormant: nothing here spawns a daemon, so
preexec_fn stays unreachable, and nothing calls a frozen shell helper.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd
2026-09-06 18:56:35 +09:00

79 lines
3.4 KiB
JSON

{
"schema_version": "1.0.0",
"description": "Multi-channel Watcher composite timeline scenario manifest",
"scenarios": {
"initial_idle": {
"file": "initial_idle.json",
"provenance": "simulated",
"expected_decision": "hold",
"description": "Dispatch record exists and native status is idle, but no execution anchor observed since dispatch_ack. Inferred completion must be held."
},
"tool_running": {
"file": "tool_running.json",
"provenance": "simulated",
"expected_decision": "hold",
"description": "Native status working or interactive_ready with active background tool execution. Inferred completion must be held."
},
"report_pause_15s": {
"file": "report_pause_15s.json",
"provenance": "simulated",
"expected_decision": "hold",
"description": "Partial report written and stable for >= 15s debounce, but lacks atomic finalization manifest. Completion must be held."
},
"finalized_candidate": {
"file": "finalized_candidate.json",
"provenance": "simulated",
"expected_decision": "candidate_approved",
"description": "Execution anchor verified, native status idle/done, atomic rename complete with valid SHA-256 commit manifest. Inferred candidate approved for CAS."
},
"blocked_permission": {
"file": "blocked_permission.json",
"provenance": "simulated",
"expected_decision": "hold_blocked",
"description": "Native status blocked on interactive permission prompt. Completion forbidden."
},
"transport_disconnected": {
"file": "transport_disconnected.json",
"provenance": "simulated",
"expected_decision": "hold_reconnect",
"description": "Herdr socket connection failure or freshness gap. Cached evidence invalidated; must reconnect and resnapshot."
},
"restarted_generation": {
"file": "restarted_generation.json",
"provenance": "simulated",
"expected_decision": "reject_stale",
"description": "Pane process restarted with new PID/start time; stale attempt rejected."
},
"race_double_dispatch": {
"file": "race_double_dispatch.json",
"provenance": "simulated",
"expected_decision": "reject_stale",
"description": "Two dispatches raced; the observed signal carries the previous process generation. The stale attempt must not decide anything."
},
"attempt_reuse": {
"file": "attempt_reuse.json",
"provenance": "simulated",
"expected_decision": "hold",
"description": "The same session was reused for a new attempt whose execution was never observed. Idle here is leftover quiescence from the prior attempt."
},
"partial_report": {
"file": "partial_report.json",
"provenance": "simulated",
"expected_decision": "hold",
"description": "A report is mid-write: bytes on disk but no atomic rename and no commit manifest."
},
"unknown_status": {
"file": "unknown_status.json",
"provenance": "simulated",
"expected_decision": "hold",
"description": "Native status is unknown. An unreadable state is not a quiescent one."
},
"restart_midflight": {
"file": "restart_midflight.json",
"provenance": "simulated",
"expected_decision": "reject_stale",
"description": "The pane was restarted mid-flight, so the idle signal comes from a different pane than the one dispatched to."
}
}
}