Skip to content

Commit b83f084

Browse files
committed
W45 §3.5: fix restore_files() to snapshot pre-script state
ROOT CAUSE FIX for the 8-incident undiagnosed-recurring file-state revert class (D-1776998268 + 7 priors). Per supervisor 04:14:27Z post-incident-python#8 ROOT CAUSE IDENTIFICATION: the §3.5 falsifier's restore_files() trap was the "external reverter" across all 8 incidents. It ran `git checkout HEAD --` on TOUCHED_FILES on script exit; if those files had unstaged modifications BEFORE the script ran (e.g., agent's in-flight Tier 8 Phase A content), the trap blew them away. Empirical validation (this session 04:13:36Z): - Test python#6 + python#7 (trivial content, single-mechanism): no revert - Tests python#5/python#7 idle: no revert - cmake build alone: no revert - §3.5 invocation on staged Phase A: REVERT (PhxExceptionTable count 13 → 0; mtime bumped 1777002918 → 1777003987; builder_state_c.h no longer M in git status) 8 prior incidents now retroactively attributed to §3.5 trap firing during build/gate cycles concurrent with agent Tier 8 attempts. NO external actor (no VS Code, no Alex, no formatter, no cron). W48 inotify daemon NOT NEEDED. (Iso-A) host relocation NOT NEEDED. Class size CLOSED — class type changed from "undiagnosed-recurring" to "self-inflicted via §3.5 trap, RESOLVED". Fix mechanism: snapshot per-file content to /tmp on first snapshot_file_if_new() call (per fixture mutation start). restore_files() copies from snapshot (not HEAD), preserving pre-script unstaged state. Snapshots cleaned + FILE_SNAPSHOTS array unset post-restore. Re-validation (this session post-fix): - §3.5 BUILD MODE 4/4 PASS - post-restore build [OK] - Phase A content (PhxExceptionTable count 13) SURVIVED §3.5 invocation - ALL 6 Tier 8 staged files still M Doc-only (script-only) push, no §3.5 BUILD MODE per touched-files rule (this IS the §3.5 script being amended; meta-circular but doc-only gate appropriate). Authorization: supervisor 04:14:27Z FIX directive post-ROOT-CAUSE identification (generalist 04:13:58Z catch). Pythia python#105 'fever has name infection still spreads' was structurally correct re self-inflicted infrastructure — but the infection wasn't external-class undiagnosable; it was OUR OWN script's exit trap trampling unstaged work. 5 detection layers (Alex directive D-1776434533, gate python#3 D-1776887480, 4-step Pre-Edit WT Integrity D-1776995670, mtime-checkpoint D-1776998268, W48 spec D-1776999077) added to detect ourselves. Audit own scripts BEFORE external-actor hypotheses (per new feedback memory entry).
1 parent 61f0e3e commit b83f084

1 file changed

Lines changed: 39 additions & 14 deletions

File tree

scripts/w45_section_3_5_derivation_drift.sh

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,32 @@ echo "HEAD: $(git rev-parse HEAD)"
7474
echo "Mode: $([ $DRY_RUN -eq 1 ] && echo DRY-RUN || echo BUILD)"
7575
echo ""
7676

