Dewey's round 3 candidate, manifest
agents/dewey/work/queue-40/candidate-manifest-r3.sha256 (d0aa0ded,
27 files, checked OK in the canonical tree).
- WebUI inbox, tasks, agents and trail views, read-only over /api/bus.
The README says the bus proof ends at the Console process.
- CHAT-03 seal: the engine command is fixed, the engine environment is
explicit, SEAL_FLAGS has --no-approve, escalating is cleared on throw.
- Terminal input typed after Ctrl-T or Ctrl-O is held. Only the run whose
own parse set held drains it (T1), and #run catches errors per action.
- DEFERRED keeps N2 and moves F2 to done, citing T1.
Reviews: Filbert approve (comment 27011, rev 260), Darkwing approve
(27013, rev 264). Landing gate on 8cad7722 plus the candidate: webui 22,
conversation 161, control-board 124, every scripts/test-*.sh green,
test-task 98/0. Mutant Mr survives; its flows test is the first
follow-up row.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
7.2 KiB
Slice 1 S5 mutation check (row 40, #1522)
Run 2026-10-09 by Dewey, finished 2026-10-10T00:01Z. Each mutant ran on a
fresh scratch copy (~/dewey-scratch/s5/mut) of packages/conversation,
control-board, discord, seat, package.json, package-lock.json and
docs/plans/chat-01, with node_modules symlinked. Every mutant got the
full conversation suite. The working tree was never mutated. The tools are
~/dewey-scratch/s5/mut-tools/ (mutants.py, run.sh).
| Mutant | Change | Result | Killed by |
|---|---|---|---|
| base | none | 157/157 | (baseline) |
| esc | the force stop no longer clears escalating when the fence throws |
killed | races: a force stop whose fence throws leaves no escalation flag behind |
| seal | the seal check at bind always passes | killed | N24b |
| keys | the envKeys check never finds a bad name | killed | N24b, N24 |
| envall | the engine environment copies every name in the source | killed | N24b |
| credname | envKeys skips the credential-name test | killed | N24b |
| restart | start() skips the seal check |
killed | N24b |
| hold | no action holds input | killed | terminal: Ctrl-T then Enter in one chunk |
| holdreload | only Ctrl-T holds input | killed | the same test's Ctrl-O case |
| throwdrain | an action that throws drops the input held behind it | killed | terminal: an action that throws still releases the input held behind it |
| manager | ScopeLauncher passes the engine environment without MANAGER_ENV |
killed | K19 |
Two fixes came out of the runs:
managersurvived the first run, since no test launched a scope with only the engine environment (the cohort fixtures pass the whole test environment). K19 now launches/bin/sleepthrough ScopeLauncher withengineEnv([])and checks that the engine's environment names come only from ENGINE_ENV, MANAGER_ENV and the names systemd and the shim's shell set (INVOCATION_ID,PWD,SHLVL).- Under
sealandrestart, N24b failed but then held its controller's socket open, soturns.test.mjsran until the 900 s timeout. The bind-time part of N24b now closes the controller infinally, and a regression there fails in seconds.
The first full run's baseline failed 2 tests because the copy lacked
docs/plans/chat-01/contracts.schema.json. The runner now copies it.
Results from that run were discarded.
Round 2 (Filbert's comment 26993)
The same runner, the round 2 candidate, and every mutant from round 1, plus three for the round 2 changes. Each mutant ran the full conversation suite on a fresh scratch copy.
| Mutant | Change | Result | Killed by |
|---|---|---|---|
| base | none | 159/159 | (baseline) |
| noapprove | --no-approve removed from SEAL_FLAGS |
killed | smoke: sealed, pinned Pi ignores a trusted project's .pi resources |
| queuecatch | key() chains on the queue without catching the previous chunk's throw |
killed | terminal: after an action throws, later input still runs |
| inputcatch | input() rethrows instead of setting the status line |
killed | the same test |
| esc | as round 1 | killed | races: a force stop whose fence throws leaves no escalation flag behind |
| seal | as round 1 | killed | N24b |
| keys | as round 1 | killed | N24b, N24 |
| envall | as round 1 | killed | N24b, K19 |
| credname | as round 1 | killed | N24b |
| restart | as round 1 | killed | N24b |
| hold | as round 1 | killed | terminal: Ctrl-T then Enter in one chunk; after an action throws |
| holdreload | as round 1 | killed | terminal: Ctrl-T then Enter in one chunk (Ctrl-O case) |
| throwdrain | as round 1 | killed | terminal: an action that throws still releases the input held behind it; after an action throws |
| manager | as round 1 | killed | K19 |
noapprove is checked against the real pinned Pi 0.85.1 with no model
call. The test's control runs the same trusted project with --approve
after the seal, and that offers skill:probe, so the sealed assertion
can see a load when one happens.
Round 3 (Darkwing's comment 27001, Filbert's comment 27005)
The same runner on the round 3 candidate. The terminal mutants were rewritten for the new #run/#feed code, and the rest are as in round 2. Each mutant ran the full conversation suite on a fresh scratch copy.
| Mutant | Change | Result | Killed by |
|---|---|---|---|
| base | none | 161/161 | (baseline) |
| holdowner | every run drains held, as in round 2 (T1) |
killed, 160/161 | terminal: input held behind Ctrl-T waits for that takeover while an earlier action is still pending |
| heldcatch | held input's key() returns the holder's promise (N4) |
killed, 160/161 | terminal: input() reports an error when it happens … |
| chunkstop | one try around the chunk's actions, so a throw skips the rest of the chunk | killed, 160/161 | the same test |
| reportlate | input() catches at the end, as in round 2 (N4) |
killed, 160/161 | the same test |
| reportdrop | input()'s error is thrown and swallowed, never shown |
killed, 159/161 | terminal: after an action throws, later input still runs; input() reports an error when it happens |
| throwdrain | a throw leaves #run before the held input |
killed, 158/161 | terminal: an action that throws still releases the input held behind it; after an action throws; input() reports an error when it happens |
| queuecatch | as round 2 | killed, 160/161 | terminal: after an action throws, later input still runs |
| noapprove | as round 2 | killed, 160/161 | smoke: sealed, pinned Pi ignores a trusted project's .pi resources |
| esc | as round 1 | killed, 160/161 | races: a force stop whose fence throws leaves no escalation flag behind |
| seal | as round 1 | killed, 160/161 | N24b |
| keys | as round 1 | killed, 159/161 | N24b, N24 |
| envall | as round 1 | killed, 159/161 | N24b, K19 |
| credname | as round 1 | killed, 160/161 | N24b |
| restart | as round 1 | killed, 160/161 | N24b |
| hold | as round 1 | killed, 157/161 | terminal: Ctrl-T then Enter in one chunk; input held behind Ctrl-T waits for that takeover while an earlier action is still pending; after an action throws; input() reports an error when it happens |
| holdreload | as round 1 | killed, 160/161 | terminal: Ctrl-T then Enter in one chunk (Ctrl-O case) |
| manager | as round 1 | killed, 160/161 | K19 |
Round 2's inputcatch (input() rethrows) has no counterpart here: input() no longer catches a rejection, and with a reporter #run never throws. reportdrop and reportlate cover its two halves.
WebUI (Darkwing's note 1). run.sh copies only the conversation packages, so these ran packages/webui/tests/bus.test.mjs on a scratch copy of the packages it imports:
| Mutant | Change | Result | Killed by |
|---|---|---|---|
| base | none | 7/7 | (baseline) |
| Mm | humanCall's timeout rejects without child.kill('SIGKILL') |
killed, 6/7 | humanCall kills a transport that runs past its timeout |
| Mp | serve --business takes any value |
killed, 6/7 | serve refuses a --business value that is not a business id |
Correction: the first Mm run hung, because the surviving child held the test process open. I stopped the child by PID. The test now kills a surviving child on cleanup, and the rerun failed the assertion in 1.5 s. Under Mp, serve started a real server on port 0 until spawnSync's 10 s timeout ended it.