בס״ד

FME — Manny Isolation Test (the Track-1 deliverable)

docs/FME_MANNY_ISOLATION_TEST.md · last changed (pre-VM history) · rendered from GitHub master

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, D1 hookstreet-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)

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)

  1. Sam creates @<MannyBot> in BotFather → gives the token.
  2. cd manny-relay && npx wrangler secret put MANNY_BOT_TOKEN (+ INBOX_SECRET), then npx wrangler deploy.
  3. Set the bot's Telegram webhook → the manny-relay worker URL.
  4. Set MANNY_CHAT_ID on 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.

Source trail · docs/FME_MANNY_ISOLATION_TEST.md @ master · rendered 2026-07-02 7:23 PM EDT by scripts/build-docs.py · the .md in the repo is the truth; this page is the phone-readable view