---
id: ATS-PFM-LLM-015
scope: CAP-PFM-LLM-015
product_area: platform
module: llm
revision: 2
status: proposed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-PFM-LLM-015-01
    title: Charge correction excludes unqualified callers
    level: api
    proves:
      - BR-CAP-PFM-LLM-015-01
    preconditions: Support and customer-administrator authority are represented.
    steps: Submit a correction under each.
    expected: Neither changes charged usage or correction history.
    negative: true
    data_needs: Fixtures representing support and customer-administrator authority are represented.
    bound_to:
      - TST-PFM-LLM-006
    provenance: test
    source: >-
      services-platform:modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js#is refused 403 for
      a Support Representative, who holds the read key and not the manage key
    category: permission
    test_sources:
      - >-
        services-platform:modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js#is refused 403
        for a Support Representative, who holds the read key and not the manage key
      - >-
        services-platform:modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js#is refused 403
        for a customer’s administrator holding every key, because the route is system
      - >-
        services-platform:modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js#changes nothing
        for the refused callers
  - id: ATS-PFM-LLM-015-02
    title: Correction values require a valid signed amount
    level: api
    proves:
      - BR-CAP-PFM-LLM-015-02
    preconditions: A month contains charges.
    steps: 'Submit zero credits, no meaningful reason and cents of opposite sign.'
    expected: All examples fail without changing the month.
    negative: true
    data_needs: Fixtures representing a month contains charges.
    bound_to:
      - TST-PFM-LLM-006
      - TST-PFM-LLM-022
    provenance: test
    source: >-
      services-platform:modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js#refuses zero
      credits as 400, naming the field
    category: validation
    test_sources:
      - >-
        services-platform:modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js#refuses zero
        credits as 400, naming the field
      - >-
        services-platform:modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js#refuses a blank
        reason as 400, naming the field
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#refuses
        money pointing the other way from the credits, leaving the period as it was
  - id: ATS-PFM-LLM-015-03
    title: Only existing or current months can be corrected
    level: api
    proves:
      - BR-CAP-PFM-LLM-015-03
    preconditions: The current and an earlier month have no period records.
    steps: Correct both months.
    expected: 'The current month is created and charged, while the absent earlier month is rejected.'
    negative: true
    data_needs: Fixtures representing the current and an earlier month have no period records.
    bound_to:
      - TST-PFM-LLM-022
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#creates
      the current period and charges it
    category: validation
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#creates
        the current period and charges it
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#refuses
        a period the organization has no row for and that is not this month, naming the period
  - id: ATS-PFM-LLM-015-04
    title: Refund cannot exceed an existing charge
    level: api
    proves:
      - BR-CAP-PFM-LLM-015-04
    preconditions: An existing period has four hundred charged credits.
    steps: Request a five-hundred-credit refund.
    expected: Validation refuses it and preserves the period.
    negative: true
    data_needs: Fixtures representing an existing period has four hundred charged credits.
    bound_to:
      - TST-PFM-LLM-022
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#refuses
      to give back more credits than the period has settled, leaving the period as it was
    category: boundary
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#refuses
        to give back more credits than the period has settled, leaving the period as it was
  - id: ATS-PFM-LLM-015-05
    title: Request references must match organization and month
    level: api
    proves:
      - BR-CAP-PFM-LLM-015-05
    preconditions: 'Current, prior-month and foreign requests are available.'
    steps: Submit a correction naming each.
    expected: Only the current local request qualifies; other references fail without change.
    negative: true
    data_needs: 'Fixtures representing current, prior-month and foreign requests are available.'
    bound_to:
      - TST-PFM-LLM-022
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#refuses
      a request of another period, naming the invocation
    category: boundary
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#refuses
        a request of another period, naming the invocation
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#refuses
        a request of another organization as if it did not exist
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#accepts
        the request of the period, as the control for the refusals above
  - id: ATS-PFM-LLM-015-06
    title: Correction and audit move together
    level: api
    proves:
      - BR-CAP-PFM-LLM-015-06
    preconditions: An allowance month has sufficient charges.
    steps: Return credits then add a charge.
    expected: 'Each correction moves totals and has one audit event, widening only for returned credits.'
    negative: false
    data_needs: Fixtures representing an allowance month has sufficient charges.
    bound_to:
      - TST-PFM-LLM-022
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#moves
      the period’s settled credits down by the credits returned
    category: invariant
    test_sources:
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#moves
        the period’s settled credits down by the credits returned
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#writes
        exactly one audit row for the adjustment
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#marks
        the audit row widening, because credits were returned
      - >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#does
        not mark the audit row widening, because nobody may spend more
  - id: ATS-PFM-LLM-015-07
    title: Signed correction survives cent flooring
    level: api
    proves:
      - BR-CAP-PFM-LLM-015-10
      - INV-DOM-PFM-LLM-003-12
    preconditions: An existing month has enough credits but fewer charged cents than the cent refund.
    steps: Apply a valid credit refund with a larger signed cent refund.
    expected: The correction retains its signed values while period cents stop at zero.
    negative: false
    data_needs: Fixtures representing an existing month has enough credits but fewer charged cents than the cent refund.
    bound_to: []
    provenance: proposed
    source: 'services-platform:modules/llm/services/persistence/allowance-periods.ts:applyAllowanceAdjustment'
    category: rule
    test_sources: []
  - id: ATS-PFM-LLM-015-08
    title: Correction input rejects fractional credits
    category: validation
    level: unit
    proves:
      - BR-CAP-PFM-LLM-015-02
    preconditions: >-
      The suite owns isolated fixtures representing the valid control and the contrasting case described by
      its steps.
    steps: Validate a correction with a fractional credit change.
    expected: The invalid credit amount is refused before any monthly movement.
    negative: true
    data_needs: 'Suite-owned fixtures, with a fixed clock where dates or grant windows matter.'
    bound_to:
      - TST-PFM-LLM-070
    provenance: test
    source: >-
      services-platform:modules/llm/tests/unit/services/adjustments/adjustment-request.spec.ts#refuses a
      fractional credit count, naming the field
    test_sources:
      - >-
        services-platform:modules/llm/tests/unit/services/adjustments/adjustment-request.spec.ts#refuses a
        fractional credit count, naming the field
