From the adversarial review of #854.
The cancel acknowledger runs only in the ROOT manager's turn loop and resolves references against its direct children (scope.view.nodes — src/runtime/supervise/scope.ts:2145). Nested drivers receive no controlDir (supervise.ts builds them without it). So an external client can cancel a top-level worker, but not exactly ONE nested worker: a request naming a deeper descendant stays unknown forever.
Pinned by test: tests/kernel/worker-cancellation.test.ts — 'a request naming a nested descendant stays unanswered' (added in #859). The TUI now refuses these and routes the operator to the lead (#859), which cancels the lead's WHOLE subtree — a larger blast radius than the operator asked for.
Design constraint discovered in review: giving every nested driver the same controlDir is NOT the fix. Label and profile-name references can resolve in more than one manager, so two acknowledgers would abort two different workers for one operation and race last-writer-wins on the acknowledgement file. Correct routing needs ownership: only the manager whose subtree prefix matches the node id applies it, or the root forwards the request down the driver chain.
Also in scope, acknowledger lifecycle gaps that affect direct workers too:
- A record can stay
cancel_requested forever when the abort is issued on the final post-drain pass (coordination-driver.ts:920) — the driver returns before the settle is observed, and a reader cannot distinguish in-progress from run-over.
- Pending requests never expire (
coordination-driver.ts:443-444). A request that matched nothing stays in the inbox and can abort a FUTURE spawn that matches by label or profile name — including on a resumed run days later. A TTL or an explicit expiry record on run end would close both.
From the adversarial review of #854.
The cancel acknowledger runs only in the ROOT manager's turn loop and resolves references against its direct children (
scope.view.nodes—src/runtime/supervise/scope.ts:2145). Nested drivers receive nocontrolDir(supervise.tsbuilds them without it). So an external client can cancel a top-level worker, but not exactly ONE nested worker: a request naming a deeper descendant staysunknownforever.Pinned by test:
tests/kernel/worker-cancellation.test.ts— 'a request naming a nested descendant stays unanswered' (added in #859). The TUI now refuses these and routes the operator to the lead (#859), which cancels the lead's WHOLE subtree — a larger blast radius than the operator asked for.Design constraint discovered in review: giving every nested driver the same
controlDiris NOT the fix. Label and profile-name references can resolve in more than one manager, so two acknowledgers would abort two different workers for one operation and race last-writer-wins on the acknowledgement file. Correct routing needs ownership: only the manager whose subtree prefix matches the node id applies it, or the root forwards the request down the driver chain.Also in scope, acknowledger lifecycle gaps that affect direct workers too:
cancel_requestedforever when the abort is issued on the final post-drain pass (coordination-driver.ts:920) — the driver returns before the settle is observed, and a reader cannot distinguish in-progress from run-over.coordination-driver.ts:443-444). A request that matched nothing stays in the inbox and can abort a FUTURE spawn that matches by label or profile name — including on a resumed run days later. A TTL or an explicit expiry record on run end would close both.