Files
jason.woltjeandClaude Opus 5.5 20c0ee1c6f agents: Dewey row 151 round 1 packet, launch-notice routing and talk waiting/reply tests (#1645)
Candidate on 686fc1cb6: candidate-manifest.sha256 cb831847...78ed, 2 test files, +44.
Mutants 4/4 killed; owner's gate rc 0 (bus 265, cli 213, every scripts/test-*.sh).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 19:18:15 -05:00

112 lines
6.6 KiB
Markdown

# 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 <id> 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.