9.7 KiB
Row 327 — reviewed binary push check (#1825)
2026-10-24 Bradford, branch bradford/row327, base b617b80f6.
Plan and boundaries
Implement the scratch check's ordered tokens in scripts/push-check.sh, using an embedded Node program for byte-safe git paths and SHA-256 blob hashing. Bash is the public entry point; Node is already a repository requirement. Git commands use explicit resolved object IDs, disable external diff/textconv, and inspect committed bytes. No queue writes, hook changes, binary evidence, or live state. Fetch is opt-in. Read reviewed rows with the queue package rows() API rooted in the caller's repository; this preserves canonical/witness/replay checks.
Only the latest round counts; any changes receipt blocks that round. A matching approval authorizes exactly the manifest path/hash, or a path changed from the commit candidate's first parent with matching committed blob hash and mode. Deleted binaries need no candidate. Multiple --row values form a union.
Add scratch-only integration coverage in scripts/test-push-check.sh. Reuse queue test fixture helpers to bootstrap real scratch queues, then use queue verbs to open rounds and record receipts. All git writes, bare remotes and queues remain under TMPDIR. Test fail-closed ordering and five required mutants, generated as text copies in scratch. No old tests are modified. Add the TOOLS entry.
Every run needs Sage CLEAR; run timeout -k 10. Record plain-text results here or in this packet. After green checks, commit and push only bradford/row327 through the repository helper, send Sage and Poe tip/base/path sha256 manifest, and move 327 in-review. Sage owns request posting and landing; Dewey reviews once there.
Recovery and choices
Initial worktree queue next refused linked-worktree access as designed. Queue claim is performed from the canonical checkout; production reads in the guard retain the same refusal rather than invent a worktree override.
Requested Sage ruling on AGENTS log appends outside the brief's owned paths.
Sage sage-3989: lead handles BUILD-LOG and SESSIONS at landing. Session entry: 2026-10-24 Bradford — row 327 / #1825 — implementation and scratch verification in this packet; outcome to be appended after acceptance.
Implementation note: commit candidates use an explicit first-parent diff (empty tree for a root commit), with rename detection disabled, like verify-commit. The changes-veto case has both an approval and a changes receipt; a veto mutant would otherwise still fail for lack of approval and provide false confidence. A receipt for another candidate cannot be produced through queue verbs: the suite corrupts only a scratch queue and expects the production reader to refuse. Diff color, external diff and textconv are disabled so scans inspect plain git output. Paths are read from NUL-delimited records (including spaces/tabs).
Verification (Sage CLEAR sage-3991)
First new-suite run red: my whitespace-path fixture attempted a manifest path that the queue intentionally forbids. Corrected the fixture to a commit candidate, which can contain that git path. Production queue code and old tests remain unchanged. Raw first-run output is test-run-1.txt.
Second run green: PASS push-check 22 checks; KILLED skip-hash, accept-changes, earlier-round, working-tree, no-row. test-run-2.txt holds the plain-text receipt. bash -n both scripts and git diff --check passed. Runs used TMPDIR recorded in tmpdir.txt and timeout -k 10 240; all generated binary bytes were in disposable scratch repositories, never in this checkout or evidence. The slot was used for only the authorized new suite and syntax/diff checks. No claim of the lead's full scripts/test-*.sh landing gate is made here.
Final inspection after the first green run found a path-decoding concern: lossy UTF-8 decoding can conflate distinct git filenames. Hardened NUL-delimited path decoding to reject invalid UTF-8, and quote newline-containing paths in refusal output to preserve one STOP line. Added scratch cases for both. Requested a new CLEAR (bradford-0005) because the previous slot had already been released.
Final run (sage-3994 CLEAR) green on final code: PASS push-check 24 checks, all five mutants KILLED again, bash -n both scripts and git diff --check passed. Receipt: test-run-3.txt. The guard rejects non-UTF-8 git paths as environment errors rather than comparing replacement characters; newline paths remain checkable through commit candidates and refusals quote them on one line.
Acceptance for the builder stage: ordered tokens and stop behavior, explicit base/fetch, exact blob manifest/commit checks, latest-round/veto checks, deletion, log/FF/secrets/attribution refusals, and all required mutants are covered. Queue reads use rows() with production validation; tests use only scratch queues. Candidate-mismatched receipts are impossible through the queue API and are covered by a corrupt scratch queue refusing its read. The lead's full-suite gate, Poe first review, Dewey landing review, and adoption for Sage's next push remain landing stages. No hooks, role policy, credentials or other seats' paths changed.
Poe first review R1 (poe-0010) — changes
cceea407e has a blocking subdirectory bypass: ls-tree without --full-tree can
omit an existing binary outside the caller cwd, making it look deleted.
Accepted the finding. Git now anchors all invocations at the repository root,
ls-tree uses --full-tree, and diff/diff-tree use --no-relative. EXPECTED_LOG still
resolves from the original caller cwd. Added outside-cwd and nested-binary cases
under diff.relative=true: unreviewed stops, reviewed manifest/commit passes.
No old test changed. New run requires Sage CLEAR before execution.
R1 verification under sage-3999 CLEAR: test-run-4.txt records PASS 29 checks and KILLED all five required mutants. Syntax and diff whitespace checks passed. A second bounded run used the new suite against cceea407e's script copied under TMPDIR: r1-regression-red.txt records the outside-cwd unreviewed binary reaching NO_BINARY/PUSH_READY (actual exit 0, expected 1). Thus the new regression detects the reviewed bug, while the revised guard refuses it. No code changed between the green run and this old-candidate reproduction. All runs used timeout -k 10.
Holding claimant queue writes per sage-3999 until Boyd finishes row 309's record. Last acknowledged row 327 state is in-progress (bradford-0010, revision 3868).
Dewey landing review B1 (dewey-0956) — changes
Read the invited review body at /mnt/storage/scratch/tmp/dew327vWXloCT/body.md. B1 identifies a brief-level gap: numstat follows candidate/host git attributes, so *.bin diff makes a NUL-containing blob disappear from the binary-only set. The production script indeed filters numstat before reading any blob, consistent with that data flow. Proposed correction: enumerate every changed numstat path, skip absent/non-blob entries at SHA, classify binary when numstat says binary OR committed blob has NUL among first 8000 bytes. Read with cat-file, never worktree. Test committed .gitattributes, info/attributes, and core.attributesFile overrides in scratch; reject with no row, allow exact reviewed bytes; add NUL-scan mutant. Sage owns the brief amendment and next CLEAR/queue sequencing.
N1 acknowledged: candidate-equality check is defense in depth; invalid receipt cannot pass queue replay, so the corrupt-queue case does not isolate that check. N2/N3 recorded as described in review, without optional secrets/reader changes. N4 planned hardening: refuse unconfirmed durable tail notes from rows() with exit 2, with a real scratch witness-prefix case rather than a test-only reader. No test run or queue write started for B1/N4 before Sage CLEAR.
Sage sage-4013/4015 authorizes B1 and N4 within the brief; amendment committed on
refactor at 9042754c4 (read with git show, no branch change). Fix and tests written
before requesting CLEAR as directed. Tests cover all three attribute sources,
approved manifest success under each override, exact 7999/8000 offset boundary,
and a real prefix-witness rollback to yield an unconfirmed approval tail.
Added only the requested sixth mutant, skip-nul-scan; the original five remain.
No new production configuration knobs, no secrets-diff change, no queue writes.
Will demonstrate red against the prior candidate using the new tests, then green
against revised code, under the approved slot. Full landing gate remains Sage's.
After Dewey's round-2 CHANGES record (comment 31522, rev3876), Sage sage-4016
released only the claimant return to in-progress. Acknowledged:
ok bradford-0017 rev 3877 row 327 in-review→in-progress.
No other queue write before the next in-review candidate move.
Test slot remains pending Sage CLEAR after Gyro's build.
Amendment 1 verification (sage-4017 CLEAR)
b1-regression-red.txt: new tests against 704910ca3 reproduce attributes-hidden
asset.bin reaching NO_BINARY/PUSH_READY with exit0 instead of exit1.
n4-regression-red.txt: revised code with only the N4 check removed lets the real
scratch unconfirmed approval tail reach BINARY_REVIEWED/PUSH_READY, exit0 rather
than exit2. These are expected negative controls; neither changed committed code.
Final full new-suite run is green: test-run-5.txt records PASS 38 checks and KILLED skip-hash, accept-changes, earlier-round, working-tree, no-row, skip-nul-scan. All runs used timeout -k 10 240 with the same scratch TMPDIR; no old tests were changed or run. bash -n both scripts and git diff --check also passed. No source changes followed this green run. Sage's full landing gate is still separate.
Scope in the final delta: classify all changed present blobs using numstat OR first-8000-byte NUL; fail closed on queue unconfirmed-tail notes; regression cases and requested sixth mutant; TOOLS entry and this plain-text packet. B1's brief amendment is Sage's 9042754c4; this branch does not edit the brief or queue files.