---
id: CAP-PFM-LLM-001
title: Run AI requests with consistent attribution and accounting
feature: FEAT-PFM-LLM-01
product_area: platform
module: llm
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/proposals/llm-observability/11-decisions.md#D-5'
purpose: 'Give consuming features a shared request boundary that records admission, model use and settlement.'
outcomes:
  - 'Requests carry organization, application, feature and person attribution.'
  - Normal completion records an outcome and a usage-based charge.
  - Admission refusals use a defined set of reasons.
concepts:
  - CON-PFM-LLM-001
  - CON-PFM-LLM-002
  - CON-PFM-LLM-003
actors:
  - ACT-PFM-032
  - ACT-PFM-034
  - ACT-PFM-012
surfaces:
  - api
  - job
preconditions:
  - A published catalog entry identifies the requested operation.
postconditions:
  - Normal settlement or refusal releases the reservation and retains request history.
permissions: []
rules:
  - id: BR-CAP-PFM-LLM-001-01
    proved_by: [ATS-PFM-LLM-001-01, ATS-PFM-LLM-001-14]
    statement: >-
      An undeclared operation or a routing without a published model price is rejected before creating a
      request or reserving credits.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/catalog/catalog-authority.ts:resolveLlmOperation'
    origin: none
    examples:
      positive: The query generator's declared operation runs.
      negative: A feature naming an undeclared operation is refused with nothing recorded.
  - id: BR-CAP-PFM-LLM-001-02
    proved_by: [ATS-PFM-LLM-001-02, ATS-PFM-LLM-001-13]
    statement: >-
      Platform creates the request record before reserving credits or contacting the model, giving later
      recovery a record to inspect.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: documented
    source: 'services-platform:docs/llm.md#The order of the steps, which is the design'
    origin: none
  - id: BR-CAP-PFM-LLM-001-03
    proved_by: [ATS-PFM-LLM-001-03, ATS-PFM-LLM-001-12, ATS-PFM-LLM-001-15, TST-PFM-LLM-018, TST-PFM-LLM-020]
    statement: >-
      Settlement uses reported usage when available, charges the reservation estimate when an attempt succeeds
      without any reported usage, and releases the hold when no usage is spent; interruptions can leave
      unresolved accounting.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/execution/run-operation.ts:settleInvocation'
    origin: none
    examples:
      positive: A request whose model reported usage is charged that usage at the published rate.
      negative: A request to a model that never answered is charged nothing.
  - id: BR-CAP-PFM-LLM-001-04
    proved_by: [ATS-PFM-LLM-001-04, ATS-PFM-LLM-001-21, TST-PFM-LLM-061]
    statement: >-
      Normal state changes compare the current state with the expected state, while settlement can close any
      nonterminal request; settled and refused requests reject a second settlement.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/persistence/invocations.ts:markInvocationSettled'
    origin: none
  - id: BR-CAP-PFM-LLM-001-05
    proved_by: [ATS-PFM-LLM-001-05]
    statement: >-
      Request attribution uses the caller context and published application and feature routing; a service’s
      asserted beneficiary is retained without independent verification.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/persistence/invocations.ts:createInvocation'
    origin: none
  - id: BR-CAP-PFM-LLM-001-06
    proved_by: [ATS-PFM-LLM-001-06, ATS-PFM-LLM-001-16, ATS-PFM-LLM-001-17, ATS-PFM-LLM-001-18, ATS-PFM-LLM-001-20, TST-PFM-LLM-020, TST-PFM-LLM-075]
    statement: >-
      Customer-relevant refusals use fixed codes and statuses: allowance and concurrency refusals are rate
      limits, disabled operations are conflicts, provider timeout, unavailability and refusal indicate
      temporary service failure, and depleted Rhythm provider credit is a server error.
    kind: policy
    enforced_at:
      - service
      - api
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/metering/llm-metering-errors.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-001-07
    proved_by: [ATS-PFM-LLM-001-07, ATS-PFM-LLM-001-11, TST-PFM-LLM-020]
    statement: >-
      Conversation budget endings return as outcomes for the consuming feature to interpret rather than
      throwing a metering error.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/lifecycle/run-operation.integration.spec.js#returns
      rather than throwing
    origin: none
  - id: BR-CAP-PFM-LLM-001-08
    proved_by: [ATS-PFM-LLM-001-08]
    statement: >-
      Provider failure messages are replaced with Rhythm wording that identifies the operation and request,
      allowing staff to locate the usage record.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/execution/run-operation.ts:providerFailure'
    origin: none
  - id: BR-CAP-PFM-LLM-001-09
    proved_by: [ATS-PFM-LLM-001-09, ATS-PFM-LLM-001-19, TST-PFM-LLM-086]
    statement: >-
      Platform’s provider-boundary guard rejects extra SDK importers, direct provider-host calls and
      prohibited provider SDK imports during verification.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:tests/unit/llm-provider-boundary.spec.ts#refuses an import of the openai sdk even in
      the adapter
    origin: none
  - id: BR-CAP-PFM-LLM-001-10
    proved_by: [ATS-PFM-LLM-001-10, TST-PFM-LLM-063]
    statement: >-
      Absent model credentials produce a configuration refusal that is distinct from allowance and provider
      refusals.
    kind: validation
    enforced_at:
      - service
      - api
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/llm/tests/unit/runtime/anthropic-credentials.spec.ts#answers
      llm_not_configured in the body, so a console says "nobody configured this" and not "try again"
    origin: none
  - id: BR-CAP-PFM-LLM-001-11
    proved_by: []
    statement: >-
      The consuming feature receives and validates the model’s final answer; the runtime does not apply that
      answer as domain state.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/llm.md#What is deliberately not here'
    origin: 'services-platform:docs/compliance/exceptions.md#EX-AI-001'
  - id: BR-CAP-PFM-LLM-001-12
    proved_by: []
    statement: >-
      Depleted Rhythm provider credit has an internal classification but the shared response mapper returns a
      generic server error without that code.
    kind: policy
    enforced_at:
      - api
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/llm.md#The code, which is the part a program reads'
    origin: 'services-platform:docs/debt/llm-server-error-code-not-in-body.md'
  - id: BR-CAP-PFM-LLM-001-13
    proved_by: [ATS-PFM-LLM-001-22, TST-PFM-LLM-076]
    statement: Allowance refusals and provider refusals contribute to separate operational measures.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/llm.md#Metrics'
    origin: none
