---
id: CAP-PFM-LLM-005
title: Publish AI operation definitions and historical prices
feature: FEAT-PFM-LLM-02
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: []
purpose: Make each operation’s model choices and cost calculations inspectable without rewriting past requests.
outcomes:
  - Published declarations connect operations with priced models.
  - Routing and price changes append historical versions.
  - HQ readers can inspect current and earlier catalog versions.
concepts:
  - CON-PFM-LLM-002
actors:
  - ACT-PFM-034
  - ACT-PFM-033
  - ACT-PFM-012
surfaces:
  - job
  - api
  - console
preconditions: []
postconditions:
  - Published versions reflect the deployed catalog declarations.
permissions:
  - key: hq.llm-usage.read
    where_checked: api
    scope: global
rules:
  - id: BR-CAP-PFM-LLM-005-01
    proved_by: [ATS-PFM-LLM-005-01, ATS-PFM-LLM-005-10, TST-PFM-LLM-058]
    statement: >-
      The reservation is the rounded per-turn estimate multiplied by permitted turns and limited to the
      operation’s declared credit ceiling.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/catalog/pricing.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-005-02
    proved_by: [ATS-PFM-LLM-005-02, ATS-PFM-LLM-005-12, TST-PFM-LLM-023, TST-PFM-LLM-060]
    statement: >-
      Publication rejects the whole catalog for unpriced routing, inconsistent timeouts, duplicate operations
      or rates, unknown applications, empty features, zero estimates or invalid prices, writing no versions.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/catalog/materialize-catalog.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-005-03
    proved_by: [ATS-PFM-LLM-002-12, ATS-PFM-LLM-005-03, ATS-PFM-LLM-005-14, ATS-PFM-LLM-005-16, TST-PFM-LLM-023, TST-PFM-LLM-042, TST-PFM-LLM-056]
    statement: >-
      An unchanged declaration adds no version, a changed declaration appends one, and reverting appends
      another version with the earlier content digest.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/services/catalog/materialize-catalog.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-005-04
    proved_by: [ATS-PFM-LLM-005-04, ATS-PFM-LLM-005-15, TST-PFM-LLM-011, TST-PFM-LLM-043]
    statement: >-
      Published routing and rate versions reject updates and deletions by both application and publishing
      roles.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/db/llm-catalog-tables.integration.spec.js#refuses an
      update by the owner, who publishes the versions, so no deploy can rewrite one
    origin: none
  - id: BR-CAP-PFM-LLM-005-05
    proved_by: [ATS-PFM-LLM-001-14, ATS-PFM-LLM-005-05, ATS-PFM-LLM-005-11, ATS-PFM-LLM-005-13, TST-PFM-LLM-040, TST-PFM-LLM-041]
    statement: >-
      A request retains its original rate version when prices change; only subsequent requests resolve the
      newer version.
    kind: calculation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/persistence/rate-versions.integration.spec.js#leaves
      the old version at the old price, because an invocation settled under it still names it
    origin: none
  - id: BR-CAP-PFM-LLM-005-06
    proved_by: [ATS-PFM-LLM-005-06, ATS-PFM-LLM-005-09, TST-PFM-LLM-058]
    statement: >-
      Usage costs are summed at per-million rates before one division, with credits rounded upward and cents
      rounded to nearest.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: 'services-platform:modules/llm/catalog/pricing.ts'
    origin: none
  - id: BR-CAP-PFM-LLM-005-07
    proved_by: []
    statement: >-
      One credit represents one hundredth of a cent, and model input, output, cache-read and cache-write units
      have declared credit and cent prices per million.
    kind: calculation
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/llm.md#Money'
    origin: none
  - id: BR-CAP-PFM-LLM-005-08
    proved_by: [ATS-PFM-LLM-005-07, ATS-PFM-LLM-005-17, TST-PFM-LLM-055, TST-PFM-LLM-058, TST-PFM-LLM-059]
    statement: >-
      Unpriced usage dimensions contribute no charge and remain visible under their provider names for later
      pricing decisions.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/llm/tests/unit/catalog/classify-usage-dimensions.spec.ts#reports it as
      unpriced rather than filtering it out
    origin: none
  - id: BR-CAP-PFM-LLM-005-09
    proved_by: []
    statement: >-
      Engineers choose and deploy model prices; Rhythm does not reconcile those declarations with the
      provider’s actual bill.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/llm.md#What is declared, and what is published'
    origin: none
  - id: BR-CAP-PFM-LLM-005-10
    proved_by: [ATS-PFM-LLM-005-08, TST-PFM-LLM-009]
    statement: The HQ catalog and rates show each key’s current version and up to nineteen preceding versions.
    kind: policy
    enforced_at:
      - api
    must_prove: false
    provenance: observed
    source: 'services-platform:modules/llm/aws/api/llm-usage.routes.ts'
    origin: none
