Skip to content

feat(coord): an external alarm for the seat clock, reading the file that can answer the question (BACKLOG #1269) - #557

Merged
wshallwshall merged 19 commits into
mainfrom
claude/builder-2-1269-seat-clock-alarm
Aug 24, 2026
Merged

feat(coord): an external alarm for the seat clock, reading the file that can answer the question (BACKLOG #1269)#557
wshallwshall merged 19 commits into
mainfrom
claude/builder-2-1269-seat-clock-alarm

Conversation

@wshallwshall

Copy link
Copy Markdown
Collaborator

An external watchdog for the seat clock, by Builder 2. New tool, no existing behaviour changed: scripts/coord/seat_clock_alarm.py plus its tests.

The seat-clock chain is serial, so it has one life. Nothing was watching it.

It was built as the inverse of what the item asked for

BACKLOG #1269 says to read seat-tick.last. seat-tick.ps1 states in its own source that that file cannot answer "when did THIS seat last get a tick", because a later run overwrites it — it answers WHY NOT, never WHEN or WHO. state.json answers both.

Building the row as written would have produced the defect the row exists to prevent. The ledger half of this inversion is PR 554, from the Dispatcher; this is the code half. The two were reached independently and agree.

Verification, as reported by the author

check result
tests/test_coord_seat_clock_alarm.py 17 passed
every tests/test_coord*.py plus the partition gate 252 passed, 296s
ruff format --check, ruff check clean
mypy strict Success

Three mutations, each with its anchor verified present before applying:

  • turn it into a freshness-only alarm: only the discriminating test reds, 1 of 17
  • take the first match for a seat name: only the twice-named test reds
  • drop the throttle sanity check: only the two self-contradiction tests red

The first is the proof the item demanded. A broken implementation passes sixteen arms and fails exactly the one that separates them, which is what makes the suite a control rather than a count.

The live run is its own control pair

watching dispatcher-582b2f  ->  OK, 559s since last tick, against a PT10M clock, exit 0
watching builder-2-65e318   ->  ABSENT, exit 1

The second result is true and worth knowing: that seat's lane has never been ticked. It has been kept alive entirely by peer messages, and until this commit nothing would have reported it. The item's thesis, live, on the seat that built it.

Landing notes

tests/tooling_manifest.txt carries the new test in the same commit. The partition gate refuses a tests/*.py that imports no engine module and is absent from the manifest, and it cost PR 542 an afternoon; the author caught it before committing this time.

backlog-hygiene does not fire. Its touches_code test matches only messagefoundry/, ide/ and messagefoundry_webconsole/ paths, and this branch touches scripts/coord/ and tests/ — established by running the gate's own logic against the pushed tip.

One commit behind main at time of push. Nothing overlaps: main's last move touched docs/BACKLOG.md and nothing else.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com

…hat can answer the question (BACKLOG #1269)

The seat clock's chain is SERIAL -- each tick re-arms the next -- so it has one life, and nothing
outside it notices when it ends.

I BUILT THE INVERSION OF WHAT THE ROW SPECIFIED, because building it as written would have
produced the defect the row was filed to prevent. The row says to read `seat-tick.last` and
check the watched seat appears in it. `seat-tick.ps1` says this where it declares its state
file: "seat-tick.last ... cannot answer 'when did THIS seat last actually get a tick', because
a run that reported COLD for a seat OVERWRITES the run in which that seat was SENT." An alarm
reading it goes healthy on the overwrite. THE ROW WOULD HAVE SPECIFIED ITS OWN TITLE.

Not a new mechanism: the throttle needed the same second question and was given its own file
for it. This reuses it. state.json answers WHEN and WHO, keyed by absolute worktree path;
seat-tick.last answers only WHY NOT.

THE SEAT NAME IS NOT A KEY. Measured today, the live one-liner carried steward, lander and
dispatcher TWICE EACH -- once STALE(no-live-session), once SENT. A first-match scan reads
STALE for all three while the clock ticks normally, which is the same first-match trap that
cost four seats a wrong answer this morning, inside the file the alarm was told to parse.

VOCABULARY IS AS MEASURED TODAY, NOT AS THE ROW LISTED IT: STALE(no-live-session) at
seat-tick.ps1:654 and the (roster-blind) suffix at :767 both postdate the row.

PROVED ABLE TO FAIL, three mutations, each with its anchor verified present first:
  become the freshness-only alarm  -> ONLY the discriminating test reds (1 of 17)
  take the first match for a seat  -> only the twice-named test reds
  drop the throttle sanity check   -> only the two self-contradiction tests red

That first one is the proof the row asked for: the broken implementation passes every arm
except one, and that one is the arm.

LIVE, against the real clock: watching dispatcher-582b2f reports OK at 559s against a PT10M
tick; watching this worktree reports ABSENT, because this lane has never been ticked at all.
wshallwshall and others added 3 commits August 23, 2026 14:25
…d file

The module docstring pinned seat-tick.ps1 at :654, :767, :647, :719 and :740.
That file is not in this repository. Measured with a control:

  git ls-tree -r origin/main --name-only | grep -ci seat-tick   ->  0
  CONTROL, scripts/coord/seat.ps1                               ->  1

It is a machine-global install, so NO READER OF THIS REPOSITORY CAN RESOLVE ANY
OF THOSE NUMBERS, and they drift silently as an untracked file changes.

THAT IS WORSE IN KIND THAN AN ORDINARY STALE CITATION. A stale one points at
something a reader can open and disagree with; these point at nothing they can
reach, so the citation cannot be checked and cannot be seen to be wrong.

Replaced with the fact that the emitter is untracked, the control that
establishes it, and a way to re-derive the vocabulary that does not depend on
line numbers: grep the file for its $results.Add sites, each token minted in
exactly one place.

Docstring only. The code is unaffected: the alarm is a TRACKED script reading
untracked state through overridable --state/--last defaults, and its tests are
hermetic. Nothing in CI touches the machine.

Author-supplied text, applied verbatim. The tracking fact was found by a third
seat while screening an unrelated item.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…269)

The alarm reported ALARM when it could not READ the state file. Corrupt JSON raised an uncaught
traceback and exited 1; a valid file whose value schema this reader does not know had every
record silently skipped, reported ABSENT, and exited 1. Both are now Unreadable -> exit 2,
CANNOT MEASURE -- the shape that ALREADY EXISTED for the MISSING file, in its second form. Same
question, two forms, and only one of them was answered.

WHY IT IS WORSE THAN AN ORDINARY FALSE POSITIVE: it fires for EVERY watched seat at once, so the
first false alarm is also the loudest -- the worst possible introduction for an instrument whose
only value is being believed. This module's own docstring names the consequence: a false-positive
watchdog is a slow-acting off switch. It does not fail on the day it fires. It fails weeks later,
having been discounted.

THE CORRUPT-FILE ARM IS AN OBSERVED EVENT HERE, NOT A HYPOTHETICAL. BACKLOG #1269 records that a
Windows path-casing collision killed this clock once already by dying on a JSON parse.

AN EMPTY REGISTRY STILL ALARMS, and that arm is the point rather than a detail. `{}` is not
unreadable: no records means the watched seat really has no tick, which is the discriminating
condition the whole tool exists for. A schema check that swallowed `{}` would silence the alarm
exactly when it should fire, which is a worse defect than the one being fixed. The natural
implementation makes that mistake, so it is pinned by a test rather than by care.

PROVED ABLE TO FAIL, mutation anchor verified present first: returning 1 instead of 2 reds
exactly the two CANNOT-MEASURE arms and leaves the empty-registry twin green. 19 of 21 survive,
and the survivors are the evidence that the suite discriminates rather than merely couples.

Found by turning another seat's root cause on my own reader: when every field you asked for comes
back empty, that is not empty data -- it is a signal you are querying a schema you never read.

21 passed, ruff format --check and ruff check clean, mypy strict Success, and the live run
against the real clock still reports OK.
@wshallwshall
wshallwshall enabled auto-merge (squash) August 23, 2026 20:42
@wshallwshall
wshallwshall merged commit 0ba326a into main Aug 24, 2026
37 of 38 checks passed
@wshallwshall
wshallwshall deleted the claude/builder-2-1269-seat-clock-alarm branch August 24, 2026 06:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant