Consume the canonical reasoning-level contract

The agents consume the config-sourced reasoning ladder from pramaan-functions (low · medium · high · max · ultra_max), accept the legacy extra_high → max alias, make every agent's thinking_tiers total, omit no-op visible levels, and emit typed tool intents stamped with an execution plane. Contract consumption only — no resolver, no floor, no execution credentials in the brain.
Story-1652 · EPIC-1646 Agentic Interaction · Wave-1 (after Wave-0 #1647/#1648) · updates Atlas + Blake (agents/) + agent_contracts · branch issue-1652-consume-level-contract · 2026-06-23

RFC-APB-004 (ACCEPTED 2026-06-23) ratified a single canonical reasoning ladder — low · medium · high · max · ultra_max, cheap open at the bottom, frontier at the top — and put its one source (the yaml) + the codegen'd enums in pramaan-functions (Story-1648, Wave-0). The typed tool-intent contract with plane: client | server landed alongside it (Story-1647). This Story is the agent-side consume (RFC-004 T5): the agents adopt the canonical level set, normalize the legacy extra_high spelling to max, make each agent's level→tier map total, surface only the levels that resolve to a distinct model for that agent, and stamp every emitted tool intent with its execution plane. The agents own no level→model resolver and no floor (those stay in the broker rails, ADR-129 §D2/§D3); they map a broker-resolved level onto their own existing tiers and emit honest intents — nothing else.

What to review

AreaWhereWhat it does
Canonical enum + aliasagent_contracts/enums.pyThinkingLevel becomes low·medium·high·max·ultra_max; _missing_ resolves the legacy extra_high → max (additive alias, never a rename-in-place) for both ThinkingLevel(value) and Pydantic validation. Adds the cost-ordered THINKING_LADDER + LEGACY_THINKING_LEVEL_ALIAS.
Agent-local mirrorsagents/atlas/runtime_axes.py, agents/registrar/runtime_axes.pyThe self-contained CodeZip can't import the repo-root contract, so each agent restates the canonical ladder + alias VERBATIM — fenced by a parity test that fails on drift (ADR-110 §9, no per-agent dialect).
Total per-agent map + frontieragents/atlas/model.json, agents/registrar/model.jsonthinking_tiers is now TOTAL over all five canonical levels (every level resolves — no silent fallback to default). A new frontier tier = anthropic/claude-opus-4-8 (via OpenRouter, not Bedrock) serves max/ultra_max — the RFC-004 §A per-agent frontier.
Selection + visible levelsagents/atlas/config.py, agents/registrar/config.py model_for_thinking() / visible_thinking_levels()model_for_thinking normalizes the alias then maps level→tier→model (totality guard); visible_thinking_levels walks the ladder and keeps a level only where it resolves to a model distinct from the previous visible one — no-op levels are omitted. Frontier pricing added so a frontier turn never under-reports cost.
Typed tool intents + planeagents/registrar/models.py, agents/registrar/runtime.pyRegistrarToolIntent gains plane: client | server (Story-1647 contract). Blake emits server-plane intents only — the broker executes them on the backend under RLS; the brain holds no execution credentials. The plane rides every wire intent via _wrap_intent.
Custody / schemaagent_contracts/schemas/agent_invoke.v1.schema.jsonRegenerated from the Pydantic source: the advertised enum is the canonical five; extra_high is accepted on input (via _missing_) but not advertised — exactly the additive-alias semantics.
Teststests/test_agent_invoke_contract.py, agents/*/tests/test_*_runtime_axes.py, test_registrar_policy.py, test_registrar_classify_capability.pyCanonical-ladder parity + fail-closed; extra_high → max normalization end-to-end; totality over the level set; visible-level no-op omission; ultra_max → frontier Opus; every emitted intent is server-plane.

The thin seam — consume the level, select the tier, omit the no-op

# Broker (Story-1562/1648) resolves + floors the level from the ONE config source, then invokes:
agent_invoke.v1 { …, thinking_level:"ultra_max" }      # or legacy "extra_high"

# Agent READS it — alias normalizes, then SELECTS its own tier. No resolver, no floor.
ThinkingLevel("extra_high") is ThinkingLevel.MAX        # _missing_ alias (RFC-004 §A)
cfg = AtlasConfig.for_invoke(request)                     # ultra_max → frontier → anthropic/claude-opus-4-8

# TOTAL map — every canonical level resolves; none falls back to the default model:
thinking_tiers = { low:quick, medium:quick, high:advisory, max:frontier, ultra_max:frontier }

# VISIBLE levels — only where the model is distinct for THIS agent (no-op neighbours dropped):
cfg.visible_thinking_levels()  ==  ["low", "max"]        # DeepSeek step + Opus step

# Brain emits a TYPED intent with its plane — it never executes:
RegistrarToolIntent(tool="apply_record_name", policy="auto", plane="server", args={…})
# the SERVER plane (broker, under RLS) runs it; Blake holds no DB/S3/SQS/audit credentials (ADR-110 §6).
Why the legacy alias is additive, never a rename-in-place: a five-place closed-enum migration that hard-renames extra_high → max would reject every saved session and in-flight invoke the moment one repo upgrades first. Instead extra_high stays accepted via _missing_ (it normalizes to max on the way in and is never re-emitted), so old payloads parse unchanged. Removal is gated on client rollout — telemetry showing no legacy traffic — not a release number.
Why the map is total but the pill is short: totality and visibility are two different guarantees. The map is TOTAL so every level the broker can stamp resolves to a real model — never a silent downgrade to the default. But Atlas runs one open model (DeepSeek) for low·medium·high and the frontier (Opus 4.8) for max·ultra_max, so a five-step pill would imply five quality steps that don't exist. visible_thinking_levels collapses the no-op neighbours, so the surface shows only the steps that are real for that agent (RFC-004 render rule; AGENT4 §2). Add a distinct mid model in model.json and the matching level surfaces automatically — no code change.
Why the brain emits an intent, not an effect: the agent has no execution credentials — no DB DSN, queue URL, or bucket name (ADR-110 §6, enforced by the brain-egress grep gate). It emits a typed tool intent stamped plane:server; the broker re-resolves authz from the session and executes under RLS + per-tool policy + audit (ADR-128). The plane field is what lets the broker route execution and makes a future client-plane (browser) tool additive, not a contract rewrite (Story-1647 / RFC-002 §C).
Why Opus 4.8 here is not a Bedrock breach: the no-Bedrock-anywhere directive (2026-06-15, ADR-120) forbids the Bedrock provider and its region-prefixed slugs (global.anthropic.*), not the Anthropic model. anthropic/claude-opus-4-8 is reached through the one sanctioned egress — OpenRouter, ZDR-enforced — exactly the frontier RFC-004 §A names for Atlas. The bedrock-marker test stays green.

How to verify

# Regenerate the contract schema from source (custody gate) — already committed
python -m agent_contracts.schema                             # canonical 5-level enum

# repo-governance lane (contract custody + alias + ladder)
ruff check agent_contracts/ tests/ scripts/
python -m pytest tests/ -q                                   # 103 passed

# each agent's own unit suite (the adopters)
cd agents/atlas     && PYTHONPATH=. python -m pytest tests -q  # 229 passed
cd agents/registrar && PYTHONPATH=. python -m pytest tests -q  # 206 passed

# lint + brain-purity egress gate stay clean (no DB/ORM/boto leak, no credentials)
ruff check agents/
python scripts/check_brain_egress.py                         # clean

Scope & boundaries honoured