scenarios:
  - id: SC-CAP-PFM-LLM-005-01
    given: An engineer changes an operation’s prompt version.
    when: Catalog publication runs.
    then: A new routing version becomes current without a new unchanged price version.
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/catalog/materialize-catalog.integration.spec.js#leaves
      the new prompt version in force
  - id: SC-CAP-PFM-LLM-005-02
    given: A declaration names an unpriced model.
    when: Publication validates the catalog.
    then: Validation reports the operation and issue without changing the active catalog.
    provenance: test
    source: >-
      services-platform:modules/llm/tests/integration/services/catalog/materialize-catalog.integration.spec.js#names
      the issue and the operation, so the failed deploy says what to fix
edge_cases: []
constraints: []
depends_on: []
related:
  - CAP-PFM-LLM-001
  - CAP-PFM-LLM-002
  - CAP-PFM-LLM-010
journeys: []
open_questions: []
evidence:
  - >-
    services-platform at ad3f6a6582843008ed0f5a17b131878d15829af1: docs/llm.md (What is declared, and what is
    published; Money); modules/llm/catalog/llm-operations.ts, llm-rate-definitions.ts, pricing.ts,
    rate-conversions.ts, digest-declarations.ts, validate-catalog-declarations.ts,
    classify-usage-dimensions.ts; services/catalog/materialize-catalog.ts, catalog-authority.ts;
    db/llm-operation-routing-versions.table.ts, llm-model-rate-versions.table.ts; aws/api/llm-usage.routes.ts
    (getHqLlmUsageCatalog, getHqLlmUsageRates); tests unit/catalog/*, integration/services/catalog/*,
    integration/db/llm-catalog-tables.integration.spec.js, integration/services/persistence/rate-versions*,
    routing-versions*.
  - >-
    react-console at baf6dae382d6f41dce976c7f848667ccc37e076f:
    components/console/hq/ai-usage/catalog-card.tsx.
controls: [TC-AI-001, TC-AI-002, TC-AI-003, TC-AI-004, TC-AI-006, TC-AI-007, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-AZ-006, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CHG-005, TC-CHG-006, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-IAM-003, TC-LOG-001, TC-LOG-005, TC-MON-001, TC-PI-001, 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-02-01, FAS-PFM-LLM-02-02, FAS-PFM-LLM-02-03, FAS-PFM-LLM-02-04, FAS-PFM-LLM-02-05]
suites: [TST-PFM-LLM-009, TST-PFM-LLM-011, TST-PFM-LLM-023, TST-PFM-LLM-040, TST-PFM-LLM-041, TST-PFM-LLM-042, TST-PFM-LLM-043, TST-PFM-LLM-055, TST-PFM-LLM-056, TST-PFM-LLM-058, TST-PFM-LLM-059, TST-PFM-LLM-060]
---

# Publish AI operation definitions and historical prices

## Purpose

Make each operation’s model choices and cost calculations inspectable without rewriting past requests.

## How It Works

Engineers declare an operation’s routing, prompt and budgets together with model rates. Publication validates the entire declaration set before appending changed versions. An unchanged deploy preserves existing histories. Reverting a declaration creates another historical version rather than erasing the intervening one. Requests retain the versions under which they run. Credit and money calculations use different rounding because they serve different purposes. An unknown usage dimension is surfaced without inventing its price. Rhythm staff can inspect the current catalog and recent versions, while engineers remain responsible for choosing accurate rates.

## Relationships


