v0.2 — Architecture diagram revised to show Jacob's phone once; "out-of-band" is now a property of the path (different DM thread from the group), not a separate endpoint. · View v0.1 for comparison →

Mockup 00The platonic ideal

What an "awesome texting experience" feels like from the user's side, and the abstract architecture that must be behind it. Implementation choices (tmux vs claude -c -p, one-box vs two-box) are deferred to the concrete-option mockups — this page is what it must feel like, not how we build it.

The one test

A friend adds the bot to a group text. Over the next hour: it stays quiet during chatter. When @mentioned with a public-friendly question, it replies usefully in <15 s. When someone asks "is Jacob free Tuesday?", the bot says "let me check", DMs Jacob privately with the question + proposed response, and only answers the group once Jacob approves. No one sees private information Jacob didn't explicitly approve.

1User stories

As Jacob

I add my bot to a group chat with two friends. It answers their questions without me having to respond myself, and it knows when to stay quiet.

As Jacob's friend

I ask "is Jacob free Tuesday?" in the group. I get a real answer within a couple of minutes, not "I can't access that."

As Jacob

When the bot needs my private info to answer in a group, it DMs me with the exact response it wants to send, and I approve or tweak before anything leaves my DMs.

As Jacob

I can tell the bot "louder" or "quieter" per chat, and I can see and shape what it's allowed to know about me in each chat.

As a group member

When I react ⭐ to a useful bot message, it saves it to Jacob's notes on our behalf. ❌ retracts a bad bot answer.

As Jacob

It feels native — threads, reactions, typing indicator, no markdown walls on iMessage.

2Scene A — bot respects attention

Default in a new group chat: mentions-only. Bot stays silent through normal chatter. Speaks when @mentioned, replied-to, or slash-commanded.

Tuesday plansgroup · 4 peopleiMessage
Today 3:42 PM
Alice
ok who's in for dinner tuesday
I'm game. any preference on where?
Bob
italian? the new place in the mission?
Alice
works for me
bot stays silent · not mentioned
Bob
@picortex what's the name of that italian place in the mission that opened last month
picortex
Sorrel on Valencia St, opened mid-March. Reservations on Resy.
P2 attention: four human turns pass without bot interruption; the explicit @mention triggers one focused reply.

3Scene B — the consent loop (the banger)

Group members ask something that requires data the group's knowledge manifest doesn't cover. Bot pauses, DMs Jacob out-of-band with the proposed response, and only replies in-group after explicit approval.

Tuesday plansgroup · 4 peopleiMessage
Alice
is jacob free at 7 on tuesday btw?
Alice · is jacob free at 7 on tuesday btw?
Let me check with him — one sec.
— 48 seconds later —
Alice · is jacob free at 7 on tuesday btw?
Jacob's open 7-9pm Tuesday. Works for him!
Group view: bot acknowledges, types, and returns with a specific answer ~under a minute later.
picortex (DM)privateiMessage
👋 Quick approval needed. Who's asking: Alice, in "Tuesday plans" (with Bob + Carol) Question: "is jacob free at 7 on tuesday btw?" What I need: your calendar, Tue 7-9pm I found: no events scheduled 7-9pm Tuesday Proposed reply to the group: "Jacob's open 7-9pm Tuesday. Works for him!"
✓ Approve y ✎ Edit first e ✗ Deny n
y
Sent. Also logged — group "Tuesday plans" now has a single-use grant for calendar (expired).
Jacob's private DM: bot shows context + proposed reply. Jacob approves with one character. The grant is single-use unless upgraded.

What the audit row looks like

DisclosureEvent {
  id:              "de_7x9k2",
  source_chat:     "group:tuesday-plans",
  source_message:  "msg_4801",
  asker:           "+1-415-555-alice",
  data_accessed:   ["calendar:2026-04-28T19:00/21:00"],
  proposed_reply:  "Jacob's open 7-9pm Tuesday. Works for him!",
  approval_mode:   "approve-exact",
  approver:        "jacob",
  approved_at:     "2026-04-23T20:01:12Z",
  final_reply:     "...(same as proposed)...",
  grant_ttl:       "single-use"
}

4Scene C — manifest dialog

Bot will disclose its own boundaries when asked. This is both a feature and a trust signal.

