Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
4.9 KiB
Filbert review, row 128 round 1: approve.
Candidate manifest: digest 9eed6a78e3254944fb88b3bf36eb7574afeb161445a846ba8f8780e96ed8d5fd (agents/researcher/work/queue-128/candidate-manifest.sha256, 8 paths, base 0f3eb25ea). I ran sha256sum on the manifest and got that digest. sha256sum -c gives OK for all 8 paths in the canonical checkout. git log 0f3eb25ea..HEAD on the 8 paths is empty, so the base hasn't drifted. Brief: docs/plans/2026-10-18_row128-thread-cli.md, blob e15cb12a92.
The gate's REQ-USER-2 condition: met
"A send to a thread the user doesn't own is refused." I checked the path end to end:
thread.listreturns only the caller's threads (WHERE business=? AND owner=?, packages/bus/src/broker.mjs:2102-2108). So the resolver (packages/cli/src/thread.mjs:53-66) can't find another user's thread by name or prefix. It refuses those as "no thread of yours", exit 2, before any call that writes.- A full UUID the list doesn't show goes to the broker as given (thread.mjs:58).
thread.send,thread.openandthread.messagesall go through#thread(broker.mjs:311-317, used at :2115, :2122 and :2149), which failsthread-not-ownedwhent.owner !== s.human. So the broker's own check decides, and the CLI adds none, as the brief says. follow --threadreads the thread once before the firstmessage.receive(members?.refresh(), packages/cli/src/cli.mjs, just before the poll loop), so a foreign thread is refused before any delivery row is written.- The test (packages/cli/tests/thread-cli.test.mjs:311-334) inserts another owner's project and thread, and leaves a message waiting for the user so a receive would write a delivery row. It asserts exit 2,
mosaic: thread-not-owned, and empty stdout for five commands:talk --thread <id>,thread open,thread read,follow --threadandtalk --thread --follow. It checks that messages,thread_opens, deliveries,message_threads, threads and projects are unchanged. It also checks a name and a prefix of that thread are refused without a write, and that an unknown UUID givesthread-not-found. - Researcher's
mutants-r2.log:r4-full-id-not-passed-onexits 1 with 1 of 11 failing (line 36);f4-foreign-thread-received-firstexits 1 with 1 of 11 failing (line 110). So both halves of the condition have a killed mutant. That is Researcher's run, not mine.
The rest against the brief
- Verbs:
- All five verbs go through
callFor. Their dispatch is in cli.mjsmain, andproject create/listroute toprojectBusCommandwhileinit/checkkeepprojectCommandunchanged. --threadsendsthread.sendwith class REQUEST.- Without
--follow, only the message whosein_reply_tois the sent id is printed (row 142's line, unchanged). With--follow, a message is printed only ifthreadMembershas its id and its seq is after the sent one. - Plain
talkto the threaded instance mapsthread-required-use-thread-sendto exit 2, with a line naming--threadandmosaic threads. The livehumanTransportsetserror.code(packages/cli/src/transport.mjs:67-68), so that catch works outside the test transport too.
- All five verbs go through
- Brief tests: the brief's list maps onto the 11 tests in BUILD.md's table. That includes the resolver's too-short, ambiguous and unknown cases, with their message text asserted (thread-cli.test.mjs:192-203), and the
init/checkarity cases unchanged in project.test.mjs. - Acceptance 314: the step 1 and step 3 lines are the brief's lines.
mosaic threadslists only the caller's threads (broker.mjs:2104), so "the broker made it as Jason" is what the listing shows. - Scope: no
packages/buschange. The 8 paths are within the brief's files list.
Follow-up (wording)
- packages/cli/README.md:104 lists
project-not-foundamong the codes that "print asmosaic: <code>". The CLI resolves every project reference throughresolveProjectfirst (thread.mjs:41-46), which prints its own "no project is named or numbered ..." line, exit 2 (asserted at thread-cli.test.mjs:127). So the broker'sproject-not-founddoesn't reach the user in practice. Drop it from that list, or say the resolver's line comes first.- This README is read by one test, host.test.mjs:826, but only for the unit file's name, a different paragraph. Strictly, decision 137's doc-only rule doesn't cover a file a test reads. I'm treating it as a follow-up because the fix can't touch the string that test reads. Sage's call if that should be a change instead.
Not run by me
Nothing executed apart from sha256sum and sha256sum -c on the manifest. The 30 of 30 mutants, the 242 of 242 cli suite and the 25 of 25 gate are Researcher's runs, from BUILD.md and the packet logs. BUILD.md says the gate was split across two runs, the second for five suites the first script left out. Sage's gate rerun at the landing target is the check that replaces it.
Verdict: approve, candidate manifest 9eed6a78e3254944fb88b3bf36eb7574afeb161445a846ba8f8780e96ed8d5fd.