Backend¶
GiveCare's current gc-sms backend is a compact v2 Convex service for SMS
support. Current-tense architecture claims should use the v2 convex/ and
src/ files first1.
Current v2 runtime
The active backend contract is the V2 convex/ and src/ runtime. The live
system is best read as a harness-owned SMS turn pipeline with a compact Convex
schema23.
What the backend owns¶
Today the backend owns eight broad kinds of state and behavior1:
- Caregiver identity, consent, and attribution — phone identity, org/sponsor attribution, consent timestamps, phase, loop stage, referrals, signup attempts, and public endpoint throttles
- Message, delivery, and outreach ledgers — inbound/outbound message records, unknown-number SMS demand, Twilio SIDs, pending outbound rows, async jobs, and outbound cadence dedupe
- Care memory — namespaced memory facts selected by a flat namespace-priority and recency ranker; the old memory-edge graph path is no longer live
- Assessments and score history — optional BSFC-s handoff, SDOH6, SDOH30, and EMA3 assessment runs, plus materialized score snapshots with component provenance and zone subscores
- Loops and opportunities — caregiver-owned open loops and benefit/resource opportunity candidates with uncertainty preserved
- Safety and review — operational
safetyEvents, human-reviewreviewQueuerows, and crisis lifecycle state - Observability, web demand, and learning signals — per-turn
traces, web events, daily rollups, alert cooldowns, ecosystem signals, knowledge gaps, and public web demand signals - Email and subscribers — unified email list, BSFC-s email staging, send ledger, and suppression list
Core Live Tables¶
| Group | Tables | What they hold |
|---|---|---|
| Identity + signup | caregivers, orgs, referrals, assessmentHandoffs |
phone identity, org isolation, consent, lifecycle state, SHARE codes, and BSFC-s/email-to-SMS handoff evidence |
| Messaging + outreach | messages, unknownInboundSms, jobs, outreachLedger |
inbound/outbound ledger, unknown-number demand, pending outbox rows, async turn queue, proactive-send dedupe, and quiet-hours/cadence skip records |
| Memory | memory |
model-visible and harness-only facts with singleton-key supersession and flat ranking before context/tool use |
| Assessments + score | assessmentRuns, scoreSnapshots |
scored assessment history, current component provenance, GiveCare Score snapshots, and per-zone subscores |
| Loops + opportunities | caregiverLoops, opportunityCandidates |
caregiver-owned open loops and benefit/resource candidates with uncertainty preserved |
| Safety + review | safetyEvents, reviewQueue |
crisis lifecycle records and human-review rows for blocked or unsafe model outputs |
| Observability + web metrics | traces, webEvents, dailyMetrics, alertState, ecosystemSignals, knowledgeGaps, webDemandSignals |
per-turn evaluator decisions, public web telemetry, growth/service rollups, alert cooldown state, cross-system signals, substrate gaps, and search demand |
| Email + subscribers | subscribers, emailSends, emailSuppressions |
unified email list across web surfaces, BSFC-s email result storage, send ledger, and suppression list |
Live Inbound Path¶
flowchart TD
A["Twilio inbound webhook"] --> B["convex/http.ts signature check"]
B --> C["agent.ingestInbound"]
C --> D{"Known caregiver?"}
D -->|No| E["Signup redirect SMS"]
D -->|Yes| F["Persist inbound message"]
F --> G["scheduler.enqueueJob"]
G --> H["scheduler.processDueJobs"]
H --> I["agent.runTurn"]
I --> J["Policy gates"]
J --> K{"Deterministic?"}
K -->|Yes| L["Commit deterministic reply"]
K -->|No| M["Build context + run model tools"]
M --> N["Evaluate reply + effects"]
L --> O["agentDb.commitTurn"]
N --> O
O --> P["Pending outbound message"]
P --> Q["outbound sender + Twilio callback"]
Turn Execution Model¶
The current runtime separates host-owned guarantees from model-owned language and judgment2.
| Layer | Current responsibility |
|---|---|
| Policy gates | STOP/HELP/SHARE, pending consent YES, START, consent gate, crisis detection |
| Context builder | recent messages, durable/volatile memory selection, active assessment/task prompts, quiet-hours cues, and bounded static knowledge/tool access |
| Model/tool path | open-ended support, typed capture tools, lookup/resources/wiki tools, assessment/eligibility tools, proactive turns |
| Judge/evaluator | pre-commit checks for safety language, SMS length, clinical claims, caregiver-first posture, operational next step, tool grounding, and effect validity |
| Commit boundary | pending outbound row, approved memory writes, caregiver profile patch, assessment completion, trace, safety event, job completion |
The practical unit of orchestration is not "a model reply"; it is a committed
turn outcome. convex/agentDb.ts:commitTurn records the outbound message before
Twilio send, applies only approved memory writes, records the trace, optionally
opens a safety event, and marks the job complete. Approved follow-up requests
are enqueued through convex/scheduler.ts after the commit boundary so scheduler
policy remains centralized1.
The current turn host delegates rules that do not need Convex state to pure
modules: memory keys live in src/memoryKeys.ts, normalization and merge
semantics live in src/memory.ts, policy gates live in src/policy.ts,
assessment handling lives in src/turn/assessment.ts, effect validation lives
in src/turn/effectValidation.ts, and reply judgment lives in
src/turn/judge.ts2.
Knowledge Bundles¶
The backend consumes public knowledge from generated static bundles rather than
from a live wiki database. src/wiki.ts fetches the deployed
agent-index.json and powers the wiki tool. src/resources.ts imports
data/resources.json, the bundle projected by gc-wiki/scripts/publish.ts,
and powers the resources tool. This keeps public knowledge ownership in the
wiki while the SMS runtime remains the serving layer1.
Scheduler and Outbox¶
The live scheduler is an async job queue. It claims due jobs, respects outbound
rate limits for non-inbound work, and schedules agent.runTurn for execution.
Outbound SMS uses a transactional outbox pattern: the commit inserts a pending
outbound messages row, convex/outbound.ts sends pending rows, and
convex/outboundDb.ts records Twilio delivery status1.
Related Pages¶
- SMS Journey — current v2 SMS state contract and runtime flow
- Crisis Routing — safety tier logic and crisis precedence