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

4.7 KiB
Raw Permalink Blame History

[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 b1fbaddaba1730, 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 TurnEvents + 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. modelrole (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.