---
id: CAP-PFM-LLM-013
title: Set an organization’s AI access and recurring limits
feature: FEAT-PFM-LLM-05
product_area: platform
module: llm
revision: 1
status: draft
product_intent: proposed
implementation_evidence: partially-observed
supersedes: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/proposals/llm-observability/11-decisions.md#D-3'
purpose: Give authorized Rhythm staff an accountable way to change future AI admission.
outcomes:
  - Configured allowance and switches apply to new admissions.
  - Ceiling and version checks reject invalid or stale updates.
  - 'Control audits retain the change, actor and reason.'
concepts:
  - CON-PFM-LLM-003
actors:
  - ACT-PFM-004
  - ACT-PFM-033
surfaces:
  - api
  - console
preconditions:
  - An existing organization is selected.
postconditions:
  - The limits update synchronizes the current period and audit.
permissions:
  - key: hq.llm-usage.manage
    where_checked: api
    scope: global
  - key: hq.llm-usage.manage
    where_checked: console
    scope: global
rules:
  - id: BR-CAP-PFM-LLM-013-01
    proved_by: [ATS-PFM-LLM-013-01, TST-PFM-LLM-007]
    statement: >-
      The sensitive HQ AI usage manage key is required to preview or change limits; read-only staff and
      customer administrators are refused.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#is refused the write before a handler
      runs, whatever the customer’s scope grants
    origin: none
  - id: BR-CAP-PFM-LLM-013-02
    proved_by: [ATS-PFM-LLM-013-02, ATS-PFM-LLM-013-15, TST-PFM-LLM-026, TST-PFM-LLM-037]
    statement: >-
      A replacement supplies the AI switch, base allowance or default, disabled operations, concurrency cap or
      default and note, with omitted optional cap and note reset.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/limits/tenant-limits.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-013-03
    proved_by: [ATS-PFM-LLM-005-12, ATS-PFM-LLM-013-03, ATS-PFM-LLM-013-12, ATS-PFM-LLM-013-17, TST-PFM-LLM-016, TST-PFM-LLM-079]
    statement: >-
      Limit validation accepts a default allowance or a whole credit amount from zero to ten million, a
      default or positive whole concurrency cap, and declared disabled operations stored once in sorted order.
      Notes are trimmed and limited to one thousand characters; reasons are trimmed to one through five
      hundred characters. Invalid input leaves state unchanged.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/limits/tenant-limits.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-013-04
    proved_by: [ATS-PFM-LLM-013-04, ATS-PFM-LLM-013-14, ATS-PFM-LLM-013-16, TST-PFM-LLM-007, TST-PFM-LLM-036, TST-PFM-LLM-053]
    statement: >-
      A changed save requires the inspected limits version, using zero for defaults, and missing or stale
      versions are rejected.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: 'services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#refuses a stale If-Match with 409'
    origin: none
  - id: BR-CAP-PFM-LLM-013-05
    proved_by: [ATS-PFM-LLM-013-05, TST-PFM-LLM-007, TST-PFM-LLM-026]
    statement: >-
      Values identical to stored limits return unchanged without a write, new version or audit entry, even
      with an older supplied version.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/persistence/limits.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-013-06
    proved_by: [ATS-PFM-LLM-007-16, ATS-PFM-LLM-011-10, ATS-PFM-LLM-013-06, TST-PFM-LLM-007, TST-PFM-LLM-019, TST-PFM-LLM-026]
    statement: >-
      A limits save atomically updates the current month’s base allowance and audit event without rewriting
      charges, holds, grants or past periods; later periods use the new base when created.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/limits/tenant-limits.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-013-07
    proved_by: [ATS-PFM-LLM-013-07, TST-PFM-LLM-026]
    statement: >-
      The audit event includes before and after values, reason and actor and marks allowance increases, AI
      re-enablement or operation re-enablement as widening.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/limits/tenant-limits.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-013-08
    proved_by: [ATS-PFM-LLM-013-08, TST-PFM-LLM-007, TST-PFM-LLM-026]
    statement: >-
      Preview reports proposed allowance, committed and remaining credits, limiting reason and
      effective-ceiling pressure without writing limits or audit events.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/limits/tenant-limits.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-013-09
    proved_by: [ATS-PFM-LLM-001-17, ATS-PFM-LLM-013-09, ATS-PFM-LLM-013-10, ATS-PFM-LLM-013-11, ATS-PFM-LLM-013-13, ATS-PFM-LLM-013-18, TST-PFM-LLM-021, TST-PFM-LLM-026, TST-PFM-LLM-077]
    statement: >-
      Disabled AI rejects every operation; an active operation exemption can bypass an operation switch but
      never the global AI switch, and refusal records the disabled-feature reason without a hold.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#refuses
      it when AI is off, whatever exemption is in force
    origin: none
  - id: BR-CAP-PFM-LLM-013-10
    proved_by: []
    statement: The reason belongs in the audit event and is distinct from the explanatory note retained with limits.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/llm.md#Limits'
    origin: none
  - id: BR-CAP-PFM-LLM-013-11
    proved_by: []
    statement: >-
      Only usage managers see the console’s Edit Limits control, which remains disabled with an unavailable
      label.
    kind: permission
    enforced_at:
      - console
    must_prove: false
    provenance: observed
    source: 'react-console:components/console/hq/tenant-ai-usage-card.tsx:639'
    origin: none
