V1.5 · "Twin can do" · workflows + architecture review

Gemini can talk; your Twin can do

Two end-to-end workflows on the voice-first Twin surface — a booking task and a guided goal — and the architecture changes that make them possible.

Workflow 1 — find & book a plumber
1 · one-tap entry from Home
Your twin is listening, Marlize
Find me a plumber in Sandton|

Home command bar is the entry point — submitting opens the Twin surface with the message already sent (B1).

2 · find_service returns options
MyTwin+
● Online · ready to act
Find me a plumber in Sandton please
Found 3 well-rated plumbers near Sandton. Pick one and I'll book.
🔧
Pro Plumber Sandton
4.8★ · 76 reviews · 1.2 km
Book this one
🔧
Plumber Sandton
4.5★ · 52 reviews · 2.8 km
Book this one

Gemini calls find_service("plumber","Sandton") — the declared-tool version of the existing Places path (A1).

3 · one clarifying question
MyTwin+
● Online · ready to act
Book Pro Plumber
When suits you? They have slots tomorrow.
Tomorrow 09:00
Afternoon
Pick a day

One question, one at a time — quick chips answer it in a tap. Conversation state comes from the last 10 stored messages (A4).

4 · executed, confirmed, undoable
MyTwin+
● Online · ready to act
Booked — tomorrow 09:00
Pro Plumber Sandton · added to your calendar with a reminder 1 hr before.
Undo
View in Calendar
Done. Want me to text you their number too?
→ users/uid/events (Calendar streams it)
→ users/uid/reminders
undo window: 5 min

action_done card with 5-min Undo. The executor wrote to Firestore, so Calendar shows the event with no app restart.

Workflow 2 — teen plans her 18th birthday (guided goal)
1 · broad goal → short interview
MyTwin+
● Online · ready to act
Twin help me plan my 18th birthday 🎉
Yes! Let's get it done. Two quick things — roughly how many friends?
~10
~20
Big — 40+
And the vibe — pool party, dinner, or something wild?
pool party 💦

System prompt caps the interview at 2–3 questions, one at a time — never an interrogation (A2).

2 · create_plan → checklist card
MyTwin+
● Online · ready to act
Plan · 18th birthday pool party
Assuming ±20 guests, home pool, budget ~R2 500 — correct me.
Venue shortlist — 3 pool venues near you
Date poll to friends group
Budget estimate — R2 500 split
Playlist draft
Cake order — reminder 12 Aug
Invites out 2 weeks before
Add all to calendar
Saved your plan — 6 steps. Cake reminder is on 12 Aug; I'll nudge you. Find pool venues now?

Draft plan with stated assumptions beats a 4th question. Steps live at users/uid/plans/planId; tapping a step writes back.

3 · preference remembered
MyTwin+
● Online · ready to act
no meat for the braai, I'm vegetarian btw
Got it — updated the menu to vegetarian options.
Remembered: food · dietary · vegetarian edit
save_preference("food","dietary","vegetarian")
→ users/uid/twin_profile/preferences
no-op if consent flag is false

A stable preference is saved transparently — the inline chip links straight to the memory screen. Sensitive data is never stored (A2).

4 · "My Twin's memory" (POPIA)
My Twin's memory

Your Twin remembers these to personalise help. Delete anything — it stops being used immediately.

Food
Dietary: vegetarian
Style
Budget band: mid
Likes: pool parties
Forget everything

Profile → My Twin's memory streams the preferences doc; per-item delete + "Forget everything" (B2). Consent captured at onboarding (B3).

Architecture review — what changes to make both possible
Twin surface (Flutter)
evolved twin_chat_screen — mic, chips, action/plan cards, Undo
Home command bar
one-tap entry; submit opens the surface with message sent
twinRun (Cloud Function)
NEW · profile injection
prepend known preferences (≤2KB) to every call
NEW · chat history
last 10 messages replace single-turn prompts
NEW · interview prompt
max 2–3 questions, then plan with assumptions
Gemini + tool declarations NEW
create_reminder · add_calendar_event
add_family_task · create_plan
save_preference · find_service
Executor NEW
runs each function call, writes Firestore docs, returns action_done + undoToken (5 min)
Firestore — same collections the screens already stream
users/uid/reminders · /events · /family_tasks · /plans/planId · /twin_profile/preferences (+ consent)
Rest of the app auto-populates
Calendar, reminders, family tasks and plan checklists appear live — no new plumbing, no app restart.
Why this shape works
  • Executor writes where screens read — no per-feature integration; both workflows land in existing UI for free.
  • One chat surface — the plumber and birthday flows are the same screen; only the cards differ.
  • Undo over confirm — act first, 5-min undo keeps trust without modal friction.
Watch-outs
  • Consent gate — save_preference must no-op when consent is false; test it explicitly.
  • Sensitive-data filter — health / ID / banking never persist; spot-check in acceptance.
  • 2KB profile cap — most-recently-updated wins; define eviction before launch.
  • Booking scope — "book" = calendar event + reminder + phone handoff; the Twin doesn't call the plumber yet. Say so in the card copy.
Acceptance (from brief)
  • Reminder request → doc + Undo card → visible in Calendar, no restart.
  • "Plan my 18th" → ≤3 questions → plan card → steps in Firestore.
  • "I'm vegetarian" → appears in memory screen; deleting removes it from next call's context.