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.DefaultFirewallVersion — v0.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.ts → SUPPORTED_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:
- Within this repo — close the triangle. Assert
docs/model-api-mapping.json ↔ SUPPORTED_COPILOT_MODELS ↔ ai-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.
- 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.
- 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
Summary
claude-opus-5and thegpt-5.6-sol/-terra/-lunafamily are missing fromSUPPORTED_COPILOT_MODELS(src/copilot-model.ts) and fromcontainers/api-proxy/ai-credits-pricing.js, while this repository's owndocs/model-api-mapping.jsonalready routes both families, andgithub/gh-awalready advertises both inpkg/cli/data/models.json.Net effect:
gh aw compileacceptsmodel: claude-opus-5with0 error(s), 0 warning(s)in strict mode, and then every run of that workflow aborts host-side before any container starts:validateCopilotModelOption()is called unconditionally fromsrc/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 AWFv0.27.42viaconstants.DefaultFirewallVersion—v0.27.42is also the newest firewall release.mainis unchanged from that tag:src/copilot-model.tsis blob13509ed1b7518535f9613c9cbc5fb4b767ff0c19at both.Current state of the three catalogues
claude-opus-5gpt-5.6-soldocs/model-api-mapping.json{"family": "claude-opus-5", "patterns": ["claude-opus-5*"]}{"family": "gpt-5.6", "patterns": ["gpt-5.6*"]}src/copilot-model.ts→SUPPORTED_COPILOT_MODELS(L44–71)containers/api-proxy/ai-credits-pricing.jsThe 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.jsonhas 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: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 NOTEat the top ofai-credits-pricing.jsdocuments 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:
docs/model-api-mapping.json↔SUPPORTED_COPILOT_MODELS↔ai-credits-pricing.jsare 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.SUPPORTED_COPILOT_MODELSagainstpkg/cli/data/models.jsoningithub/gh-awat the release whoseDefaultFirewallVersionpoints here. Any model the compiler advertises but this firewall refuses is, by construction, a workflow that compiles cleanly and cannot run..tsfile at a tag. Today the only reliable method is readingDefaultFirewallVersionout of the pinned compiler, fetchingsrc/copilot-model.tsat that tag, and parsing theSetliteral — 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-5identically toclaude-opus-4.8andgpt-5.6-solidentically togpt-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
github/gh-aw#48583— same drift viewed from the compiler side; asks for compile-time validation ofengine.modelagainst the pinned firewall's allowlist.github/gh-aw#46306— different path, same outcome: provider-scopedengine.modelcompiles cleanly, rejected by AWF at runtime.DigitalInnovation/gh-aw-control-plane#1912— downstream tracking issue; documents the manual verification procedure we now run on every compiler bump, which exists solely because of this gap.