Skip to content

claude-opus-5 and gpt-5.6-sol missing from allowlist and pricing while model-api-mapping already carries them — third recurrence, needs a cross-catalogue consistency check #6682

Description

@crmitchelmore

Summary

claude-opus-5 and the gpt-5.6-sol / -terra / -luna family are missing from SUPPORTED_COPILOT_MODELS (src/copilot-model.ts) and from containers/api-proxy/ai-credits-pricing.js, while this repository's own docs/model-api-mapping.json already routes both families, and github/gh-aw already advertises both in pkg/cli/data/models.json.

Net effect: gh aw compile accepts model: claude-opus-5 with 0 error(s), 0 warning(s) in strict mode, and then every run of that workflow aborts host-side before any container starts:

Error: model 'claude-opus-5' is unsupported or unrecognized by this AWF version.

validateCopilotModelOption() is called unconditionally from src/commands/validators/config-assembly.ts:76, so this is a total outage for the workflow, not a degraded run.

This is the same class of failure as #5969 (claude-fable-5) and #5991 (claude-sonnet-5). Both were fixed per-model. This is the third occurrence, so the interesting part of this issue is the recurrence, not the two rows — see the proposal below.

Versions

gh-aw v0.83.4 (current release) pins AWF v0.27.42 via constants.DefaultFirewallVersionv0.27.42 is also the newest firewall release. main is unchanged from that tag: src/copilot-model.ts is blob 13509ed1b7518535f9613c9cbc5fb4b767ff0c19 at both.

Current state of the three catalogues

Catalogue claude-opus-5 gpt-5.6-sol Maintained by
docs/model-api-mapping.json {"family": "claude-opus-5", "patterns": ["claude-opus-5*"]} {"family": "gpt-5.6", "patterns": ["gpt-5.6*"]} automated
src/copilot-model.tsSUPPORTED_COPILOT_MODELS (L44–71) hand-edited
containers/api-proxy/ai-credits-pricing.js hand-edited

The mapping entry even names the members explicitly: "Supports both endpoints. Includes gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna per OpenAI SDK ChatModel."

Why it keeps happening

docs/model-api-mapping.json has a scheduled updater — "chore: update model-to-API mapping", e.g. #6622 (2026-07-27), #6579, #6489 — and every one of those PRs changes exactly one file, that JSON. The other two catalogues have no such automation and nothing propagates between them.

The only guard today is src/copilot-model-catalog-sync.test.ts, which covers a single direction of a single pair:

describe('SUPPORTED_COPILOT_MODELS ↔ ai-credits-pricing catalog sync')
  it('every Copilot CLI model in ai-credits-pricing.js appears in SUPPORTED_COPILOT_MODELS')

So the automated feed lands in the one catalogue that is not covered, and the hand-edited pair stays consistent with each other while both drift from it. The SYNC NOTE at the top of ai-credits-pricing.js documents the manual obligation, which is exactly the kind of invariant that wants a test rather than a comment.

Proposal: a consistency check across the model catalogues

Please consider extending the existing sync guard into a full consistency check. Roughly in order of value:

  1. Within this repo — close the triangle. Assert docs/model-api-mapping.jsonSUPPORTED_COPILOT_MODELSai-credits-pricing.js are mutually consistent for Copilot CLI completion models, with an explicit, named exclusion list for deliberate omissions (the existing test already has the exclusion-set pattern). Since the mapping is the automated feed, this converts a silent drift into a failing check on the very PR that introduces it — the updater PR itself would go red and name the missing rows.
  2. Across repos — validate against the compiler that pins us. A scheduled check comparing SUPPORTED_COPILOT_MODELS against pkg/cli/data/models.json in github/gh-aw at the release whose DefaultFirewallVersion points here. Any model the compiler advertises but this firewall refuses is, by construction, a workflow that compiles cleanly and cannot run.
  3. Make the allowlist consumable. Publish the set as a release asset or a small JSON file, so downstream consumers can assert against it without scraping a .ts file at a tag. Today the only reliable method is reading DefaultFirewallVersion out of the pinned compiler, fetching src/copilot-model.ts at that tag, and parsing the Set literal — which is what we ended up automating.

(1) alone would have caught all three occurrences at the point of introduction.

Immediate fix

Additive rows in both hand-edited catalogues. gh-aw's own catalogue prices claude-opus-5 identically to claude-opus-4.8 and gpt-5.6-sol identically to gpt-5.5, so the values should be uncontroversial — but they are a billing input, so I have deliberately not opened a PR presuming them. Happy to raise one if you confirm the numbers.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions