docs: brief for scripts/push-check.sh, the repo push check that passes a binary only when an approved review candidate lists its path and sha256 (mos-1572 option A); doc only
This commit is contained in:
1 parent
d16958bcfd
commit
93200bb446
1 file changed
+103
@@ -0,0 +1,103 @@
|
||||
# Push check in the repository, with reviewed binaries
|
||||
|
||||
Written 2026-10-24 by Sage for Mos's mos-1572 ("Go with A for the guard"), after rows 265 and 310
|
||||
raised the binary question (mos-1570, sage-3978).
|
||||
|
||||
## Brief: push-check.sh passes a binary only when the reviewed candidate lists its path and sha256
|
||||
|
||||
**Why.** The lead's push check is a scratch script, `/mnt/storage/scratch/sage-r64/pushcheck.sh`
|
||||
(mos-0856/0857), so nobody has reviewed it and no test covers it. Its `NO_BINARY` step refuses any
|
||||
path that `git diff --numstat BASE SHA` reports as binary (`-` in the first column). Row 265 had to
|
||||
waive that step by hand for 22 gzip logs. Row 310 (W2) will need committed WASM, fonts and test blobs.
|
||||
Mos chose option A: keep the binary check, and let a binary through only when its path and sha256
|
||||
appear in the candidate a reviewer approved. Whether any large binary lands at all is a separate
|
||||
question for Jason (Vikunja 618). This row builds the guard, not that answer.
|
||||
|
||||
**Read first.**
|
||||
- The scratch script, copied under "The scratch script today" at the end of this brief. Don't read
|
||||
`/mnt/storage/scratch/sage-r64` itself; it's Sage's scratch.
|
||||
- `packages/queue/README.md`, sections on `move ID in-review` (manifest and commit candidates) and
|
||||
`review verify-commit`. `packages/queue/src/review.mjs` for how a round's candidate and its receipts
|
||||
are stored. Running `scripts/mosaic queue show N` prints them.
|
||||
- `docs/plans/2026-10-20_force-push-guard.md`, row 211 (Darkwing, in progress). That row owns
|
||||
`scripts/git-hooks/pre-push`, the hook install and `scripts/slot-busy.sh`. Don't touch those files,
|
||||
and don't wire this check into a hook.
|
||||
|
||||
**What ships.**
|
||||
|
||||
1. `scripts/push-check.sh SHA EXPECTED_LOG [--row N]...` (new). It runs the scratch script's steps in
|
||||
the same order and prints the same tokens, so the lead's push sequence only changes its path:
|
||||
`LOG_OK`, `FF_OK`, `NO_BINARY` or `BINARY_REVIEWED <n>`, `SECRETS_CLEAN`, `NO_ATTRIBUTION`, then
|
||||
`PUSH_READY BASE..SHA` as the last line. Every refusal prints one `STOP <reason>` line and exits 1.
|
||||
A usage or environment error exits 2. It works in the repository the caller's cwd is in. The base
|
||||
ref defaults to `refs/remotes/origin/refactor`, and `--base-ref REF` overrides it for tests. A fetch
|
||||
happens only when `--fetch` is given, and the lead's sequence passes it.
|
||||
2. The binary step. For each path that `git diff --numstat BASE SHA` marks binary and that exists at
|
||||
SHA (a deleted binary needs no review):
|
||||
- compute the sha256 of the blob at `SHA:path` (`git cat-file blob`, not the working tree);
|
||||
- look for an approved candidate among the `--row` rows. A round counts only when it is the row's
|
||||
latest round and has a receipt with verdict `approve` whose candidate equals that round's
|
||||
candidate. A `changes` receipt in the same round blocks it;
|
||||
- for a manifest candidate, the manifest must hold the line `<sha256> <path>` exactly;
|
||||
- for a commit candidate, use the same rule as `queue review verify-commit`. The path must be one the
|
||||
candidate changed from its first parent, and the sha256 of the candidate's blob must equal SHA's;
|
||||
- no match prints `STOP binary <path> <sha256> not in a reviewed candidate`. With no `--row`, any
|
||||
binary stops, which is today's behaviour.
|
||||
Read the queue only through `scripts/mosaic queue show N` or the queue package's read functions.
|
||||
Never write the queue or post anything.
|
||||
3. The secret scan and the attribution check stay as they are. A binary passes the secret scan only
|
||||
through the review above. Decompressing gzip to scan it is a separate row if anyone wants it
|
||||
(mos-1570). Don't add it here.
|
||||
4. `scripts/test-push-check.sh` (new), run by `timeout -k 10` like the other suites. It builds a
|
||||
scratch bare remote, a scratch clone and a scratch queue. It never touches origin, the canonical
|
||||
`docs/plans/queue.json` or a seat's queue lock. If the queue CLI can't read a scratch queue without a
|
||||
full scratch copy of the repository, use a scratch copy. If that is impractical too, stop and ask
|
||||
Sage before inventing a test-only override. Cases:
|
||||
- a text-only range prints `NO_BINARY` and `PUSH_READY`;
|
||||
- an unlisted binary stops, naming the path;
|
||||
- a listed path with a different sha256 stops;
|
||||
- an approved manifest candidate passes and prints `BINARY_REVIEWED 1`;
|
||||
- an approved commit candidate passes. One whose blob for that path differs from SHA's stops;
|
||||
- a round with a `changes` receipt, a superseded earlier round, and an approve receipt for a
|
||||
different candidate each stop;
|
||||
- a deleted binary passes with no `--row`;
|
||||
- a non-fast-forward SHA, a log mismatch, an attribution line and a planted fake secret each stop,
|
||||
and nothing after the stop prints;
|
||||
- the last line is `PUSH_READY` only on success, so `| tail -1 | grep -q '^PUSH_READY '` is safe.
|
||||
5. Mutants, each killed by the test: skip the sha256 comparison; accept a `changes` round; accept an
|
||||
earlier round; read the working tree instead of the blob; let a binary through when `--row` is absent.
|
||||
6. `docs/TOOLS.md`: one entry for `push-check.sh` with usage, the tokens and the exit codes.
|
||||
|
||||
**Files owned.** `scripts/push-check.sh`, `scripts/test-push-check.sh`, the new `docs/TOOLS.md` entry,
|
||||
and your `agents/<seat>/work/queue-<row>/` packet (BUILD.md, plain-text evidence). Anything else needs a
|
||||
brief amendment.
|
||||
|
||||
**Out of scope.** The pre-push hook and slot check (row 211). Deciding whether W2's WASM or W1's data
|
||||
lands (Jason, Vikunja 618). Gzip scanning. Retiring the scratch script, which Sage does after landing.
|
||||
|
||||
**Gate.** A separate Codex thread does the first review. Dewey reviews once on the landing candidate
|
||||
(guards go to a Claude reviewer, mos-1542). `scripts/test-push-check.sh` and every other
|
||||
`scripts/test-*.sh` are green on Sage's landing gate, and the mutants are killed. Done when Sage's next
|
||||
push runs through `scripts/push-check.sh` instead of the scratch script. Evidence is plain text
|
||||
(BRIEF-TEMPLATE, mos-1570). Use a TMPDIR from `mktemp -d /mnt/storage/scratch/tmp/XXXXXX`.
|
||||
|
||||
### The scratch script today
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Push checks for an explicit sha (mos-0856/0857). Usage: pushcheck.sh SHA EXPECTED_LIST_FILE
|
||||
# EXPECTED_LIST_FILE holds the exact `git log --oneline origin/refactor..SHA` lines, newest first.
|
||||
set -o pipefail
|
||||
cd /mnt/storage/src/mosaic-stack || exit 9
|
||||
SHA=$(git rev-parse --verify "$1^{commit}") || { echo "STOP sha"; exit 9; }
|
||||
git fetch -q origin || { echo "STOP fetch"; exit 9; }
|
||||
BASE=$(git rev-parse refs/remotes/origin/refactor) || exit 9
|
||||
diff <(git log --oneline "$BASE..$SHA") "$2" && echo LOG_OK || { echo "STOP log"; exit 1; }
|
||||
git merge-base --is-ancestor "$BASE" "$SHA" && echo FF_OK || { echo "STOP ff"; exit 1; }
|
||||
[ "$(git diff --numstat "$BASE" "$SHA" | awk '$1=="-"' | wc -l)" = 0 ] && echo NO_BINARY || { echo "STOP binary"; exit 1; }
|
||||
if git diff "$BASE" "$SHA" | grep -E '^\+' | grep -iqE 'BEGIN [A-Z ]*PRIVATE KEY|ghp_[A-Za-z0-9]{20}|sk-ant-[A-Za-z0-9-]{10}|xox[bp]-|AKIA[0-9A-Z]{16}|(token|secret|password)["'"'"' ]*[:=] *["'"'"'][A-Za-z0-9_\-]{24,}'; then echo "STOP secrets"; exit 1; fi
|
||||
echo SECRETS_CLEAN
|
||||
if git log --format=%B "$BASE..$SHA" | grep -iqE 'co-authored-by|generated with'; then echo "STOP attribution"; exit 1; fi
|
||||
echo NO_ATTRIBUTION
|
||||
echo "PUSH_READY $BASE..$SHA"
|
||||
```
|
||||
Reference in new issue
Block a user