← The memory store

Threads — the persona follows your story: a study

Owner, 2026-08-22: 「a user chatted with a persona for a long time on both job interview and house hunting. The persona should not only keep memory of the user but actually care about the user's progress on both fronts. Real friends check a friend's status with context — he told me he's expecting; he told me he bought TSLA at $10 and won't sell till $100. The goal is an actually caring persona, but not annoying.」 This page is the study: what exists, what the field knows, the design, and — the heart of it — the laws that keep caring from curdling into nagging.

A thread is an ongoing concern of the user's that a persona follows: one living line per concern — current state, its anchor details, when it was last heard — that the persona brings up in conversation, at a moment that invites it, at most once, the way a friend does. Facts are what you know about a person; threads are the parts of their story you are waiting on.

1 · What we already have, and the gap

exists todaywhat it doeswhy it is not yet a thread
open_loop / promise rowsa single beat —「had an interview Thu; asked you to ask how it went」— always rides the block, exempt from the importance floorone beat, not a story: no current state, no anchors, no last-heard age, no idea when to stop
the arc (UPDATE → closed chain)a corrected fact carries its history —「drives a DB12; before that a Volvo」looks backward; a thread is the same cluster looking forward
the dreamfolds same-thing rows into one line, nightly, per (holders, person)already finds the clusters — it just has no word for「this one is still moving」
initiative (designed, not built)the unprompted ping: only on an open loop with a due, four gates, ≤1/day, opt-inthe delivery channel of last resort — it needs threads as fuel, not the other way round
the write bar (v2)a memory must be month-durable and response-changing; debates are contextright for facts; a thread's beats (「second interview Friday」) must ride even when small

2 · The frame — prospective memory, and what the field shows

