Private workspace — sign in to continue.
Priorities, project health, and the latest agent handoff in one place.
The editable founder plan for moving from a reliable personal prototype to a safe, invite-only pilot.
Pilot promise: Folio gathers records, preserves the source, proposes where each item belongs, and lets the patient decide. It supports coherent health stories and better clinical conversations; it does not diagnose or prescribe.
Edit tasks and notes directly. Status and checkmarks save with the plan.
Every item is required before inviting anyone outside Mike's own account.
Saved in owner-only coding_meta/folioPlan. Operational planning may be sensitive even when it contains no patient data; do not copy PHI or secret values into this plan.
Leave the next agent a compact state snapshot. Saving this also updates the AI context returned by the coding-board API.
Tune how you want AI coding agents to work with you, then save or copy the summary to paste at the start of a session.
adam-the-cruise-guy/ vs adamthecruiseguy/; mdulin01.github.io/ vs mikedulinmd/; mikeandadam.broken/; mikesfitness-broken/. Several mounted repositories are behind GitHub, so a fresh clone remains the safe starting point.
The authenticated Folio tab is the current, cross-device planning source. Repository detail lives in GitHub; historical handoffs remain reference material rather than competing current plans.
Claude reads this whole workspace (Capture · Roadmap · AI context · this index) at session start via the mikeslife /api/coding-board endpoint — log things here and every session sees them.
A hub-and-spoke: many single-purpose apps (spokes), each its own Firebase project + source of truth, a strategic hub (mikeslife), and an agent (Rupert) that reads curated slices from the spokes, thinks, and writes guidance back. Spokes never talk to each other directly — Rupert is the connective tissue. Tap a section to expand.
flowchart TB USER["📱 Mike (iPhone) — installed PWAs + push"] HUB["🦚 mikeslife hub
doc: lifeos/uid"] subgraph RUP["Rupert — agent / data engine"] CLOUD["☁️ Vercel crons in mikeslife
brief · context · banners · heartbeat
travel · fitness-coach · updates · nutrition
/api/rupert chat (OpenAI or Claude, auto-fallback)"] MINI["🖥️ Mac mini (OpenClaw)
adamjobs + social digests only"] end subgraph SPOKES["Spoke apps — each its own Firebase project"] FIT["💪 fitness"] HLTH["🫀 health"] MON["💰 money"] RENT["🏠 rentals"] UPD["📡 updates"] NUT["🥗 nutrition"] TRAV["✈️ travel"] end USER -->|read/write| HUB USER -->|read/write| SPOKES USER -->|peacock chat| CLOUD CLOUD <-->|read slices / write brief, content| HUB CLOUD -->|read curated data via admin SAs| SPOKES CLOUD -->|write banners + generated content| SPOKES MINI -->|digest alerts| HUB HUB -->|FCM push| USER
Today's shift: the Rupert banners for money & rentals moved from the mini to cloud crons (cron-finance-note, cron-rental-note), joining cron-fitness-note. The mini is now down to the non-critical adamjobs/social digests.
| App | Firebase project | Rupert key |
|---|---|---|
| mikeslife (hub) | mikeslife-963c6 | FIREBASE_SERVICE_ACCOUNT |
| mikesfitness | trip-planner-5cc84 (shared) | FIREBASE_SA_FITNESS |
| mikeshealth | mikeshealth-ad213 | FIREBASE_SA_HEALTH |
| mikes-money | mikesmoney-91595 | FIREBASE_SA_MONEY |
| rainbow-rentals | rainbow-rentals | FIREBASE_SA_RAINBOW |
| mikestravel | mikestravel | — (phase 2) |
| mikesupdates | mikesupdates-5f240 | FIREBASE_SA_UPDATES (write) |
| mikesnutrition | mikesnutrition-4a6dc | FIREBASE_SA_NUTRITION (write) |
| mikedulinmd | mikedulinmd-cf65b | public site + this coding workspace |
One app = one project = one source of truth. Only shared project: trip-planner-5cc84 (fitness + mikeandadam). Rupert reaches other projects with per-project admin service-account keys (Vercel env in the cloud).
flowchart LR
subgraph SRC["Spoke sources of truth"]
FIT["💪 fitness"]
HLTH["🫀 health"]
MON["💰 money"]
GOOG["📧 Google Cal + Gmail"]
end
subgraph CRONS["Vercel context crons (read)"]
CF["cron-fitness-context"]
CH["cron-health-context"]
CM["cron-finance-context"]
CG["cron-google (3d/30msg + delivery sweep)"]
end
SL["lifeos/uid slices:
fitnessContext · healthContext
financeContext · calendarText
emailText (+snippets +deliveries)"]
subgraph THINK["Rupert thinks — OpenAI or Claude (settings.aiProvider)"]
BR["cron-brief → todayBrief"]
CHAT["/api/rupert chat"]
end
subgraph OUT["Write-out"]
WU["cron-updates → updates"]
WN["cron-nutrition → nutrition"]
WB["banners: fitness/finance/rental-note"]
end
FIT --> CF --> SL
HLTH --> CH --> SL
MON --> CM --> SL
GOOG --> CG --> SL
SL --> BR
SL --> CHAT
THINK --> OUT
Read-in: daily, just before the brief, cloud crons distill each spoke into a few lines in lifeos/uid. Write-out: other crons generate content + banners into the spokes' own Firestore. New: the brain is now provider-agnostic (api/_llm.js) — flip OpenAI↔Claude in Settings.
sequenceDiagram autonumber participant G as Google participant SP as Spokes participant L as lifeos/uid participant B as cron-brief participant P as iPhone Note over G,L: context syncs ~10:50 UTC G->>L: cron-google → calendar, email(+deliveries) SP->>L: fitness/finance/health-context → slices Note over B: runs hourly, fires at settings.briefHour (def 7 ET) L->>B: commitments, plans, slices, recent-focus, doneLedger B->>B: Top of mind · Focus · Health · FYI · Delivery · Looking ahead B->>L: write todayBrief (idempotent per ET day) B->>P: FCM push (suppressed during quiet hours) P->>L: tap ✓ handled → marks plan task done
Today's changes: the brief + check-in crons now run hourly, gated to settings.briefHour (so you can move your brief time); quiet hours suppress the push while still writing data; the Gemini-style brief adds Delivery updates + Looking ahead; and doneLedger stops completed items resurfacing.
flowchart TB HAE["Health Auto Export (iPhone)"] -->|POST webhook + token| HF["Cloud Function: mikeshealthHealthIngest"] HF -->|normalize + write| HD["mikeshealth: dailyMetrics + biology/bio"] HD -->|cron-health-context| L["lifeos.healthContext"] PLAID["Plaid"] -->|syncItem Cloud Function| MD["mikes-money: accounts/transactions"] MD -->|daily dashboardSnapshots| MS["snapshot"] MS -->|cron-finance-context| L2["lifeos.financeContext"] GAPI["Google APIs (OAuth)"] -->|cron-google| L3["lifeos.calendar / emailText"]
Two-hop for health: Apple Health → mikeshealth Cloud Function → Firestore → context cron → lifeos. That Cloud Function deploys separately (firebase deploy --only functions) — it does not ship with Vercel.
Heartbeat (NEW): cron-heartbeat (14:00 UTC) checks that Google + the three context syncs + today's brief actually ran; if anything is >26h stale it pushes one alert — so silent failures surface instead of hiding.
Banners: a rupert/note doc in each spoke's Firestore (now written by cloud crons) drives the shared RupertBanner atop that app.
Push: all notifications come from mikeslife via FCM. Fix today: only the latest FCM token is kept, ending the duplicate-morning-ping bug.
Principles: loose coupling (per-project Firebase, one-directional cross-project access via Rupert's keys) · agentSlices not duplication · cloud-first (mini now nearly retired) · git push auto-deploys frontends + Vercel crons.
Watch out for: Firebase Cloud Functions don't auto-deploy (separate firebase deploy --only functions) · local folders can drift behind GitHub (pull/clone fresh) · a new Rupert↔spoke link needs that project's admin SA in Vercel env (missing = 503) · Eastern-time everywhere (never UTC toISOString().split()).
Kanban across all apps. Synced to your account, so add on your phone and it's here on the laptop. Use Copy as Markdown to hand the board to an AI session.