From 832cbcdf91d4f739b33677b7b597cead8438ee5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20T=C3=B6rcsv=C3=A1ri?= Date: Wed, 5 Aug 2026 21:16:18 +0200 Subject: [PATCH] design-b D0: record the audit + red pin in docs 19/20/21 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doc 19: status DIAGNOSED -> DIAGNOSED + PINNED RED; the repro section leads with the automated deterministic spec (the manual Leonardo flow stays as the field repro). Doc 20: D0 work-log entry; status D-1 + D0 done; next = D1. Doc 21: red-spec section updated to "landed", with the staging test's anti-vacuity role. Carried finding: the strand reproduces on a 2-OBJECT fixture schematic, so warm-load byte volume (the 68/1 dice-loader) is not an ingredient — two concurrent parks suffice. That is why D3 closes this class and D5 is not required for it. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01TEHGiiXMShNXbBr7gSJ7iz --- .../async/19-quasimodal-fiber-strand.md | 21 +++++++++++--- docs/features/async/20-design-b-core-plan.md | 29 +++++++++++++++++-- docs/features/async/21-park-site-audit.md | 20 +++++++++---- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/docs/features/async/19-quasimodal-fiber-strand.md b/docs/features/async/19-quasimodal-fiber-strand.md index 2cba165..7b9c044 100644 --- a/docs/features/async/19-quasimodal-fiber-strand.md +++ b/docs/features/async/19-quasimodal-fiber-strand.md @@ -1,14 +1,27 @@ # 19 — Symbol Properties dialog hangs: a stranded tool fiber (live investigation) -> **Status: DIAGNOSED, NOT FIXED (2026-08-05).** Reproduced end-to-end in a real browser -> against the dev platform on the scheduler build. Regression-vs-pre-existing is **not yet +> **Status: DIAGNOSED + PINNED RED, NOT FIXED (2026-08-05).** Reproduced end-to-end in a +> real browser against the dev platform on the scheduler build, and since D0 also +> **deterministically in e2e**: `tests/kicad/quasimodal-strand.spec.ts` (6/6 identical — +> `closed=false dialogs=1 refused-resumes=1`). The fix lands at doc 20 **D3**, where that +> spec's `test.fail()` marker comes off. Regression-vs-pre-existing is **not yet > determined** — see §5. Related: [`17`](17-mailbox-scheduler-plan.md) S4 (waits), > [`16`](16-fiber-resume-guard.md) (the quarantine guard), the 8/4 three-UI-bugs triage > (which blamed the interlock drain — that is the *symptom layer*, not the proximate cause). -## 1. Repro (100%, ~40 s) +## 1. Repro -Dev platform (`npm run dev`), editor at `:3048`, Arduino Leonardo schematic: +**Automated (D0, ~30 s, deterministic):** +`npx playwright test --project=kicad-firefox kicad/quasimodal-strand.spec.ts`. The +"staging" test proves the window is real (dialog open + timer fired + concurrent-park +beacons); the "doc-19 red" test clicks OK and records the hang. The overlap is +structural, not a race: the parking timer (`wasm/bindings/timer_park.h`) is armed +*after* the dialog is confirmed open, so it necessarily parks on top of the opener's +open-ended fiber park. Note the strand reproduces on a **2-object fixture schematic** — +Leonardo's byte volume is not an ingredient, only concurrent parks are. + +**Manual (100%, ~40 s):** dev platform (`npm run dev`), editor at `:3048`, Arduino +Leonardo schematic: 1. Open the project URL, wait for load (~30 s). 2. Double-click the USB receptacle (J1) → **Symbol Properties** opens. diff --git a/docs/features/async/20-design-b-core-plan.md b/docs/features/async/20-design-b-core-plan.md index d212414..88eb8d4 100644 --- a/docs/features/async/20-design-b-core-plan.md +++ b/docs/features/async/20-design-b-core-plan.md @@ -1,6 +1,6 @@ # 20 — Design B core: parkable activities as scheduler contexts -> **Status: IN PROGRESS — D-1 DONE (2026-08-05, work log §10).** The remaining core of +> **Status: IN PROGRESS — D-1 + D0 DONE (2026-08-05, work log §10).** The remaining core of > Design B ([`06`](06-design-b-fiber-first-runtime.md) B1+B2), scoped against what S0–S6 > actually built ([`17`](17-mailbox-scheduler-plan.md)) and motivated by the > stranded-fiber hang ([`19`](19-quasimodal-fiber-strand.md)). Supersedes doc 12's @@ -218,4 +218,29 @@ occ-probe `glb` case (known-unrelated, predates D-1). Vestigial `startModal` scr from `ASYNCIFY_IMPORTS` (Makefile.wasm) and `asyncify-imports.txt` post-gate. Consequence: every later phase is single-path — one code path per park site, one glue -per build, one battery per gate. Next: **D0** (park-site audit + the doc-19 red spec). +per build, one battery per gate. + +### D0 — park-site audit + red spec (2026-08-05) ✅ + +- **Audit** → [`21`](21-park-site-audit.md) (pcbjam `d4b25a0`): 14 production park sites + (8 wx, 9 KiCad/bridge) + 3 deliberate test levers, each classified fiber / + entry-stack / main-loop with its routing phase. W1 `wxWasmYieldUntilJs` and W3 popup → + D3; the clipboard/font/lib/3D/occ/ngspice/nanosleep bridges → D4; W2's per-frame yield + stays safe-by-construction unless D5 is taken. Doc 20 risk 4 (pthreads) settled: all + Asyncify parks are main-thread-only; the lib bridge's worker path is a blocking + proxy, not a park, so contexts stay a main-thread concept. +- **Red spec** → `tests/kicad/quasimodal-strand.spec.ts` (pcbjam `6ab0843`): a GREEN + "staging" test (the window is real) plus the `test.fail()` doc-19 pin (OK must close + the dialog). 6/6 identical: `closed=false dialogs=1 refused-resumes=1`. The overlap is + structural — the parking timer is armed *after* the dialog opens, on top of the + opener's open-ended fiber park. +- **Finding worth carrying into D1:** the strand reproduces on a **2-object fixture + schematic**. Byte volume (the doc-17/gal-refresh dice-loader) is NOT an ingredient + here; two concurrent parks suffice. That makes the doc-19 class strictly easier to + hit than the 68/1 warm-load family, and it is why D3 — not D5 — is the phase that + closes it. +- Retired `tests/kicad/dialog-deadlock-probe.spec.ts` (the 8/4 throwaway probe, and the + tree's only determinism-lint violations). + +Next: **D1** — context primitives on libcontext, exercised by a dedicated test app, no +production path switched, with the context-count/peak-RSS gate doc 20 §7 risk 1 asks for. diff --git a/docs/features/async/21-park-site-audit.md b/docs/features/async/21-park-site-audit.md index 6e536f2..282cb89 100644 --- a/docs/features/async/21-park-site-audit.md +++ b/docs/features/async/21-park-site-audit.md @@ -87,9 +87,17 @@ belongs in the scheduler shim (it already owns `Fibers` bookkeeping and the ## 4. Red spec (the other D0 deliverable) -The doc-19 strand lands as `tests/kicad/quasimodal-strand.spec.ts`: open a schematic, -double-click a symbol → Symbol Properties (quasi-modal on a tool fiber = W1's fiber -lane), click OK → the dialog must close and dispatch must stay live. RED today by the -doc-19 mechanism; goes green at D3. Marked `test.fail()` so the battery stays runnable -while red — when D3 lands, Playwright flags "expected to fail but passed", forcing the -flip to a plain green pin. +**Landed** as `tests/kicad/quasimodal-strand.spec.ts` (pcbjam `6ab0843`): open a +schematic, double-click a symbol → Symbol Properties (quasi-modal on a tool fiber = +W1's fiber lane), arm the parking timer *while the dialog is up* (so its park lands on +top of the opener's open-ended park — structural overlap, not a race), click OK → the +dialog must close and the wait books must balance. RED today by the doc-19 mechanism, +6/6 identical (`closed=false dialogs=1 refused-resumes=1`); goes green at D3. Marked +`test.fail()` so the battery stays runnable while red — when D3 lands, Playwright flags +"expected to fail but passed", forcing the flip to a plain green pin. A separate GREEN +"staging" test asserts the window is real, so the pin cannot rot into vacuity. + +**Audit consequence recorded there:** the strand reproduces on a 2-object fixture — the +warm-load byte volume that dice-loads the 68/1 family is not an ingredient. Two +concurrent parks suffice, which is why D3 (waits on contexts) closes this class and D5 +(main as a context) is not required for it.