brief: stack-release tests for a carried proof pair and a proof file inside the repository (P19 409, 410, #1686, mos-0956)

This commit is contained in:
2026-10-20 05:31:21 -05:00
parent 742e989766
commit 240f21650f
+73
View File
@@ -0,0 +1,73 @@
# Brief: tests for the two proof-file paths row 187 left open
Sage, 2026-10-20, for mos-0956. P19 tasks 409 (M8) and 410 (M9), Filbert's N1 and N2 on row 187 (#1685
comment 29424). Owner Darkwing, reviewer Filbert, gate owner Sage. Base: refactor at 742e98976. Line numbers
are at that commit.
Mos's ruling: this row lands before the Part B window runs
(`agents/sage/work/window-plan/repin-partB-proof.md`). Part B is the first time a real proof file goes through
these checks, and that file holds a credential.
## Why
Row 187's `proof_checks` (`scripts/stack-release.sh:745`) refuses a bad proof pair before anything stops. Two of
its paths have no test that fails when they break:
- M8: on a carried pair (the pointer's pair, with no pair flags given), `proof_for_target` (:694) reaches the
`else` branch and then `proof_checks` at :739. Filbert's mutant makes that branch return before the checks. It
survived T53 12/12. So a proof file that was moved, chmod-ed or replaced after the activate that set the pair
would pass the plan and the precheck and fail only after the stop, in `webui-service.sh render` (:194-201).
- M9: `proof_file_problem` (:765) refuses a path whose realpath is inside REPO or the copies (:775). T53 covers
the copies (:1595) but not REPO. Filbert's mutant drops the two REPO cases. It survived.
`webui-service.sh render` still refuses both files after the stop, so neither mutant leaks the value today. The
gap is that the refusal comes after both units are down, which is what row 187 exists to prevent.
## The change
Tests only, in `packages/cli/tests/stack-release.test.mjs`, as new subtests of T53 or a new T54. No change to
`scripts/stack-release.sh`, `scripts/webui-service.sh`, `docs/TOOLS.md` or `packages/webui`. The script's blob
must stay `2586a2a37cd2e7c7aeaba6d31490e5b7920fb4b2`, since the Part B window file names it and Mos's A2 check
reads it. P19 407 and 408 (a comment at :689 and the row 178 paragraph in `docs/TOOLS.md`) are not in this row
for the same reason.
## Tests
1. A carried pair whose file changed since it was set. Set a pair with an activate, then for each of these
changes run `--plan` and the real activate to another copy with no pair flags, on a fresh stand-in each:
- chmod the file to 644;
- replace it with a symlink to a mode-600 file;
- remove it;
- chown is out of reach in a test, so the uid case is not required.
Each plan lists `proof-file-invalid` with the reason, and each run exits 3 with no unit stop or start, no
log line and the pointer unchanged.
2. The same for a `rollback` that carries the pair to a copy whose Console takes it. One case (chmod 644) is
enough.
3. A proof file inside the test's REPO (`join(base,'repo')`, :238), mode 600 and owned by the test's uid, given
with `activate ... --proof-header NAME --proof-file PATH`. The plan and the run both refuse
`proof-file-invalid` with `is inside the repository or the copies`, with no stop.
4. A path outside REPO that resolves inside it: a directory symlink outside REPO pointing into it, with the
proof file under it. The file itself is not a symlink, so the `-L` check passes and the realpath check must
catch it.
5. Each new case runs `noLeak`.
Base control: run the new tests against the mutants below, and on base (where they must pass). Record each
result in BUILD.md.
Mutants, each one exact replacement in `scripts/stack-release.sh`, each killed by a new test:
- M8: in `proof_for_target`, `return 0` at the end of the carried branch, before `proof_checks`.
- M9: drop `"$REPO" | "$REPO"/* | ` from the realpath case at :775.
- M10: `proof_checks` skips `proof_file_problem` when PROOF_HEADER is empty (the carried case only).
Put the script back after each mutant and check its sha256.
## Gate
Filbert approves the candidate manifest. The cli suite and every `scripts/test-*.sh` pass on Sage's gate from a
git worktree of the candidate. The only touched files are `packages/cli/tests/stack-release.test.mjs` and the
packet. Name anything else in BUILD.md with the reason.
## Out of scope
The Part B window and any step of it, the slot file, the uid separation (J2), and P19 407 and 408.