From 5020c417492993d16258ee449bb9cbd8d7a8acaa Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Fri, 31 Jul 2026 04:42:37 -0500 Subject: [PATCH 1/2] =?UTF-8?q?fix(wake):=20#984=20fatal=20source=20guard?= =?UTF-8?q?=20+=20#985=20absorb=20re-scan=20=E2=80=94=20#973=20follow-up?= =?UTF-8?q?=20batch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four changes, one coordinate shift: 1. #984: the ten suites sourced _wake-common.sh with `. file && wake_assert_init` under no set -e — a failed source left every helper undefined, every AND-polarity canary silently green, and the suite exiting 0 having run ZERO wake assertions. The source is now guarded alone in an explicit block that echoes a wake-authored diagnostic to real stderr and exits 97; init runs on its own line. Negative test: a copied suite without _wake-common.sh exits 97 with the diagnostic. 2. #985: the sweep absorb branch keyed on helper-token presence alone, so a converted line that ALSO ran a raw grep verdict (has_match ... && grep -q SECRET ... && fail) was absorbed as benign. The absorb decision now re-scans the line remainder for grep in command position (RX_GREP_CMD, quote-unaware by design — errs toward loud), and is factored into residual_sites(), the ONE path both sweep legs share: leg 2 previously used raw classify() and never exercised the absorb branch at all. Plants G (helper+raw-grep, must stay residual) and H (grep only in pattern argument, must absorb as note) prove both directions; SWEEP-PLANTS is now 8/8. 3. validate-973.sh arms loop: the sentinel check was the one AND-polarity grep in the file — a grep error (rc>=2) read as "no sentinel" and passed toward green. Converted to the three-valued idiom with its own loud error arm. 4. Dead polarity() deleted from check-973.py (unreferenced since the frozen derivation was ported). The #984 guard is +4 lines uniformly above every site in all ten suites, so HEADER_SHIFT moves 3 -> 7 and the nine disposition rows shift +4; the frozen artifact is untouched. Verified: expected==static (261 rows), full validate-973.sh terminal-green (10 suites, 21 arms at shifted coordinates, dispositions none-stale, sweep clean 8/8). Written-by: pepper (sb-it-1-dt) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB --- .../framework/tools/wake/test-wake-beacon.sh | 6 +- .../tools/wake/test-wake-detector.sh | 6 +- .../tools/wake/test-wake-digest-hmac.sh | 6 +- .../tools/wake/test-wake-digest-quarantine.sh | 6 +- .../tools/wake/test-wake-fn-oracle.sh | 6 +- .../framework/tools/wake/test-wake-install.sh | 6 +- .../tools/wake/test-wake-preimage.sh | 6 +- .../tools/wake/test-wake-reconcile.sh | 6 +- .../tools/wake/test-wake-store-ack.sh | 6 +- .../wake/test-wake-store-enqueue-race.sh | 6 +- .../tools/wake/validate-973/check-973.py | 120 ++++++++++++------ .../unexecuted-sites-dispositions.txt | 18 +-- .../tools/wake/validate-973/validate-973.sh | 18 ++- 13 files changed, 151 insertions(+), 65 deletions(-) diff --git a/packages/mosaic/framework/tools/wake/test-wake-beacon.sh b/packages/mosaic/framework/tools/wake/test-wake-beacon.sh index 69da67cf..8e845636 100755 --- a/packages/mosaic/framework/tools/wake/test-wake-beacon.sh +++ b/packages/mosaic/framework/tools/wake/test-wake-beacon.sh @@ -33,7 +33,11 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness. # shellcheck disable=SC1091 -. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init +if ! . "$SCRIPT_DIR/_wake-common.sh"; then + echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2 + exit 97 +fi +wake_assert_init BEACON="$SCRIPT_DIR/beacon.sh" command -v jq >/dev/null 2>&1 || { diff --git a/packages/mosaic/framework/tools/wake/test-wake-detector.sh b/packages/mosaic/framework/tools/wake/test-wake-detector.sh index 41de2668..e942caf2 100755 --- a/packages/mosaic/framework/tools/wake/test-wake-detector.sh +++ b/packages/mosaic/framework/tools/wake/test-wake-detector.sh @@ -31,7 +31,11 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness. # shellcheck disable=SC1091 -. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init +if ! . "$SCRIPT_DIR/_wake-common.sh"; then + echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2 + exit 97 +fi +wake_assert_init DET="$SCRIPT_DIR/detector.sh" STORE="$SCRIPT_DIR/store.sh" diff --git a/packages/mosaic/framework/tools/wake/test-wake-digest-hmac.sh b/packages/mosaic/framework/tools/wake/test-wake-digest-hmac.sh index 803118b9..805fea3c 100755 --- a/packages/mosaic/framework/tools/wake/test-wake-digest-hmac.sh +++ b/packages/mosaic/framework/tools/wake/test-wake-digest-hmac.sh @@ -37,7 +37,11 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness. # shellcheck disable=SC1091 -. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init +if ! . "$SCRIPT_DIR/_wake-common.sh"; then + echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2 + exit 97 +fi +wake_assert_init STORE="$SCRIPT_DIR/store.sh" DIGEST="$SCRIPT_DIR/digest.sh" SIGN="$SCRIPT_DIR/sign.sh" diff --git a/packages/mosaic/framework/tools/wake/test-wake-digest-quarantine.sh b/packages/mosaic/framework/tools/wake/test-wake-digest-quarantine.sh index 481782b6..a51e0b23 100755 --- a/packages/mosaic/framework/tools/wake/test-wake-digest-quarantine.sh +++ b/packages/mosaic/framework/tools/wake/test-wake-digest-quarantine.sh @@ -119,7 +119,11 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness. # shellcheck disable=SC1091 -. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init +if ! . "$SCRIPT_DIR/_wake-common.sh"; then + echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2 + exit 97 +fi +wake_assert_init DIGEST="$SCRIPT_DIR/digest.sh" command -v jq >/dev/null 2>&1 || { diff --git a/packages/mosaic/framework/tools/wake/test-wake-fn-oracle.sh b/packages/mosaic/framework/tools/wake/test-wake-fn-oracle.sh index f97eb1a1..0437a356 100755 --- a/packages/mosaic/framework/tools/wake/test-wake-fn-oracle.sh +++ b/packages/mosaic/framework/tools/wake/test-wake-fn-oracle.sh @@ -27,7 +27,11 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness. # shellcheck disable=SC1091 -. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init +if ! . "$SCRIPT_DIR/_wake-common.sh"; then + echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2 + exit 97 +fi +wake_assert_init ORACLE="$SCRIPT_DIR/fn-oracle.sh" DET="$SCRIPT_DIR/detector.sh" diff --git a/packages/mosaic/framework/tools/wake/test-wake-install.sh b/packages/mosaic/framework/tools/wake/test-wake-install.sh index 852c1378..ef376f7d 100755 --- a/packages/mosaic/framework/tools/wake/test-wake-install.sh +++ b/packages/mosaic/framework/tools/wake/test-wake-install.sh @@ -36,7 +36,11 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness. # shellcheck disable=SC1091 -. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init +if ! . "$SCRIPT_DIR/_wake-common.sh"; then + echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2 + exit 97 +fi +wake_assert_init WI="$SCRIPT_DIR/wake-install.sh" BEACON="$SCRIPT_DIR/beacon.sh" FRAMEWORK_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" diff --git a/packages/mosaic/framework/tools/wake/test-wake-preimage.sh b/packages/mosaic/framework/tools/wake/test-wake-preimage.sh index 3380dd5a..913d6b05 100755 --- a/packages/mosaic/framework/tools/wake/test-wake-preimage.sh +++ b/packages/mosaic/framework/tools/wake/test-wake-preimage.sh @@ -48,7 +48,11 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness. # shellcheck disable=SC1091 -. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init +if ! . "$SCRIPT_DIR/_wake-common.sh"; then + echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2 + exit 97 +fi +wake_assert_init PRE="$SCRIPT_DIR/preimage.sh" STORE="$SCRIPT_DIR/store.sh" DET="$SCRIPT_DIR/detector.sh" diff --git a/packages/mosaic/framework/tools/wake/test-wake-reconcile.sh b/packages/mosaic/framework/tools/wake/test-wake-reconcile.sh index 7705606f..bdca1500 100755 --- a/packages/mosaic/framework/tools/wake/test-wake-reconcile.sh +++ b/packages/mosaic/framework/tools/wake/test-wake-reconcile.sh @@ -31,7 +31,11 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness. # shellcheck disable=SC1091 -. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init +if ! . "$SCRIPT_DIR/_wake-common.sh"; then + echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2 + exit 97 +fi +wake_assert_init RECON="$SCRIPT_DIR/reconcile.sh" STORE="$SCRIPT_DIR/store.sh" DET="$SCRIPT_DIR/detector.sh" diff --git a/packages/mosaic/framework/tools/wake/test-wake-store-ack.sh b/packages/mosaic/framework/tools/wake/test-wake-store-ack.sh index 2be6a4c4..83084daa 100755 --- a/packages/mosaic/framework/tools/wake/test-wake-store-ack.sh +++ b/packages/mosaic/framework/tools/wake/test-wake-store-ack.sh @@ -44,7 +44,11 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness. # shellcheck disable=SC1091 -. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init +if ! . "$SCRIPT_DIR/_wake-common.sh"; then + echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2 + exit 97 +fi +wake_assert_init STORE="$SCRIPT_DIR/store.sh" ACK="$SCRIPT_DIR/ack.sh" diff --git a/packages/mosaic/framework/tools/wake/test-wake-store-enqueue-race.sh b/packages/mosaic/framework/tools/wake/test-wake-store-enqueue-race.sh index 94b19785..8dd36407 100755 --- a/packages/mosaic/framework/tools/wake/test-wake-store-enqueue-race.sh +++ b/packages/mosaic/framework/tools/wake/test-wake-store-enqueue-race.sh @@ -34,7 +34,11 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # #973: three-valued grep assertion helpers (has_match/count_lines); init saves real stderr for abort loudness. # shellcheck disable=SC1091 -. "$SCRIPT_DIR/_wake-common.sh" && wake_assert_init +if ! . "$SCRIPT_DIR/_wake-common.sh"; then + echo "WAKE-ASSERT INIT ABORT: cannot source _wake-common.sh — suite ran ZERO wake assertions (#984)" >&2 + exit 97 +fi +wake_assert_init STORE="$SCRIPT_DIR/store.sh" command -v jq >/dev/null 2>&1 || { diff --git a/packages/mosaic/framework/tools/wake/validate-973/check-973.py b/packages/mosaic/framework/tools/wake/validate-973/check-973.py index d4d9b1e9..db396758 100755 --- a/packages/mosaic/framework/tools/wake/validate-973/check-973.py +++ b/packages/mosaic/framework/tools/wake/validate-973/check-973.py @@ -10,8 +10,9 @@ comparison come from independent code paths. Subcommands (all print sorted, stable output; non-zero exit on any failure): expected The expected coordinate set from the ARTIFACT: one - " :" row per denominator row (+3 = the - uniform header shift the converter applied; converter-verified). + " :" row per denominator row (+7 = 3 + converter header lines + 4 lines from the #984 source guard, + uniform across all ten suites). Multi-grep lines stay ONE coordinate. static The converted-site inventory from the SOURCE TEXT at the current @@ -23,8 +24,8 @@ Subcommands (all print sorted, stable output; non-zero exit on any failure): from the text.) arms The forced-error arm list: the 19 denominator canaries plus one - E-form arm (store-ack:733→736, a $(count_lines) capture compared - afterward — the A6 shape) plus one F-form arm (quarantine:560→563, + E-form arm (store-ack:733→740, a $(count_lines) capture compared + afterward — the A6 shape) plus one F-form arm (quarantine:560→567, the multi-grep pipeline capture), as " :
". Both extras are asserted to exist in the artifact with the expected form — a renumber that moved them fails here, not @@ -33,7 +34,8 @@ Subcommands (all print sorted, stable output; non-zero exit on any failure): sweep Residual sweep: the denominator's own classifier (ported from the frozen derivation) over the ten suites at the current tree must find ZERO unconverted verdict-form grep sites; and, IN THE SAME - RUN, six per-form specimens planted into a temp copy of a real + RUN, eight specimens (six per-form + two absorb-branch probes, #985) + planted into a temp copy of a real suite must ALL be found with their correct forms — an instrument that reports zero must first be seen finding what it claims to find (A5). @@ -50,7 +52,9 @@ HERE = Path(__file__).resolve().parent WAKE = HERE.parent ART = HERE / "denominator-089615f.json" -HEADER_SHIFT = 3 # converter inserted 3 header lines after SCRIPT_DIR in every suite +HEADER_SHIFT = 7 # 3 converter header lines after SCRIPT_DIR + 4 lines from the +# #984 source guard (1-line `. _wake-common.sh && wake_assert_init` became a 5-line +# guarded block) — both uniform across all ten suites, both above every site. # The two hand-picked extra arms (base coordinates; forms asserted at load). EXTRA_ARMS = [ @@ -68,10 +72,14 @@ RX_ASSIGN_SUB = re.compile(r'=\s*"?\$\(.*grep') RX_IF = re.compile(r"^\s*(el)?if\s+.*grep") RX_GREP = re.compile(r"(^|[^A-Za-z0-9_.-])grep([^A-Za-z0-9_.-]|$)") - -def polarity(line): - m = RX_FAIL_SAME.search(line) - return "OR" if m.group(1) == "||" else "AND" +# grep in COMMAND position: at line start or after a command separator / subshell +# opener / shell keyword / `!`. Quote-unaware by design — a quoted "grep" after a +# separator reads as a command and lands the line in residual, which fails LOUD; +# the absorb direction (note) is the one that must never fire on a real verdict. +RX_GREP_CMD = re.compile( + r"(?:^|[;|&(`]|\$\(|\bif\b|\belif\b|\bthen\b|\belse\b|\bdo\b|\bwhile\b|\buntil\b|!)" + r"\s*grep(?:\s|$)" +) def classify(lines): @@ -137,6 +145,28 @@ def classify(lines): return sites, dispo +def residual_sites(lines): + """classify() plus the absorb decision — the ONE path both sweep legs share. + + A classified site is absorbed as a note only when its line carries a wake + helper token AND the line shows no grep in command position: a converted + line whose PATTERN argument merely contains the word grep. A helper line + that also runs a real grep verdict (has_match ... && grep -q SECRET ... && + fail) stays residual (#985). Multi-line forms anchor the site at the line + containing grep, so a command-position grep on a continuation line never + shares its line with the helper token and stays residual by construction. + """ + sites, dispo = classify(lines) + residual, notes = [], [] + for ln, form, text in sites: + line = lines[ln - 1] + if RX_HELPER.search(line) and not RX_GREP_CMD.search(line): + notes.append((ln, form, text)) + else: + residual.append((ln, form, text)) + return residual, notes, dispo + + def load_art(): art = json.loads(ART.read_text()) assert art["total"] == 261 == len(art["rows"]), "artifact self-consistency" @@ -199,13 +229,20 @@ def cmd_arms(): return 0 +# (expected classify form, expected disposition through residual_sites, snippet) PLANTS = [ - ("A-same-line", ['grep -q needle haystack || fail "plant-A"']), - ("B-cont-operator", ["grep -q needle haystack ||", ' fail "plant-B"']), - ("C-cont-backslash", ["grep -q needle \\", ' haystack || fail "plant-C"']), - ("D-if-form", ["if ! grep -q needle haystack; then", ' fail "plant-D"', "fi"]), - ("E-count-capture", ['[ "$(grep -c needle haystack)" = "1" ] || fail "plant-E"']), - ("F-extract-capture", ['val="$(grep needle haystack)"']), + ("A-same-line", "residual", ['grep -q needle haystack || fail "plant-A"']), + ("B-cont-operator", "residual", ["grep -q needle haystack ||", ' fail "plant-B"']), + ("C-cont-backslash", "residual", ["grep -q needle \\", ' haystack || fail "plant-C"']), + ("D-if-form", "residual", ["if ! grep -q needle haystack; then", ' fail "plant-D"', "fi"]), + ("E-count-capture", "residual", ['[ "$(grep -c needle haystack)" = "1" ] || fail "plant-E"']), + ("F-extract-capture", "residual", ['val="$(grep needle haystack)"']), + # G: a converted line that ALSO runs a raw grep verdict — the helper token + # must not absorb it (#985) + ("A-same-line", "residual", ['has_match -q needle "$F" && grep -q SECRET "$F" && fail "plant-G"']), + # H: negative control — helper whose PATTERN argument is the word grep; + # must be absorbed as a note, never residual + ("A-same-line", "note", ['has_match -q "grep" haystack || fail "plant-H"']), ] @@ -215,22 +252,20 @@ def cmd_sweep(): # leg 1: real suites at the current tree must be residual-free for f in suite_files(art): - lines = (WAKE / f).read_text().split("\n") - sites, _dispo = classify(lines) - residual = [] - for ln, form, text in sites: - if RX_HELPER.search(lines[ln - 1]): - # converted line whose PATTERN argument contains the word grep: - # not an unconverted site, but never silently absorbed either - print(f"SWEEP-NOTE {f}:{ln} converted line matches grep-token ({form}): {text[:80]}") - continue - residual.append((ln, form, text)) + residual, notes, _dispo = residual_sites((WAKE / f).read_text().split("\n")) + for ln, form, text in notes: + # converted line whose PATTERN argument contains the word grep: + # not an unconverted site, but never silently absorbed either + print(f"SWEEP-NOTE {f}:{ln} converted line matches grep-token ({form}): {text[:80]}") for ln, form, text in residual: print(f"SWEEP-RESIDUAL {f}:{ln} {form}: {text[:100]}") bad += 1 print(f"SWEEP {f}: {len(residual)} residual verdict site(s)") - # leg 2, SAME RUN: the instrument must find six per-form plants + # leg 2, SAME RUN, SAME PATH as leg 1: the instrument must find every plant + # with the right form AND the right absorb disposition — plants G/H exercise + # the absorb branch itself, so this leg must go through residual_sites(), + # not raw classify() donor = suite_files(art)[0] with tempfile.TemporaryDirectory() as td: planted = Path(td) / donor @@ -238,25 +273,28 @@ def cmd_sweep(): base_lines = planted.read_text().split("\n") offset = len(base_lines) expect = {} - for form, snippet in PLANTS: - expect[offset + 1] = form # first physical line of each plant + for form, dispo, snippet in PLANTS: + expect[offset + 1] = (form, dispo) # first physical line of each plant base_lines.extend(snippet) offset = len(base_lines) planted.write_text("\n".join(base_lines)) - sites, _ = classify(planted.read_text().split("\n")) - found = {ln: form for ln, form, _t in sites if ln in expect} - unexpected = [(ln, form) for ln, form, _t in sites if ln not in expect] - hits = sum(1 for ln, form in expect.items() if found.get(ln) == form) - print(f"SWEEP-PLANTS found={hits}/6 in planted copy of {donor}") - if hits != 6: - for ln, form in sorted(expect.items()): - got = found.get(ln, "") - if got != form: - print(f"SWEEP-PLANT-MISS line {ln}: expected {form}, got {got}") + residual, notes, _ = residual_sites(planted.read_text().split("\n")) + found = {ln: (form, "residual") for ln, form, _t in residual} + found.update({ln: (form, "note") for ln, form, _t in notes}) + unexpected = [(ln, form) for ln, form, _t in residual if ln not in expect] + hits = sum(1 for ln, want in expect.items() if found.get(ln) == want) + n_plants = len(PLANTS) + print(f"SWEEP-PLANTS found={hits}/{n_plants} in planted copy of {donor}") + if hits != n_plants: + for ln, want in sorted(expect.items()): + got = found.get(ln, ("", "")) + if got != want: + print(f"SWEEP-PLANT-MISS line {ln}: expected {want}, got {got}") bad += 1 if unexpected: - # the donor is a converted suite: any non-plant site the sweep finds - # in the copy contradicts the zero it just reported on the original + # the donor is a converted suite: any non-plant RESIDUAL site in the + # copy contradicts the zero leg 1 just reported on the original + # (non-plant notes mirror leg 1's treatment: printed there, not bad) for ln, form in unexpected: print(f"SWEEP-PLANT-UNEXPECTED {donor}(copy):{ln} {form}") bad += 1 diff --git a/packages/mosaic/framework/tools/wake/validate-973/unexecuted-sites-dispositions.txt b/packages/mosaic/framework/tools/wake/validate-973/unexecuted-sites-dispositions.txt index c2a0ba0b..aee395f4 100644 --- a/packages/mosaic/framework/tools/wake/validate-973/unexecuted-sites-dispositions.txt +++ b/packages/mosaic/framework/tools/wake/validate-973/unexecuted-sites-dispositions.txt @@ -26,12 +26,12 @@ # # Verified guard per site (line numbers at branch tip, +3 header shift): -count_lines test-wake-beacon.sh:350 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 349; template execution measured by microtest C11; text verified by static inventory -count_lines test-wake-detector.sh:702 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 701; template execution measured by microtest C11; text verified by static inventory -count_lines test-wake-digest-hmac.sh:434 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 433; template execution measured by microtest C11; text verified by static inventory -count_lines test-wake-digest-quarantine.sh:584 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 583; template execution measured by microtest C11; text verified by static inventory -count_lines test-wake-fn-oracle.sh:132 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 131; template execution measured by microtest C11; text verified by static inventory -count_lines test-wake-install.sh:434 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 433; template execution measured by microtest C11; text verified by static inventory -count_lines test-wake-reconcile.sh:389 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 388; template execution measured by microtest C11; text verified by static inventory -count_lines test-wake-store-ack.sh:741 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 740; template execution measured by microtest C11; text verified by static inventory -count_lines test-wake-store-enqueue-race.sh:208 — red-path summary (with "#927 TOCTOU reproduced (RED)" tail); guard `[ -s "$FAILFILE" ]` at line 207; template execution measured by microtest C11; text verified by static inventory +count_lines test-wake-beacon.sh:354 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 353; template execution measured by microtest C11; text verified by static inventory +count_lines test-wake-detector.sh:706 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 705; template execution measured by microtest C11; text verified by static inventory +count_lines test-wake-digest-hmac.sh:438 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 437; template execution measured by microtest C11; text verified by static inventory +count_lines test-wake-digest-quarantine.sh:588 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 587; template execution measured by microtest C11; text verified by static inventory +count_lines test-wake-fn-oracle.sh:136 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 135; template execution measured by microtest C11; text verified by static inventory +count_lines test-wake-install.sh:438 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 437; template execution measured by microtest C11; text verified by static inventory +count_lines test-wake-reconcile.sh:393 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 392; template execution measured by microtest C11; text verified by static inventory +count_lines test-wake-store-ack.sh:745 — red-path summary; guard `[ -s "$FAILFILE" ]` at line 744; template execution measured by microtest C11; text verified by static inventory +count_lines test-wake-store-enqueue-race.sh:212 — red-path summary (with "#927 TOCTOU reproduced (RED)" tail); guard `[ -s "$FAILFILE" ]` at line 211; template execution measured by microtest C11; text verified by static inventory diff --git a/packages/mosaic/framework/tools/wake/validate-973/validate-973.sh b/packages/mosaic/framework/tools/wake/validate-973/validate-973.sh index f6e473e7..177f535a 100755 --- a/packages/mosaic/framework/tools/wake/validate-973/validate-973.sh +++ b/packages/mosaic/framework/tools/wake/validate-973/validate-973.sh @@ -4,8 +4,8 @@ # # 0. instrument self-test (microtest) — no validate evidence is trusted # before the instrument itself has been proven, including its abort arms. -# 1. expected set: 261 coordinates from the FROZEN artifact (+3 header -# shift), count asserted against the number declared below BEFORE any +# 1. expected set: 261 coordinates from the FROZEN artifact (+7 header +# shift: 3 converter lines + 4 #984 guard lines), count asserted against the number declared below BEFORE any # suite runs. # 2. static inventory: converted call sites re-derived from SOURCE TEXT, # must equal the expected set exactly (amendment ONE, leg 1 — the @@ -33,7 +33,8 @@ # site's ledger row must already be present (the append lands before the # grep). # 6. residual sweep: the denominator's own classifier finds zero unconverted -# verdict greps in the suites — and six per-form plants in the same run. +# verdict greps in the suites — and eight plants (six per-form + two +# absorb-branch probes, #985) in the same run. # # Output discipline (A10): every line that reports on a suite names the file # under test; exit codes are reported before failure counts. @@ -180,8 +181,15 @@ while read -r helper site form; do bad="$bad no-ARMED-line" printf '%s\n' "$out" | grep -q "WAKE-ASSERT ABORT: ${helper} at ${site}: grep exit" || bad="$bad no-ABORT-line" - printf '%s\n' "$out" | grep -Eq "$(sentinel_for "$f")" && - bad="$bad sentinel-emitted" + # AND-polarity check (a match is the defect): a grep error (rc>=2) must be + # its own loud arm — it cannot fall through as "no sentinel = pass". + rc_sent=0 + printf '%s\n' "$out" | grep -Eq "$(sentinel_for "$f")" || rc_sent=$? + case "$rc_sent" in + 0) bad="$bad sentinel-emitted" ;; + 1) : ;; + *) bad="$bad sentinel-grep-error-rc=$rc_sent" ;; + esac grep -q "^${helper} ${site}\$" "$aled" || bad="$bad no-ledger-row" if [ -z "$bad" ]; then -- 2.54.0 From d3df293382c1264cf5f1c2c80f001cc4fb061af2 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Fri, 31 Jul 2026 05:04:21 -0500 Subject: [PATCH 2/2] =?UTF-8?q?docs(wake):=20arms=20docstring=20entry=20+3?= =?UTF-8?q?=20->=20+7=20=E2=80=94=20the=20one=20word=20review=20finding=20?= =?UTF-8?q?on=20PR=201001?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The arms paragraph still described its output as ": " while the same paragraph's own examples (733->740, 560->567) and the tool's actual output already said +7. Docstring-only; zero behavior change. Written-by: pepper (sb-it-1-dt) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB --- packages/mosaic/framework/tools/wake/validate-973/check-973.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/mosaic/framework/tools/wake/validate-973/check-973.py b/packages/mosaic/framework/tools/wake/validate-973/check-973.py index db396758..5110cde7 100755 --- a/packages/mosaic/framework/tools/wake/validate-973/check-973.py +++ b/packages/mosaic/framework/tools/wake/validate-973/check-973.py @@ -26,7 +26,7 @@ Subcommands (all print sorted, stable output; non-zero exit on any failure): arms The forced-error arm list: the 19 denominator canaries plus one E-form arm (store-ack:733→740, a $(count_lines) capture compared afterward — the A6 shape) plus one F-form arm (quarantine:560→567, - the multi-grep pipeline capture), as " : + the multi-grep pipeline capture), as " : ". Both extras are asserted to exist in the artifact with the expected form — a renumber that moved them fails here, not silently downstream. -- 2.54.0