Files

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

  1. 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 one queries object. The schema check follows sage-0196: it re-hashes schema.sql against the imported SCHEMA_SHA256, builds the reference digest in :memory: with the imported schemaDigest, and requires the db digest, the meta digest and schema_version '3b' to match. The decision rules follow sage-0195, and the target is exactly refactor. --base next and main refuse before the config is read. The latest verdict by seq must be approve on a full oid. ref-moved compares the working repository's ref to C. See C1 for the gaps.
  2. Squash. It applies git diff $(merge-base OLD C) C in a detached worktree at OLD, with base-conflict on an apply failure, a missing merge base or an empty diff. It then checks patch-drift by patch-id --stable of the index against OLD. The diff format is pinned (--no-ext-diff --no-textconv --no-renames --binary).
  3. root-file. Added top-level files, files in a new top-level directory, and anything added under src/ or v1/. The brief's own example is under src/, so I accept the widening.
  4. Gate. It runs every packages/*/tests suite except queue, which test-queue.sh covers, then every scripts/test-*.sh. Each step runs with pipefail into its own log, and the summary line is teed to gate.log. The first failure refuses gate-failed with the log path. There is no skip switch and no flake case.
  5. 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.
  6. PM line. It is printed exactly as the brief's format, and not sent.
  7. Dry run. It runs every check and the gate, and writes no ref. The suite compares refs, reflog and status before and after.
  8. 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_modules is a symlink to a directory holding a file and a nested file. git worktree remove --force removed the worktree and left both files, and it did the same with a modified tracked file in the worktree. rm -rf on a directory holding the same link also left them. A suggestion, not a finding: the suite's fixture node_modules is 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. expect asserts the reason, and the case gets ref-moved instead of not-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 computed git diff 4bc908991 f7c8537b3 | git patch-id --stable and got the same id, so the diff at 1c9a4910d is f7c8537b3's. Run 3's logs show tree cdd3a62c2, and git rev-parse f7c8537b3^{tree} gives cdd3a62c2ed7c25332de5fbde4fcfcc4594e112f. In both runs the dry run wrote no ref, and 19/229 refuses root-file on src/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-human into 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 !== null the answer event has actor pm not-human passes, prints the commit
    f2: drop the answer's choice === res.choice the answer says no, the close says yes not-human passes
    f3: accept more than one answer two answer events not-human passes
    f4: drop raise.task_ref from the agreement loop the raise cites vikunja:7/99 work-ref passes
    f5: seq > ? to seq <> ? in later an 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.input row has no actor, uses the same choice variable as the close, and is pushed once. The raise's task_ref is 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_ref disagrees, 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, --business or --project, which the script's usage has.

Notes, no change needed

  • The squash commit runs git commit in a worktree of the target, so the target's pre-commit hook runs. In the canonical checkout that's the queue guard. A reviewed diff touching docs/plans/queue.json or QUEUE.md would 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.log ran 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).