scenarios:
  - id: SC-CAP-PFM-LLM-013-01
    given: An organization uses default limits at version zero.
    when: An administrator submits a reasoned allowance increase.
    then: 'The update advances the version, synchronizes the current period and records widening.'
    provenance: test
    source: >-
      services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#syncs this month’s period to the new
      allowance
  - id: SC-CAP-PFM-LLM-013-02
    given: Two administrators use the same limit version.
    when: The second update arrives after the first.
    then: The stale update changes nothing.
    provenance: test
    source: 'services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#changes nothing for a stale If-Match'
edge_cases: []
constraints:
  - The console limit controls are incomplete.
depends_on:
  - CAP-PFM-LLM-005
related:
  - CAP-PFM-LLM-007
  - CAP-PFM-LLM-011
  - CAP-PFM-LLM-014
  - CAP-PFM-LLM-017
journeys: []
open_questions: []
evidence:
  - >-
    services-platform at ad3f6a6582843008ed0f5a17b131878d15829af1: docs/llm.md (Limits);
    docs/milestones/PLAT-M2-ai-usage-hq-controls.md; aws/api/llm-usage.routes.ts (putHqTenantLlmUsageLimits,
    previewHqTenantLlmUsageLimits); services/limits/tenant-limits.ts; services/persistence/limits.ts;
    db/llm-tenant-limits.table.ts; tests e2e/llm-limits.e2e.spec.js,
    integration/services/limits/tenant-limits.integration.spec.js,
    integration/lifecycle/tenant-limits.integration.spec.js, unit/services/tenant-limits.spec.ts,
    unit/services/llm-operation-disabled.spec.ts, unit/aws/api/llm-usage-limits-api.spec.ts.
  - >-
    react-console at baf6dae382d6f41dce976c7f848667ccc37e076f: components/console/hq/tenant-ai-usage-card.tsx
    (disabled Edit Limits).
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-IAM-003, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-005, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-LLM-05-01, FAS-PFM-LLM-05-02, FAS-PFM-LLM-05-03, FAS-PFM-LLM-05-04, FAS-PFM-LLM-05-05]
suites: [TST-PFM-LLM-007, TST-PFM-LLM-016, TST-PFM-LLM-019, TST-PFM-LLM-021, TST-PFM-LLM-026, TST-PFM-LLM-036, TST-PFM-LLM-037, TST-PFM-LLM-053, TST-PFM-LLM-077, TST-PFM-LLM-079]
---

# Set an organization’s AI access and recurring limits

## Purpose

Give authorized Rhythm staff an accountable way to change future AI admission.

## How It Works

A manager supplies the full replacement limits and the version they inspected. Platform validates the allowance, disabled operations, concurrency cap and reason. A preview calculates the proposed effect without writing it. A changed save updates the limits and the current period’s base allowance together with its audit event. A stale changed save is refused, while a replay of already stored values makes no further change. Running requests retain their holds and finish normally. New requests use the revised access switches and allowance. The console shows the planned management control but does not yet let staff perform the change there.

## Relationships

- Publish AI operation definitions and historical prices supplies the prerequisite behavior for this outcome.
