← board

A self-healed red leaves a permanent prio-70 stub at the head of the ranked queue

What happens

twatch auto-files a stub ticket into devdocs/progress/backlog/ on NEW-RED, with prio: 70. That is the right call: a fresh regression should outrank feature work. But nothing ever takes it back. When a later report moves the same job to FIXED, the stub is not closed, not annotated, not even re-prioritised.

Because 70 is above almost everything else in the backlog, and because tools/progress.sh next ranks by effective priority, a red that healed on its own permanently occupies the head of the queue and is handed to the next agent that asks for work.

Measured

Nine open auto-filed stubs on 2026-08-06. All nine passed at HEAD (733be3321, compiler snapshot sha256 cafd50517875), each run with its own stub's repro line:

stub's test watcher trail
test_cpyext_hello NEW-RED 34c41bd → FIXED aba953c (~1h)
test_cpyext_args_errors NEW-RED 34c41bd → FIXED aba953c
test_cpyext_containers NEW-RED 34c41bd → FIXED aba953c
test_cpyext_cython NEW-RED 34c41bd → FIXED aba953c
test_cpyext_markupsafe NEW-RED 34c41bd → FIXED aba953c
test_nilpy_dotted_package_import NEW-RED 34c41bd → FIXED aba953c
test_nilpy_qualifier_vs_cproc NEW-RED 34c41bd → FIXED 8b9d08b (~15min)
test_nilpy_pyexpr_semantics NEW-RED 9294bce → STILL-RED ×8 → FIXED 733be33
test_nilpy_augmented_assign_class_dunder NEW-RED e8450c5 → STILL-RED ×18 → FIXED 733be33

The last two rows are the healthy case — a genuine regression, correctly tracked STILL-RED across every report until a fix landed. Note the watcher does know the answer: FIXED is a section it already emits. The gap is only that the stub is not wired to it.

The six 34c41bd rows are the pathology: they had been stale for a day, and seven of the nine stubs were pure queue noise.

Second, smaller finding: test_nilpy_augmented_assign_class_dunder had two stubs filed for it, one from the test-core job and one from test-nilpy, since the same source is exercised by both. Whatever closes stubs should key on the job, but dedupe by test source when filing.

Suggested fix

In the same pass that emits the ## FIXED section, for each job listed there: resolve its stub if one is open — or, if closing from the watcher identity is outside its write scope (face 1 writes ONLY tstate/, which is the rule and should stay), then at minimum append a FIXED at <sha> line to the stub and drop its prio: well below 70, and let face 2 do the actual close. Either way the ranked queue stops advertising fixed work as the most urgent thing in the repo.

Worth considering: a --tier / progress.sh check assertion that no open auto-filed stub's job is currently green, so this class of drift is caught by the gate rather than by an agent noticing it manually.

Gate

tools/testmgr.py --tier full green (T's own gate), plus a scratch bare repo exercising the file→heal→close cycle end to end. Test the tooling with QUICK tiers, never long runs.

Log


Resolution (Track T, 2026-08-08) — commit 16720bb5f

The main half was already done. close_stub_tickets() landed 2026-08-02 in 1dd53a8ec and is wired to the FIXED pass, and the backlog held zero stub-marked tickets when this was picked up — the nine-stale-stubs symptom is gone. What remained was the ticket's "second, smaller finding".

Dedupe by test source

One source can be reached by several jobs (test/x.npy runs under both test-core and test-nilpy) while the slug is the JOB selector — so one broken file filed two tickets. stub_sources() indexes {test source -> slug} across every bucket, once per filing pass, skipping zero-byte debris and anything without STUB_MARKER (an enriched body is somebody's analysis, not a stub). Filing keys on the source and says so when it declines; closing still keys on the job, exactly as specified.

The consequence the ticket did not mention

With one stub covering N jobs, closing it because the job it was named after went green strands a still-broken source with no ticket and no way to get one — the sibling job is STILL-RED, not NEW-RED, and nothing files on still-red. The dedupe alone would have traded two tickets for zero. So close_stub_tickets() now keeps a stub open while its source is red in any job of the report.

Gate

As specified — the file→heal→close cycle end to end in a scratch dir, quick tier, no repo needed: tools/devtest_stub_lifecycle.py (new). It covers one-source-one-stub, a repeat pass adding nothing, the stub staying open while a sibling job is red, and the close landing in done/ with its sha and attribution. All pass; gate.sh quick GREEN.

Deliberately not done

The "worth considering" progress.sh check assertion that no open stub's job is currently green. The auto-close plus the guard above handles this drift at source; an assertion inside a tool every track runs is a wider blast radius than the remaining gap justifies. Recorded rather than silently skipped — if the drift reappears with autoticket off or the watcher down, that assertion is the answer.

The empty-range half of this cluster is fixed in 315029d55 ([[bug-t-empty-range-regression-cannot-be-bisected]]). It mattered here: closed_regs derives from open_regressions, so a red with an empty range opened no entry and its stub was structurally unclosable. That precondition is gone now.