ysync bug 07 UP side: superseded sheet switch never adopts onto the new screen + apply envelope sheet tag/guard (subsheet self-reference fix)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013MnySXALJiYsRQ5mCrxgwX
This commit is contained in:
parent
602f5c6fed
commit
af07a413ee
8 changed files with 306 additions and 7 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# Bug 07 — Sheet switch leaves the DOWN hook pointing at the old room; cross-room contamination window
|
||||
|
||||
**Severity:** medium (small window on warm rooms; a full network round-trip — or forever — on cold/failed switches)
|
||||
**Status:** FIXED 2026-07-03 — see [17](17-fixes-bugs-01-07.md) (batch 4: destroyed-flag hook + switch retry; fix direction 2 still open)
|
||||
**Status:** FIXED 2026-07-03 — see [17](17-fixes-bugs-01-07.md) (batch 4: destroyed-flag hook + switch retry). **UP side CLOSED 2026-08-28** — see "8/28 closure" below.
|
||||
|
||||
## Where
|
||||
|
||||
|
|
@ -83,3 +83,53 @@ Repro (2026-07-03): `web/standalone/src/wasm/collab/ysync-repros.test.ts` — 07
|
|||
REAL kicad-binding + REAL yjs with only `connectKicadDoc` faked; the cold-switch gap
|
||||
is held open and the stale hook's emit lands in the old sheet's doc). Both `it.fails`.
|
||||
See [16](16-repro-suite-results-and-empirical-findings.md).
|
||||
|
||||
## 8/28 closure — the UP-side window was NOT sub-frame; it corrupted a project
|
||||
|
||||
**Field case (staging, `mega-demo-v2`, Arduino Mega repo-as-project):** reload
|
||||
showed *"The entire schematic could not be loaded … Could not load sheet
|
||||
'…/Arduino Mega 2560/ATMEGA2560-16AU.kicad_sch' because it already appears as a
|
||||
direct ancestor … IO_ERROR: Unable to open for reading"*. The two lines are one
|
||||
event: KiCad's ancestor check blanks the filename and falls through to
|
||||
`loadFile("")`. The materialized `ATMEGA2560-16AU.kicad_sch` held the ROOT's
|
||||
content — all three of the root's `(sheet …)` items with identical uuids (one of
|
||||
them `Sheetfile "ATMEGA2560-16AU.kicad_sch"` → self-reference) and 49/52 of the
|
||||
root's symbols; its own items were gone.
|
||||
|
||||
**Mechanism (both halves of this doc, chained):**
|
||||
|
||||
1. `doSwitch(root)` was parked on `await ensureRoom()` / `await activate()`
|
||||
(cold or passive-gateway room). The user entered the subsheet; C++ moved the
|
||||
active screen and JS queued `switchTo(sub)`. The `requestedPath` guard only
|
||||
ran BEFORE `doSwitch` started, so the root switch resumed, bound the root doc
|
||||
and **adopted it onto the subsheet's screen**: doc-only roots (the root's
|
||||
items, `(sheet …)` entries included) added, the subsheet's own items removed.
|
||||
2. `doSwitch(sub)` then bound the subsheet room. Its bind wrote the contaminated
|
||||
screen into the subsheet doc (empty room → file-seed + editor-snapshot
|
||||
baseline; populated room → the next save-all uploaded the contaminated
|
||||
file). From then on every reload materialized the self-referencing sheet.
|
||||
|
||||
`doApplyItems` applies with `commit.Add(item, aFrame->GetScreen())` — whatever
|
||||
screen is active when the deferred coroutine runs — so nothing on the C++ side
|
||||
could refuse the wrong-screen apply.
|
||||
|
||||
**Fix (two layers, red→green):**
|
||||
|
||||
- `sheet-manager.ts doSwitch`: `superseded()` re-checks `requestedPath` after
|
||||
every await and bails before binding/adopting; the room stays warm (parked).
|
||||
Test: `sheet-manager.test.ts` "a switch superseded DURING its connect never
|
||||
binds/adopts onto the new screen".
|
||||
- Envelope tag (fix direction 2): `bindKicadCollab(…, { sheetPath })` stamps
|
||||
every `applyItems` wire (remote change + adopt) with `sheet: <project-relative
|
||||
path>` (`itemsWireDeltaSchema.sheet`, optional); `eeschema_embind.cpp
|
||||
applyTargetsShownSheet()` drops an envelope whose `sheet` is not the shown
|
||||
screen's filename (suffix match on the MEMFS absolute path) and logs
|
||||
`[collab] applyItems dropped`. Untagged envelopes keep the legacy behaviour
|
||||
(single-file tools, older clients). Tests: `kicad-binding.test.ts` (tag
|
||||
present on adopt + remote applies, absent when unbound),
|
||||
`sheet-manager.test.ts` (each room bound with its own path),
|
||||
`tests/kicad/apply-sheet-guard.spec.ts` (e2e: foreign-tagged apply dropped,
|
||||
own-tagged + untagged applied).
|
||||
|
||||
**Data repair:** an already-corrupted sheet doc is authoritative — re-upload the
|
||||
original `.kicad_sch` for that path (the room re-seeds from the new file).
|
||||
|
|
|
|||
Loading…
Reference in a new issue