Skip to content

feat(sync): 10.3c pairing backfill — entities predating a pair now reach it - #468

Merged
th3-br41n merged 1 commit into
mainfrom
feat/10-3c-backfill
Aug 3, 2026
Merged

th3-br41n merged 1 commit into
mainfrom
feat/10-3c-backfill

Conversation

@th3-br41n

Copy link
Copy Markdown
Contributor

The ongoing producer (#467) fires on DEK install, so it only ever reaches entities created after a device is paired. Everything written before the second device existed stayed stranded forever — the new device would sync new notes and never see a single old one. Either half alone leaves multi-device sync broken, which is why the rung named both.

Why it is a long pass, not a loop

This is O(entities × devices) HPKE seals fired by a pairing gesture. Blocking the main thread would freeze the UI at exactly the moment the user is watching a device pair. So it runs on the IE-11 contract: yields every 25 entities, reports progress, honours an abort signal.

Deliberate failure semantics

  • Never throws. One entity that cannot be sealed must not strand every entity after it. A partial backfill beats an aborted one, and the next pairing event re-runs the pass.
  • An offline run must not look broken. A null fan-out (no relay, no siblings) and a placeholder refusal are both nothing to do, counted as skipped rather than failed.
  • Idempotent. The worker no-ops a duplicate recipient and installEntityDek ignores an equal ordinal, so re-running after a second pairing is safe and cheap.

Wiring

Called from onDevicesChanged, behind a single in-flight guard — the roster can change twice in quick succession, and two concurrent passes over one vault would double the HPKE work for nothing.

New repo method listIdsWithDek, the inverse of listMissingDekIds. It carries type because that is sealed into the wrap for cold materialisation (10.14), and fetching it per id would be a query per entity on a pass that is already O(entities × devices). SQL stays in the repo per convention.

Verification

8 tests on the pure pass (zeroing on throw, continue-after-failure, abort, progress, offline-is-not-failure, multi-batch yield) · 1350 pass across sync / collab / storage / entities · typecheck + lint green.

Remaining on the rung

Both declared gates — security-review and pentest. Running them next.

🤖 Generated with Claude Code

…ach it

The ongoing producer (#467) fires on DEK install, so it only ever reaches
entities created AFTER a device is paired. Everything written before the
second device existed stayed stranded forever: the new device would sync new
notes and never see a single old one. Either half alone leaves multi-device
sync broken, which is why the rung named both.

Runs on the IE-11 long-pass contract rather than a synchronous loop — this is
O(entities x devices) HPKE seals fired by a pairing gesture, and blocking the
main thread would freeze the UI at exactly the moment the user is watching a
device pair. Yields every 25 entities, reports progress, honours an abort.

Never throws, and that is deliberate: one entity that cannot be sealed must
not strand every entity after it. A partial backfill is strictly better than
an aborted one, and the next pairing event re-runs the pass.

Counting is chosen so an offline run does not look like a broken one — a null
fan-out (no relay, no siblings) and a placeholder refusal are both "nothing to
do", not failures.

Wired to onDevicesChanged, behind a single in-flight guard: the roster can
change twice in quick succession and two concurrent passes over one vault
would double the HPKE work for nothing.

New repo method listIdsWithDek — the inverse of listMissingDekIds. Carries
`type` because it is sealed into the wrap for cold materialisation, and
fetching it per id would be a query per entity on a pass that is already
O(entities x devices). SQL stays in the repo per convention.

8 tests on the pure pass. 1350 pass across sync/collab/storage/entities;
typecheck and lint green.

REMAINING on the rung: both declared gates.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@th3-br41n
th3-br41n merged commit 0abb9eb into main Aug 3, 2026
3 checks passed
@th3-br41n
th3-br41n deleted the feat/10-3c-backfill branch August 3, 2026 15:31
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