Overview
Therouting.json file is the authoritative source for phone-to-member mapping. The runtime reads this file on every inbound message to identify the sender, load their profile, and determine their access level.
routing.json Schema
Complete schema with all fields:Top-Level Fields
Unique identifier for this family. Must match the directory name.
Dictionary keyed by phone number (E.164 format). Each value is a member object with role, access_level, and other attributes.
Name of the person receiving care. Used in agent prompts and family context.
Family status:
active, inactive, or archived. Only active families receive messages.Date this family was onboarded (YYYY-MM-DD format).
Human-readable notes about the family setup, onboarding context, or special considerations.
Phone Number Format
Always use E.164 format:- Include country code:
+1for US/Canada - No spaces, dashes, or parentheses
- Example:
+16517037981(not651-703-7981or(651) 703-7981)
The system will NOT recognize phone numbers in any format other than E.164. Formatting errors will cause “Unknown phone” failures.
Member Object Schema
Each phone number maps to a member object:Display name for this member. Used in messages, logs, and agent prompts.
One of:
primary_caregiver— Main coordinatorfamily_caregiver— Family member providing careprofessional_caregiver— Paid professional caregivercommunity_supporter— Friend, neighbor, volunteercare_recipient— Person receiving care
Controls what sections of family.md this member can see:
full— All sections, can approve changesschedule+meds— Schedule, meds, appointments, urgent notesschedule— Schedule and urgent notes onlyprovider— Medical info, meds, appointmentslimited— Basic member and care recipient info only
Whether this member currently receives messages. Set to
false to temporarily disable.Linq Partner API chat UUID. Populated after first message exchange. Used for reliable message routing (preferred over phone number).
Relationship to care recipient (e.g., “grandson”, “neighbor”). Helps agent personalize responses.
Resolution Flow
When an inbound message arrives, the system resolves the sender in this order:chat_id Resolution (Preferred)
The runtime first attempts to match the message’s Why chat_id is preferred:
chat_id by scanning all routing.json files:- Phone numbers can change
- Phone numbers can be shared (family plans)
- chat_id is stable and unique per conversation
Phone Number Fallback
If chat_id resolution fails, fall back to phone number:
Phone resolution works but is less reliable than chat_id. Always populate chat_id after first contact.
chat_id Population
Thechat_id is returned by the Linq Partner API when creating a new chat:
Access Level Enforcement
Theaccess_level field directly controls what sections of family.md the member can see. This is enforced mechanically by runtime/enforcement/role_filter.py:
| Access Level | Visible Sections |
|---|---|
full | All sections (*) |
schedule+meds | members, care_recipient, schedule, medications, appointments, availability, active_issues |
schedule | members, schedule, availability, active_issues |
provider | care_recipient, medications, appointments, members |
limited | members, care_recipient (basic info only) |
Access control happens at two layers: pre-filter (context scoping) and post-check (outbound message scanning). This ensures the agent cannot leak information even if it makes a mistake.
Multi-Family Scanning
The resolution functions scan ALL families to find the matching member:- Multiple families per coordinator (Liban coordinates for Degitu and his mother)
- Professional caregivers working with multiple families
- Community supporters helping multiple neighbors
Known Issues & Workarounds
If you encounter resolution failures:- Verify phone numbers are in E.164 format
- Check that
family_idmatches directory name - Ensure
chat_idis correct (copy from Linq response) - Confirm member’s
activeistrue - Check logs for “Unknown phone” warnings
Testing Phone Resolution
Dry-run the SMS handler to test resolution:Example: Adding Second Family
Same coordinator managing two families: Family 1: kanoWhen a member appears in multiple families, the agent uses conversation context to determine which family is being discussed. Members can say “for Degitu” or “for Roman” to disambiguate.
Best Practices
- Always use E.164 format for phone numbers
- Populate chat_id after first message exchange
- Test resolution with dry-run before going live
- Start with conservative access levels (e.g.,
schedule+medsinstead offull) - Document relationships to help agent personalize responses
- Use descriptive names (“Roman Tefera” better than “Roman”)
- Never share routing.json — it contains PHI (phone numbers + family relationships)
Next Steps
Access Control Deep Dive
Learn how access levels are enforced mechanically and what each role can see.
Member Management
Understand how to add, update, and manage care team members.