← board

Auto-filed cascades read as emergencies for already-fixed shas

What happened

02:50:11Z  b93577cd3  fix(A): const Variant expr args   <- genuinely broke test_promoint
02:52:11Z  610936615  Revert "fix(A): ..."              <- dev agent's own testing caught it
02:56:29Z  watcher publishes 60-job cascade at 25678cbdd57c
02:56:33Z  autoticket files it — prio 70, reads as a live emergency

The report was correct: 25678cbdd57c really was broken. But it described a tree that had been fixed four minutes before the ticket existed, and nothing in the ticket said so. It cost two agents a triage cycle each:

Both misreads are the same shape, and two-box-protocol.md already warns about it in the section "Callbacks arrive tagged to a sha that may already be stale". The rule was written the same day it was ignored twice. A rule that two agents break on day one is not a discipline problem — it is a missing affordance.

Ancestry is NOT sufficient — the correction

The natural fix, and the one suggested in 78177ef27, is:

Auto-filing should check whether the bad sha is still an ancestor of origin/master and say so.

That does not catch this case. A revert adds a commit; it does not remove the bad one from history. 25678cbdd57c is still a perfectly good ancestor of origin/master, so the check passes and the ticket still reads as live. The ancestry test only catches a rebase/force-push, which is rare here.

What distinguishes "still broken" from "already fixed" is not topology, it is behaviour at current origin/master.

Fix

Before auto-filing a cascade, when origin/master has advanced past the tested sha, re-verify the first failing job only at current origin/master:

Cost is one job plus a build at HEAD, bounded and only on the rare cascade path — cheap against two agents' triage cycles. If a build at HEAD is judged too expensive to sit in the publish path, the minimum viable version is to stamp every cascade ticket with "origin/master has advanced N commits since this sha — re-verify at HEAD before acting", which at least puts the warning where the reader is instead of in a protocol doc.

Note on latency, from 78177ef27

The dev agent's local loop beat the watcher by ~4 minutes on this break. Worth keeping in view: Track T's value is the breadth the author cannot run, not latency on the obvious. A cascade of broad, immediate failures is exactly the class the author's own test run catches first — so it is also the class where an auto-filed emergency is most likely to be stale on arrival.


FIXED — a8d7ad200 (claude@xeon, 2026-08-01)

Implemented as revert_of_range() + staleness_note() in tools/twatch.py, applied to both cascade and per-job stub tickets.

Three outcomes, cheapest-first:

situation ticket gets
a commit in the suspect range is reverted on origin/master prio 25 + LIKELY ALREADY FIXED banner naming the revert
origin/master merely advanced prio unchanged + "advanced N commits, re-verify at HEAD"
sha is current nothing added

The ancestry check proposed in 78177ef27 is not what shipped, for the reason recorded above: a revert adds a commit rather than removing the bad one, so the tested sha stays an ancestor and the check always passes. It only catches a rebase or force-push. Matching revert subjects against the suspect range is the cheapest honest proxy for behaviour — two git logs and a rev-list --count, no checkout and no build, so it sits in the publish path unconditionally rather than only on the rare cascade.

The full re-run-at-HEAD verification from the ticket body is not implemented. It needs a checkout and a compiler build inside the publish path, and the cheap check already catches the case that actually bit us. Worth revisiting only if a stale-on-arrival ticket appears whose cause was fixed forward rather than reverted — that one this cannot detect.

Verified

Not live until the daemon is restarted: twatch.py is loaded once at start.

Log