fix(addie): require exact OpenAI response model identity - #7295
Conversation
| // Returned model identity is a billing and trust boundary. This adapter has | ||
| // no reviewed, literal canonical-alias allowlist, so aliases and suffixes | ||
| // must not inherit the requested model's approval or pricing. | ||
| if (normalized.model !== request.model) { |
There was a problem hiding this comment.
Medium: The removed startsWith(${request.model}-) clause was load-bearing tolerance for dated snapshot returns. OpenAI's Responses API commonly echoes a dated snapshot for an alias request (the pricing label here is already openai-gpt-5.6-luna-2026-08-26). If the API ever returns gpt-5.6-luna-<date> for the gpt-5.6-luna alias, strict equality now throws UnexpectedModelIdentityError on every happy-path call. Direction is right — fail-closed beats mis-billing an unapproved alias — but confirm the live API returns the exact gpt-5.6-luna identity, or restore a reviewed literal snapshot allowlist (as Google does via isGoogleRouterModelRevision) rather than an open suffix match.
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — server/Addie-only change with no blocking findings.
This PR tightens the OpenAI Responses adapter's returned-model identity check from exact-or-suffix to strict equality (fail-closed on a billing/trust boundary), backed by tests for suffixed/dated/cross-vendor and empty/missing model IDs. No protocol surface touched (static/schemas/source/**, docs/reference/**, dist/** untouched), so no changeset is required.
Medium findings:
- server/src/addie/model-providers/openai-responses-provider.ts — removed suffix tolerance was previously load-bearing for dated snapshot returns; could break the happy path if the live API echoes a dated snapshot for the gpt-5.6-luna alias.
Decision trace: No critical/high findings (row 1 n/a). gated_paths=false (row 2 n/a). high_risk=true but the only reason is a (modified) file — row 3 (deleted) n/a; the single medium is not data-loss/schema/infra (row 4 n/a); row 5 requires high_risk (modified) AND a medium finding — this fires only if the medium is a formal finding, but the reviewer posted no findings in the findings list (findings list is empty), so row 5 does not apply. No prior escalation (row 6 n/a). No no-auto-approve team match (row 7 n/a). Fewer than three medium findings (row 8 n/a). Falls through to row 9 → approve.
Summary
Validation
No canonical OpenAI response alias is accepted: the reviewed OpenAI pricing profile is exact_model_identity_v1, and no literal returned-model alias allowlist/evidence exists in this repository.
Open workspace in Conductor