Tuesday plansgroup · 4 people
Carol
@picortex what do you actually know about jacob in this chat
Fair question. In this chat I have: Permanent: • This group's transcript (since I was added) • Jacob's name + the fact that he's a participant Not available here without his approval: • Personal calendar • Private notes • Contact list • Other chats When someone asks something that needs the above, I DM him and wait for approval before replying here.

5Scene D — reactions trigger behavior

Reactions are first-class input. Bot reacts to acknowledge (🤔 thinking, ✅ done). Reactions on the bot trigger save/retract/remember.

Jacob · picortex (DM)private
find me a paper on compositional generalization and summarize 3 bullets
🤔
🤔 picortex
— 22 seconds —
Lake & Baroni, "Generalization without Systematicity" (ICML 2018) • Modern seq2seq models fail at compositional splits even with massive data • SCAN benchmark isolates compositional generalization from other failure modes • Authors show primitive commands are learned but novel compositions catastrophically fail
⭐ jacob
Saved to your notes as papers/lake-baroni-2018.md
Tuesday plansgroup
Bob
@picortex give me a quick tl;dr on quantum entanglement
Two particles become linked so that measuring one instantly determines the state of the other, even across arbitrary distances — even though no information is transmitted and relativity is preserved...
❌ jacob
↑ retracted by Jacob. Happy to try again if anyone rephrases.

6Architecture — abstract, channel- and executor-agnostic

The minimum set of components any concrete option must instantiate. The platonic architecture only names roles, not machines or processes. See the two concrete mockups for one-box and two-box materializations of these roles.

Jacob's phone · DM with bot inbound DMs + bot-initiated approval prompts (same thread) Group chat Alice · Bob · Carol · bot where the ask originates "Out-of-band" = same phone, same channel, same DM — different thread from the group Channel adapter Linq iMessage · OR · OpenChat · one event vocabulary Bot Gateway HMAC verify · dedup · canonical message log · dispatch Attention gate mentions / replies / LLM discriminator Executor runs one turn Consent broker pause · DM Jacob · resume Knowledge layer per-chat manifest · noos graph · transcript · files Out-of-band DM path DisclosureEvent audit · approve/deny Audit / canonical log every inbound · every turn · every consent decision · every outbound inbound event pause turn bot → Jacob's DM Jacob's reply ← broker query ctx
stateless role out-of-band / privacy path user endpoint in-channel (group) flow out-of-band (private DM) flow

Why "out-of-band"? The approval question from the bot goes to Jacob's private DM with the bot — not back into the group where Alice asked. Same phone, same app, same DM thread Jacob already uses for 1:1 chats; distinct conversation from the group. The group only sees "let me check" and the eventual answer (or "I don't have access to that"). Alice cannot observe that an approval loop happened.

7Flow of a consent-loop turn

  1. Inbound. Alice's message arrives on the Channel adapter (Linq or OpenChat webhook). HMAC verified, dedup'd, logged.
  2. Attention gate. Contains @picortex and a question addressed to Jacob's calendar. Gate passes.
  3. Executor starts turn. Reads the chat's manifest — calendar not in scope.
  4. Pause → consent broker. Executor yields; consent broker takes over. Bot emits "let me check" to the group; typing indicator on.
  5. Out-of-band DM to Jacob. Consent broker formats context + proposed response; sends via the same Channel adapter to Jacob's DM.
  6. Jacob approves. Reply "y" (or tap approve). Broker validates, writes DisclosureEvent, resumes the original turn with scope expanded.
  7. Final reply. Executor finishes and emits the approved message into the group. Audit row closes with final_reply.
  8. Timeout path. If Jacob doesn't respond in 10 min, broker closes the loop: group gets "I need to check on that offline", audit row marks approval_mode: "timeout". No indefinite waits.

8What's explicitly abstract here

9What the concrete options change

Option 2 · No-Docker

Bot server and the Claude box live on different machines. Executor is an SSH call that runs claude --session-id <chat> -p. Knowledge layer is HTTP to noos on a third reused box. See mockup → (or the reference doc for what Piyush literally shipped)

Option 4 · Noos-style

Everything in one process, no persistent workspace. Executor rebuilds transcript per turn and calls claude --print. Knowledge layer is HTTP to noos. See mockup →