בס״ד

BOTTEMPLATE.md — the Private Human Memory Channel (the reusable primitive)

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

BOT_TEMPLATE.md — the Private Human Memory Channel (the reusable primitive)

The asset is NOT "Chanie Bot" or "Manny Bot." It's the pattern — a private, isolated, captured channel between one human and Sam, that any new person becomes by configuration, not engineering. (ZW-ENGINE-V9, 2026-06-07.) Once stable, @MannyBot / @MildredBot / @MomBot are config — no new architecture.

The pipeline (every bot, identical)

Telegram bot (@XBot)
      ↓   webhook
<x>-relay Worker      — PERSON const + ALLOWED_CHATS allowlist (chat-id gate)
      ↓   service binding (token)
ops-api /p/<person>/send   — token gate; person comes from the URL, not the payload
      ↓
KV  <person>:thread   — live cache (50 msgs / 14d)   ← key prefix = isolation
D1  messages person=<person>  — permanent store      ← person field = isolation
      ↓
relay → Sam (Telegram ping)  +  event_log audit row

Isolation is validated at FIVE layers (never trust just one)

Per ZW-ENGINE-V9 — client-grade isolation checks all of these, not only bot routing:
1. Bot token — each person has their OWN bot (separate token). A message can only arrive on one bot.
2. Person slug — hardcoded PERSON const in that person's relay (it can only post to its own /p/<person>).
3. Chat-id allowlistALLOWED_CHATS env (config) gates who may speak to the bot; others dropped + audited.
4. D1 person field — derived from the URL path, never the payload → rows are scoped.
5. KV key prefix<person>:thread, derived from the URL path → cache is scoped.

Proven live both directions 2026-06-07 (see FME_MANNY_ISOLATION_TEST.md): manny ≠ family ≠ chanie at KV and D1.

To add a NEW person (the whole recipe — config, not code)

  1. BotFather → create @<Name>Bot → get the token.
  2. cp -r manny-relay <name>-relay; set const PERSON = "<name>".
  3. wrangler secret put ALLOWED_CHATS = that person's chat id (+ Sam's own id while self-testing).
  4. wrangler secret put INBOX_SECRET (same shared value); wrangler deploy.
  5. Set the Telegram webhook → the new worker URL.
  6. (Two-way) add the person to personBot() in ops-api + set <NAME>_BOT_TOKEN / <NAME>_CHAT_ID.
  7. Self-test from Sam's Telegram → confirm: lands in person=<name>, no cross-leak, Sam gets the relay, D1 stores. THEN hand it over.

Production-grade checklist (per ZW-ENGINE-V9)

Self-test gate (before handing a bot to the real person)

Run from Sam's own Telegram (add Sam's chat id to ALLOWED_CHATS), confirm ALL:
- messages land in person='<name>' · Sam receives the relay · D1 stores permanently ·
- other people's bots never see them, and theirs never appear here · rejected non-allowed senders are dropped + audited.
Only after this passes → swap ALLOWED_CHATS to the real person and hand it over.


Pattern proven on chanie-relay (live) + manny-relay (scaffold). The moment a 2nd and 3rd person go live unchanged, this is no longer a custom bot — it's a reusable operating system. That transition IS the sellable asset.

Source trail · docs/BOT_TEMPLATE.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