Skip to content

fix(relay): wire EventDeleted audit into all event deletion paths - #4041

Open
iroiro147 wants to merge 1 commit into
block:mainfrom
iroiro147:claude/issue4034-20260801
Open

fix(relay): wire EventDeleted audit into all event deletion paths#4041
iroiro147 wants to merge 1 commit into
block:mainfrom
iroiro147:claude/issue4034-20260801

Conversation

@iroiro147

Copy link
Copy Markdown

Problem

AuditAction::EventDeleted is defined in buzz-audit but has no production call site anywhere in the codebase. Neither of the two paths that delete/tombstone an event (NIP-09 soft-delete, nor hard-delete-on-supersede for parameterized-replaceable events) ever writes an audit log entry. The relay currently cannot produce an audit trail for any event deletion.

Closes #4034.

Root Cause

Three separate deletion paths in crates/buzz-relay/src/handlers/side_effects.rs all call soft_delete_event_and_update_thread (or soft_delete_by_coordinate) successfully — but none of them send an audit entry to state.audit_tx:

  1. handle_delete_event_side_effect (kind:9005, NIP-29 admin delete)
  2. handle_standard_deletion_event (NIP-09 e-tag soft-delete)
  3. handle_a_tag_deletion (NIP-09 a-tag coordinate soft-delete)

Meanwhile, the event creation path (enqueue_event_created_audit in event.rs) and the media upload path (MediaUploaded in api/media.rs) both correctly write audit entries. The deletion path was simply never wired up.

Fix

Add enqueue_event_deleted_audit in crates/buzz-relay/src/handlers/event.rs as a sibling to enqueue_event_created_audit, following the same pattern:

  • Bounded channel (capacity 1000), backpressure-propagating .send().await
  • Fire-and-log on error with metrics counter
  • pub(super) visibility so side_effects.rs sibling handlers can call it

Wire it into all three deletion paths after the deleted check, so we only audit actual deletions:

  • Records the actor (the user or admin who requested the deletion), not the event author
  • Records the target event ID (or coordinate string for a-tag)
  • Includes a detail JSON with delete_kind ("nip29_admin", "nip09_e_tag", or "nip09_a_tag") and event_kind/channel_id for distinguishability

Testing

Relay lib test suite: 823 passed, 10 failed — all 10 are pre-existing baseline failures (7 media env-gated, 2 admin env-gated, 1 telemetry flaky under parallel suite #3929), zero regressions from this change.

Related

The issue reporter also noted that ARCHITECTURE.md documents only 10 audit actions and omits MediaUploaded. That doc gap is addressed separately.

…ock#4034)

AuditAction::EventDeleted was defined but had no production call site —
neither NIP-09 soft-delete (e-tag or a-tag) nor NIP-29 kind:9005 admin
delete ever wrote an audit log entry. The relay could not produce an
audit trail for any event deletion.

Add enqueue_event_deleted_audit alongside the existing
enqueue_event_created_audit in event.rs, following the same bounded-
channel, backpressure-propagating pattern. Wire it into all three
deletion paths in side_effects.rs:

  1. handle_delete_event_side_effect (kind:9005 NIP-29 admin delete)
  2. handle_standard_deletion_event (NIP-09 e-tag soft-delete)
  3. handle_a_tag_deletion (NIP-09 a-tag coordinate soft-delete)

Each call records the actor (deletion requester), the target event ID
or coordinate, and a detail JSON with the delete_kind and event_kind
so auditors can distinguish admin deletes from user self-deletes and
coordinate-based deletions.

Closes block#4034.

Signed-off-by: Claude <noreply@anthropic.com>
Signed-off-by: iroiro147 <sarthak.singh@juspay.in>
@iroiro147
iroiro147 requested a review from a team as a code owner August 1, 2026 01:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NIP-09 event deletion never writes an audit log entry (EventDeleted is defined but has no production call site)

1 participant