fix(cnpg-drill): refuse when the archive scan itself does not complete #152

Merged
binjovi-bot merged 1 commit from fix/drill-trap-scan-fail-closed into trunk 2026-09-01 19:49:21 +00:00
Owner

Follow-on to #151, which landed on trunk but fixed only half the defect. #151 hardened the comment-stripping grep; this fixes the two greps that actually decide the verdict.

if printf '%s\n' "$body" | grep -qE "$TRAP_BACKUP_RE"; then

grep -q reports absent and failed with the same non-zero status, and the if reads both as "not present". A scan that never ran therefore passed the trap, and the drill would proceed to archive into the PRODUCTION lineage.

This is not hypothetical — it is the flake that failed two seanfarm gate runs today. Each run accepted exactly one archiving manifest, at a different case each time:

run accepted
18:09 seanfarm-fb74d162d05b-… space before the colon
19:37 seanfarm-1ed6ff891438-… single-quoted key

A single failure that moves between runs is a per-invocation transient, not a broken pattern. I confirmed the patterns themselves are sound — GNU grep 3.11 matches every spelling, verified in-cluster. The status handling was the defect. In the 19:37 run, #151's own new test (a manifest the guard cannot read) passed, which is what ruled out the read path and pointed here.

trap_pattern_present answers with three outcomes instead of two: present, provably absent, or refuse. Both call sites use it.

Red: with the fix stashed, a grep shadowed to fail only during the scan is accepted.
Green: it is refused; 40 consecutive runs pass; tests/check.sh exits 0; shellcheck clean.

https://claude.ai/code/session_01LeVatedQ4sCA1u6LHjo7B5

Follow-on to #151, which landed on trunk but fixed only half the defect. #151 hardened the comment-stripping grep; this fixes the two greps that actually decide the verdict. ```bash if printf '%s\n' "$body" | grep -qE "$TRAP_BACKUP_RE"; then ``` `grep -q` reports **absent** and **failed** with the same non-zero status, and the `if` reads both as "not present". A scan that never ran therefore passed the trap, and the drill would proceed to archive into the PRODUCTION lineage. **This is not hypothetical — it is the flake that failed two seanfarm gate runs today.** Each run accepted exactly one archiving manifest, at a *different* case each time: | run | accepted | | --- | --- | | 18:09 `seanfarm-fb74d162d05b-…` | `space before the colon` | | 19:37 `seanfarm-1ed6ff891438-…` | `single-quoted key` | A single failure that moves between runs is a per-invocation transient, not a broken pattern. I confirmed the patterns themselves are sound — GNU grep 3.11 matches every spelling, verified in-cluster. The status handling was the defect. In the 19:37 run, #151's own new test (`a manifest the guard cannot read`) passed, which is what ruled out the read path and pointed here. `trap_pattern_present` answers with three outcomes instead of two: present, provably absent, or refuse. Both call sites use it. **Red:** with the fix stashed, a grep shadowed to fail only during the scan is accepted. **Green:** it is refused; 40 consecutive runs pass; `tests/check.sh` exits 0; shellcheck clean. https://claude.ai/code/session_01LeVatedQ4sCA1u6LHjo7B5
fix(cnpg-drill): refuse when the archive scan itself does not complete
All checks were successful
binjovi/ci Binjovi completed the frozen plan
5605ef921a
The previous commit hardened the comment-stripping grep and left the two greps
that actually decide the verdict:

    if printf '%s\n' "$body" | grep -qE "$TRAP_BACKUP_RE"; then

`grep -q` reports "absent" and "failed" with the same non-zero status, and the
`if` reads both as "not present". A scan that never ran therefore passed the
trap, and the drill proceeded to archive into the PRODUCTION lineage.

This is not hypothetical. Two seanfarm gate runs on the same commit each
accepted exactly one archiving manifest, at a DIFFERENT case each time — 18:09
accepted 'space before the colon', 19:37 accepted 'single-quoted key'. A
per-invocation transient explains a moving single failure; a broken pattern does
not. The patterns are sound: GNU grep 3.11 matches every spelling, verified
in-cluster. The status handling was the defect.

trap_pattern_present answers with three outcomes instead of two: present,
provably absent, or refuse. Both call sites use it.

Red: with the fix stashed, a grep shadowed to fail only for the scan is
accepted. Green: it is refused, and 40 consecutive runs pass.

Claude-Session: https://claude.ai/code/session_01LeVatedQ4sCA1u6LHjo7B5
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
sean/seanfarm!152
No description provided.