block/buzz · error · anyhow::Error

request has not crossed the explicit approval boundary

Error message

request has not crossed the explicit approval boundary

What it means

The deletion state machine guards post-approval work: a request still in the Submitted or Inventoried stage has not crossed the explicit approval boundary, so operations that assume member approval (inventory freeze, retention handling) refuse to run. Only explicitly approved requests may proceed.

Solutions

  1. Run the explicit approval step for the request first, then retry this operation
  2. Check the request's current DeletionStage before invoking the command
  3. Make orchestration scripts stage-aware: read the stage and branch instead of assuming ordering

Example fix

# before
buzz-deletion approve --id <id> && buzz-deletion run --step retention   # approval skipped/failed silently
# after
buzz-deletion show <id>          # confirm stage == Approved
buzz-deletion run --step retention
Defensive patterns

Strategy: validation

Validate before calling

-- Pre-flight: only invoke post-approval steps when the boundary is crossed
SELECT stage FROM deletion_requests WHERE id = :id;
-- proceed only if stage NOT IN ('submitted', 'inventoried')

Type guard

fn crossed_approval_boundary(stage: DeletionStage) -> bool {
    !matches!(stage, DeletionStage::Submitted | DeletionStage::Inventoried)
}

Prevention

When it happens

Trigger: Invoking the step whose stage-match lands on the Submitted | Inventoried arm at crates/buzz-deletion/src/lib.rs:1242-1245 — e.g. attempting retention/approval-flow work on a request that was submitted or inventoried but never explicitly approved.

Common situations: An operator or automation script skips the approval command and jumps straight to the next stage; a re-run after a partial pipeline assumes approval happened when it did not persist.

Related errors


AI-assisted analysis of block/buzz@dad5a33865 (2026-08-20). Data as JSON: /api/errors/5e460ca60aecb3d5. Report an issue: GitHub.

Appendix: source

Thrown at crates/buzz-deletion/src/lib.rs:1414

                    &token,
                    serde_json::json!({"postgres": true, "object_store": true, "redis": true}),
                )
                .await?;
        }
        DeletionStage::LogicallyVerified => {
            validate_frozen_inventory(request)?;
            services
                .store
                .mark_retention_pending(
                    &token,
                    serde_json::json!({
                        "policy": "member-erasure and fleet-wide shared-CAS GC are out of V1 scope"
                    }),
                )
                .await?;
        }
        DeletionStage::Submitted | DeletionStage::Inventoried => {
            anyhow::bail!("request has not crossed the explicit approval boundary")
        }
        DeletionStage::RetentionPending | DeletionStage::Aborted => {}
    }
    Ok(())
}

fn token_with_current_fence(token: &LeaseToken, request: &DeletionRequest) -> LeaseToken {
    LeaseToken {
        fence_generation: request.fence_generation,
        ..token.clone()
    }
}

/// Prove logical absence by listing each tenant prefix and requiring it
/// empty — O(1) requests per prefix, independent of fleet size.
async fn verify_storage_absence(services: &Services, request: &DeletionRequest) -> Result<()> {
    for prefix in tenant_prefixes(*request.community_id.as_uuid()) {
        let page = services

View on GitHub (pinned to dad5a33865)