← board

Pin-verify and requested-verify publish a verdict with no manifest

What the daemon log shows, and it is the whole finding

Every ordinary breadth run prints a report path. Neither special path does:

twatch: a8aa948df2f9 RED   report=…/20260906T181014Z-a8aa948-seven.md
twatch: 6a6d69ce2a80 RED   report=…/20260906T181507Z-6a6d69c-seven.md
twatch: dd742537ed52 GREEN report=…/20260906T181946Z-dd74253-seven.md

twatch: verifying PIN v406 (1b903c1ddaf2) at full          <- no report=
twatch: requested verdict RED at 5411e996794f (full)       <- no report=

No error, no truncation, no second writer. Two deliberate paths do not generate a report, and the short archive row follows from that rather than from anything going wrong.

Which shape is which

row shape count path first seen
17 keys 306 ordinary breadth 2026-08-31 (current schema)
14 keys 92 ordinary breadth, older schema before 2026-08-31
10 keys 7 pin-verify ~2026-09-01, when pin-verify began running at full
9 keys 10 requested verify 2026-08-29

The 14-key rows are a clean cutover and are not a defect. Every one predates 2026-08-31T05:23Z and every 17-key row postdates it, with no interleaving. They are listed here only so nobody audits 92 healthy rows — the anomaly is 17, not 109.

The 10-key shape being newer than the 17-key one is what killed the obvious hypothesis ("an old writer still in the tree"). It tracks when pin-verify started running at full, not a regression.

The fields that go missing

Present in a normal row, absent from both short shapes:

still_red   skips   skip_holes   skip_hole_jobs
unreached   timed_out   deadline   code_fp   first_seen

Why this is worth fixing rather than documenting

The two paths that most need a manifest are precisely the two that produce none.

The information already exists — it is dropped in transit

This is the part that makes it small. The publishing log line already names the failing jobs: test-core#src:test/c_cross_… and tools-devtest#00 for the 19:32:19Z run. So the manifest is in hand at publication and discarded on the way to the archive. The fix is to carry what is already computed, not to compute anything new.

Same shape as bug-t-a-tier-job-identifier-is-a-selector-doing-double-duty-as-a-label, where step_src is recorded per red and simply does not reach the identifier. Twice in one evening, a field that exists one layer away from the reader who needs it.

Not this ticket

Whether pin-verify and requested-verify should write a full report .md is a separate and larger question — a report is a committed artefact and these paths may have been made quiet on purpose. The archive row is the cheap half: it is already being written, it is already keyed by sha, and adding the manifest fields to it makes the verdict readable without adding a file to the repo. Do that first and decide the report separately.

CORRECTION 2026-09-06 — pin-verify DOES write a report, and I had it wrong

The filing above says neither special path writes a report. That is false for pin-verify, and the way it was wrong is the same shape as everything else in this ticket.

I read it off a daemon log line:

twatch: verifying PIN v406 (1b903c1ddaf2) at full          <- no report=

That line announces the START of a verify, not its publication. Absence of report= on it says nothing about whether a report was written later. I treated a log line about one event as evidence about a different one.

What the artefact says

For every 10-key (pin-verify) row, a report .md exists at that sha whose own tier: is full, with a timestamp identical to the row's, to the second — 8 for 8:

row 2026-09-01T21:40:34   report 2026-09-01T21:40:34   delta +0.0 min
row 2026-09-02T10:04:54   report 2026-09-02T10:04:54   delta +0.0 min
   … 6 more, all +0.0 …
row 2026-09-06T19:43:25   report 2026-09-06T19:43:25   delta +0.0 min

And the content is complete. 20260906T194325Z-1b903c1-seven.md (v406's own pin-verify) carries skips: 7, skip_holes: 2, a coverage banner, a by-reason skip list, ## NEW-RED and ## STILL-RED.

So pin-verify's manifest is written. Only its archive ROW is short. That is a queryability gap — the answer exists in the repo and not in the ndjson — and it is a much smaller thing than "publishes a verdict with no manifest".

The request path is unchanged and is the real one

10 of 10 requested-verify rows have no report at any sha, except 1d8db8667267, whose report is from a native run — a different run at the same sha. That is the confound that nearly fooled me a second time: a report is named by sha, and a sha can be tested by more than one tier, so "is there a report for this sha" is not "did this run write one". Matching the report's own tier: and its timestamp is what separates them.

On the proposed detector, tested rather than adopted

"Does a report .md exist for this sha" was suggested as a shape-independent detector, on the argument that key counts have already changed once. Measured, it does not separate thin from healthy: 398 of 398 normal rows have a report, but so do 9 of 18 thin ones. What it actually detects is the request path, cleanly. That is still worth having — it is exactly the check that would have stopped 1d8db8667267 being reported to the fleet as satisfied — but it is a request-path detector, not a thin-row detector, and calling it the latter would put the next reader back where I just was.

Log