Files
stack/docs/plans/2026-10-22_stoprun-deadline.md

2.4 KiB

stopRun reads a live run's status at the deadline (191 follow-up, MVP)

Sage, 2026-10-22, for mos-1269. Row 194 b15's gate found it (honker-0121, sage-2510).

Why

stopRun in packages/processing-control/src/runtimes.mjs (row 191, 4bdc7e0e8) waits in while (now() <= deadline) (:333). Its final status read is inside if (now() >= deadline) (:356-359), and the loop sleeps Math.min(20, Math.max(1, deadline - now())) (:361). A real sleep can wake past the deadline. When it does, the loop condition fails before the final read runs, and :363 returns 'unknown' for a process that is still alive and ignoring SIGTERM and SIGKILL. The expected outcome is 'alive'.

Row 194's T9a (cli lifecycle.test.mjs:562) caught it in the loaded cli suite: 'unknown' where 'alive' was expected, while the same file passed alone. Row 191's tests missed it because their fake clock advances by exactly the sleep, so it never overshoots. Live is 86f95bb27, which doesn't carry 191, so nothing running is affected.

Brief: stopRun's deadline branch is the only time exit

No --after. 191 has landed. This row lands before row 194 b16, which rebases onto it (mos-1269 item 4).

What to build:

  1. The time loop's only exit on time is the existing deadline branch, so the final status read always runs once the deadline passes. One shape is for (;;) with the now() >= deadline branch as the time exit. The builder picks the shape and records it in BUILD.md.
  2. The other exits stay as they are: record gone (the catch), identity changed, ended or not alive, and the deadline branch's own mapping of alive, killed, stopped, identity-changed and unknown.
  3. Nothing else in runtimes.mjs changes. Vikunja 502's four items stay out (mos-1269 item 3). They follow row 194.

Tests:

  • A fake sleep advances the clock past the deadline while the process stays alive and ignores both signals. stopRun reports 'alive'.
  • The existing stop-run tests pass unchanged.

Mutants, each killed by a named test:

  • M1. The old loop condition while (now() <= deadline) with the fall-through return finish('unknown').

Gate: Dewey approves the manifest. The processing-control package's tests (runtimes.test.mjs and stop-run.test.mjs among them) and every other touched test file run whole, the business and cli suites are green on Sage's gate, and M1 is killed. Row 194 b16's full gate then runs on top of this row. Any red goes to Mos (mos-1269).