mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-29 17:02:28 +00:00
Two replaceable-event (NIP-33/kind 30078) lifecycle fixes found auditing edit/delete/tombstone: 1. created_at monotonicity. Edits and delete tombstones used bare Date.now(), with no guarantee of being newer than the version they replace. NIP-01 keeps the highest created_at (ties -> lowest id), so a device clock that's behind — or a second edit within the same second — left relays serving the OLD version: edits silently didn't apply, and (worse) deletions didn't actually remove the video for other clients (the local in-memory tombstone masked the failure locally). The edit and revert/delete builders now use max(now, baseEvent.created_at + 1). created_at is threaded through revertVideo and _softDeleteVersions so the bulk-delete path keeps it too. 2. Legacy tombstone key mismatch. The deletion builder synthesizes videoRootId = "LEGACY:<pubkey>:<dTag>" for legacy videos, so its tombstone keyed as "ROOT:LEGACY:..." while the original legacy event (no videoRootId) keyed as "<pubkey>:<dTag>" — the tombstone never matched the zombie it was meant to suppress. getActiveKey now treats a "LEGACY:"-prefixed root as non-distinct and falls through to the pubkey:dTag identity, so both match. Verified sound and unchanged: d-tag + videoRootId preservation on edit, ownership/version checks, dual delete (NIP-09 kind-5 + per-d-tag soft-delete), and the tombstone guard wired across all ingestion paths. Tests: edit/tombstone created_at is bumped above a future-dated base (clock-skew) and uses wall-clock for a past base; a legacy deletion shares the original event's key. Both fixes mutation-verified. Co-Authored-By: Claude Opus 4.8 <[email protected]>