Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 11 additions & 22 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -489,23 +489,17 @@ All database access. Uses `sqlx::query()` (runtime, not compile-time macros) —
- Approval tokens: `create_approval` receives the raw token and hashes it internally with SHA-256.
- DDL injection protection in partition manager: allowlist of table names + strict suffix/date validators.

### Supported Writer Contract (transition state)

The repository is moving toward a **supported-writer contract** where relay-owned
write APIs provide the only supported mutation path for tenant data. The current
shape is an explicit transition, not a flag day:

- **Trajectory:** converge from trigger/function/FK-enforced fencing toward
application-owned transaction protocols, while keeping existing DB backstops
in place until coverage and fleet gates are proven.
- **Community fence (transition foundation):** runtime admission APIs now offer
one shared community deletion lock per transaction, while deletion lifecycle
transitions take the matching exclusive lock. A supported serving transaction
never spans communities. Serving leases use the same application admission.
Startup and deletion catalog validation tolerate the universal fence objects
being absent; inventories still record live fences for older executors.
Desired-state bootstraps install only explicitly declared legacy fences.
New tenant-owned tables rely on application admission, without a fence trigger.
### Supported Writer Contract

Relay-owned write APIs provide the supported mutation path for tenant data:

- **Community fence:** supported serving writers admit each tenant transaction
through the runtime API, which takes one shared community deletion lock and
checks active, undeleted state. Deletion lifecycle transitions take the
matching exclusive lock. A serving transaction never spans communities.
The universal per-table write-fence triggers and their functions have been
retired after writer coverage and fleet gates; the community tombstone guard
remains. New tenant-owned tables rely on this admission alone.
- **Replica floor:** supported channel-event insertions check `created_at`
against `clock_timestamp()` on their admitted transaction using the shared
960-second floor. The ordered heartbeat handshake and activity scan retain
Expand All @@ -517,11 +511,6 @@ shape is an explicit transition, not a flag day:
Drain old connections/in-flight transactions, stop out-of-band writers, and
hold the replica breaker closed through the drop until replay catches up.
Already-running old pods do not reverify the trigger on each heartbeat.
- **Dual enforcement (community fence transition):** application-owned
lock+precheck paths run in front of the existing community trigger/function
enforcement. Removing those backstops is a separate gated migration, after
every pod tolerates their absence and no rollback below that version is
expected.
- **Role separation:** relay/runtime code owns admission and lock protocols;
operator maintenance/backfill workflows must either use those protocols or run
under explicit reviewed procedures that keep routing fences closed.
Expand Down
8 changes: 4 additions & 4 deletions crates/buzz-db/src/runtime/admitted_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ use crate::Result;
/// statements on it, and [`AdmittedTx::commit`] and [`AdmittedTx::rollback`]
/// are the only ways it can end the transaction. Inside the crate, the
/// `conn()` accessor hands statements the connection; the type can't stop
/// crate code from issuing a raw `COMMIT` through it, so the database
/// community write fences remain the backstop while deployed. Internal writers
/// must preserve this boundary and use `commit()` for staged follow-up work.
/// Dropping the value without committing rolls back, as with [`sqlx::Transaction`].
/// crate code from issuing a raw `COMMIT` through it. Internal writers must
/// preserve this transaction boundary and use `commit()` for staged follow-up
/// work. Dropping the value without committing rolls back, as with
/// [`sqlx::Transaction`].
///
/// These are live regressions for the guarantee. Event-write helpers accept an
/// admitted transaction:
Expand Down
Loading