Atlas adopts the runtime rails — thin

Atlas accepts the three runtime-control axes off agent_invoke.v1, declares its mode matrix, and maps the thinking_level onto its own existing model.json tiers. Wiring only — zero new architecture.
Story-1564 · EPIC-1559 · adopter (updates Atlas) · branch issue-1564-atlas-adopt-rails · 2026-06-21

pramaan-docs ADR-129 ratified three orthogonal axes — run_mode, thinking_level, authority_mode — and named Atlas the thin adopter (§D12): it reuses its existing model tiers, no rebuild. The contracts landed in Story-1561; the broker-resident resolvers, floors, and effective_* computation landed in Story-1562. This Story does exactly one thing: make Atlas consume that posture. Atlas owns no resolver and no floor — it reads what the broker resolved, selects which of its own DeepSeek tiers serves the level, and stays proposal-only (ADR-070; ADR-128 does not relax Atlas).

What to review

AreaWhereWhat it does
Axis readeragents/atlas/runtime_axes.pyClosed StrEnums mirroring the contract VERBATIM + parse_posture() — reads the broker-resolved axes off the envelope, defaults authority_mode to review_exceptions, fails closed on an illegal value. No resolver, no floor.
Mode matrixagents/atlas/atlas.yaml mode_matrix:Atlas's self-declared envelope: supported_modes:[interactive], default_mode:interactive, default_thinking.interactive:medium, allowed capabilities, pause_stop:stop_cancel_turn. The broker copy is authoritative; a parity test keeps them in lock-step.
Thinking → tier mapagents/atlas/model.json thinking_tiersMaps low/medium→quick, high/extra_high→advisory onto Atlas's existing tiers — no new tier system. The seam for a stronger advisory model later.
Per-invoke resolutionagents/atlas/config.py AtlasConfig.for_invoke()Reads the posture, points model_id at the level's tier, carries run_mode/thinking_level/authority_mode. ATLAS_MODEL_ID override still wins.
Wire-inagents/atlas/runtime.pyhandle_request + stream_invoke swap AtlasConfig.load() → AtlasConfig.for_invoke(request). One-line seam; everything downstream (spans, cost, provenance) flows unchanged.
Testsagents/atlas/tests/test_atlas_runtime_axes.py, test_atlas_mode_matrix.pyAxis parity, default resolution, tier selection, env-override precedence, fail-closed on illegal value, matrix lock-step.

The thin seam

# Broker (Story-1562) resolves + floors the level, then invokes Atlas:
agent_invoke.v1 { …, run_mode:"interactive", thinking_level:"high", authority_mode:"review_exceptions" }

# Atlas (this Story) READS it — and only SELECTS its own tier. No resolver, no floor.
posture = parse_posture(request, default_run_mode=matrix.default, default_thinking=matrix.per_mode)
model_id = base.model_for_thinking(posture.thinking_level)   # high → advisory tier → DeepSeek
# authority_mode is carried, NEVER branched on — Atlas auto-applies nothing (proposal-only).
Why Atlas owns no resolver: ADR-129 §D2/§D3 put the level→model map, the safety floors, and effective_authority in one place — the broker rails (Story-1562) — so a cost-cutting matter default can't silently de-floor a privileged step for any agent. If Atlas re-derived the level it would be a second, drifting copy of that safety logic. So Atlas only maps the already-resolved level onto a tier it already had. That is the whole "thin" of thin adoption.
Why the default invoke is byte-identical: an omitted thinking_level falls back to the matrix default medium, which maps to the quick tier, which is deepseek/deepseek-v3.2 — exactly what Atlas ran before Story-1564. A legacy invoke that sends no axes at all parses unchanged and runs the same model. Behaviour unchanged at default settings, by test.

How to verify

# Atlas's own unit suite (the adopter)
cd agents/atlas && uv run --group dev python -m pytest -q        # 223 passed

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

# repo-governance lane unchanged
ruff check agent_contracts/ tests/ scripts/
python -m pytest tests/ -q -m unit                              # 101 passed

Scope & boundaries honoured