Files
amethyst/quartz
Claude 721546b140 feat(quartz): FsEventStore NIP-09 deletion + tombstones (step 4)
Tombstone files under tombstones/id/<id>.json and tombstones/addr/
<kind>/<pubkey>/<sha256(d)>.json, each a hardlink to the kind-5
event that authored the deletion. One source of truth: the tombstone
IS the deletion event, just indexed by target.

- FsTombstones — installs id tombstones unconditionally, installs
  addr tombstones with strongest-cutoff-wins semantics (later kind-5
  replaces earlier via atomic rename), and exposes hasIdTombstone /
  addrTombstoneCutoff for pre-insert checks.
- FsEventStore.insert — pre-insert guard: id tombstone always blocks;
  addr tombstone blocks when event.createdAt <= tomb.createdAt, matching
  SQLite's reject_deleted_events trigger. Kind-5 inserts trigger a
  cascade: for each e-tag target owned by the deletion author, unlink
  indexes + slot + canonical; for each a-tag (same pubkey), evict the
  slot winner if its createdAt <= deletion.createdAt. Tombstones are
  installed for every target regardless, so future re-inserts are
  blocked.

Tests: 11 new in FsDeletionTest — delete-by-id, block-reinsert-by-id,
non-author-deletion still installs tombstone but no cascade, cascade
addressable slot, newer-at-deleted-address passes, older blocked,
equal-timestamp blocked, later kind-5 raises cutoff, earlier kind-5
does not lower, deletion event stays queryable, tombstone shares
inode with kind-5 canonical. 51 fs tests green.
2026-04-24 21:38:37 +00:00
..