docs: brief for the idle-stop race row (Vikunja 588, #1809, mos-1411); docs only

This commit is contained in:
jason.woltje committed 2026-10-23 00:00:21 -05:00
1 parent c902a767dc
commit e3ef1eaf6f
1 file changed
+51
@@ -0,0 +1,51 @@
# The idle-stop race: a released run's last call ends it session-invalid
Found by row 292's gate (#1797) at 04:54Z on 10-23. Vikunja 588. Mos ruled on it in mos-1411.
## Brief: the idle-stop race (Vikunja 588)
Issue #1809.
Owner Gizmoduck. Reviewer Dewey. Gate owner Sage. After row 292 is done.
The cli suite's `packages/cli/tests/compactions-launch.test.mjs:206` failed once at `:229`. The
first run ended `['session-invalid', 22, null]` where `['stopped', 0, null]` was expected. Product
and test were unchanged since the test last passed 5/5. Gizmoduck's reading of the code, which Mos
and Sage checked, but no run has reproduced it yet:
- `packages/bus/src/broker.mjs` `threadIdle` releases the run's claim inside the call. The comment
above it records that ordering as deliberate (row 121 r2, Dewey's F3).
- `packages/cli/src/launcher.mjs` sends SIGTERM to the runner only after `threadIdle` returns.
- `packages/harness/src/runner.mjs` counts `not-holder` in `SESSION_GONE`. A poll or a call
already in flight that reaches the broker between the release and the signal gets `not-holder`.
The runner then sets exit 22 without checking whether it is stopping, and
`packages/seat/src/session.mjs` maps 22 to `session-invalid`.
So any idle stop can record `session-invalid` instead of `stopped`.
Change: make an idle-released run end `stopped/0`. The design goes to Dewey before any build, and
it must meet two conditions from mos-1411:
1. All three `SESSION_GONE` codes (`unauthenticated`, `not-holder`, `run-ended`) exit 22. A rule
that reads "a run the launcher is stopping, plus exit 22, means stopped" would also turn a real
`unauthenticated` or `run-ended` into `stopped`. The design says how it tells the idle release
apart. Mos suggested, without ruling, a distinct broker answer for a run whose claim
`threadIdle` released, which the runner maps to a clean stop. That would also cover a poll that
lands before the signal. Gizmoduck and Dewey choose.
2. The row ships a test that forces a call between the release and the SIGTERM and asserts
`stopped/0`. A failure rate is not proof.
Loosening `compactions-launch.test.mjs:229` is rejected. That test is right. Any change to an
existing assertion goes to Mos through Sage first.
Until this row lands, a gate whose only red is that exact `:229` signature may rerun the whole cli
suite once, unedited (mos-1411 point 4). Each hit is logged on Vikunja 588. The rule does not
apply to this row's own gate.
Evidence first: in Gizmoduck's slot, after 294, `compactions-launch.test.mjs` whole runs 10 times
on 292's head, recording each run's `ends[0]` and the runner log's `session stopped working:
<code>` line (mos-1411 point 1).
Gate: Dewey approves the design and then the manifest. The new forcing test, then
`compactions-launch.test.mjs`, then the bus, cli and harness suites whole, then every
`scripts/test-*.sh`. A mutant that drops the fix must die on the forcing test.