feat(relay): carry the deleted original's slot in deletion notices

Relay-signed message_deleted notices now record where the original lived
(created_at, parent, root, depth, broadcast) so clients can draw the tombstone
in place. One builder serves both the NIP-29 DELETE_EVENT path and the admin
outbox tombstone.

The NIP-29 soft-delete and its notice now commit in one transaction, so a
failed notice insert can no longer lose the marker. The admin path freezes the
slot on the action row with the mutation marker (migration 0050), and delivery
rebuilds from that payload, so retries sign identical bytes even after purge.
Rows from before the column existed freeze their slot once at finalization.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This commit is contained in:
Hayt
2026-09-24 20:07:25 -04:00
parent 2013148852
commit d19dbe7652
10 changed files with 935 additions and 129 deletions

View File

@@ -1817,6 +1817,10 @@ CREATE TABLE relay_admin_actions (
enforcement_target_pubkey BYTEA
CHECK (enforcement_target_pubkey IS NULL OR length(enforcement_target_pubkey) = 32),
enforcement_channel_id UUID,
-- Frozen original slot of a delete target (migration 0050): NULL = not
-- captured, {"slot": {...}} = captured, {"slot": null} = target was gone.
original_slot JSONB
CHECK (original_slot IS NULL OR jsonb_typeof(original_slot) = 'object'),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
-- Report-scoped idempotency: one action per (report, request_id).