77-
# Restore tracked files via `git checkout HEAD --` per spec §2.7.3.
78-
# Tracked file list assembled per fixture so we don't restore unrelated edits.
77+
# Restore tracked files to their PRE-SCRIPT-INVOCATION state. Per the
78+
# 8-incident root-cause investigation (2026-04-24, supervisor 04:14:27Z):
79+
# the prior `git checkout HEAD --` approach BLEW AWAY pre-existing
80+
# unstaged modifications on touched files (e.g., agent's in-flight
81+
# Tier 8 Phase A content), causing the recurring "external revert"
82+
# class. Fix: snapshot per-file content to /tmp on first touch; restore
83+
# from snapshot (not HEAD) so pre-script edits survive intact.
7984
TOUCHED_FILES=()
80-
restore_files() {
81-
if [ "${#TOUCHED_FILES[@]}" -gt 0 ]; then
82-
git checkout HEAD -- "${TOUCHED_FILES[@]}" 2>/dev/null || true
85+
declare -A FILE_SNAPSHOTS
86+
snapshot_file_if_new() {
87+
local f="$1"
88+
if [ -z "${FILE_SNAPSHOTS[$f]:-}" ]; then
89+
local snap
90+
snap=$(mktemp /tmp/w45_35_snap.XXXXXX)
91+
cp "$f" "$snap"
92+
FILE_SNAPSHOTS[$f]="$snap"
8393
fi
8494
}
95+
restore_files() {
96+
for f in "${!FILE_SNAPSHOTS[@]}"; do
97+
cp "${FILE_SNAPSHOTS[$f]}" "$f" 2>/dev/null || true
98+
rm -f "${FILE_SNAPSHOTS[$f]}" 2>/dev/null || true
99+
unset "FILE_SNAPSHOTS[$f]"
100+
done
101+
TOUCHED_FILES=()
102+
}
85103
trap restore_files EXIT
86104

87105
# --- Fixture mutation helpers ----------------------------------------------
@@ -90,6 +108,7 @@ trap restore_files EXIT
90108
# body (builder_emit_c.c). Renames the constant to a non-existent symbol;
91109
# C-body comparison site fails to compile (undeclared identifier).
92110
mutate_fixture_1() {
111+
snapshot_file_if_new "$BUILDER_EMIT_C"
93112
perl -i -pe 's/\bBEFORE_ASYNC_WITH\b/BEFORE_ASYNC_WITH_PHX_W45_DRIFT/g' \
94113
"$BUILDER_EMIT_C"
95114
TOUCHED_FILES+=("$BUILDER_EMIT_C")
@@ -104,6 +123,7 @@ expected_site_fixture_1="builder_emit_c.c"
104123
# the macro to a non-existent symbol so the C-body identifier site fails to
105124
# compile.
106125
mutate_fixture_2() {
126+
snapshot_file_if_new "$BUILDER_EMIT_C"
107127
# Only target the _Py_ID call sites in emitSetupWith C body region.
108128
# Rename _Py_ID identifier in lines containing the bridge function name.
109129
# Use a sentinel substitution scoped to lines 4140-4220 (emit_setup_with_c +
@@ -121,29 +141,34 @@ verify_fixture_2() {
121141
}
122142
expected_site_fixture_2="builder_emit_c.c"
123143

124-
# Fixture 3: ExceptionTableEntry struct field rename in builder.h. Renames
125-
# the `depth` field to `depth_phx_w45_drift`; the C++-side bridges
126-
# (push_cpp + entry_cpp) in builder.cpp access `e.depth` and `entry.depth`
127-
# — both fail to compile (no member named 'depth').
144+
# Fixture 3: ExceptionTableEntry struct field rename in builder_state_c.h.
145+
# Tier 8 pilot Phase A: ExceptionTableEntry moved from builder.h C++ struct
146+
# to builder_state_c.h C struct. Renames the `depth` field to
147+
# `depth_phx_w45_drift`; consumers in builder_state_c.c (parse +
148+
# find_exception_handler_c bodies populating entry.depth) and builder.cpp
149+
# (handler.depth in emitInlineExceptionMatch + emitCallExceptionHandler)
150+
# all fail to compile (no member named 'depth').
128151
mutate_fixture_3() {
152+
snapshot_file_if_new "$BUILDER_STATE_C_H"
129153
perl -i -pe '
130-
if (/^\s*int depth;\s*\/\//) {
154+
if (/^\s*int depth;\s*\/\*/ && !/depth_phx_w45_drift/) {
131155
s/\bdepth\b/depth_phx_w45_drift/;
132156
}
133-
' "$BUILDER_H"
134-
TOUCHED_FILES+=("$BUILDER_H")
157+
' "$BUILDER_STATE_C_H"
158+
TOUCHED_FILES+=("$BUILDER_STATE_C_H")
135159
}
136160
verify_fixture_3() {
137-
grep -q "depth_phx_w45_drift" "$BUILDER_H"
161+
grep -q "depth_phx_w45_drift" "$BUILDER_STATE_C_H"
138162
}
139-
expected_site_fixture_3="builder.cpp"
163+
expected_site_fixture_3="builder_state_c"
140164

141165
# Fixture 4: hir_builder_state_block_map_blocks_lookup_cpp return-type
142166
# change in builder_state_c.h. Changes return type from `void *` to `int`;
143167
# the caller in hir_c_api.cpp returns the value as `void *` from a
144168
# `void *`-returning function (`hir_builder_get_block_at_off`), causing
145169
# a return-type incompatibility in C++.
146170
mutate_fixture_4() {
171+
snapshot_file_if_new "$BUILDER_STATE_C_H"
147172
perl -i -0777 -pe \
148173
's/void \*hir_builder_state_block_map_blocks_lookup_cpp\(/int hir_builder_state_block_map_blocks_lookup_cpp(/g' \
149174
"$BUILDER_STATE_C_H"

0 commit comments

Comments
 (0)