Files
jason.woltjeandClaude Sonnet 5.5 1d8aabd3cc researcher: row 140 round 2 packet, staff-request tests judge sender and launcher by definition, rebased onto 02ee7f640 (#1634)
Test-only round for Filbert's changes request (comment 28639): three new
staff-request tests, mutants N1, N2, N2b and n2f added (25 of 25 killed),
chief-of-staff.md conflict with row 146 resolved keeping both bullets.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-15 18:57:47 -05:00

9.2 KiB
Raw Permalink Blame History

Row 140 (#1634) round 2: the pm asks the chief of staff for staff, and the chief hires and launches

Seat: Researcher. Reviewer: Filbert. Gate owner: Sage. Brief: docs/plans/2026-10-15_q167-north-star-rows.md, the row 140 section (REQ-COS-1). Round 1: ../build.md. Filbert asked for changes on #1634 (comment 28639). He found the code correct; the finding is test-only. This round adds the tests and the mutants he asked for, and rebases onto the landed rows 146 and 142.

Base and candidate

Base: 02ee7f640 (detached worktree /mnt/storage/scratch/researcher/q140r2). Canonical HEAD was c66c7fb71 at packet time; git diff --name-only 02ee7f640 HEAD -- packages roles scripts docs/TOOLS.md package.json is empty (the commits after 02ee7f640 touch docs and agents only). row140.patch (this directory) is my diff on 02ee7f640: 11 files, +429 −5. It passes git apply --cached --check on 02ee7f640 and round-trips to the candidate tree 87633b89509c4a9fcc914492e5d5968772f5342f (temp GIT_INDEX_FILE, trees equal). candidate-manifest.sha256 lists the 11 files (sha256 of the manifest: 04a381e88eeee7be99ddd4a1911cc3f5a3211668a47e7da962bb29da26d84c43). 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.

What changed since round 1

Round 1's patch was +354 −5 on dda7e31b0. Round 2's is +429 −5 on 02ee7f640. Per file, only packages/bus/tests/staff-request.test.mjs differs in size (198 to 273 added lines). The other ten files carry the same added lines as in round 1. No production code of mine changed.

Rebase

Rows 146 (277d1fa21) and 142 (02ee7f640) landed after dda7e31b0. Of my 11 files, three sit under paths they touched: packages/bus/src/broker.mjs and packages/bus/README.md (146) and roles/chief-of-staff.md (146). The first two applied with no conflict. One conflict, in roles/chief-of-staff.md: 146 put a bullet about messages from _bus where mine goes. I kept both bullets: 146's _bus bullet first ("A message from _bus is the bus telling you…"), then mine ("Answer a staff request. The pm role sends you a STAFF-REQUEST message…"). 146 had also replaced the stale "until the broker gives you a verb" sentence with the change_organization text, so the note I left for it in round 1 is closed.

Filbert's finding and the three new tests

N1 and N2 survived round 1's tests because every fixture gave an instance the same name as its role definition (instance pm with the pm definition, instance chief with the chief-of-staff definition). A check written against the instance name passed all seven tests. The broker judges both ends by role definition (b.roles[s.role]?.definition !== STAFF_FROM, b.roles[chief]?.definition !== STAFF_TO), so the tests now use names that differ from the definitions. setup() takes an arbiters option and returns staffEvents() (the action.allowed events whose operation is staff.request).

The file has 10 tests (was 7). New:

  1. The sender is judged by definition. Instance lead, with the pm definition, sends and the chief receives it from lead. Instance pm, with the coder definition and pm authority, gets staff-request-refused, and no staff.request event is left.
  2. The launcher is judged by definition. Launcher boss (the chief-of-staff definition, launch.by: 'boss') receives the request. Launcher chief with the coder definition gives no-chief-of-staff; no event and no message is left.
  3. A refused staff request leaves no staff.request action.allowed event. Three refusals: no launcher (no-chief-of-staff), a coder sender (staff-request-refused), and roles: [] (invalid-request). The event count is 0 after each. This is Filbert's assertion 5.

Assertion 5 has no mutant target, and that is on purpose. The missing event is not produced by a line that can be deleted. The request runs in one transaction, so its action.allowed event rolls back when a later check refuses. Nothing in broker.mjs says "delete the event on refusal", so there is nothing to mutate; removing the transaction would be a design change, not a mutant. The assertion pins the behavior (a refused request writes nothing); no mutant targets it. Filbert asked for the assertion, not a mutant.

Mutants

mutants.sh <worktree> <outdir> is round 1's script with four mutants added after m21. Each edits broker.mjs exactly once (the dry run, MUTANT_DRY=1, found every edit once on the new base):

Mutant Edit What it models
N1 (n1-sender-by-name) if (s.role !== STAFF_FROM) fail('staff-request-refused'); the sender checked by instance name, not definition
N2 (n2-launcher-by-name) if (!chief || chief !== 'chief') fail('no-chief-of-staff'); the launcher checked by instance name
N2b (n2b-launcher-exists-only) if (!chief || !b.roles[chief]) fail('no-chief-of-staff'); any existing launcher accepted
n2f (n2f-filbert-recipient) if (!b.roles[chief] || chief === 'coder') fail('no-chief-of-staff'); Filbert's own N2 text (sage-0430): the recipient check becomes "exists and is not named coder"

Run 2026-10-15T23:56:41Z to 23:56:50Z on q140r2 (mutants-run.txt, mutants-started.txt, mutants-finished.txt; one .out, .rc and .patch per mutant in mutants/). The slot was Sage's "slot yours" (sage-0455); a busy check by exit status (/proc cwd links only) read CLEAR before and after. HEAD was 02ee7f640 and the candidate tree was 87633b89… before and after. Three controls (staff-request, tools and bundle tests on the unmutated candidate) pass 10/10, 18/18 and 21/21. All 25 mutants fail their test file by a named assertion (rc=1 each, no timeout kills). The worktree was restored: no unstaged diff, git write-tree equals the candidate tree.

New mutants and what kills them:

Mutant Killed by Round 1's seven tests
N1 n1-sender-by-name the sender-by-definition test, and only that one passed 7/7 (survived)
N2 n2-launcher-by-name the launcher-by-definition test, and only that one passed 7/7 (survived)
N2b n2b-launcher-exists-only the launcher-by-definition test and "the request goes to the business launcher, and only when that is a chief of staff" killed already by the second one
n2f n2f-filbert-recipient the launcher-by-definition test, and only that one passed 7/7 (survived)

The round 1 column is from running round 1's seven-test file (control 7/7) against the same four edits on dda7e31b0, on 2026-10-15 at about 23:19Z to 23:21Z, as single test files in a scratch worktree (sage-0427). The n2f run overlapped the start of Rocko's slot by about 45 seconds; I reported that to Sage at the time. round1-tests-on-new-mutants/ holds their output (N1, N2 and n2f: 7/7 pass; N2b: 1 failure, the business-launcher test). The new tests also kill round 1's mutants more often than before: m1 fails 3 tests (was 1), m3 2, m15 3, m17 5.

Round 1's 21 mutants (m1 to m21) are unchanged and all still fail on the new base: m1 3 tests, m2 2, m3 2, m4 1, m5 1, m6 1, m7 to m10 1 each (the shape test), m11 2, m12 to m14 1 each, m15 3, m16 1, m17 5, m18 6 (tools.test), m19 1, m20 1, m21 1 (bundle.test). The launcher end-to-end test still has no mutant of its own, as in round 1.

Assertion 5 (a refused request leaves no staff.request event) has no mutant, per the section above; m1 and m3 fail that test only because they let a request through, not because they target the rollback.

Verification

Each test file singly (touched/, others/), on the candidate tree at 02ee7f640, 2026-10-15T23:43:52Z to 23:45:39Z, all rc=0:

  • The four files this row changes: staff-request.test.mjs 10/10 (packages/bus/tests/), tools.test.mjs 18/18, bundle.test.mjs 21/21 (packages/harness/tests/), launcher.test.mjs 18/18 (packages/cli/tests/). The launcher test uses the real bwrap runner and ran (it is skipped without one).
  • Every other test file in the bus, harness and cli packages: 61 files, rc=0 each (suites/others/_summary.txt). Row 145's lesson: a same-blob test can break on a new base, so I ran all of them and not only the files the rebase touched.

The full gate was not rerun for this packet. Sage's rule is that the gate runs at landing. I ran the bus, harness and cli test files singly, as above; I did not run the whole suites in one process, the other packages' suites, or scripts/test-*.sh. Round 1's gate (22:59 to 23:03Z on dda7e31b0, all green) does not cover this candidate, because the base and the test file changed. No Docker gate ran, so there is no network to clean (docker network ls shows none of mine). No flake (#258, #261, #262, #263) recurred in any run above. After the mutants, nothing of mine is running (/proc cwd links under my scratch show only the shell).

Not in this packet

  • The Console's send text and the STAFF-REQUEST body wording stay as in round 1 (the body is guidance, not enforcement).
  • A live pm and chief exchanging a real request; the evidence is the in-process tests and the launcher test.
  • Carried from row 132, unchanged by this row: the change_organization description says "replaces" while the broker merges per instance; a revision-only call is refused by the writer, not by the schema.