From 4f92a21cb9ff9a5b874066019e4c03a666e694b4 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Sun, 19 Jul 2026 09:20:18 -0700 Subject: [PATCH] =?UTF-8?q?memory:=20/snapshot=20=E2=80=94=20worldtree-sdk?= =?UTF-8?q?=20cutover=20slice-3=20complete=20(ca9a339+fc256bb)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- archival-memory.md | 8 +++ ...-worldtree-sdk-cutover-slice-3-complete.md | 66 +++++++++++++++++++ persistent-memory.md | 60 ++++++++--------- 3 files changed, 103 insertions(+), 31 deletions(-) create mode 100644 persistent-memory.d/2026-07-19-worldtree-sdk-cutover-slice-3-complete.md diff --git a/archival-memory.md b/archival-memory.md index 937e659..9d636ec 100644 --- a/archival-memory.md +++ b/archival-memory.md @@ -142,6 +142,14 @@ _Archived 2026-07-18._ _Archived 2026-07-18._ +`[2026-06-17]` **#296 triage sent to worldtree-dev** (`01KVBBH0…`): extraction SUBJECT-INVERSION (promotes assistant prose, drops the user's fact) + META-DESCRIPTION-not-content; verbose-persona aggravator. WAD-vs-bug resolved to BUG (extraction quality), not idle-gating. + +_Archived 2026-07-19._ + +`[2026-06-18]` **Tier-3 memory PROVEN end-to-end live** — `ratatoskr:terse-probe` recalled a seeded user fact in a COLD history-free session (scope_any → 1 hit @ cosine 0.6994). Closes the opening "how far from Tier-3 memory" question for normal agents. + +_Archived 2026-07-19._ + ## Tried and abandoned (archived) The 2026-05-20 → 2026-05-28 cluster: original-build-era foot-guns. Archived 2026-06-18. diff --git a/persistent-memory.d/2026-07-19-worldtree-sdk-cutover-slice-3-complete.md b/persistent-memory.d/2026-07-19-worldtree-sdk-cutover-slice-3-complete.md new file mode 100644 index 0000000..8f59577 --- /dev/null +++ b/persistent-memory.d/2026-07-19-worldtree-sdk-cutover-slice-3-complete.md @@ -0,0 +1,66 @@ +# 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. diff --git a/persistent-memory.md b/persistent-memory.md index 13e1d02..77652cd 100644 --- a/persistent-memory.md +++ b/persistent-memory.md @@ -46,30 +46,28 @@ upstream API key stays server-side (INV-003). _As of 2026-07-19:_ -**🔨 ACTIVE MIGRATION — worldtree-sdk cutover (issue #20): SLICE-1 + SLICE-2 COMPLETE + PUSHED, slice-3 next.** +**🔨 ACTIVE MIGRATION — worldtree-sdk cutover (issue #20): SLICE-1 + SLICE-2 + SLICE-3 COMPLETE, slice-4 next.** Operator ruled ADOPT (2026-07-18): ratatoskr cuts its CONSUMER client layer over to **worldtree-sdk (Python) 1.0.0**, retiring the hand-rolled httpx wrappers behind a thin `ratatoskr.wt` adapter. Design locked (6 DECs, -vor-cross'd, heid-panel-reviewed); contract `docs/contracts/worldtree_sdk_cutover.contract.md`. **SLICE-1 -(adapter foundation) ✅ + SLICE-2 (sessions/turn) ✅ DONE + PUSHED** — origin at `aba1730` (12-commit arc -`b1fbadd`→`aba1730`, tags v0.21.3–.10, pushed 2026-07-19): adapter (`b907a7b`, all 6 route families -create/list/messages/tools/stream/cancel + the § Error-map mapping) → CLI rewire (`e3a10ad`) → web rewire -(`5c595b8`) → orphan deletion (`59602fe`, sse_client 714→224 + sessions 677→608; DEC-4 LIVE-SMOKE PASSED on -:8081 create+stream+cancel FIRST) → heid-code-review fixup (`74d41eb`) → heid-bug-hunt fixup (`aba1730`). -Suite **497 green**. **KEY ADAPTER FACTS (foot-guns for slices 3-7):** the SDK returns **open-world dicts** -(not typed objects) for session reads → presenters read mappings, `info["session_id"]`; SDK events -(`TurnEvent`) carry `sse_id: str` + a **body-derived `turn_id` that's ABSENT on text/thinking frames** → parse -the cancel target's turn from the composite `sse_id`, NOT `event.turn_id`; the SDK **normalizes transport -failures to `ConnectFailed(status=0)`** (not raw httpx) → presenters catch it; the adapter re-wraps SDK stream -errors → ratatoskr caller-semantic exceptions (DEC-2, keep ratatoskr's typed exceptions); `consumer_key` is -BOUND-create-only (adapter nulls it when unbound, else the SDK auths as the consumer); the SDK's error-envelope -parser **prefers the nested `detail`** so a top-level `error_code` doesn't surface (why create's bound-502 is -NOT gated on error_code, unlike list's 422). **NEXT = slice-3** (persona `set_persona_state` + authored-history -`write_history` + first_message presets — retires the still-hand-rolled `create_session`/`get_session_messages` -that the `--seed-first-message` probe uses); then slice-4 (agents/tier3, FOLDS the `model`→`role` cutover), -slice-5 (characters/me/caps), slice-6 (admin — `stream_admin_events`+`get_session_bifrost` still hand-rolled), -slice-7 (teardown: retire contracts #2/#15, drop `httpx-sse`, minor bump per DEC-6 w/ operator approval). -Scope: consumer layer ONLY; Bifrost provider planes untouched. Full design → auto-memory -`project_worldtree_sdk_cutover`. +vor-cross'd, heid-panel-reviewed); contract `docs/contracts/worldtree_sdk_cutover.contract.md`. **SLICE-1+2 +(foundation + sessions/turn) ✅ PUSHED** origin `aba1730` (arc `b1fbadd`→`aba1730`, tags v0.21.3–.10). **SLICE-3 +(persona + authored-history + first-message) ✅ DONE** — `ca9a339` (feat) + `fc256bb` (heid-bug-hunt fixups), +tags v0.21.11–.12; full House Code Discipline (TDD → heid-code-review CLEAN/zero-drift → heid-bug-hunt). +Suite **469 green**. Slice-3 migrated `set_persona_state` (SDK `PadState`), `write_authored_history` +(`write_history`, 404→AuthoredHistoryUnavailable hide-existence), `get_session_messages`, + routed +`first_message` seed through the adapter; DELETED the last hand-rolled `sessions.py` paths (`create_session`+ +`SessionInfo`, `set_persona_state`, `write_authored_history`, `get_session_messages`, `_bifrost_error_from`). +LIVE-SMOKE on :8081 (b128): seed→201(seq0)→read-back; persona→204; create-path preset seed. **KEY ADAPTER FACTS +(foot-guns for slices 4-7):** SDK returns **open-world dicts** for reads → `info["session_id"]`; `TurnEvent` +carries `sse_id` + a **`turn_id` ABSENT on text/thinking frames** → parse cancel-target from `sse_id`; the SDK +**normalizes ANY transport failure to `ConnectFailed(status=0)`** (`request.py:196`, NOT raw httpx) — every +caller through the adapter must `except ConnectFailed` (the slice-3 bug-hunt caught both probes missing it); +`consumer_key` is BOUND-create-only; the SDK's envelope parser **prefers nested `detail`** (why bound-502 isn't +error_code-gated). **NEXT = slice-4** (agents/tier3 — list/get/define/patch/delete/persona_state, FOLDS the +`model`→`role` cutover); then slice-5 (characters/me/caps), slice-6 (admin — `stream_admin_events` + +`get_session_bifrost` still hand-rolled), slice-7 (teardown: retire contracts #2/#15, drop `httpx-sse`, minor +bump per DEC-6 w/ operator approval). Scope: consumer layer ONLY; Bifrost provider planes untouched. Full +design → auto-memory `project_worldtree_sdk_cutover`. **⏸️ DEFERRED — tier3 agents `model`→`role` (scope B), folds into cutover slice-4.** WT renamed the agents-RESPONSE selector `model`→`role` (spec 1.2). **DEPLOY NOW LIVE** on :8080/:8081 (v1.0.0b128, @@ -119,12 +117,13 @@ Full record → `persistent-memory.d/2026-07-18-368-silo-test-passed.md`. Siblin (2) R39 Phase-2 **matched-quartets rebuild** (confirmatory, "whenever"); (3) bifrost **snapshot-cursor adoption** (ruled normative, not blocking → `persistent-memory.d/2026-07-16-bifrost-cursor-conformance.md`). -**Substrate / environment:** branch `main` at **v0.21.10**, **fully PUSHED to origin at `aba1730`** (slice-2 -cutover arc `b1fbadd`→`aba1730` + tags v0.21.3–.10 pushed 2026-07-19). origin -`git@gitea.phasefinal.com:vh/ratatoskr.git`. **NEW core dep: `worldtree-sdk==1.0.0`** (gitea PyPI, -`[tool.uv.sources]`; `httpx-sse` retires at slice-7). bifrost **`==1.1.4`** / wire v0.7; WT openapi vendored -2.3.0, **conversation-api-spec re-synced to v1.1** (`b4a278c`); **suite 497 green** (was 534 pre-cutover; net -delta = adapter/rewire tests added, ~80 deleted hand-rolled turn-stream tests). Personal WT on **b128** +**Substrate / environment:** branch `main` at **v0.21.12**, **PUSHED to origin** (slice-3 arc `ca9a339`+ +`fc256bb` + this snapshot, tags v0.21.11–.12, pushed 2026-07-19; slice-1+2 arc `b1fbadd`→`aba1730` + +v0.21.3–.10 earlier). origin `git@gitea.phasefinal.com:vh/ratatoskr.git`. **NEW core dep: +`worldtree-sdk==1.0.0`** (gitea PyPI, `[tool.uv.sources]`; `httpx-sse` retires at slice-7). bifrost +**`==1.1.4`** / wire v0.7; WT openapi vendored 2.3.0, **conversation-api-spec re-synced to v1.1** (`b4a278c`); +**suite 469 green** (was 497 post-slice-2; net delta = slice-3 adapter/probe tests added, ~50 deleted +hand-rolled sessions tests). Personal WT on **b128** (`http://10.250.50.152:8081`; #368 silo + #364 promotion-hygiene live both instances). The combined **:8392** provider (memory+affect) + **:8765** web are THE surfaces, dev-box BACKGROUND SHELLS — restart via `scratchpad/relaunch_by_pid.py ` (pid via `ss -ltnp | grep `). `env.sh` sets @@ -147,8 +146,6 @@ relational-dynamics verify (bind `--bifrost-url :8392`); WT #356 resume-durabili Chronological log of decisions with `[YYYY-MM-DD]` prefix. One line per decision. Captures rationale that won't be obvious from code alone. -- `[2026-06-17]` **#296 triage sent to worldtree-dev** (`01KVBBH0…`): extraction SUBJECT-INVERSION (promotes assistant prose, drops the user's fact) + META-DESCRIPTION-not-content; verbose-persona aggravator. WAD-vs-bug resolved to BUG (extraction quality), not idle-gating. -- `[2026-06-18]` **Tier-3 memory PROVEN end-to-end live** — `ratatoskr:terse-probe` recalled a seeded user fact in a COLD history-free session (scope_any → 1 hit @ cosine 0.6994). Closes the opening "how far from Tier-3 memory" question for normal agents. - `[2026-06-19]` **#18 D2 SHIPPED (`v0.17.14`, `39eebd1`) and the full #17+#18 arc PUSHED to origin** → `persistent-memory.d/2026-06-19-18-d2-shipped-v0-17-14-39eebd1-and-the-full-1.md` - `[2026-06-19]` **bifrost repinned 0.8.0→0.10.0; `affect.fetch` became MANDATORY (strong-or-absent)** → `persistent-memory.d/2026-06-19-bifrost-repinned-0-8-0-0-10-0-affect-fetch-be.md` @@ -275,8 +272,9 @@ decision. Captures rationale that won't be obvious from code alone. - `[2026-07-18]` **Rata = THE reference consumer of the worldtree-sdk Python spine** — parity pass (12 grounded findings) shaped its contract BEFORE build (open-world reads, caller-injected transport, per-wire role/model — adopted); coverage-map re-anchored to the SDK's 41-op ratified surface (`b1fbadd`); 4 ergonomics items parked post-v1 with wtsdk-dev. - `[2026-07-18]` **worldtree-sdk cutover DECIDED — adopt the Python SDK for the consumer client layer** (operator, overriding "stay hand-rolled"). Issue #20; contract `docs/contracts/worldtree_sdk_cutover.contract.md` (`e45640c`, vor-cross'd + heid-reviewed); auto-memory `project_worldtree_sdk_cutover`. Consumer layer only, Bifrost provider untouched; slice-1 foundation next. See in-flight. - `[2026-07-19]` **worldtree-sdk cutover SLICE-1 + SLICE-2 COMPLETE + PUSHED (origin `aba1730`, v0.21.10, 497 green).** The biggest, riskiest cutover slice done end-to-end through the full House Code Discipline (adapter→cli→web→delete→live-smoke→both heid gates); the bug-hunt caught 4 real confirmed bugs the conformance lens couldn't, and a convergent code-review finding was correctly REJECTED as category-5 (SDK envelope-parser behavior). Slice-3 next. → `persistent-memory.d/2026-07-19-worldtree-sdk-cutover-slice-1-2-complete.md` +- `[2026-07-19]` **worldtree-sdk cutover SLICE-3 COMPLETE + pushed (`ca9a339`+`fc256bb`, v0.21.11–.12, 469 green).** Persona/authored-history/first-message onto the wt adapter; last hand-rolled `sessions.py` paths deleted; both heid gates cleared — code-review ZERO drift, bug-hunt caught + fixed a real regression I shipped (ConnectFailed escaping both rewired probes → uncaught crash; the SDK normalizes ALL transport failures to `ConnectFailed`, not raw httpx) plus a finite-PAD chokepoint gap. Slice-4 (agents/tier3 + model→role) next. → `persistent-memory.d/2026-07-19-worldtree-sdk-cutover-slice-3-complete.md` -_65 older entries (2026-05-* debug-TUI/web era + the 2026-06-14 → 06-18 Bifrost-provider build / #17+#18 / #295-296 era) archived to archival-memory.md._ +_67 older entries (2026-05-* debug-TUI/web era + the 2026-06-14 → 06-18 Bifrost-provider build / #17+#18 / #295-296 era) archived to archival-memory.md._ _For per-issue TDD implementation notes, Volva findings, and contract amendments, see the git log — every per-issue commit carries a structured message capturing the trail._