Repository navigation
buzz-db: pin explicit FK-child cleanup and same-workflow fire links - #8317
Draft
TheSentinel454 wants to merge 4 commits into
Draft
TheSentinel454 wants to merge 4 commits into
TheSentinel454 wants to merge 4 commits into
Conversation
TheSentinel454
pushed a commit
that referenced
this pull request
Oct 14, 2026
Address review on #8317: the held-tx race scaffold could not fail without the admission barrier (the FK key-share row lock blocked quiescing anyway), so seed children in sequence and rename the test; the barrier stays pinned by begin_quiescing_waits_for_open_admitted_writer_note_update. Select the heartbeat by executor_id so a SET NULL regression fails the assertion, and document why attach_scheduled_workflow_run rejects cross-workflow runs. Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
added 4 commits
October 14, 2026 11:03
Audit every remaining ON DELETE CASCADE / SET NULL foreign key (BUZZ-320) against the supported parent-removal paths, with FK actions retired in the per-test schema: - attach_scheduled_workflow_run now links a scheduled fire only to a run of the same workflow, so a cross-workflow link can never block an explicit run delete once FK actions are dropped. - The community purge test seeds channel members, personal-read frontiers, owner/agent users, product feedback and an executor heartbeat, races a held child-insert transaction against quiescing, and requires explicit removal (or provenance clearing) of every child with no FK action. - The manifest-key lifecycle test runs on the retired-FK schema. FK constraints, actions, triggers and checks are unchanged; a later migration drops the actions. Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
Address review on #8317: the held-tx race scaffold could not fail without the admission barrier (the FK key-share row lock blocked quiescing anyway), so seed children in sequence and rename the test; the barrier stays pinned by begin_quiescing_waits_for_open_admitted_writer_note_update. Select the heartbeat by executor_id so a SET NULL regression fails the assertion, and document why attach_scheduled_workflow_run rejects cross-workflow runs. Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
TheSentinel454
force-pushed
the
elrond/explicit-cascade-deletes-2
branch
from
October 14, 2026 15:04
e076bec to
a793d89
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
This closes the identified debt from #8212. Every remaining
ON DELETE CASCADE/SET NULLforeign key was audited against every supported way its parent row gets removed, with FK actions retired in the per-test schema (test_support::retire_foreign_key_delete_actions). One production change was needed. The rest is already explicit and is now covered by tests.Production change:
attach_scheduled_workflow_run(store/workflow.rs) now links a scheduled fire only to a run of the same workflow (EXISTSon(community_id, workflow_id, id)in the existing admittedUPDATE). Before this, a fire for workflow B could reference a run of A. That FK is alreadyNO ACTION, so the link would block A's explicit run delete. The only production caller (buzz-workflowcron tick) attaches the run it just created for the same workflow, so live behavior is unchanged. A mismatched attach now returnsfalselike any other non-match, and the caller already treats that as best-effort.FK audit (all 12 delete actions)
scheduled_workflow_fires → workflowsworkflow_runs → workflowsworkflow_approvals → workflowsworkflow_approvals → workflow_runsjoin_policy_acceptances → relay_memberschannel_members → channelspersonal_read_frontiers → personal_read_accountspersonal_read_frontiers → channelsusers.agent_owner_pubkey → usersproduct_feedback → communitiescommunity_idexplicitly. Pinned here.community_deletion_manifest_keys → community_deletion_requestsmark_logically_verifieddeletes chunks explicitly, and the chunk guard trigger is unchanged. The existing lifecycle test now runs with FK actions retired.community_deletion_executor_heartbeats → community_deletion_requestsAudit method: searched
crates/**/*.rsforDELETE FROMagainst each parent table. Every directDELETE FROM communities/usershit is in#[cfg(test)]fixtures. Production removes rows only through the scoped purge loop instore/deletion.rsand the channel soft delete instore/channel.rs.Not added: per-parent delete APIs. They would duplicate the community purge for parents that are never hard-deleted. I also left out a source-text "no hard delete" policy test, because it would pass without any production fix. If a single-user, channel, read-account, request or community hard delete is ever added, it has to clear
agent_owner_pubkey(only that column) and delete these children explicitly first.Tests
attach_rejects_run_from_another_workflow: a claim for B can't be linked to A's run, and the fire stays unlinked.purge_removes_fk_children_explicitly_without_fk_actions: on the retired-FK schema,channel_membersandpersonal_read_frontierschildren are seeded through an admitted transaction, and then the production quiesce → fence → purge runs. Every child must be deleted explicitly, both users must be removed, feedback must survive withcommunity_id = NULL, and the retained request's heartbeat (selected byexecutor_id) must stay linked. The quiesce barrier against open admitted writers is already pinned bybegin_quiescing_waits_for_open_admitted_writer_note_update; this test does not re-claim it.manifest_key_chunks_bind_freeze_execution_and_cleanupnow retires FK actions first.Each test was checked to fail when its production behavior is removed: dropping the
EXISTSguard, droppingpersonal_read_frontiersfrom the purge order (23503), dropping feedback provenance clearing, and dropping the explicit manifest chunk delete. All four failed as expected.What got simpler
The production change is one predicate. No new concepts or APIs. The FK audit is now settled, so the follow-up migration can drop all 12 actions at once. No new delete code was needed.
Identified debt (pre-existing, outside this diff): the cron tick in
buzz-workflow/src/lib.rslogs onlyErrfromattach_scheduled_workflow_run; anOk(false)(no matching unlinked claim) leaves the fire unlinked without a trace.Identified debt (unrelated, pre-existing):
writer_pool_rejects_non_read_committed_database_defaulthangs with no active query on clean177551ddaas well (bounded after ~270 s on both checkouts).Verification (Blox, at the exact tree of this commit)
cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningscargo nextest run -p buzz-db --libscripts/postgres-test-run.sh -pbuzz-admin / audit / deletion / push-gateway / relay / search / workflowscripts/postgres-test-run.sh -p buzz-dbPoolTimedOutinrouted_fallback_spends_one_acquire_budget_when_aurora_cache_is_cold(pool setup under full-lane load; it passed on the clean-baseline lane and passes in isolation at this tree, 1/1 in 1.7 s)The new tests are selected by the
postgres-cinextest filter(test(/postgres_tests::/) or binary(/^postgres_/)) and not test(/(^|::)external_infra[^:]*::/).