From 8ed39a72a0d944745d0395b0ce42f2c45e2d60f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20T=C3=B6rcsv=C3=A1ri?= Date: Sat, 8 Aug 2026 23:11:51 +0200 Subject: [PATCH] THE FLIP: levers re-pinned to the post-migration invariant; all gates green incl. blue-screen repro 5/5 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Td4ujboGuAw26jvbDQzehj --- .../features/async/22-absorbing-libcontext.md | 57 +++++++++++++++++++ tests/kicad/quasimodal-strand.spec.ts | 22 ++++--- tests/kicad/timer-park-repro.spec.ts | 33 +++++++---- wxwidgets | 2 +- 4 files changed, 93 insertions(+), 21 deletions(-) diff --git a/docs/features/async/22-absorbing-libcontext.md b/docs/features/async/22-absorbing-libcontext.md index 5e86344..9de5290 100644 --- a/docs/features/async/22-absorbing-libcontext.md +++ b/docs/features/async/22-absorbing-libcontext.md @@ -1067,6 +1067,63 @@ exactly as its layout-sensitivity predicts; KiCad 139/1): data at D-on (and from queued-event flows); that is by design — it is flip telemetry. +### THE FLIP — LANDED (2026-08-08) ✅ + +`wxWASM_STAR_DISPATCH=1` permanently: dispatch contexts, context waits and star +transfers are the only runtime. Contents of the flip commit: the switch, the two +lever re-pins (below), and nothing else — every mechanism was already landed and +individually gated in the preceding increments. + +**Gate 1 — KiCad suite: 138 / 2 / 30, effectively the 139/1 baseline.** The 2: +pre-existing occ-probe, plus an `ngspice-probe` bg-run streaming test that passed +4/4 on a solo rerun (parallel-load flake, the known class). **Both re-pinned lever +specs are GREEN**, including `quasimodal-strand`'s doc-19 test. + +**Gate 2 — wx battery: 395 / 1 / 3 — the single red is pre-existing +`modal.spec.ts:125`.** §10's prediction ("these harnesses go green AT the flip") +held exactly: `coroutine-nested` case 3 on both engines and +`wakeup_during_transition` are green — the hot-main wake-window class is +structurally gone. + +**Gate 3 — the blue screen's own repro (§6's only-proof-that-matters): 5/5 PASS.** +Freshly seeded V1d ballast project (123 MB, `e2e-mskn52sh-1/v1d-flip-mskn5akd-2`), +`REPRO_PROFILE` persistent context, 1 cold + 4 warm loads, `REPRO_ASSERT=1`: +every run settled (29–38 s), **`rootHotTotal=0` on all five, zero trap +signatures, zero aliased-wake-live, zero refusals.** Pre-v0.1.28 this recipe +killed warm loads 2–4 with 100% reproduction. + +**The Phase E assertion HOLDS: `fiberStackParks=0` on every repro run** — across +five full board loads at the flip, no in-place Asyncify park ever began on a +fiber stack. `earlyWaitResolves=0` there too (the retention path is armed but a +prod-shaped load never needs it). No `[wx-wait]` high-water beacons during loads: +board-load lib requests run on the main stack (entry fallback) or on workers, so +no context ever parks under a wait during an open — consistent with the counter. + +**Lever re-pins (the Phase F decision, taken at the flip as doc §10 planned):** +`timer-park-repro` and `quasimodal-strand` staging flip their overlap asserts +from "the shim observed the concurrent-park window" (>0) to **"no concurrent-park +window is observable" (==0)** — the staged overlap required the main loop's +in-place park, which D5 removed; the specs now pin the invariant the migration +exists to establish. Evidence recorded in both spec headers. + +**Bounce decision (deviation from §5 Phase C's text, deliberate):** the doc-19 +mainstack bounce STAYS for now. It is empirically green at the flip (strand +doc-19 passes through it), and its removal drags `mainstack.h`, +`main_stack_runner.h` and KiCad's `RunOnMainStackIfActiveTool` with it — a +separate increment with its own gate, queued for Phase F alongside the guard +deletions. Removing it inside the flip commit would have violated the +one-variable rule that every measurement in this doc is built on. + +**Known-residual (named at the D-on probe, unchanged):** the awaited +`kicadOpenFile` embind entry still parks the MAIN stack in place during opens; +its overlap warnings are confined to the two specs that stage entries mid-load, +both green, and the repro proves the guards hold under real load. Candidate for +the same treatment as the bridges, or for retirement when Phase F deletes the +guards it leans on. Also noted during the repro: a cosmetic +`CanvasRenderingContext2D.arcTo: Negative radius` pageerror from the DOM +chrome's `drawRoundedRect` on warm loads — unrelated to the scheduler, worth its +own small fix. + ### Prod-provider smoke (2026-08-08) — done, with one pre-existing red bisected Against the live web stack (playwright-web config, reference backend :3060): diff --git a/tests/kicad/quasimodal-strand.spec.ts b/tests/kicad/quasimodal-strand.spec.ts index ee737b8..dd11c90 100644 --- a/tests/kicad/quasimodal-strand.spec.ts +++ b/tests/kicad/quasimodal-strand.spec.ts @@ -21,9 +21,10 @@ import { test, expect } from "./fixtures"; * * Two tests, deliberately split so the red pin cannot rot into vacuity: * - "staging" is a plain GREEN test: the dialog opens, the timer window - * engages (fired + parked + done), the shim observed the overlap. If this - * breaks, the harness is broken — loudly, not silently inside a - * test.fail() wrapper. + * engages (fired + parked + done). RE-PINNED AT THE FLIP (doc 22 §10, + * 2026-08-08): the overlap the shim used to observe is structurally + * impossible post-D5, so the assert now pins ZERO observable + * concurrent-park windows instead. * - "OK closes" is the RED pin, marked test.fail(): its assertions are the * desired end state (dialog closes, no refused-resume beacon, wait books * balanced). It goes green at D3 (waits become context yields), at which @@ -297,17 +298,22 @@ test.describe("quasi-modal strand (doc 19)", () => { expect(await dialogCount(page)).toBeGreaterThan(0); await okButtonCenter(page); - // The overlap actually reached the asyncify layer: the shim must have - // beaconed at least one concurrent-context event. Silence here means the - // two parks never coexisted and the red pin below proves nothing. + // RE-PINNED AT THE FLIP (docs/features/async/22 §10, 2026-08-08). The + // overlap this staging proved (a timer park on top of an open-ended park) + // required an in-place park for the timer to land on; post-flip every + // party is a scheduler context and D5 removed the main loop's in-place + // park, so the window is structurally impossible. The staging now pins + // the post-migration invariant: the dialog opens, the timer fires and its + // park survives (asserted above), and NO concurrent-park window is + // observable. const overlapBeacons = testLogger.consoleLogs.filter((l) => /\[wx-asyncify\] (concurrent-park|aliased-wake-live|overlapped-wake)/.test(l), ); console.log(`[STRAND] staging overlap beacons: ${overlapBeacons.length}`); expect( overlapBeacons.length, - "the shim observed concurrent asyncify contexts (the doc-19 window)", - ).toBeGreaterThan(0); + "no concurrent-park window is observable post-flip", + ).toBe(0); }); test("doc-19: OK resolves the quasi-modal wait and the dialog closes", async ({ diff --git a/tests/kicad/timer-park-repro.spec.ts b/tests/kicad/timer-park-repro.spec.ts index 4a07e98..3471d0c 100644 --- a/tests/kicad/timer-park-repro.spec.ts +++ b/tests/kicad/timer-park-repro.spec.ts @@ -28,9 +28,12 @@ import { expectGuardsSilent } from "./utils/guard-beacons"; * * The spec asserts the runtime SURVIVES every cycle — on a build where the * hypothesis holds this is deterministically RED, and after the real fix it - * is the regression gate. The `[wx-asyncify]` shim diagnostics must report - * the concurrent-park window engaging; that assert fails only if the lever - * itself never created the overlap (a broken repro, not a passing one). + * is the regression gate. + * + * RE-PINNED AT THE FLIP (docs/features/async/22 §10, 2026-08-08): the staged + * overlap needed the main loop's per-frame in-place park, which D5 removed. + * The final assert now pins ZERO observable concurrent-park windows — the + * post-migration invariant — instead of demanding the overlap engage. */ const SEG_TARGET = "fa220000-0000-0000-0000-00000000cafe"; @@ -328,15 +331,21 @@ test.describe("timer Notify() Asyncify-park during main-loop yield (concurrent c ); if (cLane) expectGuardsSilent(testLogger.consoleLogs, ["timerRetry"]); - // Window-engagement proof, independent of survival: the scheduler shim - // must have SEEN the concurrent parks (its reporting is new — silence here - // means the lever never created the overlap and the repro is vacuous). - const shimLines = testLogger.consoleLogs.filter((l) => l.includes("[wx-asyncify]")); - console.log(`[TEST] shim diagnostics: ${shimLines.length} line(s)`); - for (const l of shimLines.slice(0, 10)) console.log(`[TEST] ${l}`); + // RE-PINNED AT THE FLIP (docs/features/async/22 §10, 2026-08-08). This + // lever staged "timer park × MAIN-LOOP YIELD PARK", and D5 removed the + // main loop's per-frame in-place park — the overlap is structurally + // impossible now, so "the shim observed the window" (>0) can never pass + // again. The pin flips to the invariant the migration exists to + // establish: the lever runs, the park survives (asserted above), and NO + // concurrent-park window is observable at all. + const overlapLines = testLogger.consoleLogs.filter((l) => + /\[wx-asyncify\] (concurrent-park|aliased-wake-live|overlapped-wake)/.test(l), + ); + console.log(`[TEST] overlap beacons: ${overlapLines.length} line(s)`); + for (const l of overlapLines.slice(0, 10)) console.log(`[TEST] ${l}`); expect( - shimLines.length, - "scheduler shim observed the concurrent-park window", - ).toBeGreaterThan(0); + overlapLines.length, + "no concurrent-park window is observable post-flip", + ).toBe(0); }); }); diff --git a/wxwidgets b/wxwidgets index a1b8550..f7b49cf 160000 --- a/wxwidgets +++ b/wxwidgets @@ -1 +1 @@ -Subproject commit a1b85501fbb4613e7bb71f4ca147b82120d32d0b +Subproject commit f7b49cfdd7ee6b4ecb0839884f9e6682a861b79b