Build plan: the AI Briefing Home
The honest headline: most of this already exists. The cockpit shipped on all three platforms is the conversation engine — thread, tools, receipts, chips, voice. Building the gateway means re-homing that engine onto the landing screen, adding the one genuinely new organ (profile memory), and fixing week-context so schedule answers are never wrong.
~70%of the surface is reused, not written
1new DB table (profile_facts)
0edge-function rewrites (context is client-built)
5phases, each shippable on its own
reused as-is / re-homednew code
Shared backend supabase/ · one migration, prompt constants
Migration 050 — profile_factsuser_id, category (person/rhythm/constraint/preference/context), fact, source (interview/chat/derived), updated_at, active. Owner-RLS like everything else. Kids' names live HERE under our RLS — only minimized derived strings ever go to the model vendor.
save_profile_fact tool + lab guardrails → prompt.tsThe persona rules proven in the lab move into the system prompt: never invent times, act-now-never-promise, plain text, no repetition, max-3 listing, the Maleek curiosity rule.
Week-context fix + get_schedule read toolContext sends ALL of this week's blocks + calendar events (today: one block per task) — the prerequisite for honest "what's my week" answers.
Edge fn assistant — unchangedStateless by design; the client builds context, so profile injection is a client-side append. Guardrail, limits, kill-switch all stay.
Model decisionLab finding: qwen-turbo narrates tool calls as text under a rich persona; qwen-plus acts reliably. Recommend qwen-plus for gateway turns (cost stays under a cent/user/day) — or A/B both in prod config.
Voice proxy — unchangedSame relay, same guardrail enforcement for app clients. The playground path stays for future persona iteration.
Web — ships first app/(product)/dashboard + lib/assistant/
components/assistant/briefing-home.tsxThe new landing composition: BriefCard + probe → StartNext hero → chips → input row → thread expands in place. Rendered by dashboard/page.tsx when the toggle is on; classic Today otherwise.
lib/assistant/brief.ts + patterns.tsDeterministic brief composer + pattern/gap detector — straight ports of the lab's buildBrief/derivePatterns, running on real tasks/cal_blocks. Zero tokens, instant, offline.
Cockpit thread, chips, receipts, voice — re-homedassistant-home.tsx, suggestions.ts, receipts.ts, voice-mode.tsx move from the bubble panel into the page body. The engine is untouched; only the container changes.
StartNextCard — untouchedThe hero renders exactly as today, one slot below the brief.
lib/assistant/profile.ts + "What Unstuck knows"Hydrate/sync profile_facts, tool executor + "Noted: … — Undo" receipts, and the Settings screen listing every fact with edit/delete.
components/assistant/interview.tsxFull get-to-know-you interview on first open — scripted chip flow (zero tokens), one LLM parse call only for free-text answers, skippable + resumable, every answer saved as a visible fact.
Settings toggle "Start in Assistant Home"Same pattern as the existing AI toggle. Testers opt in; the default flips in P4.
iOS unstuck_ios · App/Features + UnstuckCore/Data
HomeFeature.swift — new tab rootBriefCardView + probe chips above the existing hero; AssistantSheet's engine (AssistantModel) rendered inline as the screen instead of a sheet. Tab renamed ✦ Home.
BriefComposer + PatternDetector in UnstuckCorePure-logic ports of brief.ts/patterns.ts — unit-tested in UnstuckAppTests like lane layout is.
Start-Next hero, thread UI, receipts, voice — reusedTodayFeature's hero view and the whole AssistantSheet engine already exist; VoiceModeScreen is the mic target.
profile_facts in UnstuckDataSQLite table + outbox writes + hydrate, the same FK-safe sync pattern every other table uses. Settings gains "What Unstuck knows".
Widgets, App Intents, tabs — untouched"Ask Unstuck" Siri intent now lands on the home surface for free.
Android unstuck_android · ui/home + data
ui/home/HomeScreen.kt — new "today" tab contentBriefCard composable + probe chips; AssistantSheet's content (AssistantHome + thread) hoisted from the sheet into the screen. MainScaffold keeps its 4 tabs + FAB.
BriefComposer.kt + PatternDetector.ktSame pure-logic ports, unit-tested.
Hero, thread, receipts, VoiceModeScreen — reusedThe vc78 cockpit engine is the whole conversation layer; the mic pill stays wired to realtime Talk.
profile_facts in the data layerTable + outbox + hydrate mirroring tasks; SettingsScreen gains the facts list + start-in-home toggle.
Push order — each phase ships and is testable on its own
P0 · Backendsmallprofile_facts migration + prompt/tool/context fixes. Blocked only by the pending Supabase SQL access (migrations 048/049 queue with it). Everything after builds on this.
P1 · Web homemediumBriefing home behind the toggle on unstucknow.io — brief, probe, inline thread, profile saving with receipts. You + testers flip it on and live with it.
P2 · Memory UXmediumInterview on first open + "What Unstuck knows" + proactive probes. The full get-to-know-you flow, chip-answerable and skippable, per your call.
GATE—Your review on live web. Conversation quality, brief tone, probe frequency — tuned with real data before any mobile work.
P3 · MobilelargeiOS + Android ports in parallel (the engine's already shared; this is surface work) → TestFlight build + Firebase build.
P4 · FlipsmallDefault lands on Home once testers stop flipping it back; web bubble retires; store screenshots/tour updated.
Guardrails carry overThe scope-lock, injection resistance, kill-switch, and receipts-for-every-action all stay. The lab's new rules (no invented times, no repetition, plain text) join the server-side prompt, not just the client.
Privacy lineFacts live in our DB under owner-RLS. What crosses to the model vendor is a minimized profile block — no children's names on the wire. adhd_struggles stays out of the payload unless an explicit consent toggle says otherwise.
Offline / AI-downThe brief, hero, chips, and all navigation render from local data with no network. If the LLM is unreachable, sends land in the Capture inbox with a "saved — I'll sort it when we're back" receipt.
Existing testersNothing moves until they opt in — P1–P3 live behind the toggle, so "where did my app go" can't happen before the data says it should.