Repository navigation
ADR 0004 phase 3: compile maintained model records into deterministic projections #10293
Description
Objective and readiness
Implement ADR 0004, Gate 3: reviewed canonical source records, governed imports, deterministic compilation, and generated compatibility projections. Parent: #10290.
Ready for assignment. Foundation PRs are merged:
- test: Characterize model metadata behavior and drift #10301 completed Phase 1 (ADR 0004 phase 1: characterize model metadata behavior and drift #10291): legacy behavior characterization and the ADR's Gate 1 handoff.
- Define versioned model contracts and provider-qualified identity #10310 completed the local schema/identity foundation for Phase 2 (ADR 0004 phase 2: define canonical schemas and provider-qualified identity #10292), at merge commit
ec57d4279cc2f85bff02805568c76fb3e46ce7bb: opt-in schemas, shared identity/validation, configured-catalogue projection, and the ADR's Phase 2 compatibility matrix.
Known carry-forward dependency, not a blocker for this compiler phase: Phase 2 explicitly did not finalize the workflow-frontmatter-to-AWF-config agreement with github/gh-aw. That coordination and compiler-to-runtime wiring remain a blocker for Phase 4 (#10294). Do not claim the cross-repository handoff is agreed, invent final workflow/config field names here, or make Phase 3 depend on implementing that feature.
Re-read the current base and both handoffs before implementation. Existing production consumers remain authoritative until their later migration gates. All reflection work uses the existing /reflect; there is no /reflect/v2.
Reuse the merged foundation
Use these existing contracts rather than introducing a parallel schema or canonicalizer:
shared/model-information/schema.v1.json: definitions formodel,rule,overlay,importedSnapshot,centralFeed, andresolvedExport.shared/model-information/identity.jsand.d.ts:identity,normalizeId,matchModel, andmatchFamilyRulewith explicit matching policies and declared exceptions.shared/model-information/contracts.jsand.d.ts:validate,validateRecords, andprojectConfiguredCatalogResolution.shared/model-information/fixtures.v1.json,src/model-information-contract.test.ts, andcontainers/api-proxy/model-information-contract.test.js.
The identity key retains provider and raw ID, while lookupId normalizes separators/case. Date stripping and provider-prefix handling are explicit match policies, not unconditional identity rewrites. Duplicate normalized exact records are rejected; exact variants and aliases need deliberate source representation.
The merged foundation does not include a maintained catalogue, deterministic compiler, generated consumer assets, live resolver migration, or feed loader. Implement those parts assigned to this phase without assuming that every compiler concern is already solved by the foundation helpers. Add focused, backward-compatible schema/validator/type refinements only when actual source migration requires them; document the need and extend contract tests rather than creating another schema.
Deliverables
1. Inventory and reviewed maintained sources
Inventory every current model-fact source and its consumer, and establish reviewable provider/family source files using the merged schema. Cover host support/suggestions, lifecycle/replacements, curated fallback tariffs, endpoint mappings, routing/reasoning/context metadata, and exact-family exceptions.
Entry points include:
src/copilot-model.tsand its support/retirement/suggestion tests.containers/api-proxy/guards/retired-model-guard.js.containers/api-proxy/ai-credits-pricing.js.containers/api-proxy/model-api-mapping.jsand both mapping JSON copies.containers/api-proxy/models.dev.catalog.jsonandmodels-dev-catalog.js.- Phase 1's characterization/sync fixtures and the ADR's current-model requirements.
Classify maintained facts, imported facts, runtime observations, configured inputs, and explicit policy fallbacks separately. Runtime observations and AWF_MODEL_PRICING_CATALOG are not checked-in maintained truth. Family rules cannot establish deployability or pricing/effort support for undeclared specialized variants.
Every maintained fact group needs traceable source/revision/review metadata and appropriate confidence. Do not invent prices, harness floors, context limits, provider mappings, or observation dates to complete records. Preserve unknown facts explicitly and report any evidence that blocks a required named correction.
2. Governed imports
Wrap/import the existing bundled models.dev data into schema-validated snapshots, recording actual source/revision, retrieval/capture time, importer version, content hash, license/usage note, accepted/rejected counts, and collisions.
Inspect the actual bundled format and provenance; a filename or model-name prefix alone is not proof of the billing provider, source endpoint, or retrieval date. If upstream provenance is unavailable, document an honest pinned legacy-snapshot capture with verifiable repository/content metadata and its limitations rather than fabricating upstream provenance.
Preserve provider-qualified identity and exact model scope in normalized imported data; explicit reviewed mappings are required where namespaces differ. The legacy models.dev runtime lookup currently indexes bare model slugs and can cross providers. Correcting production fallback matching belongs to Phase 5, not an incidental import rewrite here.
Imported records must not establish first-party Copilot CLI availability, retirement, replacement, harness support, or verified AWF translation support. Unknown structural placeholders required by the schema must not be promoted into authoritative provider facts.
3. Deterministic compiler and projection ownership
Implement validation and deterministic compilation using the shared identity/contracts. Load and validate the complete assembled source set so cross-file replacements and aliases are resolved correctly. Reject collisions, ambiguous aliases, unresolved replacements, conflicting specificity, unintended family capture, and malformed import metadata with actionable source diagnostics.
Produce the smallest stable projection required for each consumer:
- Host validation/suggestions and proxy retirement/replacements.
- Curated-pricing compatibility data.
- Routing/API mapping data, including both
docs/model-api-mapping.jsonandcontainers/api-proxy/model-api-mapping.json. - Static catalogue/export and revision manifests.
- Documentation tables where applicable to the migrated facts.
Define an explicit source-to-output ownership map. Do not regenerate consumer behavior by adding another independently maintained mapping or exception list. Preserve JSON interchange across host TypeScript and proxy CommonJS; include compiler/schema versions and deterministic catalogue revision in manifests.
Sort outputs deterministically and hash canonical normalized sources plus schema/compiler versions. Derive static generatedAt from committed source review/import metadata, not the generation machine's clock. Re-running generation/checks must not fetch upstream data, alter retrieval times, or require credentials/network access; import refresh is a separate explicit operation.
Respect the packaging boundary: the API-proxy Dockerfile explicitly copies assets from its own context, and shared repository modules are not automatically available inside /app. Ensure generated assets needed by existing consumers are included in actual package/bundle/container contexts and test resolution outside the repository checkout. Do not switch production proxy modules to ../../shared/... solely because repository tests can resolve it.
4. Parity versus intended model-data corrections
Maintain two clearly distinguished expectations:
- Compatibility projections preserve existing consumer behavior, matching the Phase 1 and Phase 2 matrices.
- Reviewed target records represent the ADR's named Add curated AI-credit prices for current Copilot models #10029 pricing/availability and Complete routing effort metadata for current OpenAI and Anthropic models #10030 reasoning/context requirements, including exact variants, long-context tiers, promotion expiry/successor, and positive/negative effort fixtures.
Those two issues were still open at this handoff; inspect their latest state and linked fixes before implementation. Existing curated entries already cover Claude Opus 5.5, Claude Sonnet 5.5, and GPT-6.1 Sol; do not duplicate them or confuse already-priced stale exception entries with missing tariffs.
Adding corrected canonical facts must not silently change a live host allowlist, tariff, or routing decision. If corrected output would be loaded immediately at an existing consumer path, either stage it separately until the relevant consumer migration or isolate that data correction explicitly for review with updated named expectations. Include a machine-readable/reportable baseline-to-target diff covering model sets, lifecycle, tariffs, thresholds, efforts, and limits. Production resolver/identity changes remain outside this phase.
Do not delete known-gap assertions simply to get tests green: retain the baseline where applicable and update only expectations corresponding to an explicit, sourced, activated correction. Do not manufacture target facts to match old absence assertions.
5. Preserve pricing authority and legacy contracts
The merged ADR explicitly distinguishes scoped configured prices from fetched feeds:
operator overlay > configured catalogue > complete fresh runtime > fresh fetched feed > reviewed maintained > governed import > explicit policy fallback.
Do not change that authority classification or implement the future runtime resolver here. Preserve the existing configured catalogue's version-1 parser, shared_catalog provenance/ID/version, provider aliases, and strict inputTokens > threshold tier boundary.
projectConfiguredCatalogResolution() already projects selected legacy tiers with configured_catalog authority; legacy cacheWrite: null projects to zero to preserve current accounting, and missing review time yields unknown freshness. That compatibility rule does not mean an unavailable cache-write price in new maintained/imported records is zero.
The merged centralFeed validator permits pricing/harness facts with central_feed authority, not availability/lifecycle changes, reasoning/limits/protocol claims, or elevated operator/configured authority. A static full-catalogue export is not automatically a valid central feed; leave feed publication to Phase 8.
6. Updater ordering and CI
Before either mapping copy becomes a generated artifact, retarget the endpoint-only updater to canonical sources plus every affected output, or pause its authoring path explicitly pending Phase 8 (#10298).
The current .github/workflows/model-api-mapping-updater.md directs edits only to docs/model-api-mapping.json, restricts PR allowed-files to that path, and sets lastUpdated from wall-clock time. All three conflict with deterministic generated ownership. Address the complete workflow/permissions/output behavior rather than changing only its prompt or relying on CI to reject its PRs.
If changing workflow source, use the repository's workflow compilation/post-processing instructions and include synchronized generated locks; do not dispatch live workflows as validation. This phase does not authorize operationally disabling a remote workflow outside its reviewed repository changes.
Add documented generation and check commands and CI validation/stale-output detection. Keep the byte-identical mapping-copy regression until deterministic compiler/staleness checks fully cover it.
Acceptance criteria
- Sources and compiler reuse the merged shared schemas/identity/validation APIs; any necessary compatible extension has targeted contract fixtures and documented rationale.
- A source inventory and ownership map account for every migrated model fact and generated consumer artifact; there is no second independent authoring path.
- Maintained records and governed imports carry honest provenance, exact provider identity/scope, confidence, and reproducible metadata; imported facts do not gain first-party availability or compatibility authority.
- Complete-set validation catches cross-file aliases/replacements, normalized collisions, family exceptions, malformed sources, and import count/hash/collision inconsistencies with actionable diagnostics.
- Canonical target records and named Add curated AI-credit prices for current Copilot models #10029/Complete routing effort metadata for current OpenAI and Anthropic models #10030 fixtures cover required reviewed corrections without duplicating already-landed fixes; missing evidence is explicit rather than guessed.
- Baseline-to-target differences and activation boundaries are explicit. Existing production behavior remains characterized; only isolated, intentionally reviewed data corrections alter live projections.
- Host/proxy lifecycle, pricing, mapping/routing, documentation, and static catalogue/manifest projections have schema/contract tests; both mapping copies derive from identical canonical inputs.
- Generation is byte-identical across repeated runs and wall-clock changes; catalogue revision includes normalized sources/schema/compiler versions and static time derives from committed metadata.
- Normal generation/check mode performs no upstream fetch or timestamp refresh; explicit import operations record verifiable metadata.
- Configured-catalogue precedence, legacy null-price semantics, provider aliases, exact tier boundaries, and unknown freshness remain unchanged; runtime pricing/import fallback migrations are not activated.
- Generated assets work in actual host build/package and proxy packaging contexts, not just relative repository paths.
- The endpoint updater is retargeted or paused in the same reviewed change before generated mapping ownership becomes active; generated locks and allowed-files/validation paths are consistent.
- CI fails on invalid sources and stale outputs; contributor documentation explains source editing, generation/checks, import refresh, and the handoff to later phases.
- Existing characterization/contract suites pass except explicitly reviewed, named data-correction expectation changes; all new compiler/import/projection tests pass.
Validation and handoff
Run the new targeted compiler/import/generation tests, build/type-check, and the merged baseline suites:
# Repository root
npm run build && npx jest --runInBand src/model-information-contract.test.ts src/copilot-model.test.ts src/copilot-model-catalog-sync.test.ts
npm run type-check
# Run separately from containers/api-proxy
npm test -- --runInBand model-information-contract.test.js model-metadata-characterization.test.js guards/ai-credits-guard.test.jsAlso run affected mapping, legacy configured-catalogue, packaging, and updater tests. Verify generation followed by check mode is clean and deterministic, including rejection fixtures and real packaged asset resolution. Root Jest does not discover proxy tests.
Deliver an implementation handoff with generation/check commands, source/output paths, schema/compiler/catalogue revisions, reviewed data differences, deferred activation points, updater status, packaging evidence, and any unresolved provenance/coordination blockers.
Non-goals
No production identity/pricing resolver migration, workflow overlay wiring, harness eligibility enforcement, live central refresh/cache, feed publication, new reflection endpoint, public CLI rollout, legacy-reader removal, or broad cleanup. Phase 4 owns lifecycle/workflow integration, Phase 5 pricing and imports at runtime, Phase 6 reasoning/compatibility enforcement, Phase 7 additive /reflect and public exports, Phase 8 the unified updater/publication, and Phase 9 approved legacy removal.
Activity