Doc 20 gets a status table instead of a narrative: D-1/D0/D1 done, D2
reverted, D3's goal met but its MEANS skipped (waits still park in
place — only the stack they park on changed), D4/D5/D6 not started. Plus
an explicit "what was skipped and is still owed" list, so nothing quietly
reads as delivered: dispatch contexts, waits-as-yields, bridges,
real-park-site buffer sizing, the both-EH CI matrix.
Doc 22 is the handoff plan a fresh session can implement from:
- the bug it targets is the BLUE SCREEN (a context recovered twice or by
the wrong fiber), not doc 19's hang, which is fixed and was only one
ingredient;
- the diagnosis that matters: bookkeeping is already centralised
(currData is single-writer, the shim sees every swap) but the DECISION
is not — libcontext decides swaps and never tells anyone, so three
layers each invented heuristics. Centralising means moving the
decision;
- why D2/D3 knotted, with the measurements, so nobody retries that order;
- phases A-F with estimates (~4-6 wk): A absorbs libcontext behaviour-
preservingly and is landable ALONE (the de-risking step D2 never had),
B+C+D must land as one commit, E bridges, F deletes the guards only
once they are provably silent;
- gates including the crash's own repro, since the batteries never
reproduced it and therefore cannot certify it;
- the traps this run paid for: 16-byte fiber stack alignment, the
per-fiber stack-limits gotcha, host-side asyncify buffers, the
stack-ownership rule, partial migration, and the gitignored-artifact
triage trick;
- measured build/test cycle costs, so the estimates are grounded.
README: index rows for 21 and 22, doc 19 marked FIXED, and the stale
2026-06 "single decisive next step" folded away behind the current one.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TEHGiiXMShNXbBr7gSJ7iz
Doc 20: the remaining core of Design B, scoped against what S0-S6 built
and motivated by the doc-19 hang. Core rule: nothing parks in place —
every suspendable activity yields its own context, so a context's state
is authoritative and the guessing layer (quarantine, consume-once,
libcontext refusals, dispatch interlock) gets deleted rather than
tuned. Phases D0-D6 with gates, 6-10 wk; memory/partial-migration/
pthread risks called out; index updated.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfxKn5utcntBSnxz4ZnYKs
Doc 17: Design B phasing revised with the July-August guard record.
Test inventory with per-test fate (keep / rewrite / retire / new),
steps S0-S6 with gates and rollback, ~5-7 wk.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TfxKn5utcntBSnxz4ZnYKs
Submodule pointer bump for the wxMenuBar dangling-child fix that resolved the 18 DOM-port kicad e2e failures. Also adds the async-debug dossier (docs/features/async/08-10) root-causing the 'indirect call to null' / 'signature mismatch' family to the menu-bar use-after-free, and folds the asyncify harness into 'npm test' (new test:wx for wx-only); tests/README + WHATWORKS updated to match.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The asyncify single-slot work, executed red-green (full ledger:
docs/features/asyncify-arbiter/redgreen.md; decisions record:
docs/features/async/07-decisions-and-outcome.md):
- tests/apps/standalone/asyncify-races/ + tests/asyncify/ + dedicated
playwright config: 8 scenarios reproducing the KiCad asyncify failure
family with the kicad-faithful startup topology (pre-park fiber swap →
park throw through the live trampoline). Built in 3 variants; the
SHIM_DISABLE_TRAMPOLINE_HEAL / SHIM_DISABLE_HANDLESLEEP ablation builds
keep the historical hang and index-out-of-bounds crash reproducible
forever (mutation-style pins for the existing shims).
- scripts/common/shims/handlesleep.js: catch the "unwind" park sentinel
in the wakeUp path — when main's last pre-park suspension was a sleep,
the main-loop park throw escaped through that sleep's promise reaction
as an uncaught rejection (the calculator/gerbview console errors).
- scripts/common/inject-dyncall-shims.sh: SHIM_DISABLE_* ablation knobs.
- Spec tightening (the acceptance bar): 'uncaught exception: unwind'
tolerance DELETED from pcbnew/eeschema specs; load-pcb gained a hard
clean-console gate over 5 asyncify corruption signatures.
- wxwidgets pointer bump: modal LIFO resolvers, pump resolve-on-error,
sync clipboard IsSupported (014f67e6c1).
Final state: asyncify suite 7/7, wx e2e 291/292 (1 skip), KiCad e2e 40
passed / 2 skipped with ZERO corruption signatures in any log across all
six apps.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two research dossiers under docs/features:
- async/: Asyncify currData contention — the clipboard crash and post-idle
tool hang as one disease (single global suspension slot, three producers),
asyncify internals walkthroughs, prior art, arbiter designs A/B.
- wasm-exceptions/: -fexceptions vs -fwasm-exceptions — measured invoke-driven
share of the asyncify tax on pcbnew (59% raw / 64% gzip; download 64.5->36 MB
if migrated), KiCad dialog-in-catch audit (85 direct / 93 review of 636,
catch_audit.py included), binaryen toolchain status (partial EH support since
v125; TryTable unsupported), and a catch-arm-hoisting pre-pass design that
would obsolete the KiCad-side refactor. Cross-linked with the parked
KICAD_WASM_EH end-to-end experiment (docs/wasm-exceptions-experiment.md).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>