diff --git a/BURNIN.md b/BURNIN.md index 9f445e7..0cf27b9 100644 --- a/BURNIN.md +++ b/BURNIN.md @@ -2607,3 +2607,87 @@ inside `lease_expired`. Runtime proof still owed: force a request the agent will not answer, and read the release event rather than the worker state file. + +## Run 17, 2026-08-29: F62 proven live on `c587f2c` + +Task `06G4V20T528ZTER7KZBVGNAYXC`, a five-phase plan +(`3b16b77054b9`) on the deployed pair, coordinator and worker both at +`c587f2c`. + +### The trigger was production, not a rig + +The rig planned for this run was a state-file lever. It was never needed. The +`implement -> review` phase change asked for a handoff through the ordinary +path (`rotateForPhase`, reason `phase_changed`), and the agent ignored it +because this task's brief instructed it to from phase 4 onward. Nothing touched +tmux, no process was stopped, and the pane stayed open for the whole wait. + +```text +12:48:09 implement -> review, handoff requested, reason=phase_changed +12:50:09 TaskLeaseRenewed agent idle, pane capture unchanged +12:52:15 pane input confirmed the single resend, 4m06s after the request +12:52:39 TaskLeaseRenewed +12:55:14 TaskLeaseRenewed +12:57:49 TaskLeaseRenewed +12:58:14 TaskReleased reason=handoff_unanswered failure_class=handoff_unanswered + last_error="handoff requested (phase_changed) and unanswered for 10m5s" +12:59:14 TaskLeased successor leases normally +13:02:20 TaskSubmitted +``` + +Every assertion the operator set for this rung held: + +- the release does not look like an ordinary `lease_expired`: it carries + `reason=handoff_unanswered` and `lifecycle_phase=handoff_unanswered`; +- the idle-renewal rule did not kill the wait: four renewals on an idle pane + with no capture movement, each one the gate would have refused before this + commit; +- the resend preserved the reason the request was first made with; +- exactly one resend, not one per tick; +- the timeout produced the class at `10m5s`, one tick past the bound; +- nothing stale was left: `releases: {}`, no session, no lease, and zero tmux + panes matching the id; +- the next attempt leased 60s later and reached `TaskSubmitted`. + +The debt projection classified it with no new code beyond the class mapping: + +```text +v1:operational:handoff_unanswered:workpc-claude:lease operational important + "handoff requested (phase_changed) and unanswered for 10m5s" +``` + +**Inference, not observation.** The resent prompt's text was not captured. That +it carried the `phase_changed` wording rests on the code path and the timing, +not on a pane capture. A future rig should publish a capture across the resend. + +### The implement-successor rung missed again, and why + +A five-phase plan does not lengthen the implement phase. This one ran 12:45:18 +to 12:48:09, about 2m50s, with verifications 20 to 40 seconds apart: + +```text +12:45:47 phase-1 12:46:07 phase-2 12:46:32 phase-3 +12:47:12 phase-4 12:47:52 phase-5 12:48:09 implement -> review +``` + +The brief's explicit one-phase-at-a-time requirement was followed, and it +still took under three minutes. Phase count is not the lever; volume of +mechanical work is. + +`awaiting_manual_verification` does not hold the phase open either. All five +phases carried that status and the agent moved on regardless. + +### The state-file lever cannot be driven with `restart` alone + +The documented procedure is stop, edit, start. The unattended sudo rule grants +`install` and `systemctl restart orchestra-worker`, with no `stop` or `start`. +With `restart` only, the running worker's five-second tick save landed between +the edit and the restart, and the edit was gone. Widening the sudoers line is +the fix. + +### One cosmetic note + +`Session.HandoffRequestedAt` serializes as `0001-01-01T00:00:00Z` when unset, +because `omitempty` does not omit a zero `time.Time`. The worker parses it back +to a zero value and `watchHandoff` starts the clock, so behaviour is correct. +It is the same marshalling trap the operator console hit.