scenarios:
  - id: SC-CAP-PFM-LLM-001-01
    given: A priced AI operation receives a request.
    when: The shared request boundary completes it.
    then: The record retains attribution and the reported charge; its reservation is released.
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/lifecycle/run-operation.integration.spec.js#records the
      invocation as settled on the actual usage
  - id: SC-CAP-PFM-LLM-001-02
    given: The provider fails on every attempt.
    when: The retry policy is exhausted.
    then: The request returns an availability failure and releases its reservation without charging usage.
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/lifecycle/run-operation.integration.spec.js#charges
      nothing, because the provider never answered: there is no call to settle at an estimate
edge_cases:
  - id: SC-CAP-PFM-LLM-001-03
    given: The provider supplies no usage figures.
    when: Settlement uses the fallback estimate.
    then: The request records an estimated credit charge and an unknown money amount.
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/lifecycle/run-operation.integration.spec.js#reports no
      money figure, which would be a guess
constraints:
  - General Jazz AI replies bypass the Platform request boundary; that gap remains a finding.
depends_on:
  - CAP-PFM-LLM-005
  - CAP-PFM-LLM-007
related:
  - CAP-PFM-LLM-002
  - CAP-PFM-LLM-003
  - CAP-PFM-LLM-004
  - CAP-PFM-LLM-013
  - CAP-PFM-LLM-018
  - CAP-PFM-LLM-019
journeys:
  - JNY-PFM-LLM-001
open_questions:
  - OQ-PFM-LLM-003
evidence:
  - >-
    services-platform at ad3f6a6582843008ed0f5a17b131878d15829af1:
    docs/llm/llm-foundation-and-generate-query.md (§4, §8, §9); docs/llm.md (The contract, The order of the
    steps, Attribution, Metrics, What is deliberately not here);
    modules/llm/services/execution/run-operation.ts; services/metering/llm-metering-errors.ts;
    db/llm-invocations.table.ts (statuses, transitions, classifications); runtime/anthropic-credentials.ts;
    tests lifecycle/run-operation.integration.spec.js, unit/db/invocation-transitions.spec.ts,
    unit/services/llm-metering-errors.spec.ts, tests/unit/llm-provider-boundary.spec.ts.
  - >-
    react-console at baf6dae382d6f41dce976c7f848667ccc37e076f:
    app/api/agent/conversations/[id]/messages/route.ts (a model call outside this path, recorded as a
    finding).
controls: [TC-AI-001, TC-AI-002, TC-AI-003, TC-AI-004, TC-AI-006, TC-AI-007, TC-AVL-001, TC-AVL-004, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, 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-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-SEC-001, TC-SEC-002, TC-SEC-003, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-LLM-01-01, FAS-PFM-LLM-01-02, FAS-PFM-LLM-01-03, FAS-PFM-LLM-01-04, FAS-PFM-LLM-01-05]
suites: [TST-PFM-LLM-018, TST-PFM-LLM-020, TST-PFM-LLM-061, TST-PFM-LLM-063, TST-PFM-LLM-075, TST-PFM-LLM-076, TST-PFM-LLM-086]
---

# Run AI requests with consistent attribution and accounting

## Purpose

Give consuming features a shared request boundary that records admission, model use and settlement.

## How It Works

A feature requests an operation from the published catalog and supplies its conversation and tools. Platform resolves the routing and price before creating a usage record. It then checks organization restrictions and asks the allowance ledger to admit the work. An admitted request captures redacted evidence and enters the model conversation. When that conversation returns, Platform calculates its charge and releases its hold. Missing usage and provider failure have distinct settlement treatments. The feature receives an answer or a bounded outcome and decides how to present it. Cleanup and recovery have interruption gaps that the findings describe. The product should bring Jazz AI’s general replies within the same accounting boundary.

## Relationships

- Publish AI operation definitions and historical prices supplies the prerequisite behavior for this outcome.
- Admit AI work against the organization’s monthly allowance supplies the prerequisite behavior for this outcome.
