---
id: ATS-PFM-LLM-013
scope: CAP-PFM-LLM-013
product_area: platform
module: llm
revision: 2
status: proposed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-PFM-LLM-013-01
    title: Limit changes require management authority
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-01
    preconditions: 'Read-only staff, a customer administrator and a manager have sessions.'
    steps: Attempt limit preview and write as each.
    expected: Only the manager can proceed; denied callers write nothing.
    negative: true
    data_needs: 'Authorized and unauthorized fixtures for the scenario, with controlled request and usage records.'
    bound_to:
      - TST-PFM-LLM-007
    provenance: test
    source: 'services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#is refused the write'
    category: permission
    test_sources:
      - 'services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#is refused the write'
      - >-
        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
      - 'services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#changes nothing'
  - id: ATS-PFM-LLM-013-02
    title: Full replacement clears omitted notes
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-02
    preconditions: Stored limits include a note.
    steps: Replace limits with that note omitted.
    expected: The note clears and the changed configuration advances a version.
    negative: false
    data_needs: Fixtures representing stored limits include a note.
    bound_to:
      - TST-PFM-LLM-026
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#leaves
      the notes cleared, since a replacement states them
    category: rule
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#leaves
        the notes cleared, since a replacement states them
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#stores
        the narrower values at version 2
  - id: ATS-PFM-LLM-013-03
    title: Invalid limit values preserve all records
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-03
    preconditions: An organization has saved limits.
    steps: 'Submit excessive allowance, unknown operation and blank reason examples.'
    expected: 'Each invalid field is reported and limits, period and audit remain unchanged.'
    negative: true
    data_needs: Fixtures representing an organization has saved limits.
    bound_to: []
    provenance: proposed
    source: 'services-platform:modules/llm/services/limits/tenant-limits.ts:validateTenantLimitsInput'
    category: validation
    test_sources: []
  - id: ATS-PFM-LLM-013-04
    title: Changed saves need the inspected version
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-04
      - INV-DOM-PFM-LLM-003-09
    preconditions: Stored limits have version one.
    steps: Attempt a changed save with no version and an older version.
    expected: Missing-version and stale-version errors preserve existing state.
    negative: true
    data_needs: Fixtures representing stored limits have version one.
    bound_to:
      - TST-PFM-LLM-007
    provenance: test
    source: >-
      services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#refuses a write with no If-Match with 400
      naming the header
    category: validation
    test_sources:
      - >-
        services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#refuses a write with no If-Match with
        400 naming the header
      - 'services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#refuses a stale If-Match with 409'
      - 'services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#changes nothing for a stale If-Match'
  - id: ATS-PFM-LLM-013-05
    title: Replaying stored values adds no history
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-05
    preconditions: A valid limits replacement has committed.
    steps: Submit the same values again.
    expected: The response says unchanged and adds neither audit nor period mutation.
    negative: false
    data_needs: Fixtures representing a valid limits replacement has committed.
    bound_to:
      - TST-PFM-LLM-007
      - TST-PFM-LLM-026
    provenance: test
    source: >-
      services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#answers a replay of the write that
      committed with 200 and no second audit row
    category: invariant
    test_sources:
      - >-
        services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#answers a replay of the write that
        committed with 200 and no second audit row
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#answers
        the row as it is and says nothing changed
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#does
        not touch the period again
  - id: ATS-PFM-LLM-013-06
    title: Allowance change affects the current period only
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-06
      - INV-DOM-PFM-LLM-003-10
    preconditions: Current usage includes spend and holds alongside a prior month.
    steps: Increase the recurring allowance.
    expected: 'The current base changes while prior allowance, spend and reservations remain intact.'
    negative: false
    data_needs: Fixtures representing current usage includes spend and holds alongside a prior month.
    bound_to:
      - TST-PFM-LLM-026
      - TST-PFM-LLM-007
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#moves
      this month’s allowance to the new figure
    category: transition
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#moves
        this month’s allowance to the new figure
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#leaves
        what was spent and held exactly as it was
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#leaves
        last month’s allowance as it was
      - >-
        services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#syncs this month’s period to the new
        allowance
  - id: ATS-PFM-LLM-013-07
    title: Widening audit distinguishes more capacity
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-07
    preconditions: Changes raise and reduce allowance and toggle AI and operations.
    steps: Apply each change with a reason.
    expected: >-
      Before and after values are retained, and only increased allowance or re-enabled access is marked
      widening.
    negative: false
    data_needs: Fixtures representing changes raise and reduce allowance and toggle AI and operations.
    bound_to:
      - TST-PFM-LLM-026
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#keeps
      the row before and the row after in the audit row
    category: rule
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#keeps
        the row before and the row after in the audit row
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#records
        switching AI on as widening
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#records
        switching an operation back on as widening
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#records
        switching AI off as not widening
  - id: ATS-PFM-LLM-013-08
    title: Preview changes no saved state
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-08
    preconditions: The current period has usage.
    steps: Preview a reduced allowance.
    expected: The projected position is returned without configuration or audit writes.
    negative: false
    data_needs: Fixtures representing the current period has usage.
    bound_to:
      - TST-PFM-LLM-007
      - TST-PFM-LLM-026
    provenance: test
    source: >-
      services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#previews the limits against this month
      without writing or auditing
    category: boundary
    test_sources:
      - >-
        services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#previews the limits against this month
        without writing or auditing
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#writes
        nothing: the row keeps its version and allowance
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#audits
        nothing
  - id: ATS-PFM-LLM-013-09
    title: Global AI disablement outranks exemptions
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-09
    preconditions: Global AI and individual operation restrictions combine with an active exemption.
    steps: Evaluate operation access under each configuration.
    expected: Exemption permits a disabled operation only while the global AI switch remains on.
    negative: true
    data_needs: Fixtures representing global AI and individual operation restrictions combine with an active exemption.
    bound_to:
      - TST-PFM-LLM-026
    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
    category: rule
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#allows
        it again while an operation exemption is in force
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#refuses
        it when AI is off, whatever exemption is in force
  - id: ATS-PFM-LLM-013-10
    title: Exemption cannot bypass global disablement
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-09
      - BR-CAP-PFM-LLM-014-02
    exercises:
      - CAP-PFM-LLM-013
      - CAP-PFM-LLM-014
    preconditions: An operation is disabled and a temporary exemption exists.
    steps: 'Check admission with global AI enabled, then disable global AI and check again.'
    expected: The exemption bypasses only the operation switch; global disablement refuses without holding capacity.
    negative: true
    data_needs: 'An isolated workspace with the records, clock instants and caller authority stated in the preconditions.'
    bound_to:
      - TST-PFM-LLM-026
    provenance: test
    source:
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#allows
        it again while an operation exemption is in force
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#refuses
        it when AI is off, whatever exemption is in force
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#allows
        it again while an operation exemption is in force
      - >-
        services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#refuses
        it when AI is off, whatever exemption is in force
  - id: ATS-PFM-LLM-013-11
    title: Customer availability follows recurring switches
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-09
      - BR-CAP-PFM-LLM-017-04
    exercises:
      - CAP-PFM-LLM-013
      - CAP-PFM-LLM-017
    preconditions: A feature has one declared operation and current usage.
    steps: 'Read availability, disable its operation, then disable global AI and read each state.'
    expected: >-
      Customer restriction wording follows the current switches without exposing management configuration or
      model details.
    negative: false
    data_needs: 'An isolated workspace with the records, clock instants and caller authority stated in the preconditions.'
    bound_to: []
    provenance: proposed
    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
      - 'services-platform:modules/llm/services/usage/organization-usage.ts'
  - id: ATS-PFM-LLM-013-12
    title: Persisted limits reject a zero running cap
    category: validation
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-03
    preconditions: >-
      The suite owns isolated fixtures representing the valid control and the contrasting case described by
      its steps.
    steps: 'Insert a cap of one, then attempt zero for the same configuration shape.'
    expected: One is accepted and zero is refused.
    negative: true
    data_needs: 'Suite-owned fixtures, with a fixed clock where dates or grant windows matter.'
    bound_to:
      - TST-PFM-LLM-016
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/db/llm-tenant-limits.table.integration.spec.js#refuses
      an in-flight cap of zero, which would refuse every call
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/db/llm-tenant-limits.table.integration.spec.js#refuses
        an in-flight cap of zero, which would refuse every call
  - id: ATS-PFM-LLM-013-13
    title: An exemption restores only operation access
    category: interaction
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-09
    preconditions: >-
      The suite owns isolated fixtures representing the valid control and the contrasting case described by
      its steps.
    steps: 'Attempt a scripted operation while it is disabled, grant an operation exemption and attempt again.'
    expected: The first request refuses with no provider call; the exemption permits the later scripted request.
    negative: false
    data_needs: 'Suite-owned fixtures, with a fixed clock where dates or grant windows matter.'
    bound_to:
      - TST-PFM-LLM-021
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/lifecycle/tenant-limits.integration.spec.js#runs the
      call once the exemption is in force
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/lifecycle/tenant-limits.integration.spec.js#runs the
        call once the exemption is in force
  - id: ATS-PFM-LLM-013-14
    title: Competing limit replacements choose one writer
    category: concurrency
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-04
    preconditions: >-
      The suite owns isolated fixtures representing the valid control and the contrasting case described by
      its steps.
    steps: Race changed replacements from the same inspected version.
    expected: One replacement commits and the other receives the changed-record refusal.
    negative: false
    data_needs: 'Suite-owned fixtures, with a fixed clock where dates or grant windows matter.'
    bound_to:
      - TST-PFM-LLM-036
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/persistence/limits.integration.spec.js#lets one
      win
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/persistence/limits.integration.spec.js#lets
        one win
  - id: ATS-PFM-LLM-013-15
    title: Limit inspection retains the next write version
    category: rule
    level: api
    proves:
      - BR-CAP-PFM-LLM-013-02
    preconditions: >-
      The suite owns isolated fixtures representing the valid control and the contrasting case described by
      its steps.
    steps: Read persisted limits after a known write.
    expected: The returned version matches the saved configuration and supports a later conditional replacement.
    negative: false
    data_needs: 'Suite-owned fixtures, with a fixed clock where dates or grant windows matter.'
    bound_to:
      - TST-PFM-LLM-037
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/persistence/limits.queries.integration.spec.js#answers
      the version the next writer must send
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/persistence/limits.queries.integration.spec.js#answers
        the version the next writer must send
  - id: ATS-PFM-LLM-013-16
    title: Limit writes require an inspected version
    category: validation
    level: unit
    proves:
      - BR-CAP-PFM-LLM-013-04
    preconditions: >-
      The suite owns isolated fixtures representing the valid control and the contrasting case described by
      its steps.
    steps: Map a changed write without its version precondition and compare a valid versioned write.
    expected: The missing version is refused before the save.
    negative: true
    data_needs: 'Suite-owned fixtures, with a fixed clock where dates or grant windows matter.'
    bound_to:
      - TST-PFM-LLM-053
    provenance: test
    source: >-
      services-platform:modules/llm/tests/unit/aws/api/llm-usage-limits-api.spec.ts#is required, since a write
      with no claim would let a stale screen overwrite a change
    test_sources:
      - >-
        services-platform:modules/llm/tests/unit/aws/api/llm-usage-limits-api.spec.ts#is required, since a
        write with no claim would let a stale screen overwrite a change
  - id: ATS-PFM-LLM-013-17
    title: Limit validation rejects undeclared operations
    category: validation
    level: unit
    proves:
      - BR-CAP-PFM-LLM-013-03
    preconditions: >-
      The suite owns isolated fixtures representing the valid control and the contrasting case described by
      its steps.
    steps: Validate disabled-operation names against the declared catalog.
    expected: Undeclared names are refused before a configuration replacement.
    negative: true
    data_needs: 'Suite-owned fixtures, with a fixed clock where dates or grant windows matter.'
    bound_to:
      - TST-PFM-LLM-079
    provenance: test
    source: >-
      services-platform:modules/llm/tests/unit/services/tenant-limits.spec.ts#refuses an operation key the
      catalog does not declare, naming it
    test_sources:
      - >-
        services-platform:modules/llm/tests/unit/services/tenant-limits.spec.ts#refuses an operation key the
        catalog does not declare, naming it
  - id: ATS-PFM-LLM-013-18
    title: Disabled-operation failure maps to a conflict
    category: failure
    level: unit
    proves:
      - BR-CAP-PFM-LLM-013-09
    preconditions: The operation-disabled error is constructed by the production refusal type.
    steps: Map the error through the shared response shaper.
    expected: >-
      The response is a conflict carrying the disabled-operation code; this experiment does not evaluate
      exemptions.
    negative: true
    data_needs: A production disabled-operation error and a literal period snapshot.
    bound_to:
      - TST-PFM-LLM-077
    provenance: test
    source: >-
      services-platform:modules/llm/tests/unit/services/llm-operation-disabled.spec.ts#answers 409, because it
      holds until staff switch it back on and is neither a limit nor a failure
    test_sources:
      - >-
        services-platform:modules/llm/tests/unit/services/llm-operation-disabled.spec.ts#answers 409, because
        it holds until staff switch it back on and is neither a limit nor a failure
