Tenant and subject residency policies route primary data, indexes, logs, exports, backups, async queues, and worker dispatch to adopter-defined regions, fail closed on disallowed destinations, and define migration and disaster-recovery behavior without asserting regulatory compliance.
Package status: AI-assisted reference package. Static package validation has passed; implementation scenarios remain not run and human domain review is required before stable adoption.
Decision
Each tenant carries a residency policy referencing adopter-defined region codes. All persistence and dispatch surfaces enumerated in residency-surfaces.yaml resolve destination region before write or enqueue. Disallowed destinations fail closed. Policy cache entries invalidate on update; stale or ambiguous cache state denies writes when fail_closed_on_stale_policy_cache is true. Migration follows migration-state.yaml with durable cutover artifacts.
Scope
- Residency policy attachment, routing hooks, fail-closed enforcement, queue and worker dispatch routing, cross-region migration, and DR constraints.
Outside this block
- Legal determination of which regions satisfy a customer contract; adopters define allowed region sets.
- Global CDN caching of public non-personal assets.
- Tenant isolation authorization model (see tenant isolation block).
Contract
- Every write path consults residency resolver output before committing; missing policy fails closed when the profile requires explicit policy for the tenant class.
- Disallowed destination region returns a problem-details error and does not partially persist replicas in the forbidden region.
- Search indexes, async export jobs, async_queues, and worker_dispatch inherit the same region decision as primary data for the same tenant context.
- fail_closed_on_stale_policy_cache denies writes when policy cache is expired or mid-invalidation during policy updates.
- Backup targets must reside in a region listed as backup_allowed for the tenant policy; cross-border backup requires explicit profile flag and audit entry.
- Migration transitions through states in migration-state.yaml; cutover switches reads and writes atomically per profile cutover protocol and emits artifact_fields.
- DR failover reads from secondary region only when primary health checks fail and secondary is pre-approved in policy; writes during DR follow split_brain_write_block_during_dr rules.
- Structured logs and telemetry carrying personal data use the same region routing as primary storage when logs_in_scope is true in the profile.
Implementation guidance
- Centralize region resolution in a library used by ORM hooks, job enqueue, export schedulers, and worker dispatch routers.
- Tag objects with residency_region metadata at creation for later audit and migration inventory.
- Run pre-flight checks before migration cutover comparing row counts and checksum samples per migration_verify_sample_percent.
- Invalidate policy cache on policy update events before serving new writes when policy_cache_invalidation_on_update is true.
Failure handling and safeguards
- Resolver outage fails closed for writes requiring residency decisions.
- Partial migration rollback restores primary region authority and marks secondary copies quarantined in rollback_quarantined state.
- Misconfigured global bucket defaults cannot override per-tenant resolver output.
Verification and operations
- Tests attempt writes and enqueue operations to forbidden regions and expect denial without side effects.
- Migration drills execute copy-verify-cutover on staging tenants quarterly.
- Metrics track fail-closed denials, migration duration, policy cache stale denials, and DR activations.
Adoption assumptions
- Names and numeric values in example.yaml, residency-surfaces.yaml, and migration-state.yaml are an adoption profile, not universal defaults.
- The adopting team defines region catalogs, contractual constraints, and DR geography without this block claiming regulatory compliance.