From 087cd5a54b0799452cfef5ad2343cd6e339134d3 Mon Sep 17 00:00:00 2001 From: Danilo Campos Date: Thu, 25 Jun 2026 14:58:00 -0400 Subject: [PATCH 1/3] DIAGNOSTIC: harness dumps captured oracle output; full-mode CI to reproduce MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds captured-output dumping to the mutation harness for VACUOUS/INVALID verdicts (the black box that made the first re-land's CI failure un-diagnosable), and re-adds the CI step in temporary full-mode-on-every-event so a PR reproduces the push-to-main failure with that output visible. Not a keeper — once the 7x-pool-boot incompatibility is understood, this reverts to the gated form. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 7 +++++++ mnemion-js/scripts/invariant-mutation-probe.py | 11 ++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70c0357..7a6014d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,6 +103,13 @@ jobs: - name: Test run: npm test + # DIAGNOSTIC (temporary): full-mode mutation ratchet on every event so the PR + # reproduces the push-to-main failure with the harness's new captured-output + # dump. Once the 7x-pool-boot incompatibility is understood + fixed, this + # reverts to the gated form (PR=--changed, main=full). + - name: Boundary oracle mutation ratchet (DIAGNOSTIC full-mode) + run: python3 scripts/invariant-mutation-probe.py + # Ratchets: no new conventions, no new raw SQL interpolation sites, and the # trust atlas stays in sync with the boundary claims (no managed chokepoint # left off the atlas, no dangling edge). diff --git a/mnemion-js/scripts/invariant-mutation-probe.py b/mnemion-js/scripts/invariant-mutation-probe.py index fde4821..3aeb7ca 100755 --- a/mnemion-js/scripts/invariant-mutation-probe.py +++ b/mnemion-js/scripts/invariant-mutation-probe.py @@ -121,7 +121,7 @@ def restore(): for f in {e[0] for e in RUN}: sh(["git","checkout","--",f]) -results=[]; notes=[] +results=[]; notes=[]; diaglogs=[] try: print(f"{'BOUNDARY (oracle)':<48} VERDICT") print(f"{'-'*48} -------") @@ -145,12 +145,21 @@ def restore(): v="INVALID"; mark="~ INVALID (no compile / inconclusive)" print(f"{label:<48} {mark}"); results.append((label,v)) if v=="SHADOWED" and shadow: notes.append((label,shadow)) + # Diagnosability: dump the captured oracle output for any verdict that means + # "the harness could not confirm this oracle is semantic" — without it an + # INVALID/VACUOUS in CI is a black box (the lesson from the first re-land). + if v in ("VACUOUS","INVALID"): + tail="\n".join((log or "").splitlines()[-40:]) + diaglogs.append((label,v,tail)) finally: restore() for label,note in notes: print(f"\n note [{label}]:\n {note}") +for label,v,tail in diaglogs: + print(f"\n----- captured oracle output [{label}] ({v}) — last 40 lines -----\n{tail}") + a=sum(1 for _,v in results if v=="ANCHORED"); vc=sum(1 for _,v in results if v=="VACUOUS") iv=sum(1 for _,v in results if v=="INVALID"); sh_=sum(1 for _,v in results if v=="SHADOWED") sk=sum(1 for _,v in results if v=="SKIP") From f8ff381471343f4b5114027ef2df8a1aab5a7a62 Mon Sep 17 00:00:00 2001 From: Danilo Campos Date: Thu, 25 Jun 2026 15:03:28 -0400 Subject: [PATCH 2/3] Fix the real CI failure: ANSI codes broke the ANCHORED matcher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The diagnostic dump proved the mutations DID work in CI — the oracles caught every break (context-capability AssertionError "expected undefined to be true"; sql-ident "expected [Function] to throw"). The harness misread its own output: CI forces ANSI color, which interleaves escape codes into vitest's summary ("Tests \x1b[..m1 failed"), so the `Tests \d+ failed` regex missed and every ANCHORED edge was misfiled INVALID. The 7x-pool-boot theory was wrong; all boots ran fine. Fix: run vitest with NO_COLOR/FORCE_COLOR=0, strip ANSI before matching, and detect ANCHORED via any of vitest's failure markers (summary line, "Failed Tests N", or a "FAIL …​.test." line) rather than one brittle pattern. Co-Authored-By: Claude Opus 4.8 (1M context) --- mnemion-js/scripts/invariant-mutation-probe.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/mnemion-js/scripts/invariant-mutation-probe.py b/mnemion-js/scripts/invariant-mutation-probe.py index 3aeb7ca..6e86c11 100755 --- a/mnemion-js/scripts/invariant-mutation-probe.py +++ b/mnemion-js/scripts/invariant-mutation-probe.py @@ -131,15 +131,24 @@ def restore(): if match not in src: print(f"{label:<48} SKIP (match drifted)"); results.append((label,"SKIP")); continue open(path,"w").write(src.replace(match,repl,1)) - r=sh(["npx","vitest","run",oracle]) + # NO_COLOR: keep vitest output plain. CI forces ANSI, which interleaves + # escape codes INTO the summary ("Tests \x1b[..m1 failed") and broke the + # ANCHORED match on the first CI run — the tests DID catch the mutation, the + # harness just couldn't read its own output. Belt: strip ANSI before matching. + r=sh(["npx","vitest","run",oracle], env={**os.environ,"NO_COLOR":"1","FORCE_COLOR":"0"}) sh(["git","checkout","--",f]) # revert immediately - log=r.stdout+r.stderr + log=re.sub(r"\x1b\[[0-9;]*m","",r.stdout+r.stderr) + # ANCHORED = the oracle RAN and an assertion FAILED (any of vitest's failure + # markers), as opposed to erroring before running (INVALID). + ran_and_failed = (re.search(r"Tests\s+\d+\s+failed", log) + or re.search(r"Failed Tests\s+\d+", log) + or re.search(r"\bFAIL\b.*\.test\.", log)) if r.returncode==0: if shadow: v="SHADOWED"; mark="o SHADOWED (expected — chokepoint not operative in test runtime)" else: v="VACUOUS"; mark="x VACUOUS (oracle missed the break — CONFIRM not shadowed)" - elif re.search(r"Tests\s+\d+\s+failed", log): + elif ran_and_failed: v="ANCHORED"; mark="+ ANCHORED" else: v="INVALID"; mark="~ INVALID (no compile / inconclusive)" From 09ef7b39d3e846796f9738a8a678268aff9ed89e Mon Sep 17 00:00:00 2001 From: Danilo Campos Date: Thu, 25 Jun 2026 15:07:04 -0400 Subject: [PATCH 3/3] Re-gate the mutation ratchet: PR=--changed, main=full MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full-mode now verified green in CI (prior commit's diagnostic run: 6 anchored, 1 shadowed, 0 invalid). Switch the step from diagnostic full-mode-on-every-event back to the intended gated form: incremental on PRs, full backstop on push to main. Keep the captured-output dump — it's what made this fixable. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a6014d..ede8849 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,12 +103,24 @@ jobs: - name: Test run: npm test - # DIAGNOSTIC (temporary): full-mode mutation ratchet on every event so the PR - # reproduces the push-to-main failure with the harness's new captured-output - # dump. Once the 7x-pool-boot incompatibility is understood + fixed, this - # reverts to the gated form (PR=--changed, main=full). - - name: Boundary oracle mutation ratchet (DIAGNOSTIC full-mode) - run: python3 scripts/invariant-mutation-probe.py + # Boundary-oracle mutation ratchet: a totality oracle only protects the system + # if it actually CATCHES a break at its chokepoint. This breaks each boundary's + # chokepoint with a compile-safe mutation and requires its oracle to fail + # (ANCHORED); an oracle that stays green under a broken floor (VACUOUS) — the + # rot that let the trust-split oracle pass a literal inversion before #14 + # hardened it — fails the gate. PR runs only edges whose chokepoint/oracle + # changed (incremental); push to main runs the full backstop. (Full-mode in CI + # verified on this branch's diagnostic run.) python3 is preinstalled on + # ubuntu-latest; the harness reverts every mutation via git. + - name: Boundary oracle mutation ratchet + if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main' + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + git fetch --no-tags --depth=1 origin "${{ github.event.pull_request.base.ref }}" + python3 scripts/invariant-mutation-probe.py --changed FETCH_HEAD + else + python3 scripts/invariant-mutation-probe.py + fi # Ratchets: no new conventions, no new raw SQL interpolation sites, and the # trust atlas stays in sync with the boundary claims (no managed chokepoint