evidence:
  - >-
    services-platform at ad3f6a6582843008ed0f5a17b131878d15829af1: bound or cited
    modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js;
    modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js.
coverage:
  rule: 'gap: FND-PFM-LLM-074'
  transition: not-applicable
  validation: covered
  permission: covered
  edge: 'gap: FND-PFM-LLM-074'
  failure: 'gap: FND-PFM-LLM-074'
  boundary: covered
  concurrency: 'gap: FND-PFM-LLM-074'
  invariant: covered
  interaction: covered
coverage_notes:
  transition: This capability defines read-only presentation or validation and introduces no owned lifecycle transition.
  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-007
    scenarios:
      - ATS-PFM-LLM-007-18
    source: 'services-platform:modules/llm/services/persistence/allowance-periods.ts'
  - with: CAP-PFM-LLM-008
    scenarios:
      - ATS-PFM-LLM-008-12
    source: 'services-platform:modules/llm/services/persistence/allowance-periods.ts'
  - with: CAP-PFM-LLM-011
    scenarios:
      - ATS-PFM-LLM-011-12
    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
state_models: []
coverage_obligations:
  must_prove:
    - rule: BR-CAP-PFM-LLM-015-01
      scenarios:
        - ATS-PFM-LLM-015-01
      source: >-
        services-platform:modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js#is refused 403
        for a Support Representative, who holds the read key and not the manage key
      coverage: specified
    - rule: BR-CAP-PFM-LLM-015-02
      scenarios:
        - ATS-PFM-LLM-015-02
        - ATS-PFM-LLM-015-08
      source: 'services-platform:modules/llm/services/adjustments/adjust-allowance.ts:requireAdjustable'
      coverage: partial
      gap: FND-PFM-LLM-074
    - rule: BR-CAP-PFM-LLM-015-03
      scenarios:
        - ATS-PFM-LLM-015-03
      source: >-
        services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#refuses
        a period the organization has no row for and that is not this month, naming the period
      coverage: specified
    - rule: BR-CAP-PFM-LLM-015-04
      scenarios:
        - ATS-PFM-LLM-015-04
      source: 'services-platform:modules/llm/services/adjustments/adjust-allowance.ts:requireAdjustable'
      coverage: partial
      gap: FND-PFM-LLM-074
    - rule: BR-CAP-PFM-LLM-015-05
      scenarios:
        - ATS-PFM-LLM-015-05
      source: 'services-platform:modules/llm/services/adjustments/adjust-allowance.ts'
      coverage: specified
    - rule: BR-CAP-PFM-LLM-015-06
      scenarios:
        - ATS-PFM-LLM-015-06
      source: 'services-platform:modules/llm/services/adjustments/adjust-allowance.ts'
      coverage: partial
      gap: FND-PFM-LLM-074
    - rule: BR-CAP-PFM-LLM-015-10
      scenarios:
        - ATS-PFM-LLM-015-07
      source: 'services-platform:modules/llm/services/persistence/allowance-periods.ts:applyAllowanceAdjustment'
      coverage: partial
      gap: FND-PFM-LLM-074
  state_transitions: []
  domain_invariants:
    - invariant: INV-DOM-PFM-LLM-003-12
      scenarios:
        - ATS-PFM-LLM-015-07
      provenance: documented
      source: 'services-platform:modules/llm/services/persistence/allowance-periods.ts:applyAllowanceAdjustment'
