Commitfad41aa0Recorded25 Aug 2026Repositoryfolio

test: correct the sabotage predictions to the population split they taught

Message

The suite's first run: T3/T4/T5 red as predicted; T1/T2/TA mispredicted, and the mispredictions are the finding. The ACCOUNTING protects UNSTAGED carriers (prose/markdown files are never staged, so graph closure structurally cannot see them); GRAPH CLOSURE protects STAGED files (a site dropped inside a touched file leaves residue only closure sees). The two layers PARTITION the population rather than backing each other up -- my original legs treated them as redundant layers over one population and predicted the wrong arms.

Re-cut: T1 (accounting tolerated -> b6 red, the unstaged-carrier refusals vanish), T2 (no sites at all + accounting -> b5 red on content asserts: nothing is staged, no layer inside the product can see it, the arm's own file reads are the catch), T2c (first-site-only + accounting -> b5 red WITH the closure signature: staged residue is closure's own population). TA's plant moves the marker inside a string literal -- the first spelling's mid-expression comment swallowed the closing parens and killed the whole probe at parse, which surfaced as an EMPTY arm set, the worst red shape. All plants re-dry-verified to land uniquely.

Changed
 test/sabotage-f3b.sh | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 60 insertions(+), 19 deletions(-)
Diff
test/sabotage-f3b.shmodified
@@ -4,17 +4,24 @@
4
# sets), plant landed by hash + marker, planted tree must build, restores by
5
# git checkout verified by hash, full gate re-run green at the end.
6
#
−7
# Legs:
−8
# T1 raw-vs-semantic ACCOUNTING tolerated -> the graph-closure check
−9
# catches the stale referrer: b5-rename red (closure signature)
−10
# T2 T1 + closure check disabled -> the stale referrer PUBLISHES:
−11
# b5-rename red on its own content asserts (BOTH layers had to fall)
+7
# Legs (see the population-split comment before T1 -- the first run's
+8
# mispredictions are what taught it):
+9
# T1 raw-vs-semantic ACCOUNTING tolerated -> b6 red: the prose/markdown
+10
# carriers are UNSTAGED, so only the accounting can refuse for them
+11
# T2 semantic pass returns NO sites + accounting tolerated -> b5 red on
+12
# its CONTENT asserts (referrers never touched; closure cannot see
+13
# unstaged files either)
+14
# T2c semantic pass keeps only the FIRST site per file + accounting
+15
# tolerated -> b5 red WITH the closure signature (staged residue is
+16
# closure's own population)
17
# T3 delete ignores referrers -> b7-delete red
18
# T4 recovery goes silent (recover-root! returns '() doing nothing) ->
19
# b3-recovery-completes red (completion never happens, manifest stays)
20
# T5 recovery TOLERATES an unprovable state (the first-pass proof clause
21
# always passes) -> gate arm 5 red (the corrupt-temp driver observes
22
# recovery proceeding over garbage instead of refusing to a human)
+23
# T2c semantic pass drops sites after the first per file (accounting
+24
# tolerated) -> b5 red WITH the closure signature (staged residue)
25
# TA assertion layer: flip the bystander hash expectation -> b12 red
26
27
set -u
@@ -77,18 +84,28 @@ leg_result () {
84
[ "$2" -eq 0 ] && { reds=$((reds + 1)); echo "SAB-F3B LEG $1: RED AS PREDICTED"; }
85
}
86
+87
# ---------------------------------------------------------------------------
+88
# THE POPULATION SPLIT THESE THREE LEGS DEMONSTRATE (learned from this
+89
# suite's own first run, whose predictions had it backwards): the ACCOUNTING
+90
# protects UNSTAGED carriers -- a prose or markdown file is never staged, so
+91
# graph closure structurally cannot see it; only the raw-vs-semantic
+92
# arithmetic can refuse for it. GRAPH CLOSURE protects STAGED files -- a
+93
# rewrite site dropped inside a touched file leaves residue closure sees.
+94
# The two layers partition the population rather than backing each other up,
+95
# and each leg below fells exactly one.
96
# ---------------------------------------------------------------------------
97
echo "SAB-F3B LEG T1: raw-vs-semantic accounting tolerated"
−82
echo " PREDICT RED: b5-rename -- via the GRAPH CLOSURE check (the dropped"
−83
echo " accounting lets a semantically-invisible occurrence"
−84
echo " through, closure sees the residue and refuses)"
−85
echo " PREDICT GREEN: b1, b7 (delete's guard reads semantic+raw directly)"
+98
echo " PREDICT RED: b6-rename-refusals (the prose and markdown occurrences"
+99
echo " are silently dropped, the renames PROCEED, and b6's"
+100
echo " expected refusals never come -- closure cannot help:"
+101
echo " those files are never staged)"
+102
echo " PREDICT GREEN: b5 (every occurrence in ITS web is rewritable), b1, b7"
103
sed -i 's/(if (= accounted (length hits))/(if #t ;; SAB-T1/' src/folio/doc/structural.sgl
104
if plant_landed T1 "$ST" "$h_st" "SAB-T1" 1 && build_planted T1; then
105
run_battery T1 || true
106
ok=0
−90
expect T1 b5-rename RED || ok=1
−91
grep -q "closure" "$work/bat-T1.log" || { fail_leg T1 "red, but not with the closure signature"; ok=1; }
+107
expect T1 b6-rename-refusals RED || ok=1
+108
expect T1 b5-rename GREEN || ok=1
109
expect T1 b1-stand-down GREEN || ok=1
110
expect T1 b7-delete GREEN || ok=1
111
leg_result T1 $ok
@@ -96,20 +113,41 @@ fi
113
restore_all || exit 3
114
115
# ---------------------------------------------------------------------------
−99
echo "SAB-F3B LEG T2: accounting tolerated AND closure disabled -- the stale"
−100
echo " referrer PUBLISHES; b5's content asserts catch it (both layers fell)"
−101
echo " PREDICT RED: b5-rename (residue assert); b6 may cascade -- only b5 is"
−102
echo " asserted"
+116
echo "SAB-F3B LEG T2: the semantic pass returns NO sites (total silent loss)"
+117
echo " with the accounting tolerated -- referrer files are never touched at"
+118
echo " all, so closure (staged-only) cannot see it either; b5's own CONTENT"
+119
echo " asserts on the referrer files are what catches it"
+120
echo " PREDICT RED: b5-rename (residue in ref files)"
+121
echo " PREDICT GREEN: b1"
122
sed -i 's/(if (= accounted (length hits))/(if #t ;; SAB-T1/' src/folio/doc/structural.sgl
−104
sed -i 's/(if (pair? leak)/(if #f ;; SAB-T2/' src/folio/doc/structural.sgl
+123
sed -i 's/(walk rest (if f (cons (list n f) out) out))/(walk rest out) ;; SAB-T2/' src/folio/doc/structural.sgl
124
if plant_landed T2 "$ST" "$h_st" "SAB-T2" 1 && build_planted T2; then
125
run_battery T2 || true
126
ok=0
127
expect T2 b5-rename RED || ok=1
+128
expect T2 b1-stand-down GREEN || ok=1
129
leg_result T2 $ok
130
fi
131
restore_all || exit 3
132
+133
# ---------------------------------------------------------------------------
+134
echo "SAB-F3B LEG T2c: the semantic pass drops every site AFTER the first per"
+135
echo " file (accounting tolerated) -- ref-two stays TOUCHED with one of its"
+136
echo " two sites stale, which is exactly the residue GRAPH CLOSURE exists"
+137
echo " to catch"
+138
echo " PREDICT RED: b5-rename WITH the closure signature"
+139
sed -i 's/(if (= accounted (length hits))/(if #t ;; SAB-T1/' src/folio/doc/structural.sgl
+140
sed -i 's/(walk rest (if f (cons (list n f) out) out))/(walk rest (if (and f (null? out)) (cons (list n f) out) out)) ;; SAB-T2C/' src/folio/doc/structural.sgl
+141
if plant_landed T2c "$ST" "$h_st" "SAB-T2C" 1 && build_planted T2c; then
+142
run_battery T2c || true
+143
ok=0
+144
expect T2c b5-rename RED || ok=1
+145
grep -q "closure" "$work/bat-T2c.log" \
+146
|| { fail_leg T2c "red, but not via the closure check"; ok=1; }
+147
leg_result T2c $ok
+148
fi
+149
restore_all || exit 3
+150
151
# ---------------------------------------------------------------------------
152
echo "SAB-F3B LEG T3: delete ignores referrers"
153
echo " PREDICT RED: b7-delete (a referenced delete publishes; the arm"
@@ -175,8 +213,11 @@ restore_all || exit 3
213
# ---------------------------------------------------------------------------
214
echo "SAB-F3B LEG TA: assertion layer -- flip the bystander hash expectation"
215
echo " PREDICT RED: b12-bystander"
−178
sed -i 's/(equal? (revision-of-file (rooted "bystander.md")) bystander-hash)/(not (equal? (revision-of-file (rooted "bystander.md")) bystander-hash)) ;; SAB-TA/' test/f3b-probe.sgl
−179
if plant_landed TA "$PROBE" "$h_probe" "SAB-TA" 1; then
+216
# The marker lives INSIDE a string literal: the first spelling appended a
+217
# `;;` comment mid-expression, which swallowed the closing parens and killed
+218
# the whole probe at parse (observed: an EMPTY arm set, the worst red shape).
+219
sed -i 's/(equal? (revision-of-file (rooted "bystander.md")) bystander-hash)/(equal? "SAB-TA-impossible" (revision-of-file (rooted "bystander.md")))/' test/f3b-probe.sgl
+220
if plant_landed TA "$PROBE" "$h_probe" "SAB-TA-impossible" 1; then
221
run_battery TA || true
222
ok=0
223
expect TA b12-bystander RED || ok=1
@@ -195,5 +236,5 @@ fi
236
237
echo "---"
238
echo "F3B_SABOTAGE legs=$legs red=$reds setup_failed=$setup_fails"
−198
[ "$legs" -eq 6 ] && [ "$reds" -eq 6 ] && [ "$setup_fails" -eq 0 ] && exit 0
+239
[ "$legs" -eq 7 ] && [ "$reds" -eq 7 ] && [ "$setup_fails" -eq 0 ] && exit 0
240
exit 1