Files

5.9 KiB
Raw Permalink Blame History

Row 142 (#1636) round 3: mosaic talk prints only the reply to its own message

Seat: Researcher. Reviewer: Filbert. Gate owner: Sage. Brief: docs/plans/2026-10-15_q167-north-star-rows.md, section "mosaic talk prints only the reply to its own message". Round 2: ../r2/build.md. Filbert approved round 2 (comment 28638). This packet exists because row 146 landed first (277d1fa21, pushed) and changed three of my four paths, so the approved manifest no longer matches the base. No behavior of mine changed.

Base and candidate

Base: 277d1fa21 (detached worktree /mnt/storage/scratch/researcher/q142r3). Canonical HEAD was e2a7cb38d at packet time; git diff --name-only 277d1fa21 e2a7cb38d -- packages roles scripts docs/TOOLS.md package.json is empty (the commits after 277d1fa21 touch docs and agents only). row142.patch (this directory) is my diff on 277d1fa21: 4 files, +44 −24. It passes git apply --cached --check on 277d1fa21 and round-trips to the candidate tree b994c1ce628fed20f54aca5dfebd7047fb8b4e1d (temp GIT_INDEX_FILE, trees equal). candidate-manifest.sha256 lists the 4 files (sha256 of the manifest: c847d8fe411d1269bd751c595048d289f4a7c1f76f639b6acfe622e6d593dd81). Secrets and binary scan of the patch: nothing. Nothing is pushed; I hold no Gitea credential; the in-review move and review request are Sage's.

How the rebase went

Round 2's patch applied with git apply --3way onto 277d1fa21:

File Result
packages/cli/src/cli.mjs clean; 146 added waitingLines and one write after sent, my hunks are in the receive loop and don't overlap
packages/cli/tests/verbs.test.mjs clean; 146's new test (the "isn't running" lines) sits beside my three rewritten tests
docs/TOOLS.md clean; 146 didn't touch it, the file equals round 2's
packages/cli/README.md one conflict, in the talk bullet. Resolved by hand, below

The one judgment call: the README talk bullet. 146 inserted its "isn't running" text in the middle of the sentence my round changed; both rewrote the same lines. I kept 146's block word for word (from "When no run holds the role (row 146, #1640)," through "No verb launches launch.by on a running host.") and my sentences around it. The result reads: prints the reply to its REQUEST, marks only that read, and stops; any other message stays unread and mosaic inbox lists it; no reply in time exits 1 and mosaic inbox shows it; then 146's block; then --wait 0 only sends; --follow prints and marks every message read. Two things I did not do: I did not rewrap 146's long line (“launches launch.by on a running host. --wait 0 only sends. talk --follow keeps”, 86 characters with its indent) because the lines are 146's, and I changed "marking messages read" to "marking every message read" as in round 2.

How the talk lines combine

In talk, 146's write is if (sent.waiting) io.stdout.write(waitingLines(...)), straight after sent <id> to <role> and before the receive loop. It prints once, from the broker's reply to message.send, and doesn't read the inbox. My filter is inside the loop (if (!follow && m.in_reply_to !== sent.id) continue;), so it decides only what the loop prints and marks read after those lines. Output order for a plain talk to a stopped role: sent …, 146's "isn't running" lines, then only the reply when it arrives (other messages skipped and left unread). The two don't share state, and neither reads the other's variable. With --wait 0, 146's lines print and talk returns before the loop, so the filter never runs. With --follow the filter is off and 146's lines still print once.

Not covered by a test: one talk that prints a 146 line, then receives a non-reply message and then the reply. 146's test uses a stopped role with no incoming messages, and mine use a running role. The two code paths don't touch, so I read this as a gap in the tests, not in the code, but it is not exercised.

Verification

  • Every cli test file, one at a time, plus 146's bus test, on the rebased candidate tree (cli-single/, 20 files, all rc=0, 2026-10-15T23:33:33Z to 23:34:41Z): app 30, boot-status 3, cli 12, config 6, follow 6, format 3, git-socket 18, host 41, launcher 17, launch-limits 1, limits 4, notifier 26, other-tree 4, stack-copy 12, tester 7, thread-launch 8, trackers-boot 1, transport 3, verbs 7, and packages/bus/tests/launch-notice.test.mjs 7. verbs.test.mjs (my three rewritten tests plus 146's), follow.test.mjs, tester.test.mjs (146 added one test, 6 to 7) and launch-notice.test.mjs are among them, as asked.
  • Mutants rerun on the new base. mutants.sh from round 1, unchanged, 2026-10-15T23:34:50Z to 23:35:16Z (mutants-run.txt, mutants/). The dry run found each edit exactly once, so 146's change didn't move any line the mutants edit. Three controls (verbs 7/7, follow 6/6, tester 7/7) pass. All 6 mutants fail their tests by assertion: m1, m2, m3 and m4 fail 2 tests each, m5 and m6 fail 1 each, the same as round 2. The worktree is restored (the staged candidate is the only diff).
  • The full gate was not rerun for this packet. Sage's rule is that the gate runs at landing. I ran the cli test files singly as above, not the whole cli suite in one process, and not the other packages' suites or scripts/test-*.sh. The packages outside packages/cli are untouched by this diff apart from the bus test I ran.

Not in this packet

  1. A message talk skips stays unread, and no CLI verb marks it read (Filbert round 1 note 1; Sage queues a follow-up).
  2. The Console's send text is stale (bus.js:280 and :261, send-browser.test.mjs:105, broker.mjs:1519); a public/ change needing decision 123.
  3. A live mosaic talk against a running bus; the evidence is the in-process tests, as in rounds 1 and 2.
  4. The carried row 132 notes (the change_organization "replaces" wording versus the broker's per-instance merge; a revision-only call refused by the writer, not the schema) are unrelated to this row.