coverage_limits:
  finding: FND-PFM-LLM-074
  statement: >-
    Refund eligibility during competing changes, missing-current-period refunds, audit rollback and repeated
    corrections need focused scenarios. A correction does not generate a threshold notice.
  provenance: proposed
  source:
    - >-
      services-platform:modules/llm/tests/e2e/llm-adjustments-and-organization.e2e.spec.js#is refused 403 for
      a Support Representative, who holds the read key and not the manage key
    - 'services-platform:modules/llm/services/adjustments/adjust-allowance.ts:requireAdjustable'
    - >-
      services-platform:modules/llm/tests/integration/services/adjustments/adjust-allowance.integration.spec.js#refuses
      a period the organization has no row for and that is not this month, naming the period
    - 'services-platform:modules/llm/services/adjustments/adjust-allowance.ts:requireAdjustable'
    - 'services-platform:modules/llm/services/adjustments/adjust-allowance.ts'
    - 'services-platform:modules/llm/services/adjustments/adjust-allowance.ts'
    - 'services-platform:modules/llm/services/persistence/allowance-periods.ts:applyAllowanceAdjustment'
  invariants_without_scenarios: []
---

# Correct an organization’s AI charges: Capability Test Specification

## Coverage

| Rule | Scenario |
|---|---|
| `BR-CAP-PFM-LLM-015-01` | `ATS-PFM-LLM-015-01` |
| `BR-CAP-PFM-LLM-015-02` | `ATS-PFM-LLM-015-02` |
| `BR-CAP-PFM-LLM-015-03` | `ATS-PFM-LLM-015-03` |
| `BR-CAP-PFM-LLM-015-04` | `ATS-PFM-LLM-015-04` |
| `BR-CAP-PFM-LLM-015-05` | `ATS-PFM-LLM-015-05` |
| `BR-CAP-PFM-LLM-015-06` | `ATS-PFM-LLM-015-06` |
| `BR-CAP-PFM-LLM-015-10` | `ATS-PFM-LLM-015-07` |

## Interactions With Related Capabilities

The interaction register links concrete experiments with admit ai work against the organization’s monthly allowance; notify administrators at allowance thresholds; inspect an organization’s ai account and request history. Each experiment checks the outcome at the shared boundary; an unbound experiment remains proposed.

Refund eligibility during competing changes, missing-current-period refunds, audit rollback and repeated corrections need focused scenarios. A correction does not generate a threshold notice.
