4.8 KiB
[2026-07-19] worldtree-sdk cutover SLICE-4 COMPLETE + committed (c62b4ee+aed9429+477d98f, v0.21.13–.15, 475 green).
Agents/Tier-3 family onto the ratatoskr.wt adapter + the model→role fold (scope B),
full House Code Discipline end-to-end (contract error-map → TDD → rewire → delete → live
smoke → coverage re-anchor → both heid gates → fixups).
What moved onto the SDK (client.agents.*, open-world dicts, errors mapped by
route+(status,error_code) per INV-CUT-2): list_agents (agents.list),
get_persona_state (agents.persona_state; 404 persona_not_configured /
404 agent_not_available / 403 auth_scope_denied dual-key), define_agent
(agents.define; 429→Tier3QuotaExceeded(retry_after=0) status-only, 403
tier3_user_id_unsupported, 422 layer_deferred), patch_agent (agents.patch; bare-404→
Tier3AgentNotFound, 422 field_not_mutable), delete_agent (agents.delete; bare-404).
Rewired the python -m ratatoskr.tier3 CLI + the web _agents_endpoint /
_persona_state_endpoint. DELETED the hand-rolled sessions.list_agents /
get_persona_state / AgentInfo and tier3.define/patch/delete_agent /
Tier3AgentInfo / parse+extract helpers.
model→role fold: define/patch response echoes role (spec 1.2 / b128), read off the
open-world dict; LocalAgentEntry.model→.role, local-index _SCHEMA_VERSION 1→2 (old
index discarded, no-compat). project_tier3_agents_model_to_role_pending is RESOLVED by
this — the deferred scope-B work landed here (doing it standalone would have been throwaway).
KEY SLICE-4 FOOT-GUNS (for slices 5-7 + any tier3 work):
python -mdouble-module exception identity. Running tier3 as__main__whilewtimportsratatoskr.tier3bound TWO copies of eachTier3*class → a raisedTier3AgentNotFoundescaped the CLI'sexceptas an uncaught traceback (exit 1, not the mapped exit 20). Unit tests callmain()in-process (module isratatoskr.tier3, not__main__) so they NEVER hit the split — the LIVE SMOKE caught it. Fix: theTier3*exceptions live insessions.py(never run as__main__) → single class identity, and it removed thewt→tier3import edge. Rule: caller-semantic exceptions the adapter raises + a-mCLI catches must NOT live in the-mmodule.- Open-world presenters must degrade, never crash. The heid-bug-hunt panel (5/5/5, two
3/3 crash sites) caught the CLI (
_run_define/_run_patch) and web (_agents_endpoint) HARD-INDEXING the open-world dicts (info["agent_id"],{a["agent_id"] for a in upstream}) → KeyError/TypeError on a partial/drifted 2xx response (incl.system_prompt: null→None.splitlines()AttributeError). The wt tests + live smoke used FULL server dicts, so it never surfaced. Fix:_str_field(absent/null/non-str → default) in the CLI; well-formed-mapping filter in the web endpoint; a no-agent_id 2xx → controlled exit 20. The invariant "open-world reads degrade, never crash the presenter" must hold at EVERY presenter, not just the adapter.
Both heid gates cleared:
- code-review (panel, zero adapter/error-map/model→role drift): 3 fixups (v0.21.14,
aed9429) — persona endpoint now catcheswt.SessionApiFailed(parity with 3 sibling endpoints; a latent PRE-cutover gap, NOT a slice-4 regression); dual-key NEGATIVE tests for define/patch + flat-fieldtest; contract documents the":" in agent_idPRE. - bug-hunt (panel 5/5/5, no false positives): 3 fixups (v0.21.15,
477d98f) — the two open-world presenter crash sites above +_error_field_from_bodytype-checksfieldis str. HELD (contract-intended, Heid-confirmed): the 429→quota / bare-404→not-found status-only maps (the arms flagged them spec-free; the § Error map specifies them; the SDK's ApiError floor drops Retry-After so retry_after=0 is canonical). Dual-keying define's 429 for full row consistency is an available tightening (contract amendment), surfaced not applied.
LIVE-SMOKE on personal :8081 (b128): valid agent roles are thoughtful-character /
character / assistant (NOT the /models/available-for-characters char-rp — that's a
character-model, a different vocab; define 422s on it). define→patch→list(6 agents:
forseti/lofn/mask/mimir/vili/…)→persona_state(→PersonaNotConfigured mapped)→delete→index
empty; non-existent-id patch via -m → [agent_not_found] exit 20 (double-module fix
proven). Throwaway ratatoskr:slice4-smoke deleted, server left clean.
NEXT = slice-5 (characters + me/capabilities/models — the remaining consumer reads);
then slice-6 (admin: stream_admin_events + get_session_bifrost, admin_auth), slice-7
(teardown: delete residual hand-rolled, drop httpx-sse, retire contracts #2/#15, MINOR
bump per DEC-6 w/ operator approval). Consumer layer ONLY; Bifrost provider planes untouched.