{"record":{"id":"5e460ca60aecb3d5","repo":"block/buzz","slug":"request-has-not-crossed-the-explicit-approval-boun","errorCode":null,"errorMessage":"request has not crossed the explicit approval boundary","messagePattern":"request has not crossed the explicit approval boundary","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/buzz-deletion/src/lib.rs","lineNumber":1414,"sourceCode":"                    &token,\n                    serde_json::json!({\"postgres\": true, \"object_store\": true, \"redis\": true}),\n                )\n                .await?;\n        }\n        DeletionStage::LogicallyVerified => {\n            validate_frozen_inventory(request)?;\n            services\n                .store\n                .mark_retention_pending(\n                    &token,\n                    serde_json::json!({\n                        \"policy\": \"member-erasure and fleet-wide shared-CAS GC are out of V1 scope\"\n                    }),\n                )\n                .await?;\n        }\n        DeletionStage::Submitted | DeletionStage::Inventoried => {\n            anyhow::bail!(\"request has not crossed the explicit approval boundary\")\n        }\n        DeletionStage::RetentionPending | DeletionStage::Aborted => {}\n    }\n    Ok(())\n}\n\nfn token_with_current_fence(token: &LeaseToken, request: &DeletionRequest) -> LeaseToken {\n    LeaseToken {\n        fence_generation: request.fence_generation,\n        ..token.clone()\n    }\n}\n\n/// Prove logical absence by listing each tenant prefix and requiring it\n/// empty — O(1) requests per prefix, independent of fleet size.\nasync fn verify_storage_absence(services: &Services, request: &DeletionRequest) -> Result<()> {\n    for prefix in tenant_prefixes(*request.community_id.as_uuid()) {\n        let page = services","sourceCodeStart":1396,"sourceCodeEnd":1432,"githubUrl":"https://github.com/block/buzz/blob/dad5a33865fc81a2e55b3b60746632f615ec1e3a/crates/buzz-deletion/src/lib.rs#L1396-L1432","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run the explicit approval step for the request first, then retry this operation","Check the request's current DeletionStage before invoking the command","Make orchestration scripts stage-aware: read the stage and branch instead of assuming ordering"],"exampleFix":"# before\nbuzz-deletion approve --id <id> && buzz-deletion run --step retention   # approval skipped/failed silently\n# after\nbuzz-deletion show <id>          # confirm stage == Approved\nbuzz-deletion run --step retention","handlingStrategy":"validation","validationCode":"-- Pre-flight: only invoke post-approval steps when the boundary is crossed\nSELECT stage FROM deletion_requests WHERE id = :id;\n-- proceed only if stage NOT IN ('submitted', 'inventoried')","typeGuard":"fn crossed_approval_boundary(stage: DeletionStage) -> bool {\n    !matches!(stage, DeletionStage::Submitted | DeletionStage::Inventoried)\n}","tryCatchPattern":null,"preventionTips":["Encode the stage ordering in orchestration scripts; assert the previous stage completed before the next command","Never skip the explicit approval step even in test environments — the guard exists so member consent cannot be bypassed"],"tags":["deletion","state-machine","authorization","workflow","cli"],"backgroundTag":"workflow-stage-guard","analyzedSha":"dad5a33865fc81a2e55b3b60746632f615ec1e3a","analyzedAt":"2026-08-20T04:38:24.874Z","contentChangedAt":"2026-08-20T04:38:24.874Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}