Coverage-matrix operation x entitlement/quota x transport in INVENTORY-CUSTOCRM-0009.
Enforcement infrastructure:
- HasEntitlement DRF permission (org-level feature gate, orthogonal to
HasCapability); centralized api_exception_handler mapping
EntitlementRequired->403, QuotaExceeded HARD->409 / RATE+CONCURRENT->429
(+Retry-After), PolicyUnavailable->503, UsageConflict->409.
- quota_service.check() advisory pre-check.
- UsageReservation lease model + reserve_usage/release_usage/
expire_stale_reservations for CONCURRENT quotas (SPEC-HUB-0022 section 7);
worker sweep reaps lapsed leases. QuotaExceeded now carries mode.
Cumulative quota gates (record_usage, mirror ai_agent_slots):
- products (create_product), client_connections (create_integration),
new_dialogs_per_period (new dialog only, is_new branch in ingest + support),
managed_ai_credits (successful LlmInvocation, best-effort accounting).
Storage gate: assert_storage_quota pre-write check blocks overage on writes,
reads never gated (PLAN section 12).
Concurrent p2p_calls: reserve on CallSession create, release on terminal
transition in calls/lifecycle.py.
Entitlement gates on views: sales_department, support_department,
product_sales_api (inline), p2p_calls, knowledge_base, managed_ai
(inline handoff on deny).
Deferred (no target module): crm_api, voice_ai, sso_saml,
concurrent_voice_sessions, customer_audit (tracks B/C/C12).
bootstrap_edevs_owner now provisions an active STARTUP subscription
(ensure_default_subscription) since post-C07 every tenant operation requires
a subscription; create_test_subscription reconciles ai_agent_slot counter for
tests that create active agents directly.
Gate (PLAN section 12): coverage-matrix exists; storage overage blocks writes
not reads; downgrade/suspension zero-limit clears entitlements without delete;
Free counts only a brand-new dialog.
Targeted tests: reservations 5, quota_service 4, enforcement mapping 6.
Full backend regression green except one pre-existing SOCKS5 test and one
pre-existing membership-migration ProtectedError (both fail on clean HEAD).
UI unchanged. Production migration/deploy and publication of production
PlanVersion are not part of this commit.