From 75bcd779147945e93671ad6aec42533970e36e1c Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 25 Apr 2026 14:30:59 +0000 Subject: [PATCH] docs(quartz/store): note the NIP-01 tiebreaker, NIP-09 created_at window, and author-check on deletion in both store READMEs https://claude.ai/code/session_01X163Nr31vGkvAXoJ3JgMov --- .../vitorpamplona/quartz/nip01Core/store/sqlite/README.md | 5 ++++- .../com/vitorpamplona/quartz/nip01Core/store/fs/README.md | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/README.md b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/README.md index deee5cee3..3c3d5c610 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/README.md +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/README.md @@ -14,11 +14,13 @@ consistency can be sacrificed, but a database that will never crash and never go - Forces unique constraint by kind, pubkey - Old versions are removed when newer versions arrive. - Old versions are blocked if newer versions exist. + - Same `created_at`: NIP-01 lexical-id tiebreaker (lowest id wins). - **Addressable Events**: - Forces unique constraint by kind, pubkey, d-tag - Old versions are removed when newer versions arrive. - Old versions are blocked if newer versions exist. + - Same `created_at`: NIP-01 lexical-id tiebreaker (lowest id wins). - **Ephemeral Events** - Ephemeral events never stored. @@ -29,8 +31,9 @@ consistency can be sacrificed, but a database that will never crash and never go - **NIP-09 Deletion Events** - Deletes by event id - - Deletes by address until the `created_at` + - Deletes by address up to and including the deletion's `created_at` (newer versions are kept). - Blocks deleted events from being re-inserted. + - Only the original author's deletions take effect; cross-author kind-5s are stored but inert. - GiftWraps are deleted by p-tag - **NIP-62 Right to Vanish** diff --git a/quartz/src/jvmMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/fs/README.md b/quartz/src/jvmMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/fs/README.md index b15074ed3..15515c1cf 100644 --- a/quartz/src/jvmMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/fs/README.md +++ b/quartz/src/jvmMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/fs/README.md @@ -35,10 +35,10 @@ Everything documented in [`../sqlite/README.md`](../sqlite/README.md): | SQLite feature | This store | |---|---| | Insert + retrieve by Nostr filter | ✓ | -| Replaceable events (kinds 0, 3, 10000-19999) — newer wins, older blocked | ✓ via `replaceable//.json` slot | -| Addressable events (kinds 30000-39999) — `(kind,pubkey,d)` uniqueness | ✓ via `addressable///.json` slot | +| Replaceable events (kinds 0, 3, 10000-19999) — newer wins, older blocked, NIP-01 lexical-id tiebreaker on equal `created_at` | ✓ via `replaceable//.json` slot | +| Addressable events (kinds 30000-39999) — `(kind,pubkey,d)` uniqueness, same NIP-01 tiebreaker | ✓ via `addressable///.json` slot | | Ephemeral events never stored | ✓ rejected pre-write | -| NIP-09 deletions — by id, by address, gift-wrap by `p`-tag, blocks re-insert | ✓ via `tombstones/id/` and `tombstones/addr/` (each tombstone is a hardlink to the kind-5 event) | +| NIP-09 deletions — by id, by address (up to deletion's `created_at`), gift-wrap by `p`-tag, only the original author's deletions take effect | ✓ via `tombstones/id/` and `tombstones/addr/` (each tombstone is a hardlink to the kind-5 event) | | NIP-40 expirations — reject expired-on-insert, periodic sweep | ✓ via `idx/expires_at/` index + `deleteExpiredEvents()` | | NIP-45 counts | ✓ same planner, just count results | | NIP-50 full-text search — content tokenisation, AND of tokens | ✓ via `idx/fts//` |