Personal harness — your phone, your bot
The iMessage + WhatsApp bridges run on your own Mac and answer as you. The personal harness is the whole stack behind that: it senses what's happening, remembers you and the people you talk to across every channel, reasons about what to do, makes the reply sound like you, and then acts. The pipelines are owner-only, and your location is shared with a contact only under per-contact rules you set.
The harness, end to end
Five layers, top to bottom, fed by your surfaces and grounded by the control plane. Every cell links to the section that explains it. The memory layer (amber) is the cross-app store — one canonical identity and one timeline that every other layer reads from and writes to.
- Owner-only enforcement
- Location-leak guard
- Kill switch
- Local 0600 / path-restricted
- Secrets never logged
LANTERN_DRAFT_CONFIRM on iMessage, LANTERN_DRAFT_HIGH_STAKES on WhatsApp), concierge nudges (LANTERN_CONCIERGE), the four bridge loops, the immigration sentinel, the Mac app-usage signal (LANTERN_MAC_USAGE), voice cloning (LANTERN_VOICE_CLONE), the model-router cutover and RLS enforcement. Each is labeled where it appears below.Your agents
Sixteen agents make up the personal suite across three execution models. The scheduled ones are seeded for the dev tenant when the control plane starts with dev seeding on; elsewhere you create them with POST /v1/agents/loop. Ten are owner-facing — they nudge or brief you in your self-chat and never touch your contacts. Only the two assistant agents reply to contacts as you. Four bridge-signal agents react to device signals on your Mac. This distinction matters for trust: owner-facing agents can be aggressive and proactive; assistant agents carry the weight of impersonation.
| Agent | What it does | Runs | You see it | Touches contacts? |
|---|---|---|---|---|
| concierge | Captures tasks, researches how, nudges with 1-click actions — reply / snooze / done. | 45m cron | self-chat (nudges need LANTERN_CONCIERGE=on) | No |
| care-coordinator | Health email → meds/doctors/appts records + refill/appt reminders + coaching. | every 6h | /personal Health | No |
| garage | Vehicle service/insurance/DMV email → records + renewal reminders. | every 6h | /personal Vehicle | No |
| upskill | Job/learning email → skill records + career coaching nudges. | every 6h | /personal Career | No |
| travel-concierge | Flights/hotels → itinerary records + check-in reminders. | every 6h | /personal Travel | No |
| household | Utilities/warranties/services → records + renewal reminders. | every 6h | /personal Home | No |
| financial-sentinel | Watches bills for price hikes → review reminders. Never moves money. | daily 8am | /personal Finance | No |
| relationship-keeper | Finds people gone quiet (21d+) → reach-out reminders + draft in your voice. | weekly (Mon 9am) | self-chat | No — you do the outreach |
| inbox-triage | Every 45 min reads Gmail, classifies each message action/FYI/noise, and queues a one-tap draft for anything needing a reply. | 45m | self-chat · needs Gmail | No — you confirm every send |
| ai-radar | Every 5 min polls AI lab, people, coding-tool and aggregator feeds, dedupes by URL, and has the LLM rank the new items. Pull anytime with "news". | 5m | self-chat ("news") | No |
| commute-copilot | Driving signal → hands-free task surface + parked recap. | bridge interval | self-chat · LANTERN_COMMUTE=on | No |
| energy-guardian | Short sleep → offer to lighten the day's load. | bridge interval | self-chat · LANTERN_ENERGY=on | No |
| health-coach | Steps/sleep/workout nudges toward a daily goal. | bridge interval | self-chat · LANTERN_HEALTH=on | No |
| focus-guardian | Holds non-urgent nudges during Focus mode, recaps after. | bridge interval | self-chat · LANTERN_FOCUS=on | No |
| whatsapp-assistant | Auto-replies to your WhatsApp contacts in your voice. | reactive | replies to contacts | Yes — talks to contacts as you |
| imessage-assistant | Auto-replies to your iMessage contacts in your voice. | reactive | replies to contacts | Yes — talks to contacts as you |
How each agent loops
Each diagram shows the stages of one agent's cycle — solid arrows are the forward flow; the dashed arc loops from the last stage back to the first. Agents are grouped by how they execute. The two contact-facing agents are rose-highlighted because they reply as you to real people — they carry the full weight of impersonation.
Scheduled — runs as a Lantern agent on a cron timer
These agents are created via POST /v1/agents and run on the Lantern platform on a cron schedule, with runs, cost and history in the dashboard like any other agent. Gmail-reading agents need the Gmail connector installed. Concierge nudges to your self-chat stay off until LANTERN_CONCIERGE=on.
runs: every 45m · you see it: self-chat (reply / snooze / done)
runs: every 6h · you see it: /personal Health · needs Gmail
runs: every 6h · you see it: /personal Vehicle · needs Gmail
runs: every 6h · you see it: /personal Career · needs Gmail
runs: every 6h · you see it: /personal Travel · needs Gmail
runs: every 6h · you see it: /personal Home · needs Gmail
runs: daily 8am · you see it: /personal Finance · needs Gmail
runs: weekly (Mon 9am) · you see it: self-chat
runs: every 45m · you see it: self-chat · needs Gmail
runs: every 5m · you see it: "news" in self-chat
Bridge loops — runs on your Mac, driven by device signals
These agents run inside the bridge process at a short interval and react to iPhone signals (driving state, sleep data, step count, Focus mode). All four are off by default. Set the env var and the loop activates on the next bridge restart. If the signal threshold isn't met, they send nothing.
runs: bridge interval · you see it: self-chat · LANTERN_COMMUTE=on
runs: bridge interval · you see it: self-chat · LANTERN_ENERGY=on
runs: bridge interval · you see it: self-chat · LANTERN_HEALTH=on
runs: bridge interval · you see it: self-chat · LANTERN_FOCUS=on
Reactive — fires on every inbound message
The two assistant agents sit in the bridge's message handler and fire on every inbound message from a contact. They carry the full weight of impersonation — everything in the harness (owner voice, bot-tell guards, pacing, draft-and-confirm, claim verifier) exists to keep them indistinguishable from you.
fires: per inbound · you see it: replies to contacts
fires: per inbound · you see it: replies to contacts
L1 · Sense — signals & ingestion
The harness starts from real-world context. iPhone automations (geofences, Focus, the Action Button, NFC, and CarPlay / Bluetooth → driving) fire Shortcuts that POST one small signal (location, focus, device, health, media) to the control plane through a private tunnel; the recipe uses Tailscale Serve. Mac app usage is a separate signal, off unless LANTERN_MAC_USAGE=on, and it is distilled to one summary line for your self-chat only. Inbound email is classified into life-events, and every inbound message on every channel is a signal too. The bridge reads the signals file fresh on every owner turn, in front of the LLM, so a signal that just landed is already in context with zero polling lag.
The phone-trigger flow in detail — triggers, the token-gated /v1/signals hop over Tailscale, and the on-demand read:
Each trigger is a one-line iOS Personal Automation wired to a signed Shortcut. Generate the whole set with one command — scripts/iphone/app-context/generate-signals.sh writes 13 ready-to-import shortcuts to your Desktop (the signal token is baked in, so they're never committed). Full recipe + trigger table: RICH-SIGNALS.md; remote-access setup in REMOTE-ACCESS.md.
L2 · Remember — cross-app memory & identity
This is how the harness stores cross-app stuff. The person graph resolves any (channel, handle) — an iMessage address, a WhatsApp JID, an email, a phone number for voice — to a single canonical person, so what you learned about someone on WhatsApp is there when they email or call. On top of that identity sit two recall indices: episodic memory (a rolling 14-day log of date · topic · outcome per contact) and a 7-day topic index that surfaces what other threads said about the same topic, so cross-thread context is available without ever volunteering it.
The owner profile — your facts, per-contact relationship rules, and the style lessons the 👎 flywheel mines — is injected as ground truth into every reply. Presence is a live cross-bridge view of whether you're reachable, and the life-events ledger records classified bills, deliveries, travel, and fraud alerts so the dashboard can show a feed and per-category trust toggles. Storage is split: local 0600 JSONL on the Mac for the most personal signals (the episode, topic and dislike stores are also AES-256-GCM encrypted) and control-plane Postgres for the tenant-scoped person graph, memory events and life-events. Row-level security policies cover those tables; they are enforced once LANTERN_RLS_ENFORCE=1, which is off by default. Because both channels write the same person and the same timeline, a fact learned on one channel is recalled on the other for the same canonical person.
Life-event engine
Inbound email and messages are classified into typed life-events: bill, delivery, appointment, fraud_alert, otp, travel, receipt, promo. Each event lands in the life_events table and is routed by your per-category trust toggle: auto, ask (default) or off. Endpoints: POST /v1/life-events, GET /v1/life-events (feed, newest-first), GET /v1/life-events/prefs, PUT /v1/life-events/prefs. Deduped on (tenant, idempotencyKey).
Immigration sentinel
Off by default; LANTERN_IMMIGRATION_SENTINEL=1 turns it on. The sentinel reasons over the family's immigration PDFs and arriving USCIS / attorney email to surface derived deadlines that nobody typed in — EAD/AP expiry, I-485 windows, biometrics / RFE clocks. The LLM is capability-addressed (never a hardcoded vendor), doc and mail PII are never logged, and a deadline is dropped unless the LLM grounds it in a non-blank source_ref with confidence ≥ 0.6. Endpoints: POST /v1/immigration/scan, GET /v1/immigration/deadlines. Unset means the scan is inert and endpoints return {"enabled":false}.
L3 · Reason — decisioning & orchestration
With context and memory in hand, the harness decides what to do. The life-event engine classifies inbound into typed events and extracts their fields; the auto-act ladder routes each one by your per-category trust setting — auto (just do it), ask (one-tap confirm), or off. The availability concierge turns live presence plus your calendar into truthful replies for contacts who ask if you're around, while anticipation fires proactive nudges to your self-chat for pre-meetings, anniversaries, overdue replies, and open commitments. When a meeting is in play, scheduling can propose, hold, and confirm a concrete time and book it.
L4 · Sound like you — persona & authenticity
A correct reply still has to sound like you. Owner-voice is mined from your real sent messages, and a language & dialect modality keeps the bot in your attested forms — never invented word-forms. The last pass before every send is the bot-tell guards: they suppress drafts that use customer-service stock phrases, leak reasoning, or deny your biographical facts, and trigger a regeneration instead of staying silent. Pacing replays your real per-contact reply latency with typing indicators. The claim verifier rewrites any “I did X” the bridge can't back up into intent form. Draft-and-confirm, which holds low-confidence replies for your approval, is off by default.
Two gates hold a reply for you and never send it: the commitment gate (replies that promise money or an action, or answer a request for money, in any language) and the grounding gate (a specific date for your own plans, a contradiction of the contact about your plans, an outcome only you could confirm, or a celebratory reply to bad news). Each runs an LLM judge plus a deterministic backstop, so an LLM outage cannot let one through.
L5 · Act — actions & delivery
Finally the harness follows through. Reply send delivers the paced message on the right channel (with an SMS/RCS fallback when an iMessage send fails). Mac actions create Calendar events, Notes, and Mail via locale-safe AppleScript — only after you confirm. Connectors (Gmail, Calendar, and the rest of the 17) reach your other systems through the control plane, and voice calls place outbound calls through the Twilio connector when a task needs a phone, not a text.
Safety & privacy — the rail beside every layer
Privacy isn't a layer; it runs alongside all of them. Owner-only enforcement means the doc, action, and command pipelines fire only for the owner — DMs from non-owner contacts never reach them. The availability concierge answers “are you around?” from presence and calendar and does not volunteer a place; per-contact disclosure rules decide what a contact may learn. The kill switch makes the bridge ignore all inbound until you release it; mute only stops sends (replies are drafted to you instead). The most personal stores are local 0600 and path-restricted, and secrets never appear in logs, traces, or run state. See Security for the full model.
Privacy recap
- Device signals are appended to a mode
0600JSONL file on the host running the control plane (your Mac in the default setup). - The composite summary grounds your own self-chat — the bot never volunteers it and never reveals it to a contact.
- The token gates the endpoint; keep it server-side only.
- Turn it off any time:
LANTERN_IPHONE_SIGNALS=offon the bridge, or unsetLANTERN_SIGNAL_TOKENon the receiver.