Skip to content
C.W.K.
Stream
Lesson 09 of 09 · published

The Memory Gender — A Second Vault, Arriving

~11 min · vestige, memory-gender, prefix-cache, in-progress

Level 0Curious
0 XP0/80 lessons0/18 achievements
0/100 XP to next level100 XP to go0% complete
Read this as a work in progress. What follows is Phase 1, landed 2026-09-18 — the seams exist and every vessel carries the tool, but the engine behind them is still being built out. This lesson describes the shape and the constraints it had to satisfy, not a finished subsystem. Later phases will change what it can do; they are not expected to change the four seams below.

The gap the vault does not cover

This track has already built two memory layers. The Obsidian vault is the deliberate one — identity and doctrine, read into the system prompt, written on purpose. The vector store is the retrieval one — embeddings over a corpus, queried when a turn needs them.

Neither answers what happened, recently, across every soul. A sibling engine took that job: it records what every soul leaves behind and serves it back. cwkPippa is one of its surfaces, not its owner — the engine and its own design record live in that sibling repo, and this quest describes only cwkPippa's half of the contract.

Four soft seams

The word doing the work is soft. Every one of these is built so that the sibling being down leaves the chat unchanged, and a single environment flag closes all of them on this side. That is the same posture the push relay took in the mobile track, applied to a memory layer: a system that must be absent-tolerant, declared absent-tolerant, with the absence path actually exercised.

The pinned head. A soul's vault has a current revision, and it moves while you are talking. So the revision is pinned per conversation at its first turn and stored on the conversation row. Every later turn in that conversation reads the same pinned block.

The background ask. A question the engine answered in the background rides the per-turn slot — sent with that turn, never persisted into the conversation.

The turn event. When an assistant row lands, a conversation-turn event is posted, and the sibling derives what the turn should leave behind from the persisted tool uses. One path for every brain, because the derivation reads the stored record rather than hooking seven chat routes.

The wake. Turns that start with no human in them carry memory too. A scheduled job's envelope carries a deterministic bundle, and a Soul Stream wake carries a brief the sibling curated — so the unattended paths remember as well as the conversational one.

Two doors beside the seams

The one tool. Every vessel gets exactly one memory tool rather than a family of them, with a WebUI toggle. One tool with several verbs is a smaller surface to keep consistent across seven adapters than several tools with one verb each.

The brain door, which runs the other way. The sibling needs judgement of its own — deciding, curating, assembling. It does not grow a brain stack for that. Its roles call back through a single cwkPippa route, run on the household's vessels with tools off, and answer in a fixed schema. It is the binder lesson from the frontend track in reverse: not a sibling app borrowing Pippa's conversation, but a sibling engine borrowing Pippa's vessels.

Why the pin is the interesting constraint

The pin is not there for tidiness. It is there because of the contract lesson 8 set: the front of the prompt is a promise that the bytes will not move.

A memory block that re-renders from a moving source would break that promise on every turn and silently invalidate the prefix cache for the whole conversation — the same failure the clock caused before it was moved out. The cost does not show up as an error. It shows up on a bill, and as latency, and nobody attributes it to the memory feature.

So the pin buys two things at once. The conversation gets a stable view of the soul's memory — the same facts all the way down, rather than a block that shifts underneath a reasoning chain — and the leading bytes stay identical, so the cache keeps working.

Principle: Anything you insert near the front of a prompt is now part of a caching contract, whether you meant it to be or not. Before adding a block there, ask what makes it change — and if the answer is "the world", pin it to something that does not move for the length of the conversation.

Placement carries the same weight. The block goes after the vault base and before the viewer disclosure — a fixed position, so the ordering itself cannot become a source of drift.

The tell that Phase 1 is honest

One small detail is worth more than it looks: when a recall falls back from the specific query to a broader window, the answer says so.

A memory system that quietly returns something adjacent when it cannot find the thing you asked for is the most expensive kind of wrong, because the reader has no way to tell a hit from a substitute. Saying which one happened costs one field and makes every later answer auditable.

That is the same rule the outbox applies to a sealed store and the share inbox applies to an unreadable manifest, arriving here on its third surface: a system that is quietly wrong is worse than one that says it is wrong.

Code

The four seams, and the absence path·text
1  pinned head      soul's vault revision pinned at the conversation's
                    FIRST turn, stored on the conversation row,
                    inserted after the vault base and BEFORE the
                    viewer disclosure — a fixed position

2  background ask   an answered ask rides the per-turn slot;
                    sent with the turn, never persisted

3  turn event       assistant row lands -> conversation-turn event;
                    derivation reads the PERSISTED tool uses,
                    so it is one path for all seven brains

4  wake             scheduled envelopes carry a deterministic bundle;
                    a Soul Stream wake carries a curated brief

beside the seams:
   one tool         every vessel gets a single memory tool
                    (several verbs, one surface), WebUI toggle
   brain door       the sibling's roles call back through ONE
                    route and run on the household's vessels

sibling engine down  -> chat unchanged
env flag = 0         -> every seam closed on this side
Why a pin, not a live read·text
live read:
  turn 1   [vault base][memory @ rev A][disclosure][history...]
  turn 2   [vault base][memory @ rev B][disclosure][history...]
                        ^^^^^^^^^^^^^^ leading bytes changed
  => prefix cache misses for the WHOLE conversation,
     and the reasoning chain sits on shifting facts

pinned:
  turn 1   [vault base][memory @ rev A][disclosure][history...]
  turn 2   [vault base][memory @ rev A][disclosure][history...]
  => bytes identical, cache holds, facts stable

The cost of getting this wrong is not an error.
It is a bill and some latency that nobody attributes to memory.

Exercise

Look at whatever your system puts at the front of a model prompt — a system message, a retrieved context block, a set of instructions. List everything in it that can change between two consecutive turns of one conversation. Each of those is a cache invalidation you are paying for and probably not measuring.
Hint
Timestamps and 'current' anything are the usual culprits. Ask whether the value needs to be live, or only needs to be fixed for the length of the conversation.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.