# worldtree-sdk cutover — SLICE-3 complete (2026-07-19) Slice-3 of the #20 consumer-layer cutover: **persona + authored-history + first-message** migrated onto the `ratatoskr.wt` adapter, and the last hand-rolled `sessions.py` paths retired. Two commits: `ca9a339` (feat) + `fc256bb` (heid-bug-hunt fixups), tags v0.21.11 / v0.21.12. Suite **469 green**. ## What moved / what was deleted - **`wt.set_persona_state`** — passes 3 PAD axes; SDK owns the `{"pad": {…}}` wire (#317) via `PadState`. No route-specific error row → `SessionApiFailed` default. Finiteness enforced at the adapter precondition (chokepoint) AND the CLI. - **`wt.write_authored_history`** — SDK `write_history`; v1 fixes `author="assistant"` (dropped the unused `author`/`effects`/`claimed_original_at` params — no caller used them, and a 3-key literal type-checks against the SDK's private `AuthoredHistoryInput` without importing a non-public symbol). 404 → `AuthoredHistoryUnavailable` (hide-existence; the ROUTE is the discriminator, never the body); else the default. - **`first_message.seed_preset_first_message`** — now takes a `WorldtreeClient`, routes through `wt.write_authored_history`; best-effort invariants (INV-001..004) unchanged. Tests rewritten to drive a fake `WorldtreeClient` (the wire is the SDK's to prove via its parity corpus, not first_message's). - **CLI `--set-persona-pad` / `--seed-first-message`** + the `_amain` and web create-path first-message seeds rewired onto the adapter. - **DELETED from `sessions.py`**: `create_session` + `SessionInfo`, `set_persona_state`, `write_authored_history`, `get_session_messages`, `_bifrost_error_from`. (The exceptions + `BifrostBinding` + `AgentInfo` + slice-4/5/6 functions stay.) ## Live-smoke (INV-CUT-5, personal :8081 b128) `--seed-first-message` → 201 (seq=0, phase=seeded) → read-back verbatim; `--set-persona-pad 0.4,0.1,-0.2` → 204; `--new` create-path preset seed observed routing through the adapter. All three route families proven end-to-end. ## Both heid gates cleared - **heid-code-review (panel, cutover contract):** ZERO code-vs-contract drift, all three arms. Regin's 3 secondary items all self-graded `accept` (non-slice-3 routes / web-not-unit-tested / slice-2 stream test) — correctly declined. - **heid-bug-hunt (panel):** earned its keep — caught **a real regression I shipped in `ca9a339`**: when the two CLI probes moved off raw httpx onto the adapter, transport failures changed class — the SDK normalizes ANY pre-response transport failure to `worldtree_sdk.ConnectFailed` (`request.py:196`), a `WorldtreeError` (not `ApiError`), so it escaped the adapter unmapped AND the probes' httpx-only `except` tuples → uncaught traceback instead of `[network_error]` exit 21. `_amain` (slice-2) already handled it; the probes lagged. **Fix:** add `ConnectFailed` to both probe tuples (live-verified at a refused host → exit 21). Second finding (3/3): finite-PAD enforced only at the CLI, not the adapter chokepoint → **fix:** adapter precondition assert. Declined (correctly): deleted `sessions.py` exports (intended no-shim cutover, zero un-migrated importers), `session["session_id"]` index (accept-known-risk, matches `--new`), Regin's "web hangs forever" (refuted by Heid from source — the seed is `wait_for`-bounded). ## Foot-gun banked **The SDK wraps ALL transport failures into `ConnectFailed(status=0)`** (not raw httpx). Every ratatoskr caller that goes through the adapter must `except ConnectFailed` on its network path — the httpx-only catches are now dead. This bit the slice-3 probes; watch for it in slice-4+ call-site rewires. ## Next Slice-4 (agents/Tier-3 — list/get/define/patch/delete/persona_state) which FOLDS the pending `model`→`role` cutover ([[project-tier3-agents-model-to-role-pending]]). See [[2026-07-19-worldtree-sdk-cutover-slice-1-2-complete]] for the slice-1+2 arc.