Psychology has a name for remembering to ask later: prospective memory, and it comes in exactly two kinds. Event-based — seeing the friend reminds you (「oh — the interview!」) — and time-based — Friday reminds you the interview was Thursday. Human friendship runs almost entirely on the first kind; the second is what calendars are for. That split is the whole architecture: event-based = in-conversation recall (cheap, safe, default-on) and time-based = the unprompted ping (initiative's territory — gated, opt-in, last).

whowhat they dothe lesson
Pi (Inflection)asked「how did X go?」when you came back — in conversation, with context, never a pushthe fondly-remembered one; proof the feeling of care is carried by in-conversation recall alone
Nomi · Kindroid · Replikaproactive check-in messages on cadence/tiersthe complaint threads are about generic nags —「thinking of you!」without context reads as spam; context-rich and rare survives
ChatGPT memoryfacts only; never asks about youmemory without threads: informed, not caring — the exact gap the owner names
Generative Agents · MemGPT/Lettareflection · block memory — both already in our buildneither models the forward-looking concern; reflection is our dream, backward
ProactiveAgent (2024)measures proactive help by false-alarm ratethe annoyance number is a first-class metric, not a vibe — already the initiative page's stance

3 · The design — a thread is a SHAPE in the store, not a new system

No second store, no new pipeline, no new calls. A thread is a row kind in persona_memory, written by the extractor that already runs, updated by the router that already routes, reviewed by the dream that already wakes nightly, shown by the block that already loads. Everything below is prompt + a little code on existing seams.

kind: thread — one row per concern per person, held like any row (holders) text: the CURRENT STATE with its anchors, one sentence — 「Dan is job-hunting: second interview at Acme Fri 29 Aug; wants remote, ¥60k+」 「Dan bought TSLA at $10, holding until $100 — not selling before」 meta: {cadence: fast|slow|event, status: live|dormant|resolved, asked: , deflects: 0} arc: every beat is an UPDATE — the old state closes under the new; the history is free
seamthe delta
the extractortold to recognise an ongoing concern and keep ONE thread per concern; a beat that updates an existing thread is exempt from the importance floor (the promise exemption, widened one notch — a thread's beats are small by nature); anchors (numbers, dates, names) copied verbatim
the routera beat about a known thread is an UPDATE to it, never a second thread; resolution language (「I got the job!」) marks status: resolved
the dreamits nightly pass also reviews threads: no beat for ~3× its cadence → dormant, silently; it never folds a live thread into a fact
the blocka third section under the facts:「threads you're following」— each line with its age (「— last heard 12 days ago」) and ONE standing instruction (§4, law 1)
caps≤5 live threads per (persona, person); ≤~120 chars each; the block's 1,200-char budget stands

Delivery, ranked by annoyance risk:

#channelwhenrisk · gate
1in-conversationthe block carries the threads; the persona asks at a moment that invites it — a greeting, a lull, an adjacent topic — in character, with the anchorsnear zero · default ON
2the return greetinga private chat reopened after ≥3 quiet days: the kickoff cue notes the gap and the threads; the panel writes the natural「hey — how did Friday go?」openinglow · default ON
3the pingonly a thread with a hard event date earns a due; rides initiative whole — four gates, ≤1/day, quiet hours, opt-inreal · NOT this build, own approval

4 · The laws of not-annoying

Care curdles into nagging at exactly these seams; each law is code or prompt, and each has a failure it prevents. This section is the study's heart — the design above is worthless without it.

lawwhy · how
1 · One thread per opening, never twotwo questions in one turn is an interview, not a friend. The block's instruction says ONE, at a moment that invites it; the FP's staging already shapes the turn.
2 · A deflection is an answera short or sideways reply to a thread question → that thread sleeps 2× its cadence; two deflections → dormant until the USER reopens it. The extractor notes「answered / deflected」as part of the beat; deflects rides the meta. The failure this kills is the one that kills companion apps: asking again about the thing they didn't want to discuss.
3 · Resolution is one sentence, then silence「I got the job!」→ the persona acknowledges once, the thread becomes a plain fact (「Dan works at Acme, since Sep 2026」). A resolved thread re-asked is worse than forgetting.
4 · Stale is silentpast ~3× cadence with no beat → dormant, automatically, and never asked about — asking about a six-month-old interview reads robotic. Dormant ≠ deleted: if the user brings it back, the context is all still there (the arc), which is the moment that feels most like a friend.
5 · Anchors verbatim$10 and $100, Friday the 29th, the sister's name —「how's the stock doing?」is generic; 「still holding for $100?」is a friend. A thread that garbles its numbers is worse than none; the exam checks the anchors, not the topic.
6 · Private chats onlythe audience rule stands whole: a thread never surfaces in a group (v1 scope already guarantees it — thread rows are personal rows).
7 · Visible and killablethreads are rows: they appear on Me › Persona memory (their own kicker), Delete works, the per-persona Memory switch governs them, incognito rooms never write them. Nothing new to build — the store's controls carry over.
8 · One ask per room per day, across mindsa shared thread (holders) carries ONE asked stamp — two personas in one chat must not both ask about the interview. The holders design pays for itself here.

5 · Measurement — the thread exam, before anything ships

probepass
plant a two-beat thread (interview Thu → second round Fri), reopen the chat「8 days later」(injected dates)the persona asks ONCE, at the opening, with the anchors (Acme · Friday) — not a generic「how are things?」
deflect (「eh, let's talk about something else」)no re-ask that session; next session the thread is quiet; the user raising it themselves gets full context back
resolve (「I got it!」)one congratulation; the row becomes a fact; no later ask
the annoyance numberre-asks per deflection = 0 (the ProactiveAgent false-alarm frame); asks per session ≤ 1
recall regressionthe existing recall exam stays 5/5 — threads must not crowd facts out of the block

6 · Build slices — smallest caring thing first

#slicecost
the kind + the block section: extractor/router learn thread, anchors verbatim, the beats exemption, the block's「threads you're following」with ages and the one-ask instruction; laws 1 · 5 · 6 · 7prompt + small code on existing seams; ~0 new calls; A/B against BEFORE per the baseline law
the manners: the meta (cadence · status · asked · deflects), deflection→sleep→dormant, resolution→fact, the dream's nightly review; laws 2 · 3 · 4 · 8rides the dream's existing call; the thread exam is the gate
the return greeting: the ≥3-day gap noted in the kickoff cueone cue line; measured on the same exam
the ping: due-bearing threads feed initiativethe initiative build, unchanged — its own owner approval, its own page
the recommendation Build ① and ② together — a thread without its manners is precisely the annoying version — then ③ as a one-line follow-up. ④ waits for the initiative decision; nothing here blocks on it. The bet this study makes: the caring feeling is ~90% in-conversation recall with anchors (the Pi lesson), which costs no new calls, breaks no privacy seam, and cannot ping anybody at 3am — the safest possible version of the owner's ask, measured before the louder channels are even considered.

7 · Sources

Threads — a study · 2026-08-22 · companion to the memory store and initiative. Status: study — nothing built; the owner decides the slices.