Overview
CareSupport coordinates your care team through text messages, just like texting a trusted assistant. Send a request, ask a question, or update your team—the system handles the routing, context, and follow-through automatically.iMessage-first architecture: CareSupport automatically uses iMessage when available, falling back to RCS or SMS. You get read receipts, typing indicators, and reactions with iMessage, making coordination feel natural.
How It Works
Every message you send goes through a 13-step pipeline that resolves who you are, what you need, and how to respond safely:- Message Flow
- Example Exchange
- Channel Selection
The Complete Pipeline
- Phone Resolution — Your number maps to your family and role
- Context Assembly — Family file, recent conversations, and member profiles load
- Pre-Filter — Context is scoped to your access level (schedule-only members don’t see medication details)
- PHI Audit — Every context load is logged for HIPAA compliance
- AI Generation — The agent generates a response using your filtered context
- Post-Check — Outbound message is scanned for accidental information leakage
- Family File Updates — Any schedule changes or notes are written to
family.mdwith backup - Outreach — Messages to other team members are queued and sent
- PHI Audit — Response delivery is logged
Phone & Chat Resolution
CareSupport needs to know who you are before it can respond. The system uses two identifiers:Phone Number (E.164 format)
Phone Number (E.164 format)
Format:
+16517037981 (country code + 10 digits, no dashes or spaces)How it works:- Every family has a
routing.jsonfile that maps phone numbers to members - When you text CareSupport, your number is looked up across all families
- If found: loads your role, access level, and family context
- If not found: “Sorry, this number isn’t set up to receive messages”
Chat ID (Linq iMessage identifier)
Chat ID (Linq iMessage identifier)
What it is: A UUID that represents a specific iMessage conversation threadWhy it’s better than phone numbers:
- iMessage uses Apple ID as the primary identifier (email or phone)
- A single person might text from multiple devices or phone numbers
- Chat IDs are persistent per conversation—they don’t change
- If message includes
chat_id→ resolve viaresolve_chat_id() - If no
chat_id→ fall back to phone number viaresolve_phone()
Linq Integration
CareSupport uses Linq’s Partner API V3 for all message delivery. Linq acts as the bridge between CareSupport and Apple’s iMessage network.Key Components
- Gateway (linq_gateway.py)
- Inbound Polling (poll_inbound.py)
- Typing Indicators & Reactions
The Linq client handles all message operations:Creating a new chat:Sending to an existing chat:Reacting to messages (iMessage only):
Message Routing Logic
The system determines which channel to use for each message:Outreach: Messaging Other Team Members
When you ask CareSupport to contact someone, the system populatesneeds_outreach in the AI response:
How Outreach Works
How Outreach Works
Your message:AI response (internal structure):What happens next:
- You receive: “I’ll message Solan about Monday.”
- CareSupport immediately sends the outreach message to Solan’s phone
- When Solan replies, you’re notified with his response
needs_outreach is empty, the outreach WILL NOT HAPPEN. The array is the single source of truth.The agent learns from broken promises. If it forgets to populate
needs_outreach, the review system catches it and writes a correction to lessons.md. You’ll see the fix applied in future conversations.Configuration
All SMS/iMessage settings are loaded fromruntime/config.py:
config.py in every script.
Common Patterns
Multi-Member Coordination
Multi-Member Coordination
Scenario: You need someone to take auntie to an appointment, but you’re not sure who’s available.Why this works:
- The agent knows the care team from
family.md - It checks each member’s typical availability (stored in member profiles)
- It messages multiple people in parallel
- It notifies you as soon as someone confirms
Relay Messages Between Members
Relay Messages Between Members
Scenario: A limited-access member needs something, but only the coordinator can approve it.Why relays are necessary:
- Roman has
schedule+medsaccess (can’t directly message Liban) - CareSupport acts as the communication hub
- All messages are logged for family timeline
Handling Unknown Numbers
Handling Unknown Numbers
Scenario: Someone texts CareSupport from a number not in What happens:
routing.json.- Zero PHI is disclosed (HIPAA compliance)
- The attempt is logged to
phi_access.logwith"event": "unknown_number" - No family context is loaded
- No information about the care recipient is shared
Source Reference
The SMS coordination pipeline is implemented inruntime/scripts/sms_handler.py:
- Phone resolution:
sms_handler.py:122-169(resolve_phone, resolve_chat_id, resolve_member) - Context loading:
sms_handler.py:183-231(load_family_context, load_recent_conversations) - Main pipeline:
sms_handler.py:914-1228(handle_sms, _process_message) - Outreach logic: System prompt at
sms_handler.py:386explainsneeds_outreachto the AI - Linq integration:
runtime/scripts/linq_gateway.py(create_chat, send_message, add_reaction) - Inbound polling:
runtime/scripts/poll_inbound.pychecks for new messages every 15 seconds
Want to see the full pipeline? Read
sms_handler.py lines 1-23 for the architectural overview, then follow handle_sms() at line 914 to see each enforcement gate in action.