Skip to content

fix(decks): stop deleted decks resurrecting across devices (tombstones)#15

Merged
DocNR merged 6 commits into
mainfrom
feat/deck-delete-propagation
Jun 16, 2026
Merged

fix(decks): stop deleted decks resurrecting across devices (tombstones)#15
DocNR merged 6 commits into
mainfrom
feat/deck-delete-propagation

Conversation

@DocNR

@DocNR DocNR commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Summary

Deleted decks were reappearing across devices/tabs because the NIP-78 deck-sync merge did a pure union with no record of deletions. This adds a deletedDecks tombstone map (deckId → deletedAt ms) to the per-account workspace:

  • deleteDeck records a tombstone; the merge honors it with last-writer-wins — a deck only returns if it was saved after the delete, or is kept-and-flagged-as-conflict if it has unsaved local edits. Includes a 90-day GC and a never-leave-the-user-deckless safety net.
  • Tombstones travel inside the NIP-44-encrypted blob; WIRE_VERSION stays 1 (fully backward-compatible — old clients ignore the field, new clients reading old blobs see no tombstones).
  • The 5-second Undo clears the tombstone (via a new testable storage.restoreDeck).
  • Also fixes a latent field-drop: deleteDeck, saveActiveDeckAs, and addEmptyDeck rebuilt the workspace without spreading existing fields, silently dropping pairedAgents / allowSiblingExposure (and, post-this-feature, tombstones). All mutateActiveWorkspace callbacks audited.

5 commits, +27 tests. No new dependencies. No wire-version bump, no data migration.

Test plan

  • npm run build green; full suite 889 passed / 1 skipped / 0 failed
  • Two tabs/devices on one account: delete a deck in one → it does not reappear in the other after focus/sync
  • Delete a deck, then Undo within 5s → deck returns
  • Delete a deck on device A while editing+saving a different deck on device B → no resurrection of the deleted one

🤖 Generated with Claude Code

DocNR and others added 5 commits June 15, 2026 16:11
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…k delete

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…kAs and addEmptyDeck

mutateActiveWorkspace replaces (not merges), so these two callbacks were
dropping deletedDecks/pairedAgents/allowSiblingExposure. With tombstones now
load-bearing for cross-device delete propagation, a Save-As or Add-Deck right
after a remote delete-merge could wipe tombstones and resurrect the deck.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 16, 2026

Copy link
Copy Markdown

Deploying jank with  Cloudflare Pages  Cloudflare Pages

Latest commit: cded8ab
Status: ✅  Deploy successful!
Preview URL: https://a7afe867.jank-4ii.pages.dev
Branch Preview URL: https://feat-deck-delete-propagation.jank-4ii.pages.dev

View logs

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@DocNR
DocNR merged commit e5cba4d into main Jun 16, 2026
2 checks passed
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