Skip to content

Recover unsent layouts across reload and browser process loss - #213

Merged
mvalancy merged 2 commits into
devfrom
fix/durable-layout-recovery-20261027
Oct 28, 2026
Merged

mvalancy merged 2 commits into
devfrom
fix/durable-layout-recovery-20261027

Conversation

@mvalancy

@mvalancy mvalancy commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Problem and behavior

Unsent drags currently survive navigation but disappear when the browser reloads or exits. This change persists the newest pending coordinates in the existing account IndexedDB store before network replay, restores them before graph initialization, and distinguishes memory-only, device-committed, server-accepted and cleanup-pending states.

Owner/graph/node receipts and transactional generation checks prevent a stale tab from restoring old coordinates over a newer acknowledged layout. Replay checks the active account and bearer token, serializes matching items with Web Locks, and removes only matching revisions. Settings exposes explicit recovery/discard for inaccessible or deleted graphs. Offline-sync mode keeps its existing local mutation/sync authority. Memoized recovery overlays preserve stable LOD labels during camera movement.

Refs #181 and #193. This PR remains draft until exact-head review and all applicable checks finish; it does not close #181 before final dev CI.

Validation

Candidate: 168b98470c1051a6c48eae4132e1e4ab08c0a0ef. Parent 525ca4e5aa5bd4a918ad85165d0f2a0e8caf59ac has the same complete tree as integrated dev 780a7599d1d7949d5e0fac56091f0b07bb0e6e0d.

  • Added persistence, stale-tab, provider replacement, cleanup, quota/discard and account-recovery regressions. Retained failures before their corrections are documented in docs/quality/LAYOUT_RECOVERY_2026-10-28.md and the linked repository lessons.
  • Nine real browser cases cover reload before acknowledgement, an owned SIGKILL/restarted profile, delayed hydration and graph switching, actual two-tab/quota ordering, replacement accounts, revoked/deleted data, receipt-cleanup failure, unavailable storage/locks, and LOD camera stability while work is pending. Owned fixtures delete edges before nodes and verify graph deletion.
  • Preparatory eight-case strict run passed; the added LOD case passed separately and deliberately breaking memoization failed its geometry assertion. A later nine-case run passed its browser cases but failed source integrity because staging changed the fingerprint. That failed report is retained and is not acceptance evidence.
  • Corrected frozen-head strict layout recovery: 9 passed, 0 failed/warned/skipped, exit0, no timeout/evidence errors; clean matching source fingerprints, 259.9seconds.
  • Corrected-head full unit invocation: 741 passed, with26 existing gated database cases explicitly skipped; harness 193/193. Build, types and lint pass (existing lint/chunk warnings retained). Offline production build: guest reload, browser reopening and project transfer 3/3, zero retries.
  • Independent agent review of the exact corrected head has no remaining findings. The earlier Settings account-switch disclosure was reproduced, corrected and covered by a failing-before/passing-after regression. This is independent review evidence, not a GitHub non-author approval.
  • Existing smoke, semantic-LOD and motion regressions and CI/Comprehensive Tests are still pending. Final integration and post-dev CI evidence are required before closeout.

Limits

Committed browser storage can survive this tested process termination; it does not guarantee survival of OS/power/storage loss or browser-data clearing. Known accepted saves retry only receipt cleanup. An ambiguous response/crash boundary remains at-least-once; server-side multi-actor ordering is separate. Missing storage/coordination and capacity failures stay visible. No hosted D1, release or deployment acceptance is claimed.

@github-actions

Copy link
Copy Markdown

🧪 Comprehensive Test Suite

  • Unit suites (Node 22.18.0 & 24.x) — core, web, server, mcp-server: ✅ passed
  • Installer & deploy config: ✅ passed

Full-stack smoke gate runs in the CI workflow.

@mvalancy

Copy link
Copy Markdown
Member Author

Independent exact-head review found a Settings race in c4df01e: A starts a delayed discard, B loads its pending scopes, then A’s error path relabels B’s scopes as A. The retained probe reproduced disclosure of B’s graph ID on A’s return. This blocked integration despite the frozen nine-case browser run passing.

Corrected in 168b98470c1051a6c48eae4132e1e4ab08c0a0ef: owner-scope identity guards stale completions, prior scopes retain their original owner, busy state follows its operation scope, and refresh reads ignore older requests. The new interleaving regression failed before correction; all43 focused tests now pass. Canonical lesson and symptom-index entry are in the PR.

The corrected head is under renewed independent review and full CI/browser validation. The superseded c4df01e CI run was cancelled to release its workflow slot; cancellation is not counted as a pass. Its Comprehensive run completed successfully, but corrected-head evidence is still required.

