feat(agent): default to Claude Opus 5 - #768
Conversation
Flip the platform default model from us.anthropic.claude-opus-4-8 to us.anthropic.claude-opus-5 at all four call sites — the agent's ANTHROPIC_MODEL fallback, the TaskConfig field default, the CLI's PLATFORM_REPO_DEFAULTS (which also drives what `platform doctor` probes for access), and the documented default. The IAM grant and workflow allowlist already carry Opus 5 (#744, merged and deployed), so nothing fails at turn 0. Opus 4.8 stays granted because blueprints may pin it per repo. Per-token rate is unchanged at $5.00/MTok; the ~1.17x difference on an identical prompt is token volume, not price. Closes #745 Co-Authored-By: Claude <noreply@anthropic.com>
🔀 Merge guidance (for the reviewer)Independent of #764 — merge in either order. Prefer #764 first (tidier), but not required.
Action: review and merge whenever convenient. Why this is safe now — the prerequisite is genuinely satisfied#744 is merged and deployed. Verified three ways rather than assumed:
So the IAM grant exists in the account and nothing fails at turn 0 with The four call sites (a partial flip would be worse than none)
#742's drift guard proved itself across a real model bumpThis is the payoff that justified building it. Changing GREEN 5/5 after the doc updates. Without that test, four of those seven would have rotted silently — exactly the failure mode #742 existed to close. Orchestrator re-ran it independently on the branch head: 5/5 pass. Cost framing — read this before assuming Opus 5 is more expensiveThe per-token rate is unchanged. Measured on the pinned toolchain with an identical one-turn prompt: Opus 4.8 = 32,145 tok / $0.160850; Opus 5 = 37,584 tok / $0.188020. Both imply exactly $5.00/MTok (token ratio 1.169 == cost ratio 1.169). So the delta is token volume on an identical prompt, not a price increase — re-baseline volume, not rates. Worth knowing alongside that: The historical Opus 4.8 vs Opus 5 cost table in
|
theagenticguy
left a comment
There was a problem hiding this comment.
✅ Approve
Reviewed the full diff and independently re-verified the claims on a fresh clone of feat/745-default-opus-5 rather than taking the PR body's word for it.
What was verified
Completeness of the flip. Swept the branch for remaining claude-opus-4-8 references. Every one that remains is deliberate:
cdk/src/constructs/bedrock-models.ts+cdk/src/handlers/shared/workflows.ts— Opus 4.8 stays granted/allowlisted so blueprint pins keep working, and both already carry theclaude-opus-5entries from #744. Correct to leave untouched (and correctly stays out of #764's three files).DEVELOPER_GUIDE.md/Model-configuration.mdcost table — historical measurements, correctly left as-is.docs/abca-plugin/skills/onboard-repo/SKILL.md:119-127— pre-existing stale doc, already flagged in the PR as a follow-up. Agreed it's out of scope here (it's outside the parity guard's file set).
Both drift guards, run locally on the branch head:
cdk/test/contracts/model-default-docs-parity.test.ts→ 5/5 pass (not edited/weakened, pergh pr diff)cli/test/commands/repo-display.test.ts→ 9/9 pass, including the guard that readsagent/src/config.pydirectly and assertsPLATFORM_REPO_DEFAULTS.model_idequals the runtime fallback — so theplatform doctorprobe and the agent runtime cannot disagree after this merge.
Prerequisite. #744 is closed/merged and origin/main's grant list + workflow allowlist both contain the Opus 5 entries (bare + us.-prefixed, global. correctly withheld pending #747). Couldn't re-run the live invoke-model probe from this environment, but the merged code + green deploy.yml cited in the PR is sufficient evidence.
CI: all 8 checks green.
Notes (non-blocking)
- The #720 fixture git-config leak reproduction documented in the PR comment is worth re-opening as its own issue — it's orthogonal to this diff but nasty (rogue
bgagentcommits in any worktree). - Please do file the SKILL.md follow-up so it doesn't rot further.
Clean, well-scoped value flip with the guards doing exactly what they were built for. 🚢
Summary
Flip the platform default model from
us.anthropic.claude-opus-4-8tous.anthropic.claude-opus-5at all four call sites, in one commit.Closes #745
Why this is safe now
The prerequisite #744 (additive IAM grant + workflow allowlist for Opus 5) is merged AND deployed:
deploy.ymlrun on3412f4cb(feat(cdk): grant Claude Opus 5 (additive IAM + workflow allowlist, no default change) #744's merge commit) completed successfully.cdk/src/constructs/bedrock-models.tsonorigin/maincarries theanthropic.claude-opus-5entry.aws bedrock-runtime invoke-model --model-id us.anthropic.claude-opus-5inus-east-1returned HTTP 200.So the grant exists in the account and the new default cannot fail at turn 0 with
AccessDenied.us.anthropic.claude-opus-5andglobal.anthropic.claude-opus-5are both ACTIVE/invocable; the bare idanthropic.claude-opus-5is not (ValidationException: … on-demand throughput isn't supported). This PR uses theus.-prefixed form everywhere. The pinned toolchain (claude-agent-sdk==0.2.110, bundled CLI2.1.191) passes the prefixed forms through, so no SDK/CLI bump is needed.Opus 4.8 is not removed from any grant or allowlist — blueprints may pin it per repo.
The four call sites
agent/src/config.py:563ANTHROPIC_MODELenv fallback:us.anthropic.claude-opus-4-8→us.anthropic.claude-opus-5agent/src/models.py:157TaskConfig.anthropic_modelfield default: same flipcli/src/repo-display.ts:48PLATFORM_REPO_DEFAULTS.model_id: same flipdocs/guides/DEVELOPER_GUIDE.md,agent/README.md,docs/guides/USER_GUIDE.md,docs/design/REPO_ONBOARDING.md+ regenerated Starlight mirrorscli/src/repo-display.tsis load-bearing beyond display:platform doctorderives the model it probes for ACCESS from this value. A partial flip is worse than none — ifconfig.pyandrepo-display.tsdisagree, doctor probes the wrong model and can report a healthy stack while every task fails at turn 0.Testing
cdk/test/contracts/model-default-docs-parity.test.ts(#742's guard) was used as the executable spec. It was not edited, weakened, or skipped.Baseline GREEN on the untouched tree:
cd cdk && npx jest test/contracts/model-default-docs-parity.test.ts→ 5 passed.RED after changing only
config.py— this is the reproduction, and it named exactly which docs had gone stale:MISE_EXPERIMENTAL=1 mise //docs:sync(never hand-edited) → 5 passed.Gates run from the worktree:
mise //agent:qualitymise //cdk:eslint,mise //cli:eslintmise run buildcdk:test,cli:test,agent:test,cdk:synth:quiet,docs:build,docs:link-check, drift checks)prek run --files <changed>docs-sync,astro check)Cost framing
The per-token rate is unchanged — a one-turn smoke prompt implies exactly $5.00/MTok on both Opus 4.8 and Opus 5. Opus 5 used ~1.17x the input tokens on an identical prompt (37,584 vs 32,145), so the delta is token volume, not price. Re-baseline volume, not rates.
Worth flagging for reviewers:
max_turnsdefaults to 100 andmax_budget_usdhas no platform default (unset means unlimited), so a token-volume increase is not capped by default. The documented mitigation is a lighter-token model per repo/task (blueprintagent.modelId/ payloadmodel_id).The measured Opus 4.8 vs Opus 5 cost comparison table in
docs/guides/DEVELOPER_GUIDE.md(added by #742) is left numerically untouched — those are historical measurements of two models, not a claim about which is the default.Notes for the reviewer
--no-verify.security:sast:maskingis RED on pristinemain(~25 pre-existingts-silent-success-maskingfindings acrossagent/src,cdk/src/handlers,cli/src) and it gates the pre-push hook. Reproduced on a clean tree to confirm pre-existence and verified none of the findings are in the files this PR touches. Nonosemgrepsuppression was added.docs/abca-plugin/skills/onboard-repo/SKILL.md:119-127still claims the stack grants only "Sonnet 4.6, Opus 4, and Haiku 4.5" and uses Opus 4.8 as the example of a model that "will fail at invoke with a 403". That doc is stale independently of this change (it predates feat(cdk): grant Claude Opus 5 (additive IAM + workflow allowlist, no default change) #744) and is outside the parity test's guarded set. Worth a follow-up issue.cdk synthneedsec2:DescribeAvailabilityZones, which the dev role lacks, so the gitignoredcdk/cdk.context.jsonAZ cache was seeded locally to complete the synth gate. It is not committed (confirmed gitignored).Dependencies / related
cdk/src/constructs/bedrock-models.ts,cdk/src/stacks/agent.ts, andcdk/src/constructs/ecs-agent-cluster.ts. I deliberately stayed entirely out of those three files to avoid a conflict — this PR introduces nobedrockGeoRegion.global.; the geo staysushere.cdk/test/contracts/model-default-docs-parity.test.ts, which is untouched.ANTHROPIC_DEFAULT_HAIKU_MODEL(the auxiliary model) is unchanged, per scope.No new dependency, tool, or GitHub Action was introduced — this is a value flip.
🤖 Generated with Claude Code