Skip to content

fix(relay): soft-delete workflow definition event on workflow delete - #4318

Open
iroiro147 wants to merge 1 commit into
block:mainfrom
iroiro147:fix/2879-workflow-def-event-soft-delete
Open

fix(relay): soft-delete workflow definition event on workflow delete#4318
iroiro147 wants to merge 1 commit into
block:mainfrom
iroiro147:fix/2879-workflow-def-event-soft-delete

Conversation

@iroiro147

Copy link
Copy Markdown
Contributor

What

Makes buzz workflows delete actually hide the workflow from every read path — not just from triggers.

Why (bug report)

Filer verified end-to-end on v0.4.26 against the live relay:

$ buzz workflows delete --workflow <id>            # accepted
$ buzz workflows list                              # <id> still present, full YAML
$ buzz workflows get --workflow <id>               # full YAML returned
$ buzz workflows trigger --workflow <id>           # 400: workflow not found

The row delete succeeded; only the trigger endpoint knew. Operators monitoring the relay via list/get couldn't tell deleted from live without attempting a trigger.

Root cause

handle_a_tag_deletion in crates/buzz-relay/src/handlers/side_effects.rs dispatches on the kind in the a tag. The KIND_WORKFLOW_DEF arm called delete_workflow_for_owner and invalidate_channel_workflows, then returned — it never soft-deleted the kind:30620 event row itself. The generic addressable-events arm below it (is_parameterized_replaceable) does call soft_delete_by_coordinate, but the workflow branch returns first.

The generic arm's doc comment even called this out:

"Listed after the workflow branch so workflow's bespoke deletion (which doesn't soft-delete the events row by design — that's a separate concern) takes precedence."

That "separate concern" is exactly this bug. The "by design" doesn't survive contact with the actual read paths: workflows list and workflows get both query the kind:30620 event via REQ, so a live event row made the relay keep reporting the deleted workflow.

How

  • Refactored the workflow arm to return the deleted workflow's UUID (instead of ()).
  • Added a follow-up step gated on that UUID being Some: decode the pubkey_hex from the a tag and call soft_delete_by_coordinate(30620, pubkey, d_tag) on the live event row, with the standard created_at cutoff so a stale deletion event cannot tombstone a newer replacement head.
  • The gate matters: if delete_workflow_for_owner fails (owner mismatch, etc.), the event row is left alone. A failed delete must not be able to hide a live workflow.
  • Tracing logs success/no-op/error paths to match the rest of the module's observability.

Files

  • crates/buzz-relay/src/handlers/side_effects.rshandle_a_tag_deletion workflow arm, +54 / −1.

Verification

  • cargo check -p buzz-relay --lib — clean.
  • cargo test -p buzz-relay --lib workflow — 17/17 pass.
  • Full cargo test -p buzz-relay --lib — 827 pass, 9 fail (identical to baseline main; pre-existing media/admin/env-gated tests unrelated to this change).

Behavior

Action Before After
workflows delete (row + event) Row gone, event still live Both gone
workflows list after delete Still returns the workflow Stops returning it
workflows get after delete Still returns full YAML Returns "not found"
workflows trigger after delete 400 workflow not found 400 workflow not found (unchanged)
Delete with owner mismatch Row intact, event live (error surfaced) Row intact, event live (unchanged)

Closes #2879.

`buzz workflows delete` removes the `workflows` row and invalidates the
engine cache (so triggers fail correctly), but the kind:30620 definition
event itself stayed live — `workflows list` and `workflows get` were
still reading it via Nostr REQ, so every surface an operator could
inspect reported the workflow as live. Triggering afterwards was the
only way to find out it was gone.

The generic addressable-events arm in `handle_a_tag_deletion` already
soft-deletes by coordinate; the workflow arm never did. Extend the
workflow arm to call `soft_delete_by_coordinate(30620, pubkey, d_tag)`
once the row has been successfully deleted — gated on the delete
succeeding so a failed match can't tombstone a live workflow's event.

Refs: block#2879
Signed-off-by: Sarthak Singh <sarthak.singh@juspay.in>
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.

buzz workflows delete removes the workflow but leaves its kind:30620 event live, so workflows list and workflows get still return it

1 participant