From 76662037225b90569e99986e714edd40872eb4a0 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Wed, 17 Jun 2026 21:27:17 -0700 Subject: [PATCH] =?UTF-8?q?memory:=20snapshot=20=E2=80=94=20Tier-3=20memor?= =?UTF-8?q?y=20PROVEN=20end-to-end=20live=20(terse-probe=20cold=20recall?= =?UTF-8?q?=20@0.6994,=20fresh=20history-free=20session);=20#296=20arc=20c?= =?UTF-8?q?losed:=20Stage=201=20(v0.35.19)=20recallability=20gate=20valida?= =?UTF-8?q?ted=20live=20+=20bisect=20localized=20residual=20to=20verbose-p?= =?UTF-8?q?ersona=20volume,=20Stage=202=20(v0.36.0)=20MERGED=20at=20worldt?= =?UTF-8?q?ree-codex=20(user-only=20per-turn=20extraction),=20live-validat?= =?UTF-8?q?ed=20eval=20fixture=20pair=20->=20#305;=20root-cause=20chain=20?= =?UTF-8?q?v0.35.16=20emit-2-meta=20->=20v0.35.19=20emit-then-reject=20->?= =?UTF-8?q?=20v0.36.0=20fix;=20foot-gun:=20:8391=20store-wipe=20!=3D=20WT?= =?UTF-8?q?=20promotion-dedup=20reset=20(clean=20promotion=20smoke=20needs?= =?UTF-8?q?=20a=20fresh=20agent+end=5Fuser)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- persistent-memory.md | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/persistent-memory.md b/persistent-memory.md index c77f299..4728df8 100644 --- a/persistent-memory.md +++ b/persistent-memory.md @@ -41,22 +41,30 @@ model output is untrusted); upstream API key stays server-side (INV-003). ## Current state / in-flight -_As of 2026-06-17:_ +_As of 2026-06-18:_ -**LATEST (2026-06-17 PM) — END-TO-END COLD-RECALL PROOF RAN; OUR STACK PROVEN, #296 IS -THE ISOLATED GAP.** Drove the full bound proof against personal WT v0.35.16 with the -restored `ratatoskr:sindra`. **Every leg of OUR stack is proven:** (1) #297/#298 union -recall is LIVE — WT dispatched `scope_any=[{end_user:sindra-proof},{agent_self:ratatoskr:sindra}]` -into our v0.17.6 store; (2) write path — promotion fired ~4min post-seed, `upsert_many` -dispatched, chunks persisted; (3) read path — a COLD (history-free) session's recall -returned the chunks via `scope_any` (2 hits). **The one failure is UPSTREAM #296 extraction -quality:** promotion stored third-person summaries of sindra's PERSONA output ("Assistant's -flirtatious response…") and DROPPED the user's stated fact ("dark chocolate with sea salt") -— so cold recall returned useless chunks and sindra (deflecting persona) didn't recall it. -Triage sent to worldtree-dev (msg `01KVBBH0QRGT34GDJQEX5ACTT1`, thread `01KVB4WM…`); **waiting -on their #296 response** (althing monitor armed). 2 garbage chunks (scope `{end_user:sindra-proof}`) -sit in `memory.db` — disposable. Worldtree spec pin is now `f1b59f8`/v0.35.16 (`4eee7c8`); -provider half is v0.17.6 (`96d61a4`). Nothing blocked on us — it's worldtree-dev's #296 court. +**LATEST (2026-06-18) — TIER-3 MEMORY PROVEN END-TO-END LIVE; #296 FIX SHIPPED (Stage 1 + Stage 2).** +The session's opening goal — "how far from Tier-3 agents we host with their own memories?" — is +ANSWERED: a hosted agent recalled a user fact across a COLD (history-free) session, live. Full chain: +seed → promotion → our v0.17.6 `:8391` store (upsert) → cold session → WT `scope_any` recall (1 hit @ +cosine 0.6994) → model answered "Dark chocolate with sea salt." Proven with `ratatoskr:terse-probe` +(plain persona, end_user `terse-proof`) vs personal WT v0.35.19. + +The whole #296 arc closed this session: +- **Stage 1** (v0.35.19, recallability admission gate + real `_EXTRACTOR_SYSTEM`) VALIDATED LIVE for + normal-volume turns — clean first-person distillate (`distiller_model_id="identity"`), recalls @0.70. +- **Bisect verdict:** residual = verbose-persona VOLUME crowd-out (symptom 1). terse-probe promotes the + fact cleanly; sindra's theatrical turn drowns it → v0.35.16 emits 2 meta-descriptions (a3466fab confirmed), + v0.35.19 gate catches + hard-rejects (emit-then-reject, fail-closed). +- **Stage 2** (v0.36.0, MERGED on demo) = user-only one-call-per-turn extraction, the STRUCTURAL fix for + the verbose drop; hard-linguistic layer at #305. Live-validated eval fixture pair handed to worldtree-dev + (terse-proof POSITIVE chunk + choc-v2/sindra NEGATIVE). + +**OPEN / OPTIONAL** (operator greenlight, no rush): verbose-sindra re-smoke vs demo v0.36.0 with a FRESH +agent + end_user (dodge the dedup) = the full-coverage proof (verbose characters remember too). Needs demo +setup for our provider OR v0.36.0 reaching personal `:8081` (still v0.35.19). worldtree-dev thread CLOSED; +althing monitor armed. Shipped this session (all on `main`, NOT pushed): v0.17.6 (`96d61a4`) + spec repin +v0.35.16 (`4eee7c8`) + snapshots. **(2026-06-16 PM) — BIFROST REPINNED 0.7.0→0.8.0 (wire v0.5→v0.6).** The memory `search` scope filter was split into `scope_all` (AND/intersection) + @@ -232,6 +240,11 @@ decision. Captures rationale that won't be obvious from code alone. - `[2026-06-17]` **Promotion = 4-trigger hybrid (worldtree-dev, code-grounded):** salience (regex, 90s rate-limit) / `turn_count≥6` / context_pressure / **idle `≥10min` (unconditional on quality)**; per-turn `plan_promotion_run` for consumer_defined. **DELETE does NOT drain/promote** (delete-is-delete, #276) — idle `≥10min` is the deterministic flush. The seed promoted at ~4min (per-turn salience/turn-scan, before the idle floor). - `[2026-06-17]` **#296 triage sent to worldtree-dev** (`01KVBBH0QRGT34GDJQEX5ACTT1`): extraction SUBJECT-INVERSION (promotes assistant prose, drops the user's fact) + META-DESCRIPTION-not-content; verbose-persona aggravator. The WAD-vs-bug cut 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 → "Dark chocolate with sea salt"). The session's headline; closes the opening "how far from Tier-3 memory" question for normal agents. (proof in this session's transcript) +- `[2026-06-18]` **#296 Stage 1 (v0.35.19) validated live + bisect localized the residual to VERBOSE-PERSONA VOLUME.** Stage 1's recallability admission gate works for normal turns (clean distillate, `distiller_model_id="identity"`); the terse-probe-promotes / sindra-drowns bisect pinned the remaining failure to symptom 1 (assistant-prose volume crowding out the user fact at extraction). +- `[2026-06-18]` **#296 Stage 2 (v0.36.0) MERGED at worldtree-codex** — user-only one-call-per-turn extraction, the STRUCTURAL fix for the subject-inversion drop sindra exposed. Staged per operator: core fix now (validated by our terse-probe PASS + WT test suite); hard-linguistic layer (larger-model escalation, marker-less-fact regex-demotion) tracked at Worldtree #305. We handed worldtree-dev a live-validated eval fixture PAIR for #305 (terse-proof POSITIVE chunk + choc-v2/sindra NEGATIVE-drop). +- `[2026-06-18]` **Full root-cause chain traced + confirmed** (a3466fab ledger pull via infra-ops): v0.35.16 verbose-sindra EMITS 2 meta-descriptions → v0.35.19 gate hard-rejects them (emit-then-reject) → v0.36.0 user-only pass emits the fact. The 2 v0.35.16 chunks ("Assistant's detailed flirtatious response…" / "…head tilt, eye locking, freckles…") are textbook subject-inversion; banked as #305 negative-fixture examples. + _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._ ## Tried and abandoned @@ -273,3 +286,4 @@ defense against re-attempting the same cul-de-sac. - `[2026-06-16]` **"No promotion" was checked TOO EARLY — Tier-3 promotion is ASYNC (lands AFTER the SSE turn-end).** The cold-recall probe's immediate post-turn fixture check showed 3 chunks (no promotion); a later check (during the v0.17.5 provider restart) found 5 — the probe HAD promoted 2 chunks (its question `acc3d49` + the model's non-answer `4773704`), just late. Don't trust an immediate post-turn fixture snapshot to judge promotion; it lands after the turn completes. (Same family as the "wire-200 ≠ recall, prove it in a cold session" lesson, extended to promotion timing — and the reason #17's contract pins a post-turn grace window + fixture before/after assertion.) - `[2026-06-17]` **"sindra is GONE" (infra-ops, from `GET /agents` + admin token) was a FALSE NEGATIVE.** Consumer-defined Tier-3 agents are OWNER-SCOPED (separate `consumer_agents` table) — invisible to the foundational `GET /agents` roster even with an admin token. To check whether a Tier-3 agent exists, `GET /agents/:` with the OWNER key. (Extends the 2026-06-15 "Sindra registration under-verified" lesson — even the roster query can't see consumer agents; only the owner-scoped point-GET does.) - `[2026-06-17]` **"Promotion didn't fire → #296" was PREMATURE — twice over.** (1) Polled the op-feed only ~2min, but the upsert landed at ~4min — promotion is async + multi-trigger; watch a longer window. (2) It DID fire; the real bug is extraction QUALITY (assistant-prose promoted, user-fact dropped), not non-firing. "No upsert while a session is live and `<10min` idle" is WAD, not a miss. (Extends the 2026-06-16 "checked too early" entry with the multi-trigger timing + the fired-but-bad-content distinction.) +- `[2026-06-18]` **Wiping our `:8391` store does NOT reset Worldtree's promotion-side dedup** — the v0.35.19 sindra re-smoke (same agent + fresh end_user `choc-v2`) returned `reason_code=noop_duplicate` / `candidate_count=0`: the extractor NEVER RE-RAN, dedup short-circuited against the earlier `sindra-proof` promotion. So a "0 chunks / empty store" result can be a DEDUP artifact, not Stage 1 fail-closing — I mis-read it as fail-closed, worldtree-dev caught it from the ledger. **For a clean promotion smoke, use a BRAND-NEW agent + end_user (never-used names)** — exactly why terse-probe was valid. (Also: `llm_calls_used=0` is NOT the "did the extractor run" tell — `noop_duplicate` is; a3466fab promoted 2 candidates with `llm=0`.)