---
id: ADR-PFM-LLM-005
title: Publish Immutable Routing and Price History at Deployment
product_area: platform
module: llm
revision: 1
status: proposed
design_intent: confirmed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
decision: >-
  Validate declared model configuration before deployment appends numbered routing and price versions, and
  retain the references used by each request.
constrains:
  - DOM-PFM-LLM-002
  - STATE-PFM-LLM-004
  - WF-PFM-LLM-003
  - SVC-PFM-LLM-llm
origin: >-
  The foundation design section 4.2 (deploy-time materialization in the migration function) in the approved
  and accepted work (services-platform:docs/llm/llm-foundation-and-generate-query.md#4.2 What Is Copied, What
  Changes; #Acceptance checkpoints).
alternatives:
  - option: Overwrite current routing and price settings
    why_not: It removes the historical meaning needed to explain earlier requests.
  - option: Publish when the first request arrives
    why_not: It adds configuration work and races to a customer-triggered execution.
  - option: Skip invalid declarations and publish the rest
    why_not: It knowingly leaves a catalogue that cannot serve all declared operations.
consequences:
  - 'Routing, prompt, budget and price changes require deployment.'
  - Reverted content appends another number without discarding history.
  - Declared rates are not reconciled with the provider invoice.
  - Publication commits entries separately and warm caches can retain older resolved versions.
supersedes: []
evidence:
  - >-
    services-platform at ad3f6a6: modules/llm/services/catalog/materialize-catalog.ts;
    services/persistence/routing-versions.ts, rate-versions.ts; db/migrations/0048_llm.sql
    (llm_refuse_version_change); aws/lambda/migrate.handler.ts.
---

# Publish Immutable Routing and Price History at Deployment

## Context

Historical cost and prompt attribution must remain interpretable after configuration changes.

## Decision

Validate declared model configuration before deployment appends numbered routing and price versions, and retain the references used by each request.

## Alternatives Considered

Overwrite current routing and price settings: It removes the historical meaning needed to explain earlier requests.

Publish when the first request arrives: It adds configuration work and races to a customer-triggered execution.

Skip invalid declarations and publish the rest: It knowingly leaves a catalogue that cannot serve all declared operations.

## Consequences

Routing, prompt, budget and price changes require deployment. Reverted content appends another number without discarding history. Declared rates are not reconciled with the provider invoice. Publication commits entries separately and warm caches can retain older resolved versions.
