docs(runner): add status authority phase 5 conformance

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-08-07 16:24:58 +00:00
1 parent 56606e1d16
commit 9349db8438
5 files changed
+1069 -45

No files matched your search

+1
View File
@@ -42,6 +42,7 @@
"check:token-gates": "node scripts/check-token-gates.mjs",
"check:no-git-push": "node scripts/check-no-git-push.mjs",
"check:runner-phase4-spec": "node scripts/check-runner-phase4-spec.mjs",
"check:runner-phase5-spec": "node scripts/check-runner-phase5-spec.mjs",
"test:check-no-git-push": "node --test scripts/check-no-git-push.test.mjs",
"test:install-sh-docker": "./scripts/test-install-sh-docker.sh",
"test:hermes-gateway-smoke": "node --test scripts/smoke/hermes-gateway-smoke.test.mjs",
@@ -0,0 +1,475 @@
{
"schema": "paperclip.status-authority-conformance.v1",
"corpusRevision": 1,
"policyVersion": "status-authority-v1",
"fixtures": [
{
"id": "native-mechanical-completion",
"mode": "native",
"covers": { "decisionRows": ["SD-01"], "terminalRows": ["TC-01"], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["deterministic_replay"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "mechanically_satisfied", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "done", "reasonCode": "completion_contract_satisfied", "requiredEffects": ["release_checkout"], "forbiddenEffects": ["bind_reviewer", "bind_blocker"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "native-low-risk-policy-claim",
"mode": "native",
"covers": { "decisionRows": ["SD-02"], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["native_legacy_distinction"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "low_risk_policy_claim", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "done", "reasonCode": "completion_claim_policy_accepted", "requiredEffects": ["release_checkout"], "forbiddenEffects": ["create_interaction"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "premature-done-missing-evidence",
"mode": "native",
"covers": { "decisionRows": ["SD-03"], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["premature_done_claim", "incomplete_evidence", "partial_progress", "atomic_liveness"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "missing_required_test", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "completion_evidence_incomplete", "requiredEffects": ["enqueue_continuation"], "forbiddenEffects": ["release_checkout_as_done"], "livePathKind": "continuation", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "incomplete-evidence-no-live-path",
"mode": "native",
"covers": { "decisionRows": ["SD-03"], "terminalRows": [], "attentionRows": [], "livenessRows": ["LIVE-06"], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["incomplete_evidence", "atomic_liveness"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "missing_required_test", "trigger": "runner_finalizer", "fault": "continuation_insert_failure" },
"expected": { "runStatus": "failed", "statusAction": "preserve", "reasonCode": "side_effect_planning_failed", "requiredEffects": ["record_finalization_error"], "forbiddenEffects": ["enqueue_continuation", "status_version_increment"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "prior-status-preserved-without-live-path",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["atomic_liveness", "reconciliation"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "no_durable_continuation", "trigger": "runner_finalizer" },
"expected": { "runStatus": "failed", "statusAction": "preserve", "reasonCode": "prior_status_preserved_no_live_path", "requiredEffects": ["record_finalization_error"], "forbiddenEffects": ["set_issue_status", "enqueue_continuation", "bind_blocker", "bind_reviewer"], "livePathKind": "recovery", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "required-subjective-review",
"mode": "native",
"covers": { "decisionRows": ["SD-04"], "terminalRows": [], "attentionRows": [], "livenessRows": ["LIVE-01"], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["required_review", "atomic_liveness"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "needs_review", "nativeFinalization": "present", "completionState": "named_reviewer_required", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "in_review", "reasonCode": "completion_review_required", "requiredEffects": ["bind_reviewer", "notify_owner"], "forbiddenEffects": ["bind_blocker"], "livePathKind": "review", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 1 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "required-governed-review",
"mode": "native",
"covers": { "decisionRows": ["SD-04"], "terminalRows": [], "attentionRows": ["ATT-08"], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["required_review", "excessive_human_request"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "needs_review", "nativeFinalization": "present", "completionState": "governed_gate_pending", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "in_review", "reasonCode": "governed_gate_pending", "requiredEffects": ["create_interaction", "notify_owner"], "forbiddenEffects": ["attention_routed_to_agent"], "livePathKind": "interaction", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 1 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "review-side-effect-rollback",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": ["LIVE-02"], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["required_review", "atomic_liveness"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "needs_review", "nativeFinalization": "present", "completionState": "review_required", "trigger": "runner_finalizer", "fault": "reviewer_insert_failure" },
"expected": { "runStatus": "failed", "statusAction": "preserve", "reasonCode": "side_effect_planning_failed", "requiredEffects": ["record_finalization_error"], "forbiddenEffects": ["bind_reviewer", "notify_owner", "status_version_increment"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "invalid-native-result",
"mode": "native",
"covers": { "decisionRows": ["SD-05"], "terminalRows": ["TC-08"], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": ["COMP-02"], "migrationRows": [] },
"tags": ["native_legacy_distinction", "reconciliation"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": null, "nativeFinalization": "invalid", "completionState": "safe_partial_parse", "trigger": "runner_finalizer" },
"expected": { "runStatus": "failed", "statusAction": "preserve", "reasonCode": "native_finalization_invalid", "requiredEffects": ["record_finalization_error"], "forbiddenEffects": ["legacy_finalizer", "bind_blocker", "bind_reviewer"], "livePathKind": "recovery", "preserveClaim": true, "nativeRecords": true, "decisionCount": 0, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "valid-yielded-continuation",
"mode": "native",
"covers": { "decisionRows": ["SD-06"], "terminalRows": ["TC-05"], "attentionRows": [], "livenessRows": ["LIVE-05"], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["continuation", "partial_progress", "atomic_liveness"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "interrupted", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "valid_continuation", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "live_continuation_registered", "requiredEffects": ["enqueue_continuation"], "forbiddenEffects": ["bind_blocker"], "livePathKind": "continuation", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 3, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "false-task-wide-blocker",
"mode": "native",
"covers": { "decisionRows": ["SD-07"], "terminalRows": [], "attentionRows": ["ATT-05"], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["false_blocker", "excessive_human_request", "continuation"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "blocked", "nativeFinalization": "present", "completionState": "alternate_track_runnable", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "turn_waiting_other_track_live", "requiredEffects": ["enqueue_continuation"], "forbiddenEffects": ["bind_blocker", "create_interaction"], "livePathKind": "continuation", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "real-task-wide-blocker",
"mode": "native",
"covers": { "decisionRows": ["SD-08"], "terminalRows": [], "attentionRows": [], "livenessRows": ["LIVE-03"], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["real_blocker", "atomic_liveness"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "blocked", "nativeFinalization": "present", "completionState": "task_wide_owner_action_bound", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "blocked", "reasonCode": "task_wide_blocker_bound", "requiredEffects": ["bind_blocker", "notify_owner"], "forbiddenEffects": ["enqueue_continuation"], "livePathKind": "blocker", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 1 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "blocker-side-effect-rollback",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": ["LIVE-04"], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["real_blocker", "atomic_liveness"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "blocked", "nativeFinalization": "present", "completionState": "task_wide_owner_action_bound", "trigger": "runner_finalizer", "fault": "blocker_insert_failure" },
"expected": { "runStatus": "failed", "statusAction": "preserve", "reasonCode": "side_effect_planning_failed", "requiredEffects": ["record_finalization_error"], "forbiddenEffects": ["bind_blocker", "notify_owner", "status_version_increment"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "question-resolved-from-context",
"mode": "native",
"covers": { "decisionRows": ["SD-09"], "terminalRows": [], "attentionRows": ["ATT-01"], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["excessive_human_request", "repeated_question"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "context_answer_current", "trigger": "attention_response" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "attention_resolved_from_context", "requiredEffects": ["enqueue_continuation"], "forbiddenEffects": ["create_interaction", "notify_owner"], "livePathKind": "continuation", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "human-request-routed-to-agent",
"mode": "native",
"covers": { "decisionRows": ["SD-10"], "terminalRows": [], "attentionRows": ["ATT-04"], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["excessive_human_request"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "ordinary_domain_expertise", "trigger": "attention_candidate" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "attention_routed_to_agent", "requiredEffects": ["create_delegated_issue", "enqueue_continuation"], "forbiddenEffects": ["create_interaction"], "livePathKind": "delegated_issue", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 1 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "human-authority-required",
"mode": "native",
"covers": { "decisionRows": ["SD-11"], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["required_review"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "needs_review", "nativeFinalization": "present", "completionState": "intentional_human_judgment", "trigger": "attention_candidate" },
"expected": { "runStatus": "succeeded", "statusAction": "in_review", "reasonCode": "attention_requires_human_authority", "requiredEffects": ["create_interaction", "notify_owner"], "forbiddenEffects": ["bind_blocker"], "livePathKind": "interaction", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 1 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "duplicate-and-fresh-key-question",
"mode": "native",
"covers": { "decisionRows": ["SD-12"], "terminalRows": [], "attentionRows": ["ATT-02", "ATT-03"], "livenessRows": [], "reconciliationRows": ["REC-02"], "compatibilityRows": [], "migrationRows": [] },
"tags": ["repeated_question", "excessive_human_request", "deterministic_replay"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "equivalent_attention_family", "trigger": "attention_candidate" },
"expected": { "runStatus": "succeeded", "statusAction": "preserve", "reasonCode": "attention_duplicate_suppressed", "requiredEffects": ["link_canonical_request"], "forbiddenEffects": ["create_interaction", "notify_owner", "enqueue_continuation"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 6, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "attention-budget-exhausted",
"mode": "native",
"covers": { "decisionRows": ["SD-13"], "terminalRows": [], "attentionRows": ["ATT-07", "ATT-12"], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["excessive_human_request", "repeated_question", "reconciliation"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "resolver_budget_exhausted", "trigger": "attention_candidate" },
"expected": { "runStatus": "failed", "statusAction": "preserve", "reasonCode": "attention_budget_exhausted", "requiredEffects": ["record_finalization_error"], "forbiddenEffects": ["create_interaction", "bind_blocker", "bind_reviewer"], "livePathKind": "recovery", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 8, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "failed-run-partial-evidence",
"mode": "native",
"covers": { "decisionRows": ["SD-14"], "terminalRows": ["TC-02"], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["partial_progress", "partial_evidence_before_failure"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "failed", "runTerminalState": "failed", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "partial_evidence_persisted", "trigger": "runner_finalizer" },
"expected": { "runStatus": "failed", "statusAction": "preserve", "reasonCode": "run_failed_partial_evidence_preserved", "requiredEffects": ["schedule_retry"], "forbiddenEffects": ["release_checkout_as_done"], "livePathKind": "retry", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "completion-report-finalization-failure",
"mode": "native",
"covers": { "decisionRows": ["SD-15"], "terminalRows": ["TC-03"], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["finalization_failure", "partial_evidence_before_failure", "reconciliation"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "failed", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "claim_before_workspace_failure", "trigger": "runner_finalizer", "fault": "workspace_finalize_failure" },
"expected": { "runStatus": "failed", "statusAction": "preserve", "reasonCode": "finalization_failed_claim_preserved", "requiredEffects": ["record_finalization_error"], "forbiddenEffects": ["release_checkout_as_done"], "livePathKind": "recovery", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "turn-only-cancellation",
"mode": "native",
"covers": { "decisionRows": ["SD-16"], "terminalRows": ["TC-06"], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["cancellation_scope"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "cancelled", "runTerminalState": "active", "reportedWorkDisposition": null, "nativeFinalization": "present", "completionState": "turn_scope", "trigger": "authorized_agent" },
"expected": { "runStatus": "running", "statusAction": "preserve", "reasonCode": "cancellation_turn_only", "requiredEffects": ["accept_replacement_turn"], "forbiddenEffects": ["cancel_issue", "release_run_resources"], "livePathKind": "continuation", "preserveClaim": false, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "run-only-cancellation",
"mode": "native",
"covers": { "decisionRows": ["SD-17"], "terminalRows": ["TC-06"], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["cancellation_scope"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "cancelled", "runTerminalState": "cancelled", "reportedWorkDisposition": null, "nativeFinalization": "present", "completionState": "run_scope", "trigger": "authorized_agent" },
"expected": { "runStatus": "cancelled", "statusAction": "preserve", "reasonCode": "cancellation_run_only", "requiredEffects": ["release_run_resources"], "forbiddenEffects": ["cancel_issue"], "livePathKind": null, "preserveClaim": false, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "issue-cancellation-authorized",
"mode": "native",
"covers": { "decisionRows": ["SD-18"], "terminalRows": ["TC-07"], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["cancellation_scope"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "cancelled", "runTerminalState": "cancelled", "reportedWorkDisposition": null, "nativeFinalization": "present", "completionState": "issue_scope_authorized", "trigger": "board_user" },
"expected": { "runStatus": "cancelled", "statusAction": "cancelled", "reasonCode": "cancellation_issue_authorized", "requiredEffects": ["release_checkout", "cancel_continuations"], "forbiddenEffects": ["authorized_resume"], "livePathKind": null, "preserveClaim": false, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 1 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "new-evidence-supersedes-decision",
"mode": "native",
"covers": { "decisionRows": ["SD-19"], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": ["REC-07"], "compatibilityRows": [], "migrationRows": [] },
"tags": ["supersession", "deterministic_replay", "reconciliation"],
"given": { "priorIssueStatus": "in_review", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "new_evidence_satisfies_contract", "trigger": "interaction" },
"expected": { "runStatus": "succeeded", "statusAction": "done", "reasonCode": "decision_superseded_by_new_evidence", "requiredEffects": ["release_checkout"], "forbiddenEffects": ["replay_superseded_effect"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 2, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 3, "sameDecisionDigest": false, "maxSemanticDecisions": 2, "maxDomainEffectsPerKey": 1 }
},
{
"id": "dependency-resolution-supersession",
"mode": "native",
"covers": { "decisionRows": ["SD-19"], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["supersession", "continuation"],
"given": { "priorIssueStatus": "blocked", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": "blocked", "nativeFinalization": "present", "completionState": "dependency_now_done", "trigger": "dependency" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "dependency_resolved", "requiredEffects": ["enqueue_continuation"], "forbiddenEffects": ["duplicate_dependency_wake"], "livePathKind": "continuation", "preserveClaim": true, "nativeRecords": true, "decisionCount": 2, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 3, "sameDecisionDigest": false, "maxSemanticDecisions": 2, "maxDomainEffectsPerKey": 1 }
},
{
"id": "authorized-resume-terminal-issue",
"mode": "native",
"covers": { "decisionRows": ["SD-19"], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": ["COMP-05"], "migrationRows": [] },
"tags": ["authorized_resume", "supersession", "existing_issue_state"],
"given": { "priorIssueStatus": "done", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": null, "nativeFinalization": "present", "completionState": "explicit_resume_capability", "trigger": "board_user" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "authorized_resume", "requiredEffects": ["enqueue_continuation"], "forbiddenEffects": ["late_result_reopen"], "livePathKind": "continuation", "preserveClaim": false, "nativeRecords": true, "decisionCount": 2, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": false, "maxSemanticDecisions": 2, "maxDomainEffectsPerKey": 1 }
},
{
"id": "interrupted-active-run",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": ["TC-04"], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["continuation"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "interrupted", "runTerminalState": "active", "reportedWorkDisposition": null, "nativeFinalization": "present", "completionState": "replacement_turn_accepted", "trigger": "runner_finalizer" },
"expected": { "runStatus": "running", "statusAction": "preserve", "reasonCode": null, "requiredEffects": ["accept_replacement_turn"], "forbiddenEffects": ["finalize_run", "set_issue_status"], "livePathKind": "continuation", "preserveClaim": false, "nativeRecords": true, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
},
{
"id": "retry-succeeds-before-escalation",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": ["ATT-06"], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["excessive_human_request"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "transient_retry_then_success", "trigger": "attention_candidate" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "attention_resolved_from_context", "requiredEffects": ["enqueue_continuation"], "forbiddenEffects": ["create_delegated_issue", "create_interaction"], "livePathKind": "continuation", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "cross-company-attention-rejected",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": ["ATT-09"], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["excessive_human_request"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "cross_company_target", "trigger": "attention_candidate" },
"expected": { "runStatus": "failed", "statusAction": "preserve", "reasonCode": "result_schema_rejected", "requiredEffects": ["record_finalization_error"], "forbiddenEffects": ["create_interaction", "notify_owner", "enqueue_continuation"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
},
{
"id": "stale-attention-response",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": ["ATT-10"], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["supersession", "repeated_question"],
"given": { "priorIssueStatus": "in_review", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": null, "nativeFinalization": "present", "completionState": "response_after_supersession", "trigger": "interaction" },
"expected": { "runStatus": "succeeded", "statusAction": "preserve", "reasonCode": "attention_duplicate_suppressed", "requiredEffects": ["record_stale_response"], "forbiddenEffects": ["enqueue_continuation", "set_issue_status"], "livePathKind": null, "preserveClaim": false, "nativeRecords": true, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 3, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
},
{
"id": "expired-human-interaction",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": ["ATT-11"], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": [] },
"tags": ["repeated_question", "excessive_human_request"],
"given": { "priorIssueStatus": "in_review", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": null, "nativeFinalization": "present", "completionState": "interaction_expired", "trigger": "monitor" },
"expected": { "runStatus": "succeeded", "statusAction": "preserve", "reasonCode": "attention_budget_exhausted", "requiredEffects": ["record_expiry"], "forbiddenEffects": ["recreate_equivalent_interaction"], "livePathKind": "recovery", "preserveClaim": false, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 3, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "identical-result-replay",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": ["REC-01"], "compatibilityRows": [], "migrationRows": [] },
"tags": ["deterministic_replay"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "identical_result_before_ack", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "done", "reasonCode": "completion_contract_satisfied", "requiredEffects": ["release_checkout"], "forbiddenEffects": ["duplicate_decision", "duplicate_effect"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 3, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "caller-id-mutation-conflict",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": ["REC-03"], "compatibilityRows": [], "migrationRows": [] },
"tags": ["deterministic_replay"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "reused_id_changed_material", "trigger": "runner_finalizer" },
"expected": { "runStatus": "failed", "statusAction": "preserve", "reasonCode": "structured_result_replay_conflict", "requiredEffects": ["record_finalization_error"], "forbiddenEffects": ["set_issue_status", "notify_owner", "enqueue_continuation"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
},
{
"id": "crash-before-workspace-finalization",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": ["REC-04"], "compatibilityRows": [], "migrationRows": [] },
"tags": ["reconciliation", "deterministic_replay", "finalization_failure"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "result_preserved", "trigger": "runner_finalizer", "fault": "crash_before_workspace_finalize" },
"expected": { "runStatus": "succeeded", "statusAction": "done", "reasonCode": "completion_contract_satisfied", "requiredEffects": ["resume_workspace_operation", "release_checkout"], "forbiddenEffects": ["duplicate_workspace_finalize"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 3, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "crash-after-decision-commit",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": ["REC-05"], "compatibilityRows": [], "migrationRows": [] },
"tags": ["reconciliation", "deterministic_replay"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "decision_committed_delivery_pending", "trigger": "runner_finalizer", "fault": "crash_before_outbox_ack" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "live_continuation_registered", "requiredEffects": ["enqueue_continuation", "dispatch_pending_effect"], "forbiddenEffects": ["re_arbitrate", "duplicate_continuation"], "livePathKind": "continuation", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 3, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "board-wins-finalizer-race",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": ["REC-06"], "compatibilityRows": [], "migrationRows": [] },
"tags": ["supersession", "reconciliation"],
"given": { "priorIssueStatus": "cancelled", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "board_cancelled_before_cas", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "preserve", "reasonCode": "prior_status_terminal_preserved", "requiredEffects": ["append_superseding_assessment"], "forbiddenEffects": ["reopen_issue", "release_checkout_as_done"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 2, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": false, "maxSemanticDecisions": 2, "maxDomainEffectsPerKey": 1 }
},
{
"id": "policy-version-changes-before-replay",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": ["REC-08"], "compatibilityRows": [], "migrationRows": [] },
"tags": ["supersession", "reconciliation", "deterministic_replay"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "new_policy_requires_review", "trigger": "authorized_agent" },
"expected": { "runStatus": "succeeded", "statusAction": "in_review", "reasonCode": "completion_review_required", "requiredEffects": ["bind_reviewer", "append_superseding_assessment"], "forbiddenEffects": ["mutate_old_decision"], "livePathKind": "review", "preserveClaim": true, "nativeRecords": true, "decisionCount": 2, "maxWakeCount": 1, "maxNotificationCount": 1 },
"replay": { "attempts": 2, "sameDecisionDigest": false, "maxSemanticDecisions": 2, "maxDomainEffectsPerKey": 1 }
},
{
"id": "legacy-adapter-unchanged",
"mode": "legacy",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": ["COMP-01", "COMP-07"], "migrationRows": [] },
"tags": ["native_legacy_distinction"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": null, "nativeFinalization": "not_applicable", "completionState": "legacy_exit_zero", "trigger": "legacy_finalizer" },
"expected": { "runStatus": "legacy_derived", "statusAction": "legacy_finalizer", "reasonCode": null, "requiredEffects": ["legacy_existing_behavior"], "forbiddenEffects": ["create_completion_contract", "create_work_assessment", "create_status_decision"], "livePathKind": null, "preserveClaim": false, "nativeRecords": false, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
},
{
"id": "model-authored-native-field-ignored",
"mode": "legacy",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": ["COMP-03"], "migrationRows": [] },
"tags": ["native_legacy_distinction"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": null, "nativeFinalization": "not_applicable", "completionState": "native_field_only_in_result_json", "trigger": "legacy_finalizer" },
"expected": { "runStatus": "legacy_derived", "statusAction": "legacy_finalizer", "reasonCode": null, "requiredEffects": ["legacy_existing_behavior"], "forbiddenEffects": ["select_native_mode", "create_work_assessment"], "livePathKind": null, "preserveClaim": false, "nativeRecords": false, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
},
{
"id": "existing-open-issues-expand-only",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": ["COMP-04"], "migrationRows": [] },
"tags": ["existing_issue_state"],
"given": { "priorIssueStatus": "in_review", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": null, "nativeFinalization": "missing", "completionState": "preexisting_open_issue", "trigger": "migration" },
"expected": { "runStatus": "running", "statusAction": "preserve", "reasonCode": null, "requiredEffects": ["initialize_status_version_zero"], "forbiddenEffects": ["synthesize_contract", "synthesize_decision", "change_liveness_path"], "livePathKind": "review", "preserveClaim": false, "nativeRecords": false, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
},
{
"id": "shadow-records-remain-unapplied",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": ["COMP-06"], "migrationRows": [] },
"tags": ["native_legacy_distinction", "rollback"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "shadow_application_disabled", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "preserve", "reasonCode": "completion_contract_satisfied", "requiredEffects": ["record_shadow_decision"], "forbiddenEffects": ["set_issue_status", "dispatch_effect"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "mixed-ledger-native-legacy",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": ["COMP-07"], "migrationRows": [] },
"tags": ["native_legacy_distinction"],
"given": { "priorIssueStatus": "done", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "mixed_ledger", "trigger": "read_model" },
"expected": { "runStatus": "succeeded", "statusAction": "preserve", "reasonCode": "completion_contract_satisfied", "requiredEffects": ["render_four_layers"], "forbiddenEffects": ["decorate_legacy_row", "aggregate_modes"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "authorized-writer-version-race",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": ["COMP-08"], "migrationRows": [] },
"tags": ["existing_issue_state", "reconciliation"],
"given": { "priorIssueStatus": "in_review", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "authorized_writer_incremented_version", "trigger": "board_user" },
"expected": { "runStatus": "succeeded", "statusAction": "preserve", "reasonCode": "arbitration_conflict_reloaded", "requiredEffects": ["increment_status_version", "schedule_reconciliation"], "forbiddenEffects": ["apply_stale_decision"], "livePathKind": "recovery", "preserveClaim": true, "nativeRecords": true, "decisionCount": 2, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": false, "maxSemanticDecisions": 2, "maxDomainEffectsPerKey": 1 }
},
{
"id": "migration-expand-schema",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": ["MIG-01"] },
"tags": ["existing_issue_state", "rollback"],
"given": { "priorIssueStatus": "todo", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": null, "nativeFinalization": "missing", "completionState": "production_shaped_upgrade", "trigger": "migration" },
"expected": { "runStatus": "running", "statusAction": "preserve", "reasonCode": null, "requiredEffects": ["expand_schema", "status_version_default_zero"], "forbiddenEffects": ["rewrite_issue", "synthesize_history"], "livePathKind": null, "preserveClaim": false, "nativeRecords": false, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
},
{
"id": "migration-version-all-writers",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": ["MIG-02"] },
"tags": ["existing_issue_state"],
"given": { "priorIssueStatus": "todo", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": null, "nativeFinalization": "missing", "completionState": "authorized_status_write", "trigger": "board_user" },
"expected": { "runStatus": "running", "statusAction": "in_review", "reasonCode": null, "requiredEffects": ["increment_status_version_once", "bind_reviewer"], "forbiddenEffects": ["double_increment"], "livePathKind": "review", "preserveClaim": false, "nativeRecords": false, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 1, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
},
{
"id": "migration-read-only-compatibility",
"mode": "legacy",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": ["MIG-03"] },
"tags": ["native_legacy_distinction"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": null, "nativeFinalization": "not_applicable", "completionState": "no_native_rows", "trigger": "read_model" },
"expected": { "runStatus": "legacy_derived", "statusAction": "legacy_finalizer", "reasonCode": null, "requiredEffects": ["return_native_false"], "forbiddenEffects": ["read_error", "native_ui_decoration"], "livePathKind": null, "preserveClaim": false, "nativeRecords": false, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
},
{
"id": "migration-shadow-materialization",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": ["MIG-04"] },
"tags": ["native_legacy_distinction", "deterministic_replay"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "shadow_compute", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "preserve", "reasonCode": "completion_contract_satisfied", "requiredEffects": ["materialize_contract", "record_shadow_decision"], "forbiddenEffects": ["set_issue_status", "dispatch_effect"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "migration-shadow-comparison",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": ["MIG-05"] },
"tags": ["native_legacy_distinction", "deterministic_replay"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "classified_native_legacy_divergence", "trigger": "shadow_comparator" },
"expected": { "runStatus": "succeeded", "statusAction": "preserve", "reasonCode": "completion_evidence_incomplete", "requiredEffects": ["record_mode_labeled_divergence"], "forbiddenEffects": ["apply_shadow_decision", "aggregate_modes"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "migration-internal-canary",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": ["MIG-06"] },
"tags": ["atomic_liveness", "native_legacy_distinction"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "allowlisted_company_adapter_policy", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "live_continuation_registered", "requiredEffects": ["enqueue_continuation", "record_mode_native"], "forbiddenEffects": ["mode_switch_mid_run"], "livePathKind": "continuation", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "migration-cohort-rollout",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": ["MIG-07"] },
"tags": ["reconciliation", "native_legacy_distinction"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "done", "nativeFinalization": "present", "completionState": "cohort_policy_pinned", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "done", "reasonCode": "completion_contract_satisfied", "requiredEffects": ["record_mode_native", "record_policy_version"], "forbiddenEffects": ["latest_policy_rebind"], "livePathKind": null, "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "migration-kill-switch-rollback",
"mode": "native",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": ["MIG-08"] },
"tags": ["rollback", "native_legacy_distinction", "reconciliation"],
"given": { "priorIssueStatus": "in_progress", "turnTerminalState": "completed", "runTerminalState": "succeeded", "reportedWorkDisposition": "yielded", "nativeFinalization": "present", "completionState": "kill_switch_during_active_native_run", "trigger": "runner_finalizer" },
"expected": { "runStatus": "succeeded", "statusAction": "in_progress", "reasonCode": "live_continuation_registered", "requiredEffects": ["enqueue_continuation", "finish_as_native", "stop_new_native_dispatch"], "forbiddenEffects": ["convert_active_run_to_legacy", "drop_coordinator"], "livePathKind": "continuation", "preserveClaim": true, "nativeRecords": true, "decisionCount": 1, "maxWakeCount": 1, "maxNotificationCount": 0 },
"replay": { "attempts": 3, "sameDecisionDigest": true, "maxSemanticDecisions": 1, "maxDomainEffectsPerKey": 1 }
},
{
"id": "migration-explicit-contract-migration",
"mode": "legacy",
"covers": { "decisionRows": [], "terminalRows": [], "attentionRows": [], "livenessRows": [], "reconciliationRows": [], "compatibilityRows": [], "migrationRows": ["MIG-09"] },
"tags": ["native_legacy_distinction", "existing_issue_state", "rollback"],
"given": { "priorIssueStatus": "done", "turnTerminalState": null, "runTerminalState": null, "reportedWorkDisposition": null, "nativeFinalization": "not_applicable", "completionState": "no_reviewed_adapter_contract_migration", "trigger": "migration" },
"expected": { "runStatus": "legacy_derived", "statusAction": "legacy_finalizer", "reasonCode": null, "requiredEffects": ["retain_legacy_mode", "retain_audit_lineage"], "forbiddenEffects": ["infer_contract_from_exit_code", "delete_history"], "livePathKind": null, "preserveClaim": false, "nativeRecords": false, "decisionCount": 0, "maxWakeCount": 0, "maxNotificationCount": 0 },
"replay": { "attempts": 2, "sameDecisionDigest": true, "maxSemanticDecisions": 0, "maxDomainEffectsPerKey": 1 }
}
]
}
@@ -511,6 +511,9 @@ server/src/services/environment-run-orchestrator.ts
- terminal conversion to `AdapterExecutionResult`;
- typed `nativeFinalization` validation and complete terminal/arbitration handling;
- server-owned status arbiter for completion, blocker, review, attention, and continuation signals;
- the shared Section 18.13 status-authority corpus consumed without changing
fixture expectations by arbiter, database, finalizer, migration, legacy, and
UI tests;
- native interaction bridge binding, materialization, continuation projection,
and response-delivery integration;
- native finalizer conformance tests for run status, issue status, continuation/review effects, and cancellation scope;
@@ -524,6 +527,8 @@ server/src/services/environment-run-orchestrator.ts
- a missing or invalid native finalization discriminator fails closed instead of using the legacy success heuristic;
- an agent signal cannot move an issue to `blocked` or `in_review` without the required blocker or review path;
- human-needed requests persist and wake the correct owner without requiring an invalid issue status;
- `pnpm check:runner-phase5-spec` passes and implementation output reports a
result for every `SD`, `TC`, `ATT`, `LIVE`, `REC`, `COMP`, and `MIG` fixture;
- a blocking semantic interaction yields only after durable materialization and
resumes with a typed response without model-visible Paperclip credentials;
- legacy integration tests are unchanged;
@@ -3497,27 +3497,27 @@ result_schema_rejected
The complete arbitration table is normative. “Preserve” means that the current issue status remains unchanged.
| Case | Authority and required inputs | Authoritative decision | Required atomic side effects and liveness | Reason code |
|---|---|---|---|---|
| Run succeeded; contract mechanically satisfied | Arbiter; accepted current-revision evidence, required artifacts, no missing criteria, no pending gate, no remaining completion work | `done` | Persist assessment/decision, compact handoff, release checkout | `completion_contract_satisfied` |
| Run succeeded; low-risk agent claims done under explicit policy | Arbiter; current claim, policy permits agent authority, no contradictory evidence or pending gate | `done` | Persist policy basis and evidence classifications, release checkout | `completion_claim_policy_accepted` |
| Run succeeded; agent claims done but required evidence or criteria are incomplete | Arbiter; completion claim plus missing/rejected/unverifiable requirements | `in_progress` only when a live path is created; otherwise preserve | Register continuation/retry/delegated verification; if none can be created, record finalization error and preserve status | `completion_evidence_incomplete` |
| Run succeeded; completion requires subjective, Security, QA, CTO, board, or governed review | Arbiter; contract gate or risk policy and a real review target | `in_review` | Atomically bind reviewer, approval, interaction, delegated review issue, or monitor that wakes the assignee | `completion_review_required` or `governed_gate_pending` |
| Structured result is invalid, stale, cross-boundary, or remains uncorrected after the bounded correction policy | Runner/finalizer + arbiter; rejected result, binding/schema failure, runtime facts, safely parsed evidence | Preserve | Persist the rejected input and reason, terminalize the run from runtime facts, and atomically create a bounded correction/recovery path when policy permits; never infer `in_review`, `blocked`, or `done` from rejection | `result_schema_rejected` |
| Run succeeded; agent reports yielded and continuation is valid | Arbiter; declared continuation with valid target/idempotency and policy budget | `in_progress` | Atomically enqueue continuation, retry, delegated issue, response wake, or monitor | `live_continuation_registered` |
| Current turn waits for an answer, but another productive track exists | Attention resolver + arbiter; `scope: current_turn` or `current_track`, alternate track and continuation | `in_progress` | Persist/rout attention and enqueue alternate productive track; do not create task-wide blocker | `turn_waiting_other_track_live` |
| A task-wide blocker prevents all productive progress | Arbiter; blocker `scope: task_wide`, concrete owner, unblock action, evidence, no alternate live track | `blocked` | Atomically bind blocker issue or named owner/action and wake/notify route | `task_wide_blocker_bound` |
| Agent asks a question answerable from durable context or policy | Attention resolver; context hit bound to request and current revision | `in_progress` only when a response wake is registered; otherwise preserve | Record answer, resolve request, wake current turn/assignee as requested | `attention_resolved_from_context` |
| Agent asks for expertise another in-company agent can supply | Attention resolver; capability match, company scope, delegation policy | `in_progress` only when delegation creates a live response path; otherwise preserve | Route request or create delegated issue with response binding and wake path | `attention_routed_to_agent` |
| Agent asks for human help and only human/board authority or intentional judgment can resolve it | Attention resolver + arbiter; authority match, company scope, dedupe/budget checks | `in_review` only for contract review; otherwise `in_progress` only with a response wake; otherwise preserve | Create board interaction/approval and required wake atomically; `scope: current_turn` alone does not set status | `attention_requires_human_authority` |
| Duplicate or repeated attention request has no new evidence | Attention resolver; same dedupe key or superseded request, no material evidence delta | Preserve | Link duplicate to canonical request; do not notify or create another interaction | `attention_duplicate_suppressed` |
| Attention retry/escalation budget is exhausted with no valid resolver | Arbiter; attempt history and failed capability routing | Preserve | Record finalization error and named recovery owner/action; never manufacture `blocked` or `in_review` | `attention_budget_exhausted` |
| Run fails after producing partial work or evidence | Runner/finalizer + arbiter; failed run facts and safely persisted result/evidence | Preserve | Persist claims/evidence, apply retry/recovery policy, schedule live path when allowed | `run_failed_partial_evidence_preserved` |
| Model reports completion but transport, workspace, or finalization later fails | Runner/finalizer + arbiter; accepted completion claim plus finalization failure | Preserve | Persist claim and evidence, mark run failed, open/schedule reconciliation; never mark done | `finalization_failed_claim_preserved` |
| Cancellation targets only the active turn | Cancellation authority; authenticated command with `scope: turn` | Preserve | Terminalize turn `cancelled`; continue or await replacement turn according to run policy | `cancellation_turn_only` |
| Cancellation targets the run, not the issue | Cancellation authority; authenticated command with `scope: run` | Preserve | Terminalize run `cancelled`, release runtime resources, keep issue available for resume | `cancellation_run_only` |
| Cancellation explicitly targets the issue | Board or otherwise authorized issue-status actor; authenticated command with `scope: issue` | `cancelled` | Cancel active turn/run, record issue transition, release checkout and continuations | `cancellation_issue_authorized` |
| Later evidence, dependency resolution, interaction response, or authorized resume changes the facts | Arbiter; new assessment, prior decision, authorized trigger | Re-evaluate to any legal status | Append superseding assessment/decision and create the required new liveness path | `decision_superseded_by_new_evidence`, `dependency_resolved`, or `authorized_resume` |
| ID | Case | Authority and required inputs | Authoritative decision | Required atomic side effects and liveness | Reason code |
|---|---|---|---|---|---|
| SD-01 | Run succeeded; contract mechanically satisfied | Arbiter; accepted current-revision evidence, required artifacts, no missing criteria, no pending gate, no remaining completion work | `done` | Persist assessment/decision, compact handoff, release checkout | `completion_contract_satisfied` |
| SD-02 | Run succeeded; low-risk agent claims done under explicit policy | Arbiter; current claim, policy permits agent authority, no contradictory evidence or pending gate | `done` | Persist policy basis and evidence classifications, release checkout | `completion_claim_policy_accepted` |
| SD-03 | Run succeeded; agent claims done but required evidence or criteria are incomplete | Arbiter; completion claim plus missing/rejected/unverifiable requirements | `in_progress` only when a live path is created; otherwise preserve | Register continuation/retry/delegated verification; if none can be created, record finalization error and preserve status | `completion_evidence_incomplete` |
| SD-04 | Run succeeded; completion requires subjective, Security, QA, CTO, board, or governed review | Arbiter; contract gate or risk policy and a real review target | `in_review` | Atomically bind reviewer, approval, interaction, delegated review issue, or monitor that wakes the assignee | `completion_review_required` or `governed_gate_pending` |
| SD-05 | Structured result is invalid, stale, cross-boundary, or remains uncorrected after the bounded correction policy | Runner/finalizer + arbiter; rejected result, binding/schema failure, runtime facts, safely parsed evidence | Preserve | Persist the rejected input and reason, terminalize the run from runtime facts, and atomically create a bounded correction/recovery path when policy permits; never infer `in_review`, `blocked`, or `done` from rejection | `result_schema_rejected` |
| SD-06 | Run succeeded; agent reports yielded and continuation is valid | Arbiter; declared continuation with valid target/idempotency and policy budget | `in_progress` | Atomically enqueue continuation, retry, delegated issue, response wake, or monitor | `live_continuation_registered` |
| SD-07 | Current turn waits for an answer, but another productive track exists | Attention resolver + arbiter; `scope: current_turn` or `current_track`, alternate track and continuation | `in_progress` | Persist/route attention and enqueue alternate productive track; do not create task-wide blocker | `turn_waiting_other_track_live` |
| SD-08 | A task-wide blocker prevents all productive progress | Arbiter; blocker `scope: task_wide`, concrete owner, unblock action, evidence, no alternate live track | `blocked` | Atomically bind blocker issue or named owner/action and wake/notify route | `task_wide_blocker_bound` |
| SD-09 | Agent asks a question answerable from durable context or policy | Attention resolver; context hit bound to request and current revision | `in_progress` only when a response wake is registered; otherwise preserve | Record answer, resolve request, wake current turn/assignee as requested | `attention_resolved_from_context` |
| SD-10 | Agent asks for expertise another in-company agent can supply | Attention resolver; capability match, company scope, delegation policy | `in_progress` only when delegation creates a live response path; otherwise preserve | Route request or create delegated issue with response binding and wake path | `attention_routed_to_agent` |
| SD-11 | Agent asks for human help and only human/board authority or intentional judgment can resolve it | Attention resolver + arbiter; authority match, company scope, dedupe/budget checks | `in_review` only for contract review; otherwise `in_progress` only with a response wake; otherwise preserve | Create board interaction/approval and required wake atomically; `scope: current_turn` alone does not set status | `attention_requires_human_authority` |
| SD-12 | Duplicate or repeated attention request has no new evidence | Attention resolver; same dedupe key or superseded request, no material evidence delta | Preserve | Link duplicate to canonical request; do not notify or create another interaction | `attention_duplicate_suppressed` |
| SD-13 | Attention retry/escalation budget is exhausted with no valid resolver | Arbiter; attempt history and failed capability routing | Preserve | Record finalization error and named recovery owner/action; never manufacture `blocked` or `in_review` | `attention_budget_exhausted` |
| SD-14 | Run fails after producing partial work or evidence | Runner/finalizer + arbiter; failed run facts and safely persisted result/evidence | Preserve | Persist claims/evidence, apply retry/recovery policy, schedule live path when allowed | `run_failed_partial_evidence_preserved` |
| SD-15 | Model reports completion but transport, workspace, or finalization later fails | Runner/finalizer + arbiter; accepted completion claim plus finalization failure | Preserve | Persist claim and evidence, mark run failed, open/schedule reconciliation; never mark done | `finalization_failed_claim_preserved` |
| SD-16 | Cancellation targets only the active turn | Cancellation authority; authenticated command with `scope: turn` | Preserve | Terminalize turn `cancelled`; continue or await replacement turn according to run policy | `cancellation_turn_only` |
| SD-17 | Cancellation targets the run, not the issue | Cancellation authority; authenticated command with `scope: run` | Preserve | Terminalize run `cancelled`, release runtime resources, keep issue available for resume | `cancellation_run_only` |
| SD-18 | Cancellation explicitly targets the issue | Board or otherwise authorized issue-status actor; authenticated command with `scope: issue` | `cancelled` | Cancel active turn/run, record issue transition, release checkout and continuations | `cancellation_issue_authorized` |
| SD-19 | Later evidence, dependency resolution, interaction response, or authorized resume changes the facts | Arbiter; new assessment, prior decision, authorized trigger | Re-evaluate to any legal status | Append superseding assessment/decision and create the required new liveness path | `decision_superseded_by_new_evidence`, `dependency_resolved`, or `authorized_resume` |
Every decision records the arbiter authority, exact input assessment, reason code, side effects, and policy version. An issue transition and its liveness side effects commit in one transaction. A failed side effect means the transition is not applied.
@@ -3744,20 +3744,20 @@ The transaction rolls back if any required liveness side effect cannot be create
This matrix is the required Phase 3 design verification. Each row has a bounded terminal routing outcome and no infinite wake edge.
| Scenario | Expected resolver outcome | Status/liveness assertion |
|---|---|---|
| Agent asks a question already answered in the current document revision | Context response with versioned source refs | No human route; one response wake at most. |
| Agent repeats the same question with the same key | Return canonical request | No new attempt, notification, status decision, or wake. |
| Agent paraphrases the same question with fresh IDs | Match equivalence family and consume the shared budget | Duplicate suppressed; fresh keys cannot reset escalation. |
| Agent requests a human for ordinary domain expertise | Reclassify to `expertise`; match an in-company agent | No human wait by default; delegation has a bound response path. |
| Agent claims `task_wide` while an independent acceptance track is runnable | Narrow to `current_turn` or `current_track` and queue the alternate track | Issue remains truthfully `in_progress`; waiting track remains durable. |
| Retry-safe tool call fails transiently, then succeeds | One bounded idempotent retry resolves it | No delegation or human route. |
| Retry-safe failure exhausts two retries | Advance once to qualified agent/recovery or truthful fallback | No retry loop and no automatic human escalation without human authority. |
| Agent labels a governed action as `requiredAuthority: none` | Policy derives the governed minimum authority | Exact approval route; expertise cannot downgrade it. |
| Candidate names an agent, user, resource, or integration in another company | Generic side-effect-free rejection | No target disclosure, route, notification, or wake. |
| Selected resolver changes or replies after supersession/expiry | Record stale response only | No issue transition, execution, or wake. |
| Human interaction expires unanswered | Resolve expiry once; use policy fallback only with a durable new state or authorized resume | At most one fallback wake; no equivalent interaction recreation loop. |
| No eligible agent, human authority, integration, or safe retry exists | Mark request exhausted and record finalization error/recovery alert | Preserve prior issue status; do not manufacture `blocked` or `in_review`. |
| ID | Scenario | Expected resolver outcome | Status/liveness assertion |
|---|---|---|---|
| ATT-01 | Agent asks a question already answered in the current document revision | Context response with versioned source refs | No human route; one response wake at most. |
| ATT-02 | Agent repeats the same question with the same key | Return canonical request | No new attempt, notification, status decision, or wake. |
| ATT-03 | Agent paraphrases the same question with fresh IDs | Match equivalence family and consume the shared budget | Duplicate suppressed; fresh keys cannot reset escalation. |
| ATT-04 | Agent requests a human for ordinary domain expertise | Reclassify to `expertise`; match an in-company agent | No human wait by default; delegation has a bound response path. |
| ATT-05 | Agent claims `task_wide` while an independent acceptance track is runnable | Narrow to `current_turn` or `current_track` and queue the alternate track | Issue remains truthfully `in_progress`; waiting track remains durable. |
| ATT-06 | Retry-safe tool call fails transiently, then succeeds | One bounded idempotent retry resolves it | No delegation or human route. |
| ATT-07 | Retry-safe failure exhausts two retries | Advance once to qualified agent/recovery or truthful fallback | No retry loop and no automatic human escalation without human authority. |
| ATT-08 | Agent labels a governed action as `requiredAuthority: none` | Policy derives the governed minimum authority | Exact approval route; expertise cannot downgrade it. |
| ATT-09 | Candidate names an agent, user, resource, or integration in another company | Generic side-effect-free rejection | No target disclosure, route, notification, or wake. |
| ATT-10 | Selected resolver changes or replies after supersession/expiry | Record stale response only | No issue transition, execution, or wake. |
| ATT-11 | Human interaction expires unanswered | Resolve expiry once; use policy fallback only with a durable new state or authorized resume | At most one fallback wake; no equivalent interaction recreation loop. |
| ATT-12 | No eligible agent, human authority, integration, or safe retry exists | Mark request exhausted and record finalization error/recovery alert | Preserve prior issue status; do not manufacture `blocked` or `in_review`. |
The implementation test plan must turn every row into a deterministic fixture that asserts canonical/equivalence identity, counters, selected route, effective scope, status decision reason, side effects, wake count, and stale-response behavior.
@@ -3830,16 +3830,16 @@ interface AdapterExecutionResult {
Native adapters must set `nativeFinalization`. The heartbeat finalizer validates it against `resultJson` and persisted terminal events, derives the heartbeat run status from `runTerminalState`, and then submits a `WorkAssessment` to the arbiter. Compatibility fields are process diagnostics only.
| Native facts | Compatibility fields | Required native behavior |
|---|---|---|
| Turn `completed`; run `succeeded`; reported disposition present | Usually `exitCode: 0`, `timedOut: false`; result in `resultJson` | Persist succeeded run and assess the report. No reported disposition maps directly to issue status. |
| Turn `failed`; run `failed`; partial result/evidence may exist | Nonzero exit when available; error metadata populated | Persist failed run, preserve partial claims/evidence, apply retry/recovery, preserve issue status unless a separate authorized decision applies. |
| Turn `completed`; run `failed` because workspace/transport/finalization failed after a report | Exit code may still be zero; finalization error identifies failure | Persist failed run and preserve the completion claim for reconciliation. Never mark the issue done. |
| Turn `interrupted`; run remains active or a replacement turn is accepted | No terminal adapter result yet | Terminalize only the turn; continue the same run/session. |
| Turn `interrupted`; run `succeeded` with valid `yielded` report and continuation | Usually `exitCode: 0` | Assess yielded work and atomically register continuation; interruption alone grants no issue transition. |
| Turn `cancelled`; run `cancelled`; scope `turn` or `run` | `exitCode: null`; cancellation diagnostics optional | Preserve issue status. Turn scope may permit replacement work; run scope releases run resources. |
| Turn/run `cancelled`; scope `issue` and actor is authorized | `exitCode: null`; cancellation command reference persisted | Arbiter applies issue `cancelled` and cancels continuations atomically. |
| Native finalization missing, inconsistent, stale, or invalid | Any compatibility values | Fail closed as `native_finalization_missing` or `native_finalization_invalid`; never use the legacy heuristic. Preserve safe evidence and create recovery. |
| ID | Native facts | Compatibility fields | Required native behavior |
|---|---|---|---|
| TC-01 | Turn `completed`; run `succeeded`; reported disposition present | Usually `exitCode: 0`, `timedOut: false`; result in `resultJson` | Persist succeeded run and assess the report. No reported disposition maps directly to issue status. |
| TC-02 | Turn `failed`; run `failed`; partial result/evidence may exist | Nonzero exit when available; error metadata populated | Persist failed run, preserve partial claims/evidence, apply retry/recovery, preserve issue status unless a separate authorized decision applies. |
| TC-03 | Turn `completed`; run `failed` because workspace/transport/finalization failed after a report | Exit code may still be zero; finalization error identifies failure | Persist failed run and preserve the completion claim for reconciliation. Never mark the issue done. |
| TC-04 | Turn `interrupted`; run remains active or a replacement turn is accepted | No terminal adapter result yet | Terminalize only the turn; continue the same run/session. |
| TC-05 | Turn `interrupted`; run `succeeded` with valid `yielded` report and continuation | Usually `exitCode: 0` | Assess yielded work and atomically register continuation; interruption alone grants no issue transition. |
| TC-06 | Turn `cancelled`; run `cancelled`; scope `turn` or `run` | `exitCode: null`; cancellation diagnostics optional | Preserve issue status. Turn scope may permit replacement work; run scope releases run resources. |
| TC-07 | Turn/run `cancelled`; scope `issue` and actor is authorized | `exitCode: null`; cancellation command reference persisted | Arbiter applies issue `cancelled` and cancels continuations atomically. |
| TC-08 | Native finalization missing, inconsistent, stale, or invalid | Any compatibility values | Fail closed as `native_finalization_missing` or `native_finalization_invalid`; never use the legacy heuristic. Preserve safe evidence and create recovery. |
All compatibility results set `signal: null` unless the harness reported a real signal. They preserve usage, cost, session, provider, model, billing, and runtime-service fields without changing their meaning. `resultJson` contains the original structured result when one exists, plus references to the assessment and status decision after arbitration.
@@ -4870,6 +4870,234 @@ affordance matrix, duplicate suppression, finalization error truthfulness,
unknown reason code fallback, clock-skew countdown, legacy fallback, and
keyboard operation of the response control.
### 18.13 Phase 5 conformance, migration, and rollback contract
Phase 5 turns the authority, resolver, finalizer, and operator contracts into an
independently executable scenario matrix. The checked-in source of truth is
[`fixtures/status-authority-phase5.json`](./fixtures/status-authority-phase5.json),
and `pnpm check:runner-phase5-spec` is the standing spec-level conformance gate.
The corpus is language-neutral: TypeScript server tests, Rust protocol tests,
the deterministic driver, migration tests, and QA harnesses consume the same
fixture IDs and expected facts. An implementation may add transport-specific
setup, but it must not rewrite an expected status, reason code, effect, count,
or compatibility mode.
Each fixture names the exact normative rows it covers:
- `SD-01`–`SD-19`: every row of the section 18.3 status-decision table;
- `TC-01`–`TC-08`: every row of the section 18.5 terminal conversion table;
- `ATT-01`–`ATT-12`: every row of the section 18.3.7 adversarial-attention table;
- `LIVE-01`–`LIVE-06`: atomic liveness success and rollback paths below;
- `REC-01`–`REC-08`: deterministic replay and reconciliation paths below;
- `COMP-01`–`COMP-08`: native/legacy and existing-state compatibility below;
- `MIG-01`–`MIG-09`: rollout, migration, rollback, and reconciliation stages below.
The fixture schema separates input facts from assertions:
```ts
interface StatusAuthorityConformanceFixtureV1 {
id: string;
mode: "native" | "legacy";
covers: {
decisionRows: string[];
terminalRows: string[];
attentionRows: string[];
livenessRows: string[];
reconciliationRows: string[];
compatibilityRows: string[];
migrationRows: string[];
};
tags: string[];
given: {
priorIssueStatus: AuthoritativeIssueStatus;
turnTerminalState: TurnTerminalState | "active" | null;
runTerminalState: RunTerminalState | "active" | null;
reportedWorkDisposition: ReportedWorkDisposition | null;
nativeFinalization: "present" | "missing" | "invalid" | "not_applicable";
completionState: string;
trigger: string;
fault?: string;
};
expected: {
runStatus: "succeeded" | "failed" | "cancelled" | "running" | "legacy_derived";
statusAction:
| AuthoritativeIssueStatus
| "preserve"
| "legacy_finalizer";
reasonCode: StatusDecisionReasonCode | string | null;
requiredEffects: string[];
forbiddenEffects: string[];
livePathKind: LivePathView["kind"] | null;
preserveClaim: boolean;
nativeRecords: boolean;
decisionCount: number;
maxWakeCount: number;
maxNotificationCount: number;
};
replay: {
attempts: number;
sameDecisionDigest: boolean;
maxSemanticDecisions: number;
maxDomainEffectsPerKey: number;
};
}
```
Fixture assertions are database assertions, not only response assertions. Every
case records the terminal turn/run facts, original result/evidence retention,
issue `status` and `status_version`, contract/policy version, assessment and
decision lineage, effect-ledger rows, domain liveness rows, outbox counts,
notifications, wakes, activity, and the coordinator phase. A failure response
with a leaked row or a correct row with an extra wake both fail conformance.
Timestamps and allocated UUIDs may differ; canonical input and decision digests,
ordered effect kinds, reason codes, and semantic counts may not.
#### 18.13.1 Required adversarial scenario inventory
The corpus must keep at least one fixture carrying each tag below. Tags are
stable QA selectors; renaming or removing one is a protocol change.
| Tag | Required behavior |
|---|---|
| `premature_done_claim` | A `done` claim with missing proof cannot set `done`; accepted claim/evidence remains inspectable. |
| `incomplete_evidence` | Missing, rejected, and unverifiable evidence stay distinct and choose continuation or truthful preservation. |
| `required_review` | Subjective/governed completion reaches `in_review` only with the matching reviewer/approval path. |
| `continuation` | A valid yielded result creates one canonical continuation and keeps the issue `in_progress`. |
| `partial_progress` | Useful partial work survives a non-terminal result and remains attached to the next run. |
| `real_blocker` | Only a task-wide stop with an owner/action and no alternate track can set `blocked`. |
| `excessive_human_request` | Agent-resolvable requests route through context, retry, or another agent before a human route. |
| `repeated_question` | Same-key and fresh-key equivalents share one canonical family and bounded counters. |
| `false_blocker` | Claimed task-wide scope is narrowed while another productive track is queued. |
| `partial_evidence_before_failure` | Failed execution preserves safely parsed evidence and never upgrades the issue from that evidence alone. |
| `finalization_failure` | A completion claim followed by workspace/transport/finalizer failure remains preserved but unapplied. |
| `cancellation_scope` | Turn, run, and issue cancellation have three intentionally different issue effects. |
| `authorized_resume` | Only an authorized trigger can supersede a terminal/waiting decision and it creates a new liveness path. |
| `supersession` | New evidence produces append-only assessment/decision lineage; stale effects do not replay. |
| `native_legacy_distinction` | Native rows use contracts/assessments/decisions; legacy rows remain on the existing finalizer and create none. |
| `existing_issue_state` | Upgrade does not synthesize history or silently rewrite open or terminal issue status. |
| `atomic_liveness` | A non-terminal status and its durable next-action path commit or roll back together. |
| `deterministic_replay` | Same canonical input/policy returns one digest and at-most-one semantic effect. |
| `reconciliation` | Crash/race recovery resumes from durable phase and appends supersession when facts changed. |
| `rollback` | Disabling native application stops new native dispatch without converting an active native run to legacy. |
#### 18.13.2 Atomic liveness fixtures
| ID | Injection | Required result |
|---|---|---|
| LIVE-01 | Valid completion-review target | `in_review`, reviewer/approval/interaction domain row, return owner, and wake outbox commit in one transaction. |
| LIVE-02 | Reviewer/interaction insert fails | Prior status/version preserved; no reviewer, notification, or wake leaks; `side_effect_planning_failed` recovery is recorded. |
| LIVE-03 | Valid task-wide blocker | `blocked`, company-scoped blocker relation or unblock descriptor, owner notification intent, and dependency wake identity commit together. |
| LIVE-04 | Blocker relation/owner binding fails | Prior status/version preserved; no `blocked` projection or owner notification leaks. |
| LIVE-05 | Valid continuation | Continued `in_progress`, cleared completed-run lock, one canonical queued continuation/response wake/monitor, and attempt budget increment commit together. |
| LIVE-06 | Continuation/outbox insert fails | Prior status/version preserved; no orphan continuation, wake, or `in_progress` transition; recovery names an owner. |
The failpoint is after validation but before transaction commit. Each failure is
replayed after the failpoint is removed to prove that rollback did not consume
the canonical idempotency key. A post-commit websocket or external-notification
failure is different: the authoritative transition stays committed and only
the existing effect-ledger row is retried.
#### 18.13.3 Deterministic replay and reconciliation fixtures
| ID | Scenario | Required result |
|---|---|---|
| REC-01 | Identical result is ingested twice before acknowledgement | One result fingerprint, assessment, decision digest, status transition, and domain effect per idempotency key. |
| REC-02 | Equivalent material arrives with fresh caller IDs/dedupe keys | Resolve to the canonical result and shared attention budget; caller keys cannot mint another semantic action. |
| REC-03 | Caller reuses an ID with changed material | `structured_result_replay_conflict`; no decision, status change, route, notification, or wake. |
| REC-04 | Finalizer crashes after result preservation and before workspace finalization | Reconciler resumes the existing workspace operation, then assesses once. |
| REC-05 | Finalizer crashes after decision commit and before outbox acknowledgement | Replay dispatches only pending effect rows; it does not re-arbitrate or duplicate a domain row. |
| REC-06 | Board update wins the status-row race | Finalizer reloads and appends a superseding assessment; stale effects remain cancelled/preserved and cannot reopen a terminal issue. |
| REC-07 | Dependency or interaction response wins the race | Superseding assessment includes the resolved fact and emits at most one newly legal continuation. |
| REC-08 | Contract or policy version changes before replay | Old inputs remain bound to their immutable versions; a new assessment uses the new versions and links, rather than mutating, the old decision. |
Every replay fixture runs once in original order, once with duplicate delivery,
and once after a simulated control-plane restart. The final database projection
and ordered semantic-effect identities must be equal. When the authoritative
facts intentionally change, only the append-only supersession chain may differ.
#### 18.13.4 Native, legacy, and existing-state compatibility
| ID | Starting condition | Compatibility behavior |
|---|---|---|
| COMP-01 | Existing adapter omits `nativeFinalization` | Select the legacy finalizer exactly as before; create no contract, result, coordinator, assessment, decision, or attention row. |
| COMP-02 | Persisted run profile is native and the discriminator is missing/invalid | Fail closed with native finalization failure and recovery; never select the legacy heuristic. |
| COMP-03 | Adapter result contains a native-looking model-authored field only inside `resultJson` | Ignore it for mode selection; the persisted run profile plus typed adapter boundary are authoritative. |
| COMP-04 | Existing issue upgraded in `todo`, `in_progress`, `in_review`, or `blocked` | Initialize `status_version = 0` without changing status, owner, blocker, review path, monitor, checkout, or timestamps; create no synthetic history. |
| COMP-05 | Existing issue upgraded in `done` or `cancelled` | Preserve terminal status/timestamps; late native evidence is audit-only unless an authorized resume/cancellation capability permits a legal new decision. |
| COMP-06 | Native application flag disabled after shadow records exist | Shadow rows remain inspectable and unapplied; legacy runs keep existing behavior; no shadow decision may dispatch an effect. |
| COMP-07 | One ledger contains native and legacy runs | Native rows expose four authority layers and decision lineage; legacy rows render the byte-identical pre-change path with `native: false`. |
| COMP-08 | Existing authorized status route races or runs during rollout | It increments `status_version` in every mode and triggers native reconciliation only when a native coordinator is active. |
There is no implicit “upgrade legacy history” job. A later migration that wants
native contracts for a legacy adapter must define how the contract is sourced,
how historical evidence is classified, and who authorizes semantic backfill.
Until then, native and legacy metrics, UI summaries, audit exports, and QA
reports carry an explicit `mode` dimension and are never aggregated as though
their completion semantics were identical.
#### 18.13.5 Rollout and migration sequence
| ID | Stage | Entry gate | Action and exit evidence |
|---|---|---|---|
| MIG-01 | Expand schema | Migration dry-run and rollback rehearsal pass on production-shaped data | Add nullable references/new tables plus `status_version default 0`; no behavior or issue-state change. |
| MIG-02 | Version all writers | Every issue-status mutation test asserts one `status_version` increment | Deploy writer compatibility before any native arbiter can apply decisions. |
| MIG-03 | Read-only compatibility | Legacy UI/API snapshots and cross-company read tests pass | Ship read types/routes behind flags; missing native rows are an intentional `native: false`/`404`, not an error. |
| MIG-04 | Shadow materialization | Contract/result redaction, digest, and storage tests pass | Materialize native contracts/results and compute assessments/decisions with effect dispatch disabled. |
| MIG-05 | Shadow comparison | Complete Phase 5 corpus passes and divergence dashboard labels expected legacy/native differences | Compare proposed native decisions with existing behavior; reconcile or classify every unexplained divergence. |
| MIG-06 | Internal canary | QA accepts the complete matrix; Security/CTO gates remain satisfied | Enable application for allowlisted company + adapter profile + policy version; keep per-run mode immutable. |
| MIG-07 | Cohort rollout | Canary has no unreconciled coordinator, liveness-integrity, cross-company, or duplicate-effect failures | Increase cohorts by company/adapter profile; pin policy/algorithm versions for in-flight runs. |
| MIG-08 | Disable/rollback | Kill-switch drill and active-run inventory are available | Stop new native dispatch/application, retain read visibility, let active native runs finish/reconcile as native, and send later attempts to legacy only when their profile is newly selected as legacy. |
| MIG-09 | Contract migration or cleanup | Explicit reviewed migration exists for each adapter family | Only then migrate a legacy adapter or remove compatibility columns/flags; never infer contracts from exit codes or delete audit lineage. |
Schema rollback is expand/contract, never destructive in the incident window.
The application can roll back while the expanded schema remains. New binaries
must tolerate old rows with no native references, and the immediately previous
binary must tolerate the added nullable columns/tables. A destructive contract
phase is forbidden until retention, export, audit, and downgrade compatibility
are reviewed separately.
Policy compatibility is exact-version, not “latest wins.” A run binds the
immutable completion-contract, resolver-policy, and arbiter-algorithm versions
at envelope creation. Replay uses those versions. A policy rollout affects new
runs and explicit authorized re-assessments only. Emergency policy revocation
may prevent an undelivered effect from executing, but it records a new
superseding assessment/reason; it never silently edits the committed decision.
Unknown contract, fixture, result, or policy schema versions fail closed and
remain recoverable/readable as preserved input.
Rollback reconciliation is complete only when every native coordinator is in
`committed` or `terminal_failure` with a named recovery owner, every committed
effect is delivered or durably retryable, no active native run was converted
mid-session, and the native/legacy/shadow counts reconcile to the dispatch
ledger. Re-enablement resumes from coordinator state; it does not bulk replay
all historical reports.
#### 18.13.6 Independent QA acceptance package
QA receives the fixture corpus, this specification, the Phase 4 operator
contract, the conformance command output, implementation test output grouped by
fixture ID, migration rehearsal output, and a failure-injection ledger. The
matrix is accepted only when:
1. every `SD`, `TC`, `ATT`, `LIVE`, `REC`, `COMP`, and `MIG` ID has at least one
passing implementation result;
2. every required adversarial tag has a passing fixture and no unclassified
divergence;
3. native and legacy results are reported in separate columns and the legacy
baseline snapshot is unchanged;
4. duplicate/replay runs prove bounded wakes, notifications, decisions, and
domain effects;
5. the three non-terminal status families pass both success and transaction
rollback failpoints;
6. a production-shaped upgrade, kill-switch rollback, and re-enable rehearsal
reconcile without status loss, synthetic history, or mode conversion; and
7. Phase 4 rendering fixtures consume the same decision/attention outcomes and
preserve OPX-1–OPX-10.
QA records acceptance against the corpus schema version and git revision.
Changing an expected semantic assertion after acceptance requires a new corpus
schema or fixture revision and a fresh independent acceptance run.
---
## 19. Sandbox and provider integration
@@ -6216,6 +6444,30 @@ and interaction, run, and issue statuses remain server-only fields. Neither a
model hint, runner lease, response payload, continuation intent, nor replay/ACK
can bypass those invariants.
### 27.10 Status-authority Phase 5 conformance
Section 18.13 and
[`fixtures/status-authority-phase5.json`](./fixtures/status-authority-phase5.json)
are the sole scenario inventory for status-authority implementation and QA.
`pnpm check:runner-phase5-spec` must pass before a runtime suite starts. Runtime
suites then execute the same fixture IDs at these layers:
| Consumer | Required assertions |
|---|---|
| Shared/validator | Input schema, enum, contract/policy version, server-owned field rejection, and safe error code. |
| Status arbiter | Pure decision digest, status/no-op, reason code, ordered effect plan, and supersession lineage. |
| Server/database | Transactional status version, domain liveness rows, coordinator phase, effect ledger, activity, notification, and wake counts. |
| Runner/finalizer | Turn/run terminal conversion, claim/evidence preservation, workspace-finalization order, and native discriminator fail-closed behavior. |
| Legacy regression | Existing finalizer behavior and byte-identical legacy read/UI snapshots with zero native history rows. |
| Migration harness | Production-shaped expand migration, writer versioning, shadow comparison, canary, kill-switch rollback, reconciliation, and re-enable. |
| Phase 4 UI | Four authority layers, decision/attention truthfulness, liveness owner, finalization recovery, and native/legacy distinction from the same outcomes. |
Each test result is emitted as `{ corpusRevision, gitRevision, fixtureId,
consumer, outcome, observedDigests, semanticCounts }`. QA rejects aggregate
“suite passed” evidence that cannot be joined back to every required fixture
ID. Failure injection runs record the failpoint and pre/post database counts;
replay runs record all attempt IDs and the one canonical semantic identity.
---
## 28. Rollout and compatibility
@@ -6268,6 +6520,13 @@ them to collapse into one public endpoint.
10. Five-kind interaction bridge, response replay, and resumed-run gates.
11. Additional drivers.
Native status application additionally follows the ordered `MIG-01`–`MIG-09`
sequence in section 18.13.5. The generic runner gates above cannot skip shadow
comparison, complete Phase 5 fixture acceptance, internal canary, or the
kill-switch reconciliation drill. A driver may reach a later runner gate while
its status application remains shadow-only; mode is persisted per run and never
changes mid-session.
### 28.4 Kill switch
The control plane can:
+284
View File
@@ -0,0 +1,284 @@
#!/usr/bin/env node
// Structural conformance gate for the 18.3 Phase 5 status-authority corpus.
//
// Usage: pnpm check:runner-phase5-spec
//
// This validates the language-neutral fixture matrix before runtime
// implementations exist. Runtime suites consume the same fixture IDs and add
// database/transport setup without changing the expected semantics.
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
const specPath = join(root, "packages", "paperclip-runner", "spec", "paperclip-native-runner-spike-spec.md");
const fixturePath = join(root, "packages", "paperclip-runner", "spec", "fixtures", "status-authority-phase5.json");
const spec = readFileSync(specPath, "utf8");
const corpus = JSON.parse(readFileSync(fixturePath, "utf8"));
const failures = [];
const checks = [];
function check(name, fn) {
try {
const detail = fn();
checks.push(`PASS ${name}${detail ? ` — ${detail}` : ""}`);
} catch (error) {
failures.push(`FAIL ${name} — ${error.message}`);
}
}
function section(source, heading) {
const start = source.indexOf(heading);
if (start === -1) throw new Error(`missing heading: ${heading}`);
const level = heading.match(/^#+/)[0].length;
const rest = source.slice(start + heading.length);
const next = rest.search(new RegExp(`\\n#{1,${level}} `));
return next === -1 ? rest : rest.slice(0, next);
}
function tableIds(source, prefix) {
return [...source.matchAll(new RegExp(`^\\| (${prefix}-\\d+) \\|`, "gm"))].map((match) => match[1]);
}
function assertExactCoverage(label, definedIds, coverKey) {
const covered = new Set(corpus.fixtures.flatMap((fixture) => fixture.covers[coverKey]));
const missing = definedIds.filter((id) => !covered.has(id));
const unknown = [...covered].filter((id) => !definedIds.includes(id));
if (missing.length || unknown.length) {
throw new Error([
missing.length ? `missing ${missing.join(", ")}` : null,
unknown.length ? `unknown ${unknown.join(", ")}` : null,
].filter(Boolean).join("; "));
}
return `${definedIds.length} ${label} rows covered`;
}
const decisionSection = section(spec, "### 18.3 Status authority and human-needed signaling");
const attentionSection = section(spec, "#### 18.3.7 Weak-agent and adversarial scenario check");
const terminalSection = section(spec, "### 18.5 Complete terminal conversion contract");
const phase5 = section(spec, "### 18.13 Phase 5 conformance, migration, and rollback contract");
check("corpus header is versioned", () => {
if (corpus.schema !== "paperclip.status-authority-conformance.v1") {
throw new Error(`unexpected schema ${corpus.schema}`);
}
if (!Number.isInteger(corpus.corpusRevision) || corpus.corpusRevision < 1) {
throw new Error("corpusRevision must be a positive integer");
}
if (typeof corpus.policyVersion !== "string" || corpus.policyVersion.length === 0) {
throw new Error("policyVersion is required");
}
if (!Array.isArray(corpus.fixtures) || corpus.fixtures.length < 35) {
throw new Error(`fixture corpus looks truncated (${corpus.fixtures?.length ?? 0})`);
}
return `revision ${corpus.corpusRevision}, ${corpus.fixtures.length} fixtures`;
});
check("fixture IDs and required fields are valid", () => {
const ids = new Set();
const coverKeys = [
"decisionRows",
"terminalRows",
"attentionRows",
"livenessRows",
"reconciliationRows",
"compatibilityRows",
"migrationRows",
];
const requiredGiven = [
"priorIssueStatus",
"turnTerminalState",
"runTerminalState",
"reportedWorkDisposition",
"nativeFinalization",
"completionState",
"trigger",
];
const requiredExpected = [
"runStatus",
"statusAction",
"reasonCode",
"requiredEffects",
"forbiddenEffects",
"livePathKind",
"preserveClaim",
"nativeRecords",
"decisionCount",
"maxWakeCount",
"maxNotificationCount",
];
for (const fixture of corpus.fixtures) {
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(fixture.id)) throw new Error(`invalid fixture id ${fixture.id}`);
if (ids.has(fixture.id)) throw new Error(`duplicate fixture id ${fixture.id}`);
ids.add(fixture.id);
if (!["native", "legacy"].includes(fixture.mode)) throw new Error(`${fixture.id}: invalid mode`);
if (!fixture.covers || coverKeys.some((key) => !Array.isArray(fixture.covers[key]))) {
throw new Error(`${fixture.id}: incomplete covers object`);
}
if (!Array.isArray(fixture.tags)) throw new Error(`${fixture.id}: tags must be an array`);
if (!fixture.given || requiredGiven.some((key) => !(key in fixture.given))) {
throw new Error(`${fixture.id}: incomplete given facts`);
}
if (!fixture.expected || requiredExpected.some((key) => !(key in fixture.expected))) {
throw new Error(`${fixture.id}: incomplete expected facts`);
}
if (!fixture.replay || !Number.isInteger(fixture.replay.attempts) || fixture.replay.attempts < 1) {
throw new Error(`${fixture.id}: invalid replay contract`);
}
}
return `${ids.size} unique IDs`;
});
check("every status-decision row has a fixture", () =>
assertExactCoverage("decision", tableIds(decisionSection, "SD"), "decisionRows"));
check("every terminal-conversion row has a fixture", () =>
assertExactCoverage("terminal", tableIds(terminalSection, "TC"), "terminalRows"));
check("every adversarial-attention row has a fixture", () =>
assertExactCoverage("attention", tableIds(attentionSection, "ATT"), "attentionRows"));
for (const [label, heading, prefix, coverKey] of [
["atomic liveness", "#### 18.13.2 Atomic liveness fixtures", "LIVE", "livenessRows"],
["reconciliation", "#### 18.13.3 Deterministic replay and reconciliation fixtures", "REC", "reconciliationRows"],
["compatibility", "#### 18.13.4 Native, legacy, and existing-state compatibility", "COMP", "compatibilityRows"],
["migration", "#### 18.13.5 Rollout and migration sequence", "MIG", "migrationRows"],
]) {
check(`every ${label} row has a fixture`, () =>
assertExactCoverage(label, tableIds(section(spec, heading), prefix), coverKey));
}
check("all stable decision reason codes are exercised", () => {
const enumBlock = spec.match(/`StatusDecisionReasonCode` is a stable protocol enum[\s\S]*?```text\n([\s\S]*?)```/);
if (!enumBlock) throw new Error("could not locate StatusDecisionReasonCode enum");
const defined = enumBlock[1].trim().split("\n").map((line) => line.trim()).filter(Boolean);
const exercised = new Set(corpus.fixtures.map((fixture) => fixture.expected.reasonCode).filter(Boolean));
const missing = defined.filter((code) => !exercised.has(code));
if (missing.length) throw new Error(`unexercised reason code(s): ${missing.join(", ")}`);
return `${defined.length} reason codes exercised`;
});
check("required adversarial tags are all selectable", () => {
const required = [
"premature_done_claim",
"incomplete_evidence",
"required_review",
"continuation",
"partial_progress",
"real_blocker",
"excessive_human_request",
"repeated_question",
"false_blocker",
"partial_evidence_before_failure",
"finalization_failure",
"cancellation_scope",
"authorized_resume",
"supersession",
"native_legacy_distinction",
"existing_issue_state",
"atomic_liveness",
"deterministic_replay",
"reconciliation",
"rollback",
];
const tags = new Set(corpus.fixtures.flatMap((fixture) => fixture.tags));
const missing = required.filter((tag) => !tags.has(tag));
if (missing.length) throw new Error(`missing tag(s): ${missing.join(", ")}`);
return `${required.length} required tags present`;
});
check("non-terminal status fixtures carry an atomic liveness path", () => {
const acceptedEffects = {
in_review: new Set(["bind_reviewer", "create_interaction"]),
blocked: new Set(["bind_blocker"]),
in_progress: new Set(["enqueue_continuation", "schedule_retry", "create_delegated_issue"]),
};
const violations = [];
for (const fixture of corpus.fixtures) {
const expected = fixture.expected;
const allowed = acceptedEffects[expected.statusAction];
if (!allowed) continue;
if (expected.livePathKind === null || !expected.requiredEffects.some((effect) => allowed.has(effect))) {
violations.push(fixture.id);
}
}
if (violations.length) throw new Error(`missing atomic path/effect: ${violations.join(", ")}`);
return "in_review, blocked, and in_progress paths validated";
});
check("duplicate attention cannot create an unbounded loop", () => {
const duplicates = corpus.fixtures.filter((fixture) => fixture.expected.reasonCode === "attention_duplicate_suppressed");
if (duplicates.length === 0) throw new Error("no duplicate-attention fixture");
const unsafe = duplicates.filter((fixture) =>
fixture.expected.maxWakeCount !== 0 ||
fixture.expected.maxNotificationCount !== 0 ||
fixture.replay.maxSemanticDecisions > 1 ||
fixture.replay.maxDomainEffectsPerKey > 1);
if (unsafe.length) throw new Error(`unbounded duplicate fixture(s): ${unsafe.map((fixture) => fixture.id).join(", ")}`);
return `${duplicates.length} duplicate fixture(s) bounded at zero wakes/notifications`;
});
check("replay effects are at-most-once per semantic key", () => {
const unsafe = corpus.fixtures.filter((fixture) =>
fixture.replay.maxDomainEffectsPerKey !== 1 ||
fixture.replay.maxSemanticDecisions > fixture.expected.decisionCount + 1);
if (unsafe.length) throw new Error(`unsafe replay bounds: ${unsafe.map((fixture) => fixture.id).join(", ")}`);
const replayed = corpus.fixtures.filter((fixture) => fixture.replay.attempts > 1);
if (replayed.length < 30) throw new Error(`too few replayed fixtures (${replayed.length})`);
return `${replayed.length} fixtures replayed with one effect per key`;
});
check("native and legacy expectations remain intentionally distinct", () => {
const legacy = corpus.fixtures.filter((fixture) => fixture.mode === "legacy");
const native = corpus.fixtures.filter((fixture) => fixture.mode === "native");
if (!legacy.length || !native.length) throw new Error("both modes are required");
const badLegacy = legacy.filter((fixture) =>
fixture.expected.nativeRecords || fixture.expected.decisionCount !== 0 || fixture.expected.statusAction !== "legacy_finalizer");
const badNative = native.filter((fixture) => fixture.expected.statusAction === "legacy_finalizer");
if (badLegacy.length || badNative.length) {
throw new Error(`mode leakage in: ${[...badLegacy, ...badNative].map((fixture) => fixture.id).join(", ")}`);
}
return `${native.length} native / ${legacy.length} legacy fixtures`;
});
check("rollback fixture forbids active-run mode conversion", () => {
const rollback = corpus.fixtures.find((fixture) => fixture.covers.migrationRows.includes("MIG-08"));
if (!rollback) throw new Error("missing MIG-08 fixture");
if (!rollback.expected.requiredEffects.includes("stop_new_native_dispatch") ||
!rollback.expected.forbiddenEffects.includes("convert_active_run_to_legacy")) {
throw new Error("MIG-08 does not prove dispatch stop plus immutable active-run mode");
}
return rollback.id;
});
check("Phase 5 markdown tables are rectangular", () => {
const lines = phase5.split("\n");
let inFence = false;
let expectedColumns = null;
let tables = 0;
lines.forEach((line, index) => {
if (line.trimStart().startsWith("```")) inFence = !inFence;
if (inFence) return;
const isRow = line.trimStart().startsWith("|") && line.trimEnd().endsWith("|");
if (!isRow) {
expectedColumns = null;
return;
}
const columns = line.trim().slice(1, -1).split(/(?<!\\)\|/).length;
if (expectedColumns === null) {
expectedColumns = columns;
tables += 1;
} else if (columns !== expectedColumns) {
throw new Error(`ragged table at Phase 5 offset line ${index + 1}: ${columns} vs ${expectedColumns}`);
}
});
if (inFence) throw new Error("unbalanced code fence in section 18.13");
return `${tables} tables`;
});
for (const line of checks) console.log(line);
for (const line of failures) console.error(line);
console.log(`\n${checks.length} passed, ${failures.length} failed`);
process.exit(failures.length ? 1 : 0);