Files
ratatoskr/persistent-memory.d/2026-07-19-worldtree-sdk-cutover-slice-1-2-complete.md
vh 0b23334c68 memory: /snapshot — worldtree-sdk cutover slice-1+2 complete + pushed (aba1730)
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.
2026-07-19 08:23:23 -07:00

58 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
`[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`.