FME — Manny Isolation Test (the Track-1 deliverable)
What this proves: a new PERSON can be added to the Family Memory Engine with zero new per-person code, and that person's data is fully isolated — it can never appear in another person's read, and theirs never appears in his. Verified live against production (ops-api
353d260e, D1hookstreet-memory) on 2026-06-07 ~02:40 ET. Not from memory — from actual HTTP + SQL.
The rule being proven (ZW-ENGINE-V9, locked)
New client ≠ new features. One expansion axis: a new PERSON, not a new CAPABILITY. Manny proves repeatability, not intelligence. Retrieval / classification / voice / media / grocery all stay PARKED until this passes.
What changed (the generalization)
- ops-api
src/index.ts— added ONE generic route block:GET|POST /p/<person>/send+/p/<person>/thread. It scopes every message to<person>:thread(KV cache) and D1 rows taggedperson=<person>. The old/chanie /family /mildredroutes are untouched (they remain as aliases — Chanie's live path can't break). personBot()helper — maps a person → their own bot token + chat id, so Sam's reply pushes back into that person's bot.nulluntil a person is wired (Manny waits on his BotFather token).manny-relay/— the generalized relay template (PERSON = "manny", points at/p/manny/send). Adding the next client = copy this folder, changePERSON+ the bot-token secret. No ops-api change.
Test 1 — routing works with NO per-person code
/p/manny/send and /p/manny/thread were never written for Manny specifically — they fell out of the generic route. Three live sends returned {"ok":true}:
| # | Call | Result |
|---|---|---|
| 1 | POST /p/manny/send {from:manny, …} (the person) | {"ok":true} |
| 2 | POST /p/manny/send {from:sam, …} (Sam's reply) | {"ok":true} |
| 3 | POST /p/family/send {from:family, …} (a different world) | {"ok":true} |
Test 2 — KV cache isolation (the live thread)
GET /p/manny/thread → [ manny: "ISO-TEST manny inbound A", sam: "ISO-TEST sam reply to manny" ] ✅ manny-only
GET /p/family/thread → [ family: "ISO-TEST family-only secret X" ] ✅ NO manny
GET /p/chanie/thread → Chanie's real history only — NO ISO-TEST manny/family anywhere ✅ untouched
Manny's two messages appear only in his thread. The family secret appears only in family. Chanie's live data is untouched.
Test 3 — D1 permanent-store isolation (the forever record)
Every message also lands in D1 tagged by person:
SELECT person, sender, text FROM messages WHERE text LIKE 'ISO-TEST%':
manny | manny | ISO-TEST manny inbound A
manny | sam | ISO-TEST sam reply to manny
family | family| ISO-TEST family-only secret X
And the scoped read (how retrieval will query) returns only that person:
WHERE person='manny' → 2 rows, both manny ✅
WHERE person='family' → 1 row, NO manny ✅
Cross-isolation holds at both layers — the 14-day KV cache and the permanent D1 log.
Verdict
PASS. A new person routes with zero per-person code; his data is isolated from family/chanie/mildred in both KV and D1, in both directions. The pattern repeats. This is the sellable proof: "your stuff is yours, walled off, and I can add the next person in minutes."
Cleanup
All ISO-TEST% rows deleted from D1 (3 message rows + orphaned event_log rows); manny:thread KV cache deleted; the one ISO-TEST entry removed from family:thread. The store is back to real data only.
What's still needed for a LIVE two-way Manny (waiting on Sam)
- Sam creates
@<MannyBot>in BotFather → gives the token. cd manny-relay && npx wrangler secret put MANNY_BOT_TOKEN(+INBOX_SECRET), thennpx wrangler deploy.- Set the bot's Telegram webhook → the
manny-relayworker URL. - Set
MANNY_CHAT_IDon ops-api (Manny's chat id, captured on his first message) so Sam's replies push back into Manny's bot.Until then, the server-side isolation is already proven (above) — the bot wiring is the last, mechanical mile.
Source trail: ops-api/src/index.ts (generic /p/<person> block + personBot), manny-relay/, D1 hookstreet-memory, ops-api version 353d260e-2f71-4a4c-a070-f52ef04d1ebb. Generated 2026-06-07 ~02:42 ET.