# 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.
