New doc 16: the full repro-suite map (per-bug unit/e2e paths with verified failure sites), the phase-C probe outcome, and four findings only the RUNNING system revealed: - F1: bug 03's sending half emits NOTHING — a child-only delete commit never triggers a flush at all (worse than the doc's predicted bare removed-wire); the GetWidth-assert tracer evidence and the fix implication. - F2: Firefox cannot host two kicad_editor tabs in one context (per-process wasm budget) — bug-01 two-tab repros are Chromium-only. - F3: headless emit WORKS on both pcbnew and eeschema — the legacy two-tab skip rationale and items-bridge localEdit omissions are stale. - F4: drift-detect is strictly ITEM-silent on the green path (no writer- formatting false positives). Cross-updates: 00 index + verdict note; 01/04/05/06/07 Verification sections gain their repro paths; 02 upgraded to runtime-CONFIRMED; 03 gains the F1 empirical correction; 11 (no v2 e2e coverage) CLOSED with a point-by-point status update — only the legacy retirement remains. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DPfrVhfYgPPgtawjSssZfn
3.6 KiB
Design miss 10 — Drift is detected and reported, never repaired; saves and the room can diverge with the room winning
Severity: design gap (turns every other bug from "transient" into "permanent") Status: open decision
Where
web/standalone/src/wasm/collab/drift-detect.ts— computes the exact editor↔doc delta (docDelta(ydocDoc, wasmDoc)+layoutChanged/metaChanged) every N doc updates and atbeforeunload, then…reportDrift()(telemetry) onlyweb/standalone/src/wasm/save-flow.ts+WasmTool.tsx:553,795—onSaveroutes the saved bytes to the API/local disk; it does not reconcile the saved state into the Y.Docweb/standalone/src/components/WasmTool.tsx:248-289— ydoc-mode open prefers the room (docToFile(yToDoc(doc))) over the API copy whenever the room has state
The two halves
1. No self-heal. Every divergence source in this review — apply failures (blob
parse errors are logged and skipped), the projection gaps
(04), swallowed cleanup
(05), skipped child removals
(03) — ends as a drift report and stays
diverged for the rest of the session. The ironic part: computeDrift already holds
the exact repair payload. docDelta(ydocDoc, wasmDoc) is the delta that would make
the doc match the editor; applying it via applyDeltaToY (tagged with the local
origin) is precisely what the DOWN path does for normal edits.
2. Save vs room divergence, room wins. The editor's Save writes the true model (including everything the sync missed) to the API. The room is a separate store. On the next ydoc-mode open, the room is preferred — so edits that drifted but were correctly saved get silently dropped in favor of the stale doc. The author loses work they explicitly saved. (When materialization fails — e.g. bug 03's dangling slot — the API fallback accidentally preserves data better than the healthy path.)
Fix directions
- Self-heal from the drift check (cheap, high leverage). When
computeDriftfinds an item-level diff, don't just report — applybody.diffinto the Y.Doc as a local-origin transaction (editor is the source of truth for local drift by definition: the wasm model is what the user sees). Guardrails:- only auto-apply the item diff; report-only for
layoutChanged/metaChangeduntil 08 is decided; - cap the auto-applied delta size (a huge diff means something structural broke — report and stop rather than bulk-rewrite the room);
- keep the report either way, flagged
repaired: true, so telemetry still shows the underlying bug frequency. This one change converts bugs 03/04/05's permanent divergence into a bounded lag (≤ N doc updates or session end).
- only auto-apply the item diff; report-only for
- Reconcile on save. The
onSavehook has the saved file text in MEMFS; run the samefileToDoc→docDelta→applyDeltaToYreconciliation there. Save is the user's explicit "this is the state I mean" signal — it's the natural sync barrier, and it fixes the save-vs-room precedence problem at the same time (after a save, the room equals the saved file, so "room wins on open" becomes harmless). - Precedence tie-break on open (defense in depth). ydoc-mode open could compare the API copy's mtime/content against the room and at least warn (or prefer the newer) when they disagree materially, instead of unconditionally trusting the room.
Recommendation: do 2 first (save is low-frequency, zero perf risk, biggest user-visible win), then 1 with the size cap.