28b23b5e63
- NIP-09 (#2): a-tag and replaceable deletes now respect `created_at <= deletion.created_at` so a stale deletion request cannot remove a newer addressable that legitimately replaced it. `+created_at` hint on the addressable path keeps the d_tag-selective index in use. - NIP-01 (#1): replaceable / addressable triggers now apply the lexical-id tiebreaker — when two events share `created_at`, the one with the lexicographically smaller id wins, matching the spec. - Schema (#5): FullTextSearchModule.versionFinder probes FTS support with a dummy table, but used to leave it behind. The first v1->v2 upgrade then failed because re-running create() would hit "already exists". Now we drop the probe table immediately and defensively clean up any stragglers. - Schema (#6): onCreate / onUpgrade and the matching `setUserVersion` are now wrapped in a single transaction so a partial migration cannot leave the DB with mismatched user_version and schema. - SQL DSL (#4): Condition.NotEquals(null) now produces `IS NOT NULL` instead of `IS NULL`. - Doc fix (#13): swapped vacuum/analyse comments now describe the right command. Tests: same-`created_at` tiebreaker for replaceables and addressables, NIP-09 created_at window for a-tag deletes, schema drop+recreate idempotency (covers the FTS dummy-table regression). https://claude.ai/code/session_01X163Nr31vGkvAXoJ3JgMov