From bad9013e64ded2b0058c771bfd30c5f6c7ce8a25 Mon Sep 17 00:00:00 2001 From: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz> Date: Wed, 14 Oct 2026 11:45:21 -0400 Subject: [PATCH] buzz-db: retire prose describing the dropped fence triggers Rewrite comments and docs that still described the dropped community-write triggers as a backstop. Remove the admission fixture's raw witness insert, which no longer witnesses a trigger bypass once the triggers are gone. Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz> --- crates/buzz-db/src/store/admission_postgres_tests.rs | 12 ++---------- crates/buzz-db/src/store/relay_invite.rs | 6 +++--- crates/buzz-db/src/test_support.rs | 2 +- crates/buzz-relay/src/api/git/transport.rs | 4 ++-- docs/buzz-v1-read-state.md | 5 +++-- scripts/cutover/README.md | 6 +++--- 6 files changed, 14 insertions(+), 21 deletions(-) diff --git a/crates/buzz-db/src/store/admission_postgres_tests.rs b/crates/buzz-db/src/store/admission_postgres_tests.rs index 6f1d8cab68..6ec671a664 100644 --- a/crates/buzz-db/src/store/admission_postgres_tests.rs +++ b/crates/buzz-db/src/store/admission_postgres_tests.rs @@ -29,8 +29,8 @@ async fn fixture() -> (Db, [CommunityId; 3]) { crate::test_support::set_deletion_state(pool, *communities[2].as_uuid(), "fenced").await; // One physical session serves every test API call. PostgreSQL's replica - // role skips the 32 community-write triggers as well as other ordinary - // triggers; the application precheck remains fully active. + // role skips ordinary triggers; application admission remains the only + // community write fence after migration 0061. sqlx::query("SET session_replication_role = replica") .execute(pool) .await @@ -40,14 +40,6 @@ async fn fixture() -> (Db, [CommunityId; 3]) { .await .expect("read replication role"); assert_eq!(role, "replica"); - // Witness that the database backstop is truly bypassed: this raw fenced - // insert would be rejected with the community-write trigger enabled. - sqlx::query("INSERT INTO users (community_id, pubkey) VALUES ($1, $2)") - .bind(communities[2].as_uuid()) - .bind(vec![0xfe_u8; 32]) - .execute(pool) - .await - .expect("raw fenced insert succeeds with triggers disabled"); (db, communities) } diff --git a/crates/buzz-db/src/store/relay_invite.rs b/crates/buzz-db/src/store/relay_invite.rs index 6487696151..c0617058d6 100644 --- a/crates/buzz-db/src/store/relay_invite.rs +++ b/crates/buzz-db/src/store/relay_invite.rs @@ -113,9 +113,9 @@ pub async fn mint_relay_invite( let expires_at = now + chrono::Duration::seconds(ttl_secs as i64); // Mint a v2 opaque invite inside the same lifecycle gate as every other - // community-scoped database write. The trigger remains the final backstop, - // but this typed guard keeps a quiescing community from surfacing as an - // opaque SQLSTATE/HTTP 500 at the API boundary. + // community-scoped database write. The app-side guard is the community + // fence: it holds the shared deletion lock and refuses quiescing writes + // before the insert. let mut tx = crate::begin_community_write_transaction( pool, community, diff --git a/crates/buzz-db/src/test_support.rs b/crates/buzz-db/src/test_support.rs index e94b8b1449..64cdcd3a90 100644 --- a/crates/buzz-db/src/test_support.rs +++ b/crates/buzz-db/src/test_support.rs @@ -47,7 +47,7 @@ pub(crate) async fn quiesce_community_for_tests( } /// Whether `error` is the community-admission rejection taken at transaction -/// entry, as opposed to a later commit-time trigger rejection. +/// entry, as opposed to a later database constraint rejection. pub(crate) fn is_admission_rejection(error: &crate::DbError) -> bool { matches!(error, crate::DbError::AccessDenied(message) if message.contains("write-fenced (quiescing)")) } diff --git a/crates/buzz-relay/src/api/git/transport.rs b/crates/buzz-relay/src/api/git/transport.rs index c3b292d8b4..c84a88c154 100644 --- a/crates/buzz-relay/src/api/git/transport.rs +++ b/crates/buzz-relay/src/api/git/transport.rs @@ -1971,8 +1971,8 @@ async fn finalize_push_inner( } // An already-running receive-pack may cross the durable fence after - // request admission. Revalidate immediately before object-store CAS; DB - // trigger fencing alone cannot roll back an S3 pointer mutation. + // request admission. Revalidate immediately before object-store CAS; + // database admission alone cannot roll back an S3 pointer mutation. let serving_write = match buzz_deletion::acquire_serving_write( &state.db, ctx.tenant.community(), diff --git a/docs/buzz-v1-read-state.md b/docs/buzz-v1-read-state.md index f89e2e0774..07890364cd 100644 --- a/docs/buzz-v1-read-state.md +++ b/docs/buzz-v1-read-state.md @@ -259,8 +259,9 @@ no fixed context-count ceiling. Leaving/rejoining does not erase progress; revoked access hides it. Soft-deleted channels are inaccessible, while hard channel deletion cascades their frontiers. Deleting an account row cascades that actor's frontiers in the same community; -community erasure inventories both tables under the existing write fence. There -is no new public account export/reset endpoint. Operator-assisted erasure/export +community erasure inventories both tables, with serving writes fenced by the +app-side admission guard and the community deletion-lock protocol. There is no +new public account export/reset endpoint. Operator-assisted erasure/export must use the established authenticated operational process and explicitly scope both community and actor; never equate the read-time horizon with data erasure. diff --git a/scripts/cutover/README.md b/scripts/cutover/README.md index 92fd2e0ff8..354870e124 100644 --- a/scripts/cutover/README.md +++ b/scripts/cutover/README.md @@ -30,9 +30,9 @@ steady-state path unless explicitly reviewed. replica-floor shared/exclusive lock ordering). - If a workflow cannot use those protocols yet, execute it under an explicitly reviewed procedure that keeps replica routing fences closed for the run. -- Existing trigger/function backstops remain the commit-time authority during - this transition. Their removal requires separate coverage and fleet gates; - this cutover does not authorize it. +- Community writes use application admission and the deletion-lock protocol. + Retained trigger/function guards remain authoritative for their invariants; + this cutover does not authorize their removal. - Role separation is deliberate: schema reconciliation scripts carry schema convergence only; serving admission/fencing semantics remain in runtime/store code paths with startup verification and metrics.