Slice-2 (sessions/turn) done end-to-end through the House Code Discipline; both heid gates triaged+fixed. Captures the KEY ADAPTER FACTS foot-guns for slices 3-7 (open-world dicts, body-derived turn_id, ConnectFailed(0) transport normalization, consumer_key bound-only, nested-detail error_code parsing) + the two-lens gate value proof. Slice-3 (persona/authored-history) next.
58 lines
4.7 KiB
Markdown
58 lines
4.7 KiB
Markdown
`[2026-07-19]` **worldtree-sdk cutover — SLICE-1 + SLICE-2 COMPLETE + PUSHED (origin `aba1730`, v0.21.10).**
|
||
|
||
The consumer client layer's biggest, riskiest slice (sessions/turn) is fully migrated onto
|
||
`worldtree-sdk (Python) 1.0.0` behind the `ratatoskr.wt` adapter, run end-to-end through the House Code
|
||
Discipline. Pushed 2026-07-19 (12-commit arc `b1fbadd`→`aba1730`, tags v0.21.3–.10). Suite **497 green**.
|
||
|
||
## The arc (all on origin/main)
|
||
|
||
| Part | Commit | What |
|
||
|---|---|---|
|
||
| Slice-1 foundation | `12cd864` (v0.21.3) | `build_client` + `translate_error` DEFAULT (ApiError→SessionApiFailed) + passthrough; INV-CUT-1 (injected transport, `_owns_client=False`) test-proven |
|
||
| Slice-2 adapter (read/create) | `bb158ae` (v0.21.4) | create/list/messages/tools over `client.sessions.*`, per-route error mapping |
|
||
| Slice-2 adapter (stream/cancel) | `b907a7b` (v0.21.5) | resilient `stream_turn` + `cancel_turn`; SDK stream errors re-wrapped → ratatoskr caller-semantic exceptions (DEC-2) |
|
||
| Slice-2 CLI rewire | `e3a10ad` (v0.21.6) | `_amain`/`_run_turn`/render onto SDK `TurnEvent`s + open dicts |
|
||
| Slice-2 web rewire | `5c595b8` (v0.21.7) | Starlette endpoints + SSE→JSON serialization; browser contract preserved |
|
||
| Slice-2 deletion | `59602fe` (v0.21.8) | sse_client 714→224, sessions 677→608; orphaned turn-stream family + Event model removed; **DEC-4 live-smoke PASSED first** |
|
||
| heid-code-review fixup | `74d41eb` (v0.21.9) | INV-CUT-2 completeness (cancel/stream ApiError default) + contract error-map amendments |
|
||
| heid-bug-hunt fixup | `aba1730` (v0.21.10) | 4 confirmed bugs + open-world render hardening |
|
||
|
||
## KEY ADAPTER FACTS (foot-guns for slices 3-7)
|
||
|
||
- **The SDK returns open-world dicts** (`Mapping`, NOT typed objects) for session reads → presenters read
|
||
mappings (`info["session_id"]`), never attributes. Ratatoskr's typed `SessionInfo`/`SessionPage` retired.
|
||
- **SDK `TurnEvent` shape:** `sse_id: str` (the composite `"{turn}:{seq}"`) + a **body-derived `turn_id`
|
||
that is ABSENT (None) on text/thinking frames.** The mid-stream cancel target must parse the turn from
|
||
`sse_id`, NOT read `event.turn_id`. (This was a live bug — sigint-cancel saw "no event".)
|
||
- **The SDK normalizes transport failures to `ConnectFailed(status=0)`** (not raw httpx errors) → presenters
|
||
catch `wtsdk.ConnectFailed` for network paths; a stream `ConnectFailed` maps → `SseConnectFailed`.
|
||
- **The adapter re-wraps SDK stream errors → ratatoskr's caller-semantic exceptions** (DEC-2 keeps ratatoskr's
|
||
typed exceptions; SessionRetired→SessionApiFailed, ConnectionDropped→SseConnectionDropped, Malformed*/
|
||
TurnIdFlip→same-named, ConnectFailed/terminal ResumeError→SseConnectFailed).
|
||
- **`consumer_key` is BOUND-create-only** — the adapter nulls it when `bifrost is None`, else the SDK's
|
||
credential precedence auths as the consumer instead of the default bearer.
|
||
- **The SDK's error-envelope parser PREFERS the nested `detail`** dict when present, so a top-level
|
||
`error_code` doesn't surface. That's why create's bound-502 is NOT gated on error_code (unlike list's
|
||
422+cursor_invalid, whose flat body surfaces the code) — INV-002 also makes the handshake the sole
|
||
bound-502 cause. This is a genuine cross-frontier triage win: 2/3 heid arms flagged the missing gate; it
|
||
was correctly REJECTED as category-5 wrong-grounding (the SDK parser wasn't in the arms' file set).
|
||
|
||
## The two heid gates (the value proof)
|
||
|
||
- **heid-code-review** (Gróa+Hulda substantive, Regin zero=weak): adopted the cancel/stream ApiError-default
|
||
completeness + error-map table amendments; correctly rejected the bound-502-gate finding (above).
|
||
- **heid-bug-hunt** (Gróa 8 / Hulda 6 / Regin 6; Heid source-checked, refuted 2 Regin FPs): caught **4 real
|
||
confirmed bugs the conformance lens structurally could not see** — SessionRetired(410) uncaught by both
|
||
presenters (crash/dropped-stream), cli consumer_key forwarded on unbound create (auth divergence), sse_id
|
||
None-crash, cancel never-raise gap — plus open-world render hardening. Rejected 4 as verified FPs (incl.
|
||
Hulda's "deleted funcs break callers" — grep-verified zero callers pre-deletion). Both surfaces re-smoked
|
||
live after fixup: create+stream+cancel round-trip clean on :8081 (b128).
|
||
|
||
## What's still hand-rolled (later slices)
|
||
|
||
`create_session`/`get_session_messages` (the `--seed-first-message` probe uses them — retire in slice-3);
|
||
`set_persona_state`/`write_authored_history`/`first_message` (slice-3); agents/tier3 incl. `model`→`role`
|
||
(slice-4, deploy live b128); characters/me/capabilities/models (slice-5); `stream_admin_events`/
|
||
`get_session_bifrost` (slice-6). Slice-7 teardown: retire contracts #2/#15, drop `httpx-sse`, minor bump
|
||
(DEC-6, operator approval). Full design → auto-memory `project_worldtree_sdk_cutover`.
|