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.6 KiB
Filbert review: row 115 round 1 (#1609): changes
Candidate manifest sha256 f37bc933bbfd2e5f10fd5dd500f60a37e16de324c4e63395bb8d62cc3b5068ab (5 files), as named in comment 28420. I rebuilt it in my own worktree at BASE 94ece491f with build.patch from packet b3fca1f1a. All 5 hashes match, git diff --check is clean, no manifest path has drifted from 94ece491f to HEAD, and the patch's added lines have no dashes, bidi or control characters.
The brief, item by item
- The message. It is inserted in the
decision.resolve/seen/withdrawcase, right after thedecision_eventsrow and the human answer event, so it is in the same transaction.to_roleisraised_by_role, the class isDECISION,decisionis the id, andin_reply_toandcorrectsare null. The sender ishuman/human-clifor a human close, and the closing role and run otherwise. The body has the fixed forms, with the option text and an optionalNote:line. It is routed through#holderand#deliverythe same waymessage.sendroutes. - No message. This covers seen, a withdraw by the raising run (
s.run !== d.raised_by_run), and supersede and within-role, which write theirdecision_eventsrows insidedecision.raiseand never reach this case. request. See C1.- Runner. It is unchanged, and the new
runner.test.mjstest shows a human resolve becoming a turn that cites the decision and the request. - README. It has the rows and the new section. I agree with scope note 1 on
single-use.test.mjs.
The close paths Darkwing asked about
decision_events has three writers in broker.mjs: the supersede withdraw and the within-role resolve inside decision.raise, and this case. The broker never writes expired. In this case, #closed refuses decision-closed before any write, and request() runs each call in one BEGIN IMMEDIATE transaction. A second close therefore refuses, and a refused close rolls back its message. Only the raising run can withdraw as an agent, so an agent withdraw never sends. A resolve comes from the human, or from the arbiter role, which decision.raise never sets to the raiser's own role. I found no path that sends twice or skips the message.
Change requested
-
C1. The fallback's op filter is untested, and dropping it gives the wrong
request. In#request, the fallback for a human DECISION message picks the decision's firsthuman.inputanswer event, filtered toop IN ('resolved','withdrawn'). A humandecision.seenon a human-routed decision also writes an answer event with the decision as its subject, withop: 'seen'. I removedAND json_extract(body,'$.op') IN ('resolved','withdrawn')(mutant f4), anddecision-close,single-useandrunnerall still passed, 41/41. No test has the human run seen and then close the same decision. In the no-message test, the human seenstoHumanbut never closes it.The mutant is not equivalent. I added a throwaway probe: the coder raises
deploy, the human seens it, then resolves it (or withdraws it), and the coder receives the message. With the filter,requestis the resolved (or withdrawn) event. Under f4 it is the seen event in both cases, which breaks brief item 3 ("the id of that close'shuman.inputanswer event"). The probe file was deleted afterwards and the manifest hashes rechecked.Fix: add a test where the human runs
decision.seenand then resolves (or withdraws) a human-routed decision, and assert that the message'srequestequals the resolve's answer event, not the seen one. The test'sanswer()helper doesn't filter on op, so it would need to selectop='resolved'. The broker needs no change.
Mutants, rerun by me (decision-close, single-use and harness runner together)
| Mutant | Result |
|---|---|
| m1, the packet's (no insert) | killed, 8 fail |
m2, the packet's (to route_to) |
killed, 7 fail |
| m3, the packet's (send on the raiser's withdraw) | killed, 1 fail |
| f4: op filter dropped from the fallback | survived, 41/41 pass |
f5: no fallback (own only) |
killed, 5 fail |
| f6: route always unheld | killed, 1 fail |
f7: Note: line dropped |
killed, 2 fail |
I restored the source after each one and rechecked all 5 hashes.
What I ran (single files, no slot)
bus: decision-close 7/7, single-use 12/12, decisions 7/7, broker 16/16, messages 4/4, review 8/8, tester 11/11. harness: runner 22/22. I also ran the mutants and the probe above. I didn't rerun the full gate and relied on gate-run.log for it (bus 155, harness 81, GATE_PASSED). The worktree is removed and no process is left in it.
Verdict: changes (C1, one test).