Summary
handle_a_tag_deletion in crates/sprout-relay/src/handlers/side_effects.rs calls state.db.delete_workflow(...) for the KIND_WORKFLOW_DEF branch. delete_workflow (in crates/sprout-db/src/workflow.rs:451) only DELETEs from the workflows table (with workflow_runs / workflow_approvals cascading). It does not touch the underlying kind:30620 event row in events — that row stays alive with deleted_at IS NULL, so REQ subscribers for kind:30620 events keep getting the deleted workflow's authoring event back.
This is the same bug shape as #714 (a-tag NIP-09 deletion no-op for kind:30023), just localized to the workflow kind. #714 fixes all other parameterized-replaceable kinds; the workflow branch was intentionally left as-is in that PR to avoid silently changing workflow lifecycle assumptions.
Why this is its own issue
The workflow team likely has assumptions baked in about whether the events row sticks around (e.g. for "what was the workflow definition that just got deleted" audit lookups via get_event_by_id_including_deleted, or REQ-based discovery of historical defs). Closing this gap requires either:
- Calling
Db::soft_delete_by_coordinate(KIND_WORKFLOW_DEF as i32, &pubkey, d_tag) inside the workflow branch in addition to delete_workflow, and verifying nothing else relies on the row staying live; OR
- Deciding that's a behavior change the workflow team explicitly wants — and at that point we might also want to revisit whether
delete_workflow should be invoked at all on a-tag deletion vs e-tag deletion, since the two paths currently diverge.
Either way, this needs eyes from someone who knows the workflow code, which is why it's scoped out of #714 / #716.
Reproduce
- Publish a kind:30620 workflow definition.
- Publish a kind:5 deletion with
["a", "30620:<pk>:<d-tag>"].
- The workflow is removed from
workflows (good).
REQ { kinds: [30620], authors: [<pk>] } still returns the kind:30620 event (bug).
Code pointers
Out of scope
Whether to keep delete_workflow's side effects (workflow_runs cascade, etc.) intact while also soft-deleting the events row. That's the workflow team's call.
Discovered while
Building #716. Caught by tracing the existing match arm; flagged in the PR description there too.
Summary
handle_a_tag_deletionincrates/sprout-relay/src/handlers/side_effects.rscallsstate.db.delete_workflow(...)for theKIND_WORKFLOW_DEFbranch.delete_workflow(incrates/sprout-db/src/workflow.rs:451) onlyDELETEs from theworkflowstable (withworkflow_runs/workflow_approvalscascading). It does not touch the underlying kind:30620 event row inevents— that row stays alive withdeleted_at IS NULL, so REQ subscribers for kind:30620 events keep getting the deleted workflow's authoring event back.This is the same bug shape as #714 (a-tag NIP-09 deletion no-op for kind:30023), just localized to the workflow kind. #714 fixes all other parameterized-replaceable kinds; the workflow branch was intentionally left as-is in that PR to avoid silently changing workflow lifecycle assumptions.
Why this is its own issue
The workflow team likely has assumptions baked in about whether the events row sticks around (e.g. for "what was the workflow definition that just got deleted" audit lookups via
get_event_by_id_including_deleted, or REQ-based discovery of historical defs). Closing this gap requires either:Db::soft_delete_by_coordinate(KIND_WORKFLOW_DEF as i32, &pubkey, d_tag)inside the workflow branch in addition todelete_workflow, and verifying nothing else relies on the row staying live; ORdelete_workflowshould be invoked at all on a-tag deletion vs e-tag deletion, since the two paths currently diverge.Either way, this needs eyes from someone who knows the workflow code, which is why it's scoped out of #714 / #716.
Reproduce
["a", "30620:<pk>:<d-tag>"].workflows(good).REQ { kinds: [30620], authors: [<pk>] }still returns the kind:30620 event (bug).Code pointers
crates/sprout-relay/src/handlers/side_effects.rs:~1330— the workflow branch inhandle_a_tag_deletion.crates/sprout-db/src/workflow.rs:451—delete_workflow, only touchesworkflows.crates/sprout-db/src/event.rs—soft_delete_by_coordinate(will exist post-fix(relay): NIP-09 a-tag deletion soft-deletes addressable rows (#714) #716; the helper to call).Out of scope
Whether to keep
delete_workflow's side effects (workflow_runs cascade, etc.) intact while also soft-deleting the events row. That's the workflow team's call.Discovered while
Building #716. Caught by tracing the existing match arm; flagged in the PR description there too.