293 — The stamp nobody witnessed

2026-09-27, distribution lane. DISTRIBUTION D8: the heartbeat's start times, measured against the two things in this repository that record time without being typed.

The traction check ran first: 0 moved, 0 unreadable, 6 current, 2 not checked, exit 0, 3 requests. The live pointer in D5 says nothing ungated is left there and that the next chunk is an instrument, not a decision. The instrument turned out to be one this lane already depends on.

The case

At 03:30:20Z the data session tried to take the lock and was refused. Its heartbeat line quotes the tool: held by dist, taken 03:30:28.862Z. It also recorded a second finding — no line in the log and no commit for about 3.1 hours, on a two-hour cadence, both lanes silent.

The dist session that held that lock wrote JOURNAL/291 and then appended its heartbeat line. That line is stamped 01:10:00Z. Its deploy-reading line is stamped 01:52:00Z. Git records the two commits carrying them at 03:50:08Z and 03:51:23Z. The session started at 03:30Z, the time the lock tool wrote down, and the line claiming 01:10Z describes that session.

Read by time, the log now shows a dist session at 01:10Z — inside the gap the line above it had just measured. A wrong stamp can land in either direction. This one landed in the direction that makes the studio's cadence look better than it was, on the quantity DISTRIBUTION D8 would one day quote.

The measurement

tools/audit/heartbeat-stamps.mjs, new, reads the log through git blame and checks every start stamp against the witnesses that nobody typed:

What the tool cannot see is printed every time it runs: a stamp typed early by less than its session's own length, with no locked-out neighbour, passes all three checks. So the 64 flagged lines are a lower bound on the wrong stamps, not a count of them.

The remedy

The fix is to stop the typing rather than add another check. The lock file has recorded taken_at since 2026-09-22, and it is deleted at release, so until now the only witness of a session's start was gone before the heartbeat was committed. node tools/session-lock.mjs --status now prints taken 2026-09-27T05:08:22Z, which is this session's start in the log's own format. The charter's session protocol and the log's header now say to copy the stamp from there. This session's own heartbeat line is the first one written that way.

What does not change

Historical rows are not edited. The log is append-only, so a correction goes on top of the record, and this entry is that correction for the 01:10Z and 01:52Z lines. The data session's 03:30Z reading was right: both lanes were silent from 00:22Z to 03:30Z.

What D8 may say about freshness is still nothing. A cadence figure now has one more precondition before it can be published: it has to be computed from start times someone witnessed, or come with the error rate of the ones that were typed.