fix(board-roll): reject >1 marker pair instead of spanning across zones
Some checks failed
ci/woodpecker/pr/ci Pipeline failed

rev0 (PR #868, Gitea comment #18505) caught a real data-relocation bug:
the marker scan locked start_idx to the FIRST START but overwrote end_idx
on EVERY END, so a board with two BOARD-ROLL zones collapsed into one
first-START..last-END span. That span engulfed the curated `##` content
and the intermediate START/END markers between the two zones, silently
relocating pinned lines into the LEDGER — the exact failure this tool
exists to prevent.

Fix (conservative, matches the "no markers = exit 3" posture): count
START and END markers; if either appears more than once, refuse with
exit 3 and change nothing. Single-zone behavior is unchanged.

Adds regression group 8: two zones with a curated CANARY section between
them, cap 80 → asserts exit 3, LIVE unchanged, and the canary never
leaks into the LEDGER. shellcheck -S warning clean; 8/8 groups pass.

Refs #868
This commit is contained in:
enhance
2026-07-22 04:17:29 -05:00
parent 406a8464f9
commit 676a906649
3 changed files with 69 additions and 8 deletions

View File

@@ -10,6 +10,8 @@
# 5. --dry-run changes nothing and reports a plan.
# 6. Zone emptied but pinned sections alone exceed cap → exit 3.
# 7. --help exits 0 and prints usage; an unknown flag exits nonzero (#701 discipline).
# 8. More than one marker pair → exit 3, unchanged; curated content between the two
# zones is never relocated to the LEDGER (rev0 #868 regression).
set -euo pipefail
@@ -114,7 +116,41 @@ bash "$SUT" -h >/dev/null 2>&1 || note "-h exited nonzero"
if bash "$SUT" --not-a-real-flag >/dev/null 2>&1; then note "unknown flag was accepted"; fi
if bash "$SUT" --live "$WORK/live3.md" >/dev/null 2>&1; then note "missing --ledger was accepted"; fi
# ── 8. multiple marker pairs → exit 3, unchanged (no cross-zone relocation) ─────
# Two separately-marked zones with a curated pinned section BETWEEN them. A naive
# first-START..last-END span would sweep that curated section (and the intermediate
# markers) into the LEDGER. board-roll must refuse (exit 3) and touch nothing.
L="$WORK/live8.md"; G="$WORK/ledger8.md"; echo "# LEDGER" > "$G"
pad8=$(head -c 300 < /dev/zero | tr '\0' 'x')
{
echo "# BOARD — LIVE"
echo "> pinned protocol blockquote"
echo
echo '<!-- BOARD-ROLL:START -->'
echo "### 2026-07-10 zone-A newest"
echo "- detail A2 $pad8"
echo "### 2026-07-09 zone-A oldest"
echo "- detail A1 $pad8"
echo '<!-- BOARD-ROLL:END -->'
echo
echo "## Curated-between-zones (pinned — must never move)"
echo "- CANARY-BETWEEN keep me"
echo
echo '<!-- BOARD-ROLL:START -->'
echo "### 2026-07-08 zone-B newest"
echo "- detail B2 $pad8"
echo "### 2026-07-07 zone-B oldest"
echo "- detail B1 $pad8"
echo '<!-- BOARD-ROLL:END -->'
} > "$L"
before8=$(cat "$L")
set +e; bash "$SUT" --live "$L" --ledger "$G" --cap 80 >/dev/null 2>&1; rc=$?; set -e
[[ "$rc" -eq 3 ]] || note "multi-pair board should exit 3 (got $rc)"
[[ "$(cat "$L")" == "$before8" ]] || note "multi-pair run modified LIVE (must never guess across zones)"
grep -q "CANARY-BETWEEN keep me" "$L" || note "multi-pair run relocated curated between-zones content"
grep -q "CANARY-BETWEEN" "$G" && note "curated between-zones content leaked into LEDGER"
if [[ "$fail" -eq 0 ]]; then
echo "board-roll regression passed (7 groups)"
echo "board-roll regression passed (8 groups)"
fi
exit "$fail"