evidence:
  - >-
    services-platform at ad3f6a6582843008ed0f5a17b131878d15829af1: bound or cited
    modules/llm/tests/e2e/llm-limits.e2e.spec.js;
    modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js;
    modules/llm/tests/unit/services/llm-operation-disabled.spec.ts.
coverage:
  rule: 'gap: FND-PFM-LLM-072'
  transition: 'gap: FND-PFM-LLM-072'
  validation: covered
  permission: covered
  edge: 'gap: FND-PFM-LLM-072'
  failure: covered
  boundary: covered
  concurrency: covered
  invariant: covered
  interaction: covered
coverage_notes:
  transition: >-
    Existing transition scenarios are retained; the model transition register below records the remaining
    exhaustive mapping obligation.
  interaction: >-
    The related interaction register cites a concrete experiment for every dependency and related capability,
    including cross-capability workflow seams.
  rule: >-
    All must-prove rules have scenario references, but the coverage finding retains untested clauses and
    combined outcomes; scenario presence alone is not exhaustive rule proof.
related_interactions:
  - with: CAP-PFM-LLM-001
    scenarios:
      - ATS-PFM-LLM-001-17
    source: 'services-platform:modules/llm/services/catalog/catalog-authority.ts:resolveLlmOperation'
  - with: CAP-PFM-LLM-005
    scenarios:
      - ATS-PFM-LLM-005-12
    source: 'services-platform:modules/llm/catalog/pricing.ts'
  - with: CAP-PFM-LLM-007
    scenarios:
      - ATS-PFM-LLM-007-16
    source: 'services-platform:modules/llm/services/persistence/allowance-periods.ts'
  - with: CAP-PFM-LLM-011
    scenarios:
      - ATS-PFM-LLM-011-10
    source: >-
      services-platform:modules/llm/tests/e2e/llm-usage.e2e.spec.js#refuses a customer’s administrator a
      tenant’s usage even in their own tenant
  - with: CAP-PFM-LLM-014
    scenarios:
      - ATS-PFM-LLM-013-10
    source: >-
      services-platform:modules/llm/tests/e2e/llm-overrides.e2e.spec.js#is refused the grant before a handler
      runs, whatever the customer’s scope grants
  - with: CAP-PFM-LLM-017
    scenarios:
      - ATS-PFM-LLM-013-11
    source: >-
      services-platform:modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js#is refused to
      Rhythm staff holding every HQ key, because the routes are console
