Outbound Provider Cutover Acceptance Test
Test a migration between outbound providers for legacy-worker fencing, uncertain sends and shared allowance continuity. Use when replacing a sender while other lanes continue operating; this is an isolated acceptance procedure, not production cutover authorization.
Produce executable checks tying the migration decision to actual old/new transport requests, external effects and durable accounting. A routing flag alone does not establish that the old sender has stopped. ## Key Points - [Azure Strangler Fig pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/strangler-fig): gradual routing of replaced functionality. - [AWS retry and idempotency design](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/): caller intent, identity and late requests. - [Firestore transactions](https://firebase.google.com/docs/firestore/manage-data/transactions): callback retries after concurrent edits.
skilldb get production-audit-skills/outbound-provider-cutover-acceptance-testFull skill: 50 linesOutbound Provider Cutover Acceptance Test
Produce executable checks tying the migration decision to actual old/new transport requests, external effects and durable accounting. A routing flag alone does not establish that the old sender has stopped.
Freeze the handover contract
Identify the migration scope, immutable account identity, reviewed configuration revision, every sending entrypoint, outstanding-attempt states and permitted transitions. Include scheduled, manual and external senders: an application gate cannot fence a sender that bypasses it. Unknown ingress means the handover is not yet proved.
Record the application's allowance scope, period/timezone, charged outcomes, reservation lifecycle and required legacy-history evidence. Distinguish zero usage from unavailable accounting. A ten-minute delay, UTC day or platform-wide quota may be a local policy; do not impose it elsewhere. Define logical intent from the application's operation and approval identity, not equal text alone.
Use controlled synthetic destinations with two observable transports, resettable durable state and bounded execution. No test should publish through a real account. Inspect the actual service/worker entrypoints and caller results; a mock of the routing decision alone cannot demonstrate enforcement. Setup or observer failure makes evidence unavailable.
Exercise the ownership boundary
Start with a permitted handover: complete owned history, resolved old attempts and the exact reviewed revision. Activate one lane and submit an approved intent. Verify the new transport's effect and stored receipt, rejection through the old path, and continued operation of an unrelated legacy lane. Migration must not silently approve held content or change an intent's account/revision.
Use barriers to pause an old worker immediately after its durable claim. Begin draining, attempt another old claim, and attempt activation while the first remains outstanding. Require the declared fence at admission and activation. Release the worker, settle its exact attempt with evidence, then retry the migration decision under a fresh reviewed revision where required. Waiting longer is not evidence that the worker or its external effect ceased.
Separately let the old provider commit an effect and lose its response. Advance beyond the configured drain/lease time and try the new route for that intent. Preserve the unresolved attempt, identity and reservation; do not clear it or fall back to the replacement provider. Provider-local idempotency keys do not establish cross-provider deduplication. Incident reconciliation requires that provider's actual lookup/retry contract, not a new key or another destination.
Test stale migration revisions and a different immutable account with the same display handle. Require rejection before activation or sending. Pausing a lane may block future admission without cancelling an already-started request; verify the declared boundary rather than expecting cancellation.
Prove accounting survives the switch
Import a known legacy baseline that leaves one allowed slot. Race two distinct approved intents through different supported entrypoints. Observe the imported count, reservations and both providers' effect counters. At most the permitted new effects may occur; changing transport must not reset the allowance. Exercise zero allowance and the declared period boundary separately.
Provide incomplete pages, changing history, unresolved attempts and unproved ownership. Require an unavailable/blocked result rather than a fabricated zero baseline. Document the history API's actual completeness/consistency guarantee: rereading one page does not prove an atomic snapshot. Account matching must use the provider's documented identity scope.
Where the datastore can rerun transaction callbacks, force a retry and check that admission/accounting stays consistent without repeating the external write inside the callback. Firestore documents this behavior; do not infer identical retry semantics for every store. Shared local reservations alone cannot prove remote exactly-once execution after a crash.
Demonstrate sensitivity and report limits
Run the same checks against a valid implementation and separate negative controls that ignore outstanding claims, discard imported usage or scope deduplication only to the selected provider. Require an observable invariant failure for each exercised fault. A safe rollback may pause both paths; automatically reopening the old sender can duplicate unresolved work.
Record source/fixture versions, contract, controlled interleaving, immutable account/intent/revision, request order, effect counts, stored claims/reservations and caller outcome. Separate attempted requests from applied effects. Classify cases as passed, failed or unavailable and list unexercised entrypoints, history consistency and crash windows. A synthetic pass proves neither real account authorization/delivery nor adoption or causal agent improvement.
References and rights
Primary documentation checked 2026-11-04:
- Azure Strangler Fig pattern: gradual routing of replaced functionality.
- AWS retry and idempotency design: caller intent, identity and late requests.
- Firestore transactions: callback retries after concurrent edits.
Original SkillDB-authored procedure under LicenseRef-SkillDB-Content. References verify behavior; no source prose or code is copied. The adapter's MIT license does not apply to catalog bodies.
Install this skill directly: skilldb add production-audit-skills
Related Skills
Permission Drift Audit
Verify that permissions remain correct as objects evolve through their lifecycle. Permissions are not static: they change when teams change, projects are…
Production Audit Master Checklist
This meta-skill ties together all 11 production audit skills into a prioritized execution plan. Use this as the starting point for any production audit…
Recovery & Resume Audit
Verify that interrupted workflows can restart safely without losing progress, duplicating work, or leaving the system in an inconsistent state. This audit…
Reliability & Resilience Audit
This is the most comprehensive audit in the production audit pack. It tests long-running, distributed workflows under real-world conditions: timeouts, partial…
State Machine Audit
Verify that workflow states are explicitly defined, transitions are validated, impossible states are prevented, and the system never gets stuck in an…
Throughput & Scale Audit
Verify that the system behaves correctly and remains responsive as work volume increases. This audit catches the class of bugs that only appear at real-world…