0058 — The row-lease lapse sweep runs on a schedule, and observes only
Status: Accepted as to the decision; not yet in force, because the schedule it calls for has not been registered. This record exists so the decision does not die where it was made (ADR-0004: a decision that changes how systems relate is not done until its ADR is written). The registration is a separate PR and a human act — see What this ADR deliberately does not do.
Date: 2026-10-15
Deciders: both decider rungs, independently, verdict
RESOLVED— receiptsfc5c58e46(Fable) andf22988a8c(Astra). Theirrecstrings are byte-identical:register a scheduled system-domain daemon via fleet-daemon that sweeps live boards and records, with its own SYSTEMS.md entry and an ADR, since a detector nothing invokes is not a detector.
⚠️ The CLI's "AGREE" banner is not the evidence for that agreement and must not be cited as such: its agreement test reads a key the verdict dict does not carry, so it prints unconditionally. The agreement is real because the two
recstrings were compared by hand.Filed from: board row
bug-the-row-lease-lapse-detector-has-never-run-on-a-real-board-and-nothing-schedules-it-so-every-lapse-is-found-by-accident(dockdock-found-rows, 2026-10-15), which carries the full measurement.
The problem: a detector that works, and that nothing invokes
A row on a phase board is claimed under a 3-hour lease
(expires_in_seconds 10800). When a lease lapses on a still-open row, that row
can be neither worked (the holder's generation is stale, so its writes are
refused) nor adopted (another lane's claim is refused because the row is
still held). It is stuck, and silently.
smith-row-lease sweep is the detector for exactly that condition, and it
works. Run by hand against this dock's 75 rows it returned rc=0,
rows_asked 75, rows_read 75, counts {held: 35, parked: 40}, 0 lapsed,
0 foreign holders, recorded: false.
It has never swept a real board.
$ smith-row-lease sweep-status --board portfolio-architecture-phases
rc=3 {"status": "never", … "the detector has never run on this board, so a
lapse here has never been looked for, let alone found"}
The liveness log holds exactly one line, and that line is itself the
positive control — the format works, the writer works, and a real lapsed
count has rendered once:
2026-09-10 23:50:46 row-sweep rollout-x: 3 rows — held 1, lapsed 1, never_claimed 1
rollout-x is a test board. One sweep, of a test board, thirty-five days
ago, and none since on anything.
And nothing schedules it. fleet-daemon --status lists 67 labels, of
which 8 are out-of-scope (not fleet jobs — Google updaters and the like),
leaving 59 in scope: 43 daemon, 12 deferred, 2 agent, 2 disabled.
Four of those are sweeps (ccswitch-walled-sweep, decider-sweep,
decision-block-sweep, inspo-sweep). No row-lease or row-sweep daemon at
any of those grains. Paired control: doctrine-pull is in that listing
(grep count 1) while the target greps 0, so the registry is complete and
greppable and the absence is about this job.
⚠️ A grain correction, recorded because the count is the kind of number this fleet gets wrong. The row that filed this said "66 registered daemons". Read live for this record, the listing is 67 labels / 59 in scope — 66 is not the count at any grain the tool reports. The finding is unchanged, because the finding never rested on the total: it rests on the paired control.
What it has already cost. Earlier the same day a hand sweep found fifteen of this dock's rows lapsed — thirteen of them still open — known only because a driver happened to look. ⚠️ Attributed, not re-measured here: that is the dock driver's own hand sweep as recorded on the row. This record did not re-run it, because re-running it now would read a board whose leases have since moved, and a fresh count would answer a different question than the one the row asked.
⚠️ A method warning this row paid for, recorded because it is the reusable
part. The first attempt to prove "nothing schedules it" grepped
~/Library/LaunchAgents and found nothing — and its control, a grep for
doctrine-pull, also found nothing there, while doctrine-pull
demonstrably runs. The zero was about the scope, not the world: these jobs live
in the system domain through fleet-daemon. A control that fails alongside
the thing it is controlling has not certified an absence; it has reported that
you are looking in the wrong place.
The decision
The sweep runs on a schedule, as a system-domain daemon registered via
fleet-daemon, against the live boards, passing --record so the evidence
line exists. It gets its own SYSTEMS.md entry with liveness signals.
The hosting half — that a fleet background job belongs in the system
domain, and that anything asking "is job X loaded" must ask both domains — is
not decided here. It is the subject of
PR #227
("fleet background jobs run in the system domain"), whose own number is
contested on main and which a ruling on that PR has renumbered to 0057.
⚠️ It has not merged, and
ADR-0055
records what that has cost. This ADR depends on that hosting rule but does not
restate it as settled.
The two reasons that bind the shape, not just the outcome
Both were verified at source, not taken from the ruling.
(a) A driver may not sweep its own board, because a driver does not poll. The option that looks conservative — "make each driver sweep its own board on every wake" — is a driver polling, and it reverses a standing ruling: ADR-0017 is the driver is fed, it does not poll. Coverage built that way would also be a function of who happened to wake, which is the accident this row is about.
(b) The liveness line belongs to the scheduled sweeper and to nothing else.
row_lease_cli.py's _sweep docstring says it verbatim:
⚠️ IT DOES NOT WRITE THE LIVENESS LOG unless
--recordis passed. The line is the evidence that the SCHEDULED sweeper ran; a hand-run that wrote one would make a board nobody armed read as watched — this row's own defect, one layer down.
So an attended driver sweep could never legitimately record. Combined with (a),
an attended-only world is one where sweep-status reads "never" forever
while coverage silently depended on whoever happened to look. The author had
already named this row's defect in a docstring.
What the sweep may NOT do — observation only
The scheduled sweep never owner-starts, never acquires, and never
heartbeats. It reads row ownership, classifies it, and appends one evidence
line. That is a constraint on anything built under this ADR, and it is also
already true of the code: _sweep calls only read_sweep_evidence,
sweep_rows, an optional write_sweep_evidence under --record, and _emit.
It acquires nothing, mints no owner and mutates no lease. Negative control:
a grep for acquire over that range finds it only inside a comment.
This matters because the row that produced this ADR was filed on the opposite
premise — that a sweep is an attended act because smith-row-lease owner-start mints a one-hour attended owner. That conflated two separate
subcommands and was false (row_lease_cli.py dispatches sweep and
owner-start at different lines, and declares owner-start elsewhere again).
A sweep is a read. Writing the constraint down is what keeps a later
implementation from quietly making it an act, which would put the scheduled job
in the path of the very leases it is meant to observe.
Why the liveness signal reads sweep-status's own answer
sweep-status already returns an honest three-valued answer, and the
catalog needs nothing more inventive than to read the same thing:
sweep-status |
means | catalog signal renders |
|---|---|---|
rc 0, status "recorded" |
a sweep of this board is on record | ok / stale by age |
rc 3, status "never" |
log read, this board not in it — a definite no | down |
rc 1 |
the log could not be read — not the same as 3 | unknown |
The catalog is read-only by construction — its evaluators stat, read
files and run launchctl list, and there is deliberately no signal type that
shells out to a command. So the signal cannot literally invoke sweep-status.
It does not need to: sweep-status's needle is
" row-sweep <board>: " against ~/Library/Logs/smith-row-sweep.log, and a
log-match-age signal declaring that same file and that same needle
performs the identical read, with evalLogMatchAge already separating
unreadable (unknown) from read, no line (down) from found (ok/
stale). No new file to watch, and the three-valued distinction holds by
construction rather than by a convention someone must maintain.
⚠️ The needle must be board-scoped. A bare row-sweep pattern would match
the 2026-09-10 rollout-x test-board line and render ok for a production
board nothing has ever swept — this row's own defect, one layer down again. The
pattern carries the board id and the colon, exactly as sweep-status does.
staleAfterS is 10800 because that is the lease TTL: a lapse takes three
hours to form, so a sweep older than three hours has not seen the current set.
What this ADR deliberately does not do
- It does not register or load the daemon. That is a separate PR, and its
load is a human act — a new scheduled job on this machine is infra blast
radius, which the unattended pane that wrote this record does not perform.
Until it lands, the new catalog entry's status is
proposedand its prose says not scheduled, so the catalog cannot read as coverage. - It changes nothing in
agent-smith. The tool is correct; what was missing is a schedule and a catalog row. - It does not reopen the three rejected
row-fencesignal candidates. They stay rejected on their own merits (see ADR-0009 for the rule they are rejected under). What this ADR corrects, in the same PR, is one sentence of the premise beneath that rejection, which had expired: the fence now has steady-state emission. The rejection survives; only its reason is brought current. This ADR does not add signals torow-fence— the sweep log "would go green while the fence was entirely broken: it is a different system", and a different system gets its own entry.
Residual — stated so it is not mistaken for checked
- Whether
rollout-x's single 2026-09-10 line was a deliberate test or a first-and-only production attempt is not established. - Whether any other machine in the fleet runs this sweep is not established. Both were out of reach from the seat that filed the row; neither changes the finding on this board.
- This record is one host's reading, measured on the mini.