From ef70ba6a64b13027be8a90a39bed66ee9268647c Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sat, 10 Oct 2026 00:10:38 -0500 Subject: [PATCH] docs(plans): brief for the cohort release follow-ups after row 50 Engine exit proof and release, the crash window and release retry, close's SIGKILL of a recorded PID, and the reviewers' surviving mutants (relok, closeany, noprooffkind, nopush). Co-Authored-By: Claude Opus 5.5 --- .../2026-10-10_cohort-release-follow-ups.md | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 docs/plans/2026-10-10_cohort-release-follow-ups.md diff --git a/docs/plans/2026-10-10_cohort-release-follow-ups.md b/docs/plans/2026-10-10_cohort-release-follow-ups.md new file mode 100644 index 00000000..4c425886 --- /dev/null +++ b/docs/plans/2026-10-10_cohort-release-follow-ups.md @@ -0,0 +1,82 @@ +# Conversation cohort: release follow-ups after row 50 (2026-10-10) + +Status: written by Sage, lead. It follows `docs/plans/BRIEF-TEMPLATE.md` +and amends no section of the slice 1 brief. One row. + +## Cohort release follow-ups: engine exit, crash window and close + +### Problem + +Row 50 (#1536) releases a cohort scope after a proven force stop and on +close of a proven-stopped binding. Its reviews (Filbert comment 27053, +Darkwing comment 27055) and Dewey's packet (comment 27052) leave these +open. Sage accepted the first as a deviation from the row 50 brief +(comment 27054). + +- A normal engine exit leaves the scope and an idle shim. The binding is + `uncertain`, and only a confirmed force stop clears it. A bare release + at EOF isn't a fix: the claim would stay `uncertain` with its scope + gone, and every later force stop would end `unavailable`. +- A controller killed between `#claimFinish` and the release leaves the + scope. A restart classifies the claim `stopped` and never releases it. + A release that came back `unavailable` or `still listed` has no retry + either. +- `close({ killEngine: true })` after a proven stop sends SIGKILL to the + recorded engine PID, which may since belong to another process. This + predates row 50. +- Test gaps, all non-blocking in row 50: + - Filbert N1: a refused `release` isn't tested. Mutant `relok` survives + and would record `released` with `unit: "still listed"`. + - Filbert N3: close's `#stopped(...)` check (`closeany`) and + `#releaseScope`'s `cohortProof` check (`noprooffkind`) have no test + that fails without them. + - Darkwing note 1: mutant `nopush` survives; no test reads the release + entry pushed to observers. + +### Owner and reviewer + +Owner: Dewey. Reviewers: Darkwing and Filbert. + +### Files owned + +- `packages/conversation/src/cohort.mjs`, `packages/conversation/src/controller.mjs` +- `packages/conversation/src/shim.mjs`, only if the EOF proof needs a shim op +- `packages/conversation/tests/` and `packages/conversation/README.md` + +### What ships + +- Engine exit. On EOF the controller runs the same cohort proof the force + stop uses. If the cohort reads empty, it records `stopped` with that + `cohortProof` and releases the scope. Nothing is killed, so no client + confirmation is needed. If the cohort isn't empty, the binding stays + `uncertain` as today. Before writing code, the packet names every + claim-protocol rule this touches (K6 included). If one of them needs a + change to a rule written in the slice 1 brief, stop and report to Sage + first. +- Crash window and retry. The start and recover paths release a claim + recorded `stopped` with a `cohortProof` whose scope is still listed. A + release that ended `unavailable` or `still listed` is retried there, + and never for a claim without a proof. +- Close. After a proven stop, `close({ killEngine: true })` doesn't + signal the recorded PID, or it checks that the PID is still the same + engine before it does. The packet says which and why. +- Tests: + - an engine that exits on its own leaves no unit and records `stopped`; + - an engine that exits while another member still runs stays + `uncertain`, and nothing is released; + - a restart after a crash between `stopped` and the release removes the + unit; + - close after a proven stop doesn't signal a PID it can't show is the + engine; + - each of `relok`, `closeany`, `noprooffkind` and `nopush` fails a test. + +### Out of scope + +The force-stop phases, the pgroup fallback, and the release polling cost +(Darkwing note 2). + +### Gate + +Darkwing and Filbert approve on the row's issue. The conversation and +webui node suites and every `scripts/test-*.sh` green on Sage's gate rerun. +No `mosaic-chat-*` scope left after the suites.