state_models:
  - STATE-PFM-LLM-005
coverage_obligations:
  must_prove:
    - rule: BR-CAP-PFM-LLM-013-01
      scenarios:
        - ATS-PFM-LLM-013-01
      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
      coverage: specified
    - rule: BR-CAP-PFM-LLM-013-02
      scenarios:
        - ATS-PFM-LLM-013-02
        - ATS-PFM-LLM-013-15
      source: 'services-platform:modules/llm/services/limits/tenant-limits.ts'
      coverage: partial
      gap: FND-PFM-LLM-072
    - rule: BR-CAP-PFM-LLM-013-03
      scenarios:
        - ATS-PFM-LLM-013-03
        - ATS-PFM-LLM-013-12
        - ATS-PFM-LLM-013-17
      source: 'services-platform:modules/llm/services/limits/tenant-limits.ts'
      coverage: partial
      gap: FND-PFM-LLM-072
    - rule: BR-CAP-PFM-LLM-013-04
      scenarios:
        - ATS-PFM-LLM-013-04
        - ATS-PFM-LLM-013-14
        - ATS-PFM-LLM-013-16
      source: 'services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#refuses a stale If-Match with 409'
      coverage: partial
      gap: FND-PFM-LLM-072
    - rule: BR-CAP-PFM-LLM-013-05
      scenarios:
        - ATS-PFM-LLM-013-05
      source: 'services-platform:modules/llm/services/persistence/limits.ts'
      coverage: partial
      gap: FND-PFM-LLM-072
    - rule: BR-CAP-PFM-LLM-013-06
      scenarios:
        - ATS-PFM-LLM-013-06
      source: 'services-platform:modules/llm/services/limits/tenant-limits.ts'
      coverage: partial
      gap: FND-PFM-LLM-072
    - rule: BR-CAP-PFM-LLM-013-07
      scenarios:
        - ATS-PFM-LLM-013-07
      source: 'services-platform:modules/llm/services/limits/tenant-limits.ts'
      coverage: partial
      gap: FND-PFM-LLM-072
    - rule: BR-CAP-PFM-LLM-013-08
      scenarios:
        - ATS-PFM-LLM-013-08
      source: 'services-platform:modules/llm/services/limits/tenant-limits.ts'
      coverage: specified
    - rule: BR-CAP-PFM-LLM-013-09
      scenarios:
        - 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
      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
      coverage: partial
      gap: FND-PFM-LLM-072
  state_transitions:
    - model: STATE-PFM-LLM-005
      transition: 1
      from: within
      to: warned
      trigger: Commitments increase or effective capacity decreases into warning range.
      gap: FND-PFM-LLM-072
      provenance: proposed
      source: 'services-platform:modules/llm/services/usage-reports/usage-status.ts:deriveUsageStatus'
    - model: STATE-PFM-LLM-005
      transition: 2
      from: warned
      to: hard_stopped
      trigger: Committed usage reaches full effective capacity.
      gap: FND-PFM-LLM-072
      provenance: proposed
      source: 'services-platform:modules/llm/services/usage-reports/usage-status.ts:deriveUsageStatus'
    - model: STATE-PFM-LLM-005
      transition: 3
      from: within
      to: hard_stopped
      trigger: A large movement skips directly from below warning to full usage.
      gap: FND-PFM-LLM-072
      provenance: proposed
      source: 'services-platform:modules/llm/services/usage-reports/usage-status.ts:deriveUsageStatus'
    - model: STATE-PFM-LLM-005
      transition: 4
      from: hard_stopped
      to: within
      trigger: 'Capacity rises, commitments fall or the month changes.'
      gap: FND-PFM-LLM-072
      provenance: proposed
      source: 'services-platform:modules/llm/services/overrides/allowance-overrides.ts:grantOverride'
    - model: STATE-PFM-LLM-005
      transition: 5
      from: hard_stopped
      to: warned
      trigger: Capacity returns without removing the warning.
      gap: FND-PFM-LLM-072
      provenance: proposed
      source: 'services-platform:modules/llm/services/usage-reports/usage-status.ts:deriveUsageStatus'
    - model: STATE-PFM-LLM-005
      transition: 6
      from: warned
      to: within
      trigger: Capacity increases or commitments decrease below warning.
      gap: FND-PFM-LLM-072
      provenance: proposed
      source: 'services-platform:modules/llm/services/usage-reports/usage-status.ts:deriveUsageStatus'
    - model: STATE-PFM-LLM-005
      transition: 7
      from: within
      to: disabled
      trigger: The AI switch is disabled or organization availability changes.
      gap: FND-PFM-LLM-072
      provenance: proposed
      source: 'services-platform:modules/llm/services/limits/tenant-limits.ts:checkOperationAccess'
    - model: STATE-PFM-LLM-005
      transition: 8
      from: disabled
      to: within
      trigger: AI and organization availability return.
      gap: FND-PFM-LLM-072
      provenance: proposed
      source: 'services-platform:modules/llm/services/limits/tenant-limits.ts:upsertTenantLimits'
  domain_invariants:
    - invariant: INV-DOM-PFM-LLM-003-09
      scenarios:
        - ATS-PFM-LLM-013-04
      provenance: documented
      source: 'services-platform:modules/llm/services/persistence/limits.ts:writeTenantLimits'
    - invariant: INV-DOM-PFM-LLM-003-10
      scenarios:
        - ATS-PFM-LLM-013-06
      provenance: documented
      source: 'services-platform:modules/llm/services/persistence/allowance-periods.ts:syncAllowancePeriodToLimits'
