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.
7.1 KiB
Filbert review: row 116 round 1 (#1610): changes
Candidate manifest sha256 59065cac9d08e5734a072654c4b80b13f854d137c92bbdf5d539028e92538f7c (6 files), as named in comment 28462. I rebuilt it in my own worktree at BASE 1223a0f37 with build.patch from the packet. All 6 hashes match, and git diff --check is clean. No manifest path has drifted from 1223a0f37 to HEAD f1f6f913a. The patch's added lines have no dashes, bidi or control characters.
The brief, item by item
- Read path. read.mjs lstats the database (a regular file, owned by the user, not a symlink) and opens it
readOnly: true. Every query is a SELECT in onequeriesobject. The schema check follows sage-0196: it re-hashes schema.sql against the importedSCHEMA_SHA256, builds the reference digest in:memory:with the importedschemaDigest, and requires the db digest, the meta digest andschema_version'3b' to match. The decision rules follow sage-0195, and the target is exactlyrefactor.--base nextandmainrefuse before the config is read. The latest verdict by seq must be approve on a full oid.ref-movedcompares the working repository's ref to C. See C1 for the gaps. - Squash. It applies
git diff $(merge-base OLD C) Cin a detached worktree at OLD, withbase-conflicton an apply failure, a missing merge base or an empty diff. It then checkspatch-driftbypatch-id --stableof the index against OLD. The diff format is pinned (--no-ext-diff --no-textconv --no-renames --binary). - root-file. Added top-level files, files in a new top-level directory, and anything added under
src/orv1/. The brief's own example is undersrc/, so I accept the widening. - Gate. It runs every
packages/*/testssuite except queue, which test-queue.sh covers, then everyscripts/test-*.sh. Each step runs with pipefail into its own log, and the summary line is teed to gate.log. The first failure refusesgate-failedwith the log path. There is no skip switch and no flake case. - Commit. The subject is the merge option's first line (sage-0196) or
--subject. The body cites the decision, verdict, work ref, C, base and patch-id, and the attribution is the last line. - PM line. It is printed exactly as the brief's format, and not sent.
- Dry run. It runs every check and the gate, and writes no ref. The suite compares refs, reflog and status before and after.
- Cleanup. An EXIT trap removes the worktree, the link, the Docker network and the scratch. Gate logs stay and are named.
I accept the two extra refusals. checkout-dirty is checked before the worktree and again before the commit. base-moved is a CAS update-ref from OLD. Both fail closed and protect the checked-out base.
Rulings asked for
- s26 is equivalent. I checked it directly on git 2.55.0 in a throwaway repository. I made a worktree whose
node_modulesis a symlink to a directory holding a file and a nested file.git worktree remove --forceremoved the worktree and left both files, and it did the same with a modified tracked file in the worktree.rm -rfon a directory holding the same link also left them. A suggestion, not a finding: the suite's fixturenode_modulesis an empty directory, so "the target's node_modules is still there" can't see contents being deleted. A canary file in it would make that case meaningful. - r23 is killed.
expectasserts the reason, and the case getsref-movedinstead ofnot-approved, so the case fails. The second check catching it is defence in depth. - Replay, under sage-0204. Both runs print patch-id
26100825e4128d64e9a84690dba008b9549fe6a5. I computedgit diff 4bc908991 f7c8537b3 | git patch-id --stableand got the same id, so the diff at1c9a4910dis f7c8537b3's. Run 3's logs show treecdd3a62c2, andgit rev-parse f7c8537b3^{tree}givescdd3a62c2ed7c25332de5fbde4fcfcc4594e112f. In both runs the dry run wrote no ref, and 19/229 refusesroot-fileonsrc/parse-requirement-id.mjs.
Change requested
-
C1. Five conditions in read.mjs have no case, so removing any of them passes all 78. The brief asks for one mutant per check. The packet splits
not-humaninto r08 (by), r09 (via) and r10 (missing answer), but the other conditions sage-0195 ruled for have none. I built probe databases with fixture.mjs and ran read.mjs on them, first unchanged and then with one condition removed:Mutant Probe Real read.mjs Mutant f1: drop answer.actor_role/actor_run !== nullthe answer event has actor pm not-human passes, prints the commit f2: drop the answer's choice === res.choicethe answer says no, the close saysyesnot-human passes f3: accept more than one answer two answer events not-human passes f4: drop raise.task_reffrom the agreement loopthe raise cites vikunja:7/99 work-ref passes f5: seq > ?toseq <> ?inlateran earlier merge decision on the same ref passes refuses superseded f1 to f4 let a decision land that the real code refuses. f5 refuses a valid landing, for example when a first merge decision was withdrawn and then raised again. I didn't run test-land-work.sh with these mutants, because it runs a gate loop and needs the shared slot. The survival is by reading gen.mjs. Its only
human.inputrow has no actor, uses the samechoicevariable as the close, and is pushed once. The raise'stask_refis always null, and the only extra decision (L) comes after D. No variant reaches any of the five conditions.Fix: add gen.mjs variants for an answer with an actor, an answer whose choice differs, two answers, a raise whose
task_refdisagrees, and an earlier merge decision on the same ref. The earlier-decision case should reach a later stage, for example a dry run exiting 0. List f1 to f5, or your names for them, in the mutant table. read.mjs and land-work.sh need no change.
Doc-only, follow-up (decision 137)
grep -rlF TOOLS.md packages/*/tests scripts/test-*.sh and the same for CONDUCTOR.md both return nothing, so these don't block.
- D1.
docs/TOOLS.md: the usage line shows[--subject TEXT]but not--attribution,--businessor--project, which the script's usage has.
Notes, no change needed
- The squash commit runs
git commitin a worktree of the target, so the target'spre-commithook runs. In the canonical checkout that's the queue guard. A reviewed diff touchingdocs/plans/queue.jsonorQUEUE.mdwould end as "git commit failed" with exit 1 after the gate, not as a named refusal. It still fails closed. - The builder gate in
gate-run.logran 4 steps (bus 156, land-work 78, conductor 17, webui pinned-copy). Sage's full gate at the landing target is the "full gate green" check.
What I ran (single files, no slot)
The rebuild, then read.mjs directly on 6 probe databases with the 5 mutants above. I restored the file after each mutant and rechecked all 6 hashes. I ran the s26 check in a throwaway repository, and the patch-id and tree checks against f7c8537b3. I didn't run test-land-work.sh or the full gate. The worktree is removed and no process is left in it.
Verdict: changes (C1, five cases in the suite).