Skip to content

Commit aa5a2b7

Browse files
committed
fix(scripts/pm): mark the record at the hand-off assertion's exit too
The uncommitted-regen-path refusal is the second exit that leaves step 2 discharged — committed, in that one's case — and it also left the record `pending`. With the rerun now gated on equality that would refuse the next run instead of redoing step 2, which is safe but points the operator at the wrong remedy. Marked `handoff`, the next clean-tree run reports the sequence discharged and resumes at step 4. Claude-Session: https://claude.ai/code/session_017ETYWqMQD4qMtZzAGovWNi Co-authored-by: Claude <noreply@anthropic.com>
1 parent a999f52 commit aa5a2b7

1 file changed

Lines changed: 21 additions & 21 deletions

File tree

‎scripts/pm/os-regen-merge.sh‎

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -627,11 +627,10 @@ rr_write_record() {
627627
# which routes to `plain` — today's behaviour — and never to a repair on a base
628628
# this script cannot prove.
629629

630-
# Is HEAD the very merge this record was written for? ⚠️ Containment is NOT that
631-
# question, and asking it for the rerun was the measured defect: every later branch
632-
# commit contains the recorded pre-merge tip too, so a run made after the operator
633-
# finished step 3 BY HAND re-entered `rerun`, took main's side back over their own
634-
# regeneration commit, and step 3 COMMITTED it. Both parents answer equality.
630+
# Is HEAD the very merge this record was written for? ⚠️ Containment is NOT that question, and
631+
# asking it for the rerun was the measured defect: every later branch commit contains the recorded
632+
# pre-merge tip too, so a run made after the operator finished step 3 BY HAND re-entered `rerun`,
633+
# took main's side back over their own regeneration commit, and step 3 COMMITTED it.
635634
rr_head_is_recorded_merge() {
636635
[ "$(git rev-parse --verify --quiet 'HEAD^1' || true)" = "$rr_rec_branch_tip" ] &&
637636
[ "$(git rev-parse --verify --quiet 'HEAD^2' || true)" = "$rr_rec_main_tip" ]
@@ -700,11 +699,11 @@ rr_refuse_advanced() {
700699
echo " commits PAST that merge — refusing to redo step 2 over them." >&2
701700
rr_print_record
702701
echo " \`pending\` means no run ever marked step 2 discharged, and the later commits mean" >&2
703-
echo " somebody did. Redoing it now pins the base to the PRE-MERGE shas above, takes main's" >&2
704-
echo " side of every generated path both sides moved — discarding those commits' bytes — and" >&2
705-
echo " step 3 COMMITS that, exit 0: ⛔ a revert wearing a repair's message. Finished step 3 BY" >&2
706-
echo " HAND, as its refusal says to? Then step 2 IS discharged: \`rm -f $rr_record\` and resume" >&2
707-
echo " at STEP 4. If it is NOT, do step 2 by hand against the RECORDED base, commit, then go:" >&2
702+
echo " somebody did. Redoing it now pins the base to the PRE-MERGE shas above, takes main's side" >&2
703+
echo " of every generated path both sides moved — discarding those commits' bytes — and step 3" >&2
704+
echo " COMMITS that, exit 0: ⛔ a revert wearing a repair's message. Finished step 3 BY HAND, as" >&2
705+
echo " its refusal says to? Then step 2 IS discharged: \`rm -f $rr_record\` and resume at STEP 4." >&2
706+
echo " If NOT, do step 2 by hand against the RECORDED base, commit, and continue with step 4:" >&2
708707
echo " git diff --name-only $rr_rec_base $rr_rec_main_tip -- <the merge=os-regen patterns>" >&2
709708
echo " git diff --name-only $rr_rec_base $rr_rec_branch_tip -- <the same patterns>" >&2
710709
echo " git restore --source=$rr_rec_main_tip -- <every path in BOTH lists> # tree only" >&2
@@ -1192,9 +1191,12 @@ mode_run() {
11921191
fi
11931192

11941193
# Hand-off assertion: step 4 regenerates on top of this tree and commits the
1195-
# result, so anything uncommitted here rides into that commit unread.
1194+
# result, so anything uncommitted here rides into that commit unread. ⛔ This exit marks
1195+
# the record too: step 2 is COMMITTED by now, and a record left `pending` would send the
1196+
# next run back through step 2 over it.
11961197
handoff="$(git status --porcelain -- "${regen_paths[@]}")"
11971198
if [ -n "$handoff" ]; then
1199+
rr_write_record handoff "$merge_base" "$branch_tip" "$main_side" "$rr_rec_conflicted"
11981200
echo "✗ refusing to hand off to step 4 — generated paths are not committed:" >&2
11991201
printf '%s\n' "$handoff" >&2
12001202
echo " A regen path whose INDEX and WORKTREE disagree (porcelain \`MM\`) is the trap:" >&2
@@ -2147,35 +2149,33 @@ mode_self_test() {
21472149
"$(git show HEAD:gen/deferred.txt | grep -c 'deferred v1-MAIN' || true)" 0
21482150
cd "$here"
21492151

2150-
# --- 11. REPRO 1 (this card): step 3's commit REFUSED hands the commit to the
2151-
# operator, and until the record said so the NEXT run re-entered `rerun`, redid
2152-
# step 2 against the pre-merge base and COMMITTED a revert of the operator's own
2153-
# regeneration — exit 0, nothing refused. `FLOWX` stands in for it.
2152+
# --- 11. REPRO 1 (this card): step 3's commit REFUSED hands the commit to the operator, and
2153+
# until the record said so the NEXT run re-entered `rerun`, redid step 2 against the
2154+
# pre-merge base and COMMITTED a revert of that operator's own regeneration (`FLOWX`
2155+
# below) — exit 0, nothing refused.
21542156
st_fixture_rerun "$tmp/m"
21552157
bash "$SELF" >/dev/null 2>&1 || true # run 1 stops on the MIXED conflict
21562158
st_resolve_and_commit && st_record="$(rr_record_path)" # the merge, committed by hand
21572159
printf '#!/bin/sh\nexit 1\n' > .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit
21582160
out="$(bash "$SELF" 2>&1)" && rc=0 || rc=$? # run 2: the rerun, step 3 refused
21592161
st_case 'r1: the refused step-3 commit fails, MARKS handoff, warns against rerunning' \
21602162
"$rc/$(rr_field phase "$st_record")/$(printf '%s' "$out" | grep -c 'Do NOT rerun this script' || true)" '1/handoff/1'
2161-
# Then do EXACTLY what it says: clear the hook, regenerate, `git add -A && commit`.
2162-
rm -f .git/hooks/pre-commit && printf 'deferred v1-MAIN\nFLOWX\n' > gen/deferred.txt
2163+
rm -f .git/hooks/pre-commit && printf 'deferred v1-MAIN\nFLOWX\n' > gen/deferred.txt # as told
21632164
git add -A && git commit -qm 'step 4 by hand: regenerate (FLOWX)'
21642165
cp -a "$tmp/m" "$tmp/m-mut" # 11b replays run 3 from right here
21652166
out="$(bash "$SELF" 2>&1)" && rc=0 || rc=$? # run 3: the card's own run
21662167
st_case 'r1: run 3 exits 0 discharged — no rerun, no side taken, and FLOWX SURVIVES (the card read 0)' \
21672168
"$rc/$(printf '%s' "$out" | grep -c '^→ RERUN:' || true)/$(printf '%s' "$out" | grep -c 'already discharged' || true)/$(printf '%s' "$out" | grep -c "TAKING main.s side" || true)/$(git show HEAD:gen/deferred.txt | grep -c FLOWX || true)" '0/0/1/0/1'
2168-
# The safety net for a record nothing ever marked (a run killed after step 1, or one
2169-
# written before the marking existed): refused, ⛔ never silently redone.
2169+
# The safety net for a record nothing ever marked: refused, ⛔ never silently redone.
21702170
sed 's/^phase=.*/phase=pending/' "$st_record" > "$st_record.t" && mv "$st_record.t" "$st_record"
21712171
out="$(bash "$SELF" 2>&1)" && rc=0 || rc=$?
21722172
st_case 'r1: a pending record past its own merge is REFUSED with the by-hand step 2' \
21732173
"$rc/$(printf '%s' "$out" | grep -c "git restore --source=$(rr_field main_tip "$st_record")" || true)" '1/1'
21742174
cd "$here"
21752175

21762176
# --- 11b. THE DISCRIMINATING MUTATION for case 11: put the containment gate back —
2177-
# the ONE line — and the card reproduces on demand, in the tree case 11 copied
2178-
# aside one commit earlier. Same perl/\Q..\E replacement 6b, 8b, 9b, 10b use.
2177+
# the ONE line — and the card reproduces on demand, in the tree case 11 copied aside
2178+
# one commit earlier. Same perl/\Q..\E replacement 6b, 8b, 9b and 10b use.
21792179
mutated_reentry="$tmp/mutated-reentry-os-regen-merge.sh"
21802180
MUT_ANCHOR=' if [ "$rr_rec_phase" != done ] && rr_head_is_recorded_merge; then' \
21812181
MUT_INSERT=' if [ "$rr_rec_phase" != done ]; then' \

0 commit comments

Comments
 (0)