coverage_limits:
  finding: FND-PFM-LLM-072
  statement: >-
    Audit rollback, identical first-write races and full live-position transitions after configuration
    replacement need explicit proof. The console save remains disabled.
  provenance: proposed
  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
    - 'services-platform:modules/llm/services/limits/tenant-limits.ts'
    - 'services-platform:modules/llm/services/limits/tenant-limits.ts'
    - 'services-platform:modules/llm/tests/e2e/llm-limits.e2e.spec.js#refuses a stale If-Match with 409'
    - 'services-platform:modules/llm/services/persistence/limits.ts'
    - 'services-platform:modules/llm/services/limits/tenant-limits.ts'
    - 'services-platform:modules/llm/services/limits/tenant-limits.ts'
    - 'services-platform:modules/llm/services/limits/tenant-limits.ts'
    - >-
      services-platform:modules/llm/tests/integration/services/limits/tenant-limits.integration.spec.js#refuses
      it when AI is off, whatever exemption is in force
  invariants_without_scenarios: []
---

# undefined

## Coverage

The scenarios identify the rules or journey assertions they are intended to prove. A test binding names existing evidence; an unbound proposal remains work to verify.

| Scenario | Title | Level | Provenance |
|---|---|---|---|
| `ATS-PFM-LLM-013-01` | Limit changes require management authority | api | test |
| `ATS-PFM-LLM-013-02` | Full replacement clears omitted notes | api | test |
| `ATS-PFM-LLM-013-03` | Invalid limit values preserve all records | api | proposed |
| `ATS-PFM-LLM-013-04` | Changed saves need the inspected version | api | test |
| `ATS-PFM-LLM-013-05` | Replaying stored values adds no history | api | test |
| `ATS-PFM-LLM-013-06` | Allowance change affects the current period only | api | test |
| `ATS-PFM-LLM-013-07` | Widening audit distinguishes more capacity | api | test |
| `ATS-PFM-LLM-013-08` | Preview changes no saved state | api | test |
| `ATS-PFM-LLM-013-09` | Global AI disablement outranks exemptions | api | test |

## Interactions With Related Capabilities

The interaction register links concrete experiments with run ai requests with consistent attribution and accounting; publish ai operation definitions and historical prices; admit ai work against the organization’s monthly allowance; inspect an organization’s ai account and request history; provide temporary ai capacity and revoke it; show administrators their organization’s ai allowance. Each experiment checks the outcome at the shared boundary; an unbound experiment remains proposed.

Audit rollback, identical first-write races and full live-position transitions after configuration replacement need explicit proof. The console save remains disabled.
