Context
A plan sometimes grants a plain number that counts no model: the audit service’s visible window in days, a retention, an export size. The three kinds (feature, limit, module) had nowhere for it. Separately, ADR 0397 put aLimitReservation port around every action’s unit of work, but no driver used LimitReservationService, so creates at
a limit were still checked from a snapshot only.
Decision
EntitlementKind.Value(value): granted as a number of zero or more (Infinityfor no bound), counting no model.EntitlementValueService.valueOf(entitlement, scope)reads it from the effective plan;undefinedmeans the plan does not set it. A value that gates a call gates it by being in the plan.PlanLimitReservationDriverbindsLimitReservation: for a call a limit entitlement gates (gen’sgates), the unit of work runs insideLimitReservationService.reserve; a call no limit gates commits as it is.
Consequences
- The audit window and similar numbers are plan-catalogue data, edited without code.
- A service with plan limits binds the driver; two creates at the last slot can no longer both pass.
Enforcement
packages/security/entitlements/src/core/services/__tests__/entitlement-value.service.test.ts,
packages/security/entitlements/src/core/drivers/__tests__/plan-limit-reservation.driver.test.ts.