Skip to content

Retire a push tombstone only under the account that owns its row - #1239

Merged
nedtwigg merged 3 commits into
mainfrom
pocket-push-tombstone-account
Oct 20, 2026
Merged

nedtwigg merged 3 commits into
mainfrom
pocket-push-tombstone-account

Conversation

@nedtwigg

Copy link
Copy Markdown
Member

Hardening for Pocket's durable push-deletion queue.

When Pocket forgets a delivery id (Remove, an authenticated pairing-required, or a re-pair that mints a new id), it queues a tombstone so the Relay row can still be deleted later. The Relay's DELETE /api/push/subscriptions/:deliveryId is scoped to the caller's account and answers 204 whether or not it held the row. Until now the tombstone named no account, so if the phone was signed in to another account when the queue drained, that account's 204 cleared it and the first account's row stayed.

  • PendingDeliveryDeletionV1 in lib/src/remote/client/pocket-db.ts now carries accountId, taken from the KnownBurrowV1 the delivery id belonged to.
  • retirePendingDeletions in lib/src/remote/client/pocket-client.ts sends and clears only tombstones for the signed-in account. Others stay queued until that account signs in. The immediate delete after a pairing-required uses the same gate.
  • A tombstone queued before this change has no accountId and drains under any session, as before. No IndexedDB version bump is needed because the store keeps records as written.

Tests

lib/src/remote/client/pocket-client.test.ts → "the durable deletion queue":

  • another account's tombstone is neither sent nor cleared, and the signed-in account's own tombstone still drains;
  • forgetBurrow on a record from another account queues the deletion under that record's account and sends nothing;
  • a tombstone with no account still drains.

The first two fail when the gate is removed.

Specs

  • docs/specs/pocket-app.md → the delivery-mapping retirement rule: the tombstone records the record's account, and only a session of that account sends or clears it. The rationale is added, and the word budget is ratcheted to 3500.

🤖 Generated with Claude Code

A tombstone now records the record's `accountId`, and `retirePendingDeletions` sends and clears only the signed-in account's tombstones. The Relay's push deletion is account-scoped and answers 204 for a row it does not hold, so clearing on another account's 204 left the first account's row in place. A tombstone queued before this change carries no account and drains as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: f115a23
Status: ✅  Deploy successful!
Preview URL: https://a51d9faa.mouseterm.pages.dev
Branch Preview URL: https://pocket-push-tombstone-accoun.mouseterm.pages.dev

View logs

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No findings on the diff. Approval is held only because Workflow Lint is red at this head: zizmor flags the hash pin at ci.yml:403 for a mismatched version comment. This PR doesn't touch workflows, and the latest main run of the same workflow (at ed40d01) fails too, so the fix belongs on main.

@nedtwigg
nedtwigg merged commit 5c8721e into main Oct 20, 2026
15 checks passed
@nedtwigg
nedtwigg deleted the pocket-push-tombstone-account branch October 20, 2026 16:25
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.

2 participants