Miss 08A: the binding stores wire-carried (lib_symbols …) definitions in kdoc_libsymbols and prefixes them on apply wires — a joiner that never saw a symbol adopts it WITH its definition (new e2e ysync-libsymbols.spec.ts). Miss 08B: registerSaveHook gains onSavedText; WasmTool routes saved-file text to syncLayoutToY (per sheet room via the manager's syncLayoutFromSave, or the single-room doc) so title block / paper / setup edits converge instead of drifting. Opt 12 (TS half): zod off the observer hot path (yToItemUnchecked), children index built once per conversion. Opt 13: seed()'s adopt diffs the editor snapshot against the doc view and applies only the doc-authoritative difference — clean rebinds apply nothing, the adopt undo entry shrinks to the real changed set. Opt 14 deliberately deferred (doc 18). All TS-side; no wasm rebuild (the C++ blob/findLib sides already carried definitions). Verified: shared 107, standalone 79 (+2 known pre-existing wasm-assets), ysync e2e 21/21 chromium, collab regression 21/3-skip firefox. Bumps: web/pcbjam-shared (lib_symbols channel + syncLayoutToY + opts). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JgThWXtdvrYLK47EDFoGdq
4 KiB
Design miss 08 — Non-item document state only syncs at seed; lib_symbols is a landmine for the symbol-libraries milestone
Severity: design gap (silent divergence for settings edits; structural blocker later) Status: IMPLEMENTED 2026-07-03 — see 18 (lib_symbols channel + coarse layout save-sync; nets stay seed-frozen by design)
Where
web/pcbjam-shared/src/kicad-y.ts:79-94—kdoc_layoutis written bydocToY(seed) and only ever appended to / pruned byapplyDeltaToYfor root items; non-item layout slots are never updated liveweb/pcbjam-shared/src/items-wire.ts:85-117—unwrapWireItemdeliberately strips the blob's envelope, including a symbol blob's(lib_symbols …)cache ("sender context, not document content")wasm/bindings/eeschema_embind.cpp:786-808—doApplyItems'findLibfallback chain: blob's own lib cache (stripped upstream) → live screen's cache → nullptr- Drift flags:
web/standalone/src/wasm/collab/drift-detect.ts:110-115(layoutChanged/metaChangedare computed and reported — but nothing consumes them beyond telemetry)
What doesn't sync (by design, today)
Everything that lives in layout (non-uuid forms at the document root):
- eeschema: title block, paper size/orientation,
(settings …),lib_symbols - pcbnew:
(setup …)(design rules), net declarations ((net N "NAME")at root), layer table, title block / paper
A peer editing the title block or board setup diverges silently from the room and
from other peers; drift-detect reports layoutChanged forever and nothing repairs it
(10-miss-no-repair-path.md). Because ydoc-mode opens
materialize from the doc, the author's own settings edit is lost on the next reload
(the saved file went to the API, but the doc wins on open — see the save-vs-room note
in 10).
The lib_symbols landmine
Today symbol placement is blocked (no bundled symbol libraries), which masks this. When that lands:
- Sender places a symbol → the emit's clipboard blob carries the symbol AND its
(lib_symbols …)definition (that's whataForClipboardFormat does). unwrapWireItemstrips thelib_symbolsenvelope → the definition never enters the Y.Doc.- Peers apply the symbol;
findLibfalls back to the live screen's cache — which doesn't have the definition for a symbol the peer has never seen →nullptr→ symbol added without aLIB_SYMBOL(renders broken). - Worse, persistently: the room's
layout.lib_symbolsstill has only the seed-time definitions, sodocToFileproduces a schematic referencing a lib id it doesn't contain — an invalid file.
Fix directions
- Short term (before symbol placement ships): stop stripping
lib_symbolson the eeschema wire. Either merge the blob's definitions into a dedicatedkdoc_libsymbolsY.Map (keyed by lib id, LWW per definition — definitions are content-addressed-ish and rarely conflict), or fold them into the layout'slib_symbolsslot on upsert. Mirror on apply: render the definitions into the wire sofindLib's first branch works. - Layout state generally: decide per class:
- Settings/title block: add a coarse "layout rev" sync — on local save (the
existing
onSavehook) diff the saved file's layout against the doc's (docDeltacovers items; layout needs a slot-list compare, whichdrift-detectalready does) and write changed non-item slots intokdoc_layoutwith LWW-at-slot-head granularity. Coarse but converging. - Net declarations (pcbnew): must be kept in step if/when net-creating edits are possible in the standalone; otherwise document explicitly that nets are seed-frozen.
- Settings/title block: add a coarse "layout rev" sync — on local save (the
existing
- Minimum bar if deliberately deferred: document the freeze and make drift-detect's
layoutChangeddistinguish "expected class" (title block) from "unexpected" (missing lib_symbols), so telemetry stays actionable.