@github-actions

Copy link
Copy Markdown

🧪 Comprehensive Test Suite

  • Unit suites (Node 22.18.0 & 24.x) — core, web, server, mcp-server: ✅ passed
  • Installer & deploy config: ✅ passed

Full-stack smoke gate runs in the CI workflow.

@mvalancy

Copy link
Copy Markdown
Member Author

Exact-head integration evidence for 168b98470c1051a6c48eae4132e1e4ab08c0a0ef:

  • Independent agent review is clear after the retained Settings disclosure regression and correction. This is not a GitHub non-author approval.
  • CI40613741533 and Comprehensive40613741553 completed successfully for this source. Build/types/lint/security, package suites, both Node versions, real Neo4j, installer, all three runtime-image contracts, effects and showcase passed. The main/nightly production-stack job is inapplicable on this dev PR, not counted as a pass.
  • Inspected actual uploaded strict reports: smoke6, new-user42, semantic-LOD2, layout-recovery9, routes7, mobile27 and perf3. Every required report has zero failed/warned/skipped cases, exit0, no timeout or evidence errors, and unchanged source fingerprints.
  • Browser reports identify GitHub’s tested merge c882e2c2d0ae5d3ac3b1263251dfaf3474912ee7; fetched that commit and verified its complete tree equals the reviewed source: cfbc1fedf6f097762555b80ea792801afa307c8f.
  • Local corrected-source checks also passed:741 unit cases (26 preexisting gated database skips separately recorded),193 harness cases, build/types/lint, strict9 recovery/6 smoke/2 LOD cases,4 motion/resize cases and3 offline production-build guest/transfer cases. Earlier failures and the cancelled superseded CI run remain retained.

Live dev is 780a7599d1d7949d5e0fac56091f0b07bb0e6e0d, whose full tree equals the source parent525ca4e. I will use the owner’s standing dev-only administrative merge authorization with an exact-head match and verify the actual parents/full tree afterward. #181 remains open until final dev CI. Main, publication, deployment and protections remain outside this operation.

@mvalancy
mvalancy marked this pull request as ready for review October 28, 2026 01:50
@mvalancy
mvalancy merged commit ed96321 into dev Oct 28, 2026
19 checks passed
@mvalancy

Copy link
Copy Markdown
Member Author

Native administrative merge completed under the owner’s standing dev-only authorization. Actual dev is ed963219a0ecec9c750a1d06909b0da027dc221a, with verified parents 780a7599d1d7949d5e0fac56091f0b07bb0e6e0d and reviewed source 168b98470c1051a6c48eae4132e1e4ab08c0a0ef. The complete resulting tree is cfbc1fedf6f097762555b80ea792801afa307c8f, identical to the reviewed/tested source and GitHub’s tested PR composition.

Final dev CI40617447937 and Comprehensive40617447914 are running. #181 remains open pending those results. Main remains 775362eace0723c57b7ba3c7936645c9d0d36cb4. This operation did not supply a non-author approval, publish a release, deploy a site or change protection.

@mvalancy

Copy link
Copy Markdown
Member Author

Resolved by reviewed #213, integrated with #214. Durable account/graph/node-scoped receipts preserve unsent positions across reload and actual owned-browser process termination/restart. Generation fences and exact-session replay checks prevent stale/cross-account replay; accepted writes with failed cleanup retry cleanup only. Pending Settings state and delayed error ownership were independently reviewed and corrected. Nine strict browser cases include actualquota/two-tab ordering, account replacement, revoked/deleted targets, unavailable storage/locks and stable LOD labels while work is pending. Earlier negative evidence and the review correction remain in the PR and canonical lessons.

Final aggregate dev acceptance passed at 77899e98a081e725ae8ddc15b6566cc50c9a584f: CI40618347427 and Comprehensive40618347395. Actual downloaded browser reports confirm smoke6, new-user42, semanticLOD2, layout-recovery9, routes7, mobile27 and performance3, all zero failures/warnings/skips, exit0, no timeout/evidence errors, and matching clean fingerprints on this exact dev SHA. Browser artifact.

All applicable quality/build/unit/security, realNeo4j/MCP, three runtime-image, effects/showcase, supported Node22.18/24 and installer/config jobs passed. Main/nightly production-stack job was inapplicable and skipped, not claimed as passed. Native dev parents/tree were verified before closeout; main remains775362e. No release/deployment/protection changes. The intermediate ed963 dev CI was cancelled by the newer aggregate push and was not counted as success.

Closing the defined durability acceptance. Unsupported storage/locks and inaccessible records remain explicit recoverable states; no universal network/hosted guarantee is inferred. Nested LOD continues separately in #215/#216 and must preserve these regressions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant