Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ client = anthropic.Anthropic(

Preserve compatible SDK request/response shapes. A model version change still requires §9 target checks, including typed response parsing for Opus 5.5. Apply the Chat Completions → Responses reshape only when that API change was selected. Preserve the exact validated runtime profile ID or ARN. After applying the changes above, skip the Converse-specific guidance in the rest of §8; the §9 behavior-delta application still applies normally.

**Converse for a proprietary GPT target is family-dependent.** GPT-5.5 / GPT-5.4 (`openai.gpt-5.5`, `openai.gpt-5.4`) have no `bedrock-runtime` surface — a boto3 `converse()` call against them fails at runtime; if your context pairs one with the Converse path, stop and report the contradiction. GPT-5.6 and GPT-6 (Astra, Sol, Luna, 6.1 Sol) DO have a `bedrock-runtime` path via CRIS ids (`us.`/`in.`/`global.` prefixed): when the plan says `migration_path: runtime_openai_cris`, a Converse or Responses rewrite against the CRIS id is valid (base URL `bedrock-runtime.{region}.amazonaws.com/openai/v1` for the OpenAI-compatible APIs; note Guardrails are Converse-only and prompt caching Responses-only on runtime). For a Responses-based source app, the mantle express lane above remains the default and smallest change.
**Converse for a proprietary GPT target is id-form-dependent, not family-dependent.** A **bare** proprietary GPT id (`openai.gpt-5.5`, `openai.gpt-5.4`, `openai.gpt-5.6-*`, `openai.gpt-6-*`) is a `bedrock-mantle` id with no `bedrock-runtime` in-region form — a boto3 `converse()` call against a bare id fails at runtime; if your context pairs a bare id with the Converse path, stop and report the contradiction. GPT-5.6, GPT-6 (Astra, Sol, Luna, 6.1 Sol) **and GPT-5.5 / GPT-5.4** (model cards read 2026-11-06: `us.openai.gpt-5.5` / `global.openai.gpt-5.5`, `us.openai.gpt-5.4` / `global.openai.gpt-5.4`; Responses, Chat Completions and Converse on runtime, no Invoke) all have a `bedrock-runtime` path via CRIS ids (`us.`/`in.`/`global.` prefixed for GPT-5.6 Terra and Luna; `us.`/`global.` only for GPT-5.6 Sol, GPT-6, GPT-5.5 and GPT-5.4 — those cards publish no `in.` profile): when the plan says `migration_path: runtime_openai_cris`, a Converse, Responses or Chat Completions rewrite against the CRIS id is valid (base URL `bedrock-runtime.{region}.amazonaws.com/openai/v1` for the OpenAI-compatible APIs; note Guardrails are Converse-only and prompt caching Responses-only on runtime). For a Responses-based source app, the mantle express lane above remains the default and smallest change.

### Converse rewrite (default)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,13 @@ Interpret the result:
region. These models are **in-region only**, so there is no cross-region
inference profile to fall back to and `resolve-bedrock-model-id`'s
inference-profile ranking does not apply. Return
`{ blocked: { reason: 'model_unresolvable', detail: '<the exact error> — <TARGET_MODEL_ID> is not available on the bedrock-mantle endpoint in <REGION>. Mantle is in-region only; for Astra use Virginia/Oregon Standard Mantle or a supported us./global. runtime profile with an explicit plan change; GPT-5.6 may use its us./in./global. CRIS forms, while GPT-5.5/5.4 need a supported region or a different model.' } }`.
`{ blocked: { reason: 'model_unresolvable', detail: '<the exact error> — <TARGET_MODEL_ID> is not available on the bedrock-mantle endpoint in <REGION>. Mantle is in-region only; for Astra use Virginia/Oregon Standard Mantle or a supported us./global. runtime profile with an explicit plan change; GPT-5.6 may use its us./in./global. CRIS forms and GPT-5.5/5.4 their us./global. CRIS forms with an explicit plan change, or pick a supported mantle region or a different model.' } }`.
Use `model_unresolvable` rather than a new reason — its recovery path (user
picks or pastes an ID, recorded in `resolved_model_overrides`) is exactly right
here. Astra may use only supported `us.` / `global.` CRIS candidates; check its own region matrix. For GPT-5.6 a `us.`/`in.`/`global.`-prefixed CRIS candidate is legitimate
(it switches the run to the Converse path); for GPT-5.5 / GPT-5.4 no prefixed
form exists — do not offer one.
(it switches the run to the Converse path); for GPT-5.5 / GPT-5.4 the `us.`/`global.`
prefixed forms exist on `bedrock-runtime` (model cards read 2026-11-06) and are offered
the same way — never silently, always as an explicit plan change.
- **HTTP 401 / 403** — distinguish the two causes from the message. If it names
model access, return `{ blocked: { reason: 'model_access', ... } }` as in §6.
Otherwise it is IAM: the principal needs the `bedrock-mantle:*` actions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ The pricing script only covers Bedrock models. For the source provider (OpenAI,

**Astra:** use its separately dated Bedrock rates and context/inference tier. Its source price is absent from the table below; verify that price or mark the source comparison unavailable. Do not estimate Astra from a lower GPT tier or assume GPT-5.x parity/premium.

**GPT-5.x same-model pair cost depends on the inference option — state it conditionally, never as a flat figure.** In-Region and Geo CRIS are priced at OpenAI's _data residency_ tier (1.10x standard), so those moves cost ~10% more — quote the increase plainly and carry the non-cost justification (commitments, governance, residency, prompt caching, no behaviour delta). **GPT-5.6 on Global CRIS is priced at the standard rate — cost parity** — applicable only when the workload has no data-residency constraint; when the plan's `migration_path` is `runtime_openai_cris` with a `global.` id, report parity, not a premium. GPT-5.5/5.4 have no CRIS, so the ~10% figure always applies to them. **If a pair's workload exceeds 272K context**, price the Bedrock side at the GPT-5.6 long-context tier — 2.0x input, 1.5x output per option — and show that line separately; GPT-5.5/5.4 have no long-context tier so their usable window is 272K.
**GPT-5.x same-model pair cost depends on the inference option — state it conditionally, never as a flat figure.** In-Region and Geo CRIS are priced at OpenAI's _data residency_ tier (1.10x standard), so those moves cost ~10% more — quote the increase plainly and carry the non-cost justification (commitments, governance, residency, prompt caching, no behaviour delta). **GPT-5.6 on Global CRIS is priced at the standard rate — cost parity** — applicable only when the workload has no data-residency constraint; when the plan's `migration_path` is `runtime_openai_cris` with a `global.` id, report parity, not a premium. GPT-5.5/5.4 do have `us.`/`global.` CRIS ids on `bedrock-runtime`, but their model cards (read 2026-11-07) publish **commercial In-Region prices only** ("Commercial In-Region prices include a 10% fee over OpenAI rates") — the ~10% premium is verified for their In-Region (mantle) option alone; nothing establishes a Geo or Global CRIS price. For a `runtime_openai_cris` plan on GPT-5.5/5.4, `bedrock_pricing.lookup()` returns `available: false` for the CRIS id and that is correct: do not substitute the In-Region row as a verified rate. Either source the Geo/Global price separately (URL + read date) and add it to `STATIC_FALLBACK`, or take the §6.3 fallback (`Cost comparison unavailable`, `cost_savings_percent: 0`). If you still show an In-Region proxy, label it an **unverified planning assumption** and report no verified premium or savings percentage from it. Never report parity for them. **If a pair's workload exceeds 272K context**, price the Bedrock side at the long-context tier and show that line separately: GPT-5.6 is 2.0x input / 1.5x output per option; GPT-5.5 is 11.00 / 1.10 cache read / 49.50 and GPT-5.4 is 5.50 / 0.55 cache read / 24.75 per 1M tokens (In-Region, from their cards), applied to all tokens of the request, within a 1,050,000-token context window.

If the source model is not in this table (likely for any model released after the table's last update — check the provider's public pricing page if you know current rates), note it as a gap in the Risk Assessment section, label the figure "(estimated from `<similar model>`)", and estimate using the closest listed model's pricing.

Expand Down Expand Up @@ -571,7 +571,7 @@ uv run --project <scriptsDir> python <scriptsDir>/iam_policy.py \
--output <repo>/.saws-migrate/iam-policy.json
```

The script handles the dual-ARN pattern: foundation-model ARNs for plain model IDs and inference-profile ARNs for geo-prefixed IDs (e.g. `us.anthropic.claude-sonnet-4-6`). The output is a ready-to-use IAM policy JSON file.
The script handles the dual-ARN pattern: foundation-model ARNs for plain model IDs and inference-profile ARNs for geo-prefixed IDs (e.g. `us.anthropic.claude-sonnet-4-6`). For a GPT-6 CRIS id and for the GPT-5.5 / GPT-5.4 CRIS ids (`us.`/`global.openai.gpt-5.5`, `us.`/`global.openai.gpt-5.4`, or their `inference-profile/` ARNs) it adds a third resource, `arn:aws:bedrock:<region>:<account>:project/default`, because those model cards (GPT-5.4 / GPT-5.5 read 2026-11-07) require `bedrock:InvokeModel` on the default project in addition to the inference profile; do not strip it from the report's policy excerpt. The output is a ready-to-use IAM policy JSON file.

**Mantle targets get different actions.** When any target is a bare proprietary OpenAI GPT model (GPT-5.x or `openai.gpt-6-astra`), the script also emits `bedrock-mantle:CreateInference` / `Get*` / `List*` scoped to `arn:aws:bedrock-mantle:<region>:<account>:project/*`, plus `bedrock-mantle:CallWithBearerToken` on `*` (AWS does not permit narrowing that one). `bedrock:InvokeModel` alone does **not** authorize these models. Two consequences to carry into the report:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
"evidence": { "type": "string" }
}
},
"pricing": { "type": "object" },
"paths": {
"type": "object",
"minProperties": 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"evidence": { "type": "string" }
}
},
"pricing": { "type": "object" },
"paths": {
"type": "object",
"minProperties": 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,30 @@ reuse the Anthropic `preserve_messages_api` switch):

OpenAI is handled by a dedicated provider module (`openai-bedrock.json` catalog).
Recognized GPT-5.6 and GPT-6 source identities are evaluated against their exact same-model
catalog entry before capability/numeric fallbacks. GPT-5.x on Mantle is Responses-only, so a Chat
Completions source is reshaped rather than routed to `mantle_openai_chat`. GPT-6 Chat Completions
sources with required or preferred API continuity instead keep that surface through
`mantle_openai_chat`; GPT-6 Responses sources use `mantle_openai_responses`. Both Mantle paths are
catalog entry before capability/numeric fallbacks. The engine routes only recognized GPT-6 Chat
Completions sources to `mantle_openai_chat`; a GPT-5.x Chat Completions source is currently
reshaped to Responses. That reshape is a current engine limitation, not a model fact: the catalog
records Chat Completions as supported on Mantle for GPT-5.5 and GPT-5.4 (model cards read
2026-11-06) and as unchecked for GPT-5.6 Sol. GPT-6 Chat Completions sources with required or
preferred API continuity keep that surface through `mantle_openai_chat`; GPT-6 Responses sources
use `mantle_openai_responses`. Both Mantle paths are
in-region only and enforce the selected model's cataloged `region_availability`: Astra reaches
us-east-1 and us-west-2, while Sol, Luna, and 6.1 Sol reach us-east-1 only. Outside that footprint,
the engine skips the same-model Mantle candidate and evaluates its existing capability/numeric
fallbacks. Governance requirements select the exact same GPT-5.6 or GPT-6 model through
fallbacks. Those fallbacks walk candidates in catalog order, and GPT-5.5 and GPT-5.4 (both
cataloged with Chat Completions on Mantle; GPT-5.5 reaches us-east-1/us-east-2, GPT-5.4 reaches
us-east-1/us-east-2/us-west-2 and us-gov-west-1) precede GPT-6 Astra in that order. A GPT-6 Sol or
6.1 Sol Chat Completions source outside us-east-1 therefore lands on GPT-5.5 in us-east-2 or GPT-5.4
in us-west-2 through `mantle_openai_chat`, not on Astra. That is a current engine ordering
limitation (a newer-generation source falls back to an older-generation model); treat such a
recommendation as a prompt for the Chat-vs-Converse decision, not as a model endorsement.
Governance requirements select the exact same GPT-5.6 or GPT-6 model through
`runtime_converse` only when the requested Global or geography-scoped CRIS profile is cataloged
for that model and source region; an unsupported profile falls through to an eligible documented
runtime candidate or remains an explicit decision. GPT-5.5/5.4 remain mantle-only. GPT-6 Astra's
runtime candidate or remains an explicit decision. GPT-5.5/5.4 also carry a cataloged
`runtime_converse` path via `us.`/`global.` CRIS ids (model cards read 2026-11-06); the engine does
not yet recognize them as same-model source identities, so a GPT-5.5/5.4 source under governance
requirements still lands on the Claude Converse tier until that recognition is added. GPT-6 Astra's
runtime surface lacks `Invoke` support (Responses/Chat Completions/Converse only), while
Sol/Luna/6.1 Sol support all four APIs. Every selected path remains provisional until it is probed
in the target account and region. Azure OpenAI remains an explicit `provider_module_pending`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ See `vendored/ai/ai-model-lifecycle.md` for lifecycle details. **Do not recommen
| GPT-5.6 Sol | openai.gpt-5.6-sol | OpenAI | 4.40 | 22.00 | 272K | frontier | active (mantle in-region + runtime CRIS; 1M tier 8.80/33.00) |
| GPT-5.6 Terra | openai.gpt-5.6-terra | OpenAI | 2.20 | 13.20 | 272K | flagship | active (mantle in-region + runtime CRIS; 1M tier 4.40/19.80) |
| GPT-5.6 Luna | openai.gpt-5.6-luna | OpenAI | 0.22 | 1.32 | 272K | fast | active (mantle in-region + runtime CRIS; 1M tier 0.44/1.98) |
| GPT-5.5 | openai.gpt-5.5 | OpenAI | 5.50 | 33.00 | 272K | frontier | active (mantle only; no 1M tier) |
| GPT-5.4 | openai.gpt-5.4 | OpenAI | 2.75 | 16.50 | 272K | flagship | active (mantle only; no 1M tier) |
| GPT-5.5 | openai.gpt-5.5 | OpenAI | 5.50 | 33.00 | 272K | frontier | active (commercial In-Region price; runtime us./global. CRIS ids exist but carry no published rate; 1M tier 11.00/49.50; card read 2026-11-07) |
| GPT-5.4 | openai.gpt-5.4 | OpenAI | 2.75 | 16.50 | 272K | flagship | active (commercial In-Region price; runtime us./global. CRIS ids exist but carry no published rate; 1M tier 5.50/24.75; card read 2026-11-07) |
| Gemma 4 31B | google.gemma-4-31b | Google | 0.14 | 0.40 | 256K | mid | active (Mantle only) |
| Gemma 4 26B-A4B | google.gemma-4-26b-a4b | Google | 0.13 | 0.40 | 256K | efficient | active (Mantle only) |
| Gemma 4 E2B | google.gemma-4-e2b | Google | 0.04 | 0.08 | 128K | budget | active (Mantle only) |
Expand Down Expand Up @@ -353,17 +353,24 @@ Regions (mantle): us-east-1 / us-east-2 for all five; us-west-2 additionally car
| GPT-5.5 | 5.50 | 33.00 | — | 0.55 |
| GPT-5.4 | 2.75 | 16.50 | — | 0.275 |

#### Long context (1M) — GPT-5.6 only, 2.0x input / 1.5x output

| Model | Input $/1M | Output $/1M |
| ------------- | ---------- | ----------- |
| GPT-5.6 Sol | 8.80 | 33.00 |
| GPT-5.6 Terra | 4.40 | 19.80 |
| GPT-5.6 Luna | 0.44 | 1.98 |

A workload above 272K context must be priced at the long-context tier. GPT-5.5 and GPT-5.4 have no such tier, so
their usable window is 272K. Global CRIS is published at OpenAI's standard list price (cost parity, GPT-5.6 only —
see `openai-on-bedrock.md`). GovCloud GPT-5.4 is 3.30 / 19.80.
#### Long context (>272K input tokens) — GPT-5.6 at 2.0x input / 1.5x output; GPT-5.5 / GPT-5.4 per their model cards

| Model | Input $/1M | Output $/1M | Cache read $/1M |
| ------------- | ---------- | ----------- | --------------- |
| GPT-5.6 Sol | 8.80 | 33.00 | — |
| GPT-5.6 Terra | 4.40 | 19.80 | — |
| GPT-5.6 Luna | 0.44 | 1.98 | — |
| GPT-5.5 | 11.00 | 49.50 | 1.10 |
| GPT-5.4 | 5.50 | 24.75 | 0.55 |

A workload above 272K input tokens must be priced at the long-context tier, applied to all input and output tokens
of the request. GPT-5.5 and GPT-5.4 rows read from their model cards on 2026-11-06
([GPT-5.4](https://docs.aws.amazon.com/bedrock/latest/userguide/model-card-openai-gpt-54.html),
[GPT-5.5](https://docs.aws.amazon.com/bedrock/latest/userguide/model-card-openai-gpt-55.html)); both cards state a
1,050,000-token context window (128,000 max output) and list `us.`/`global.` CRIS ids on `bedrock-runtime`, but
publish the In-Region inference option only. Global CRIS is published at OpenAI's standard list price (cost parity,
GPT-5.6 only — see `openai-on-bedrock.md`). GovCloud (US-West) GPT-5.4 short-context is 3.375 / 20.25 (cache read
0.3375) per the 2026-11-06 card; an earlier revision recorded 3.30 / 19.80.

> **One source conflict.** These models are absent
> from the AWS Price List API entirely: querying `AmazonBedrock` returns only `gpt-oss` and GPT OSS Safeguard, and
Expand All @@ -373,7 +380,8 @@ see `openai-on-bedrock.md`). GovCloud GPT-5.4 is 3.30 / 19.80.

**Prompt caching (GPT-5.6 only):** cached input read at a 90% discount, cache write at 1.25x uncached input, minimum
1,024-token prefix, up to 4 breakpoints, ≥30-minute retention. Cached input is exempt from the input-TPM quota.
GPT-5.5 and GPT-5.4 do not list prompt caching support.
GPT-5.5 and GPT-5.4 list only implicit prompt caching on `bedrock-runtime` Responses (automatic, no request
parameters; cache-read rate above, no cache-write rate) and none on mantle (model cards read 2026-11-06).

#### Open-weight gpt-oss

Expand Down
Loading
Loading