# Row 151 (#1645): tests pin where a launch notice is routed and how talk prints it with a reply Builder: Dewey. Reviewer: Filbert. Gate owner: Sage. Brief: docs/plans/2026-10-15_landing-followups.md, the first `##` section (blob 4e620d79, commit c66c7fb71). Assignment: sage-0454. Sources: Filbert's row 146 round 1 review, note 1 and mutant M1 (comment 28641), and the row 142 round 3 hand probe the brief describes. Base: 686fc1cb6 (base.txt, origin/refactor after rows 136 and 147). The candidate is build.patch on that base, and candidate-manifest.sha256 lists both changed paths with their sha256. repro.sh applies the patch to a fresh detached worktree and checks the digests; it printed DIGESTS_OK. Built on 02ee7f640 (after row 142). Row 136 landed as d8487b3af and changed packages/bus/src/broker.mjs under the launch-notice test, and none of this row's paths. Per sage-0463 the worktree moved to d8487b3af: the patch applied with no change to either file, the manifest digests are the same, and repro.sh on the new base printed DIGESTS_OK. Row 147 then landed as 686fc1cb6. Sage's check (`git diff --name-only 02ee7f640 686fc1cb6` on the two test files, sage-0467) printed nothing, so the base could have stayed. But row 147 changed packages/cli/src/cli.mjs, the file C1 to C3 mutate and verbs runs, so I moved to 686fc1cb6 so that the mutants and the gate run on the cli.mjs that lands. The patch and the digests are unchanged again, each mutant target still occurs once, and repro.sh printed DIGESTS_OK. ## The change Test-only: no product code changes. The two files the brief names, +44 lines, nothing removed. - **packages/bus/tests/launch-notice.test.mjs**, test 1. After the second send (human to coder) with chief, launch.by, running, the latest notice's `routed` delivery has `holder_run` equal to `chief-run`. The test already asserted a null holder for the first notice, sent while chief was stopped. message.receive selects on `to_role`, so chief still receives a notice routed elsewhere. This row's `routed` delivery is the only place the routing shows, and it's the row the Console's waiting lists read. - **packages/cli/tests/verbs.test.mjs**, a new test, "talk to a stopped role prints the waiting line once, skips a non-reply and prints the reply". The business's launch block names pm as launch.by, and pm runs. `talk cto` with `--wait 5` goes to cto, which has no session. A transport wrapper injects the other side. On poll 1, pm sends the human an INFO note, "launching cto". On poll 2, cto is launched and claims, receives the waiting message and replies with RESULT in_reply_to it. Assertions: - exit 0; - the whole stdout equals `sent to cto`, then `cto isn't running, pm has been told`, then the reply, so the waiting line prints once, the note doesn't print, and nothing else prints; - polls is 2, so the note did arrive before the reply; - message.read was called once, for the reply's id; - `mosaic inbox` then shows 1 unread, pm's note. This is the case Filbert probed by hand on the row 142 candidate. Row 146's talk test uses `--wait 0`, which never polls. Row 142's tests talk to coder, which runs, so they never print a waiting line. ### Choices - **The non-reply comes from launch.by (pm), not from the target.** That is the message a human is likely to get first when a stopped role is launched. Row 142's test already covers an unsolicited note from the target role itself. - **Exact stdout instead of separate matches.** One equality pins the order (sent, waiting line, reply), says the waiting line prints once, and says the note never prints. Separate matches would each need a count. - **C3, a mutant beyond the brief's two.** The brief says the waiting line prints once. C3 prints it again on every receive poll, so the "once" has a mutant of its own. ## Mutants mutants.py applies one fault at a time, runs the owning test file with the spec reporter, and restores the source after each one. Run 2026-10-16T00:13:46Z to 00:13:59Z on 686fc1cb6 plus the candidate, in the sage-0470 slot: 4 of 4 killed, `restored True` (mutants-run.log, logs in mutants/). | Mutant | Fault | Runs | Result | Failing tests | |---|---|---|---|---| | B1-notice-routed-to-target | Filbert's row 146 M1: `#notice` routes to `to`, not `by` | bus launch-notice | KILLED | test 1, at the new assertion (line 97: actual null, expected `chief-run`). Nothing else fails, so this assertion is the only thing holding it, as Filbert found. | | C1-no-reply-filter | talk drops row 142's `m.in_reply_to !== sent.id` skip | cli verbs | KILLED | the new test; row 142's two talk tests | | C2-no-waiting-lines | talk drops row 146's `waitingLines` write | cli verbs | KILLED | the new test; row 146's talk test | | C3-waiting-every-poll | talk writes the waiting line on every receive poll | cli verbs | KILLED | the new test only | C1 and C2 were already killed by the row 142 and row 146 tests. The new test adds what neither had: both paths in one talk, plus the "once" that only C3 checks. ## Receipts Single files on the candidate, without the slot, TMPDIR in my scratch, 0 fail and 0 skipped: - on 02ee7f640: bus launch-notice 7/7, cli verbs 8/8; - on d8487b3af, 2026-10-16T00:05:44Z to 00:05:48Z: bus launch-notice 7/7, cli verbs 8/8. B1's target string still occurs once in broker.mjs. - on 686fc1cb6, 2026-10-16T00:12:33Z to 00:12:38Z: bus launch-notice 7/7, cli verbs 8/8. Slot granted by Sage in sage-0470 (00:13:38Z). - **Mutants**, 00:13:46Z to 00:13:59Z: 4 of 4 killed, source restored. See the kill table above. - **Gate**, gate.sh from ~/dewey-scratch/r151 on 686fc1cb6, 2026-10-16T00:14:06Z to 00:16:58Z, exit 0 (gate-run.log, logs under gate/). It covers the bus and cli suites and every scripts/test-*.sh, as the brief's gate names them: | Step | Result | |---|---| | bus | 265 pass, 0 fail | | cli | 213 pass, 0 fail | | test-auth | 15 passed, 0 failed | | test-conductor | 17 passed, 0 failed | | test-config | 24 passed, 0 failed | | test-discord | 78 passed, 0 failed | | test-extension-package | 18 passed, 0 failed | | test-foundation | 44 passed, 0 failed | | test-land-work | 84 passed, 0 failed | | test-queue | 28 passed, 0 failed | | test-release | 14 passed, 0 failed | | test-task | 98 passed, 0 failed | No recurrence of flakes #258, #261, #262 or #263. gate.sh exports `COMPOSE_PROJECT_NAME=dewey-r151`, and its EXIT trap printed `removed network dewey-r151_default`. Afterwards no network named dewey* or wt* exists. - **Candidate:** candidate-manifest.sha256, sha256 cb831847239e9ea60bd77ed8c765dafbf607a03cadeed3d0fc8d8284846878ed, 2 files.