Skip to content

fix: stop sync retry loops and preserve newer edits - #1702

Merged
elkimek merged 33 commits into
mainfrom
codex/fix-sync-popover-refresh
Nov 1, 2026
Merged

elkimek merged 33 commits into
mainfrom
codex/fix-sync-popover-refresh

Conversation

@elkimek

@elkimek elkimek commented Oct 31, 2026 •

Copy link
Copy Markdown
Owner

Generating a new sync identity could repeatedly republish committed profiles and fill relay storage. Recovery now advances per profile, confirms and binds its durable journal before identity changes, rejects stale-tab acknowledgements, and retargets pending recovery during a deliberate join. Failed owner resets restore only their own journal. Explicit deletion releases recovery even after the profile leaves the saved list; unavailable profiles without delete intent remain protected. Startup reconciliation and AI-setting saves stop retrying equivalent successful work.

Sync updates retain open controls, and optional guided Chat yields to foreground modals and the Sync popover while lazy code/styles load. A successful save rebases into a replacement same-profile object using that object’s read baseline, preserving committed edits and newer drafts. Overlapping forced pushes now retain per-profile generations: newer saves invalidate older plans before submission, newer pushes retire older completion callbacks, and neither completion order can hide another outstanding profile push. Timed-out callbacks stay retired. A superseded plan settles its status before releasing ownership; it neither leaves Sync pending after the final push nor hides another profile’s outstanding send. Manual sync retries a superseded snapshot within its existing deadline; concurrent recovery renames retain their clock and dirty marker.

Coverage aggregation folds one shard at a time and unions exact byte ranges without changing fingerprints, diagnostics, denominators or budgets. A 4,000-shard regression runs within a 96 MB child heap. Retained fixtures require current database-import options, explicit analytics consent, and completion of a real measurement migration before replacing its independent fixture.

Validation includes negative controls for the repaired races, 187 focused sync/persistence tests, all 130 legacy fixtures, strict source/test typing, quality 17/17 and architecture 1,867 modules / zero cycles. The expanded real-SDK/relay matrix passes 36 scenarios across Evolu 7, Evolu 8 and mixed clients; the final callback refinements also pass the delayed native Force resend regression on all three combinations. Its negative control delays only one real gzip stream completion: a newer edit reaches the peer, then the older send regresses the active profile on the preceding runtime. SDK storage, queries, owner proof and transport remain real.

Current head e035aa564622289751510870545b1f8e815e170f passes all required PR tests, CodeQL, and all seven sync compatibility jobs, including 36 real-relay scenarios and startup in Chromium, Firefox and WebKit. Greptile reports 5/5 on this exact head; all review threads are resolved.

The exact-head CI shipping artifact (13055628231, SHA-256 1e3940fd9e9b8c102972f2b892a1a11ccbe8bff95e482498f624d8cc40fb2cb1) passed a local 19-workflow rehearsal against the production relay, expanded identity recovery, SDK/header Synced and zero page errors. Identity generation preserved usage across two unchanged reloads. All five disposable owners were verified at zero bytes/messages afterward. These are local pre-deployment synthetic checks, not acceptance of the user's stored profiles or full release qualification.

Release qualification remains blocked. The latest exhaustive run passed 15,207 unit cases and 1,358 critical cases, but its unit job reached the existing time limit during reporting. Mobile WebKit's Lens-shell case timed out in the unchanged navigator.serviceWorker.ready wait before editing or navigation; the trace records app readiness and no page errors. The frozen helper, assertions and deadlines remain unchanged. The other browser and runtime jobs passed; combined coverage did not run because the unit job was cancelled.

The preceding completed combined measurement also failed the unchanged 89% global function floor at 37.48% (25,519/68,079). Compiled client bundles account for 44,821 functions with only 5,275 credited, and 36,965 client functions have no observed browser byte coverage. Sync's feature group measured 91.97%, above its 89% floor; global coverage plus Wallet/providers and Biology-score feature floors remain unresolved. Authenticated raw-capture comparisons for ordinary and compiled component modules produce identical mappings/counts/rejection reasons with this mapper and main. Unknown entries still receive zero credit; no denominators, floors, provenance checks or budgets were weakened. Final production acceptance remains required after merge. No user data has been cleared.

@elkimek
elkimek force-pushed the codex/fix-sync-popover-refresh branch from a60fa62 to 88364ff Compare October 31, 2026 07:51
@greptile-apps

greptile-apps Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[High impact] The reviewed changes appear safe to merge.

Summary

This PR limits repeated Sync uploads and protects newer edits during saves, recovery, and overlapping pushes.

  • Restored profiles publish under the new identity one at a time.
  • Newer saves and pushes take priority over older Sync work.
  • Optional Chat yields to foreground controls and Sync keeps open controls in place.
  • Coverage tools combine shards incrementally while preserving exact byte ranges.
  • CI and test fixtures add coverage for Sync compatibility and existing workflows.

No new actionable issues were found. The five supplied, unnumbered findings are addressed in the current code. Tests were inspected, not run during this review.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Build profile update] --> B{Still current?}
  B -- Yes --> C[Submit update]
  C --> D[Commit current completion]
  B -- No --> E[Set idle only when no other profile is pending]
  E --> F[Release only this push]
  D --> F
Loading

Reviews (29) · Last reviewed commit: "fix: settle superseded push status befor..." · Reviewed by Greptile

@elkimek elkimek changed the title Keep sync controls clickable during status updates Keep sync controls usable and recover optional startup loads Oct 31, 2026
Comment thread js/chat-panel.ts Resolved
@elkimek elkimek changed the title Keep sync controls usable and recover optional startup loads fix: stabilize sync controls and retire stale Chat openings Oct 31, 2026
@elkimek elkimek changed the title fix: stabilize sync controls and retire stale Chat openings fix: stop repeated recovery uploads and stabilize sync controls Oct 31, 2026
Comment thread js/sync-configure.ts Resolved
Comment thread js/sync-identity.ts Resolved
Comment thread js/sync-backup-restore-state.ts Resolved
Comment thread js/sync-backup-restore-state.ts Resolved
@elkimek elkimek changed the title fix: stop repeated recovery uploads and stabilize sync controls fix: stop sync retry loops and preserve newer edits Oct 31, 2026
@elkimek
elkimek merged commit db3d764 into main Nov 1, 2026
59 of 62 checks passed
@elkimek
elkimek deleted the codex/fix-sync-popover-refresh branch November 1, 2026 05:37
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