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.8 KiB
Filbert review: row 109 round 2 (#1603): changes
Candidate manifest sha256 daa942cd5d03597479c2e9f6bd159b8f7ec5dec135ce1fbc1138e95e5b8ea69d (8 files). I rebuilt it in my own worktree at BASE 02fe2d9d5 with row109.patch. All 8 hashes match, git diff --check is clean, and no manifest path has drifted from 02fe2d9d5 to HEAD. The added lines have no dashes, bidi or control characters.
Blocker
B1. Two tests outside the manifest fail with the patch. Both still expect the request to begin with the message header, but every request now begins with the state block.
packages/seat/tests/session.test.mjs:227:/^echo: Message .* from pm, class REQUEST:\n\nhello/. The test "a session runs in its sandbox as pid 1 of its namespace, claims, answers, and stops on mosaic stop" fails, 8/9 pass.packages/cli/tests/launcher.test.mjs:240:/^echo: Message .* from cto, class REQUEST:\n\nhello/. The test at line 203 fails, 16/17 pass.
The reply body now reads echo: Current state, read at ...:\nLaunches: allowed (never switched).\nOpen tasks: 0.\n\nMessage <id> from pm, sent <at>, class REQUEST:\n\nhello. On a clean BASE 02fe2d9d5 worktree the same two files pass, 9/9 and 17/17, so the patch causes both failures. Neither file is under scripts/test-*.sh, which may be why the packet's suite claims missed them.
Fix: add both test files to the manifest and update the two assertions to the new request shape. Anchoring the block, the header with sent, and hello is better than loosening the ^. After that, run the package tests for seat and cli along with bus and harness.
Sage's five checks (all pass on reading and in tests)
- Failed read. In
runner.mjsa throw fromclient.call("state")that isn't SESSION_GONE setsunread. The turn becomes{ok:false, reason}without callingrunTurn. The existing path then logsturn N ... failed, sends RESULTThe turn failed: could not read the current state: <code>(it skips this only for an incoming RESULT, as before), and runsmessage.read. SESSION_GONE logs and exits with EXIT.session. The runner test checks the RESULT text, in_reply_to, the read delivery, the stderr log, and thatturns/0001.stderrdoesn't exist, so no adapter ran. - The
stateverb is read-only. It runskeys(a, [])and calls#agent(s)only for role sessions, so a non-holder role refusesnot-holder. Human and reader sessions read without a check, and the reader allowlist gainsstate. It does oneSELECTonevents, then#tasks(business,{done:false}), which only readstask_currentandevents. It has no insert, update or#eventcall.ORDER BY seq DESC LIMIT 1over the two launch kinds is the same rule as thelaunch_stateview (max(seq)), so the block agrees with therole.launchcheck. - Fixture. The old first-blank-line split would have put the
Message ...:header intobody, soTOOL,SLEEP,FAILandNOMARKERwould all have dropped through to echo. The regex takes the text after the header. The fallback keeps the old split for a request without a header. If the runner ever lost the header, the fallback could let the TOOL tests pass. The first end-to-end runner test anchors the whole request including the header, so that regression would still fail. Nothing is hidden. - pm.md. The rule says the block is "the truth for launch state and task status", that a disagreeing message or note "is out of date", and that the PM checks the task with
get_taskbefore planning to resume or launch work on it.get_taskis the tool name intools.mjs(unchanged). - Cap and newest event.
stateBlockwritesOpen tasks: <total>, the first <n> of cap <cap>.whenever the list is shorter than the total.statereturnscap: TASK_PAGE(50), andstate.test.mjschecks 55 open tasks give 50 shown, total 55 and cap 50. Launchatandeventcome from the newest launch event byseq. The revoke-then-restore tests (bus and runner) check that the restore's id and time win.
Notes (not blocking)
- N1. The broker comment says the verb is "A read for role and reader sessions". The code and the bus README also allow human sessions. Add human to the comment.
- N2.
state.test.mjscovers role and reader but not a human cap, and doesn't check that the verb writes nothing. One assertion each would pin both: the human's read equals the role's, and theeventsandmessagesrow counts are unchanged across astatecall.
What I ran (single files, no slot)
bus/tests/state.test.mjs 6/6, harness/tests/runner.test.mjs 20/20, bus/tests/broker.test.mjs 15/15, harness/tests/tools.test.mjs 11/11, seat/tests/session.test.mjs 8/9 (B1), cli/tests/launcher.test.mjs 16/17 (B1). On BASE: session 9/9, launcher 17/17. I didn't rerun the mutants. Worktrees are removed and no process is left in them.
Verdict: changes (B1).