SERVICE MATCHES API CONTRACT¶
Cross-track schema: Meridian (producer) ↔ LastVet dashboard / iOS (consumer)¶
Confidential — Last 1 Enterprises trade secret
Status: LOCKED Gate 2.2 (2026-09-10). Agree here before deep UI or deep matcher build.
Endpoint: GET /api/veteran/me/service-matches
Owners: Meridian track produces match payloads; last.vet-api serves this route; LastVet iOS Service Matches section consumes it.
Naming¶
| Name | Role |
|---|---|
| Matcher-0 | Meridian net-new care matcher (intelligence) |
| Service Matches | Dashboard / iOS presentation of matcher output |
m1_eligible |
Clinical safety go-live for any live Meridian intelligence |
Shared safety foundation (Gate 2.1)¶
Crisis gate and safety-refusal gate fire on all Meridian surfaces, including matcher interactions. The matcher is not a bypass. A veteran asking about a match, discussing care, or typing into a matcher-adjacent surface who expresses crisis or solicits diagnosis hits the same deterministic short-circuits as the explainer.
Arc invariants (structural — in the type system)¶
- Matcher only attaches provider-authored request templates. It never synthesizes grant scope.
- Every match carries
requiresVeteranApproval: true(literal; not optional). - No API path creates or activates a grant from matcher output without an explicit veteran approve/edit step.
- When
m1_eligibleis false, responsemodeis"preview"with honest copy (not fake live matches).
Response schema (ServiceMatchesResponse)¶
{
"schemaVersion": "1.0.0",
"mode": "preview",
"m1Eligible": false,
"previewNotice": "SYNTHETIC PREVIEW: Matching machinery on synthetic data. Not real veterans matched. Live Meridian matching waits on clinical safety sign-off.",
"matches": [
{
"matchId": "sm-synth-001",
"rank": 1,
"provider": {
"providerId": "00000000-0000-4000-8000-000000000101",
"displayName": "Harbor Mental Health (synthetic)",
"orgName": "Harbor MH Collaborative",
"specialty": "mental_health",
"region": "San Diego, CA"
},
"rationale": {
"summary": "Ranked for mental_health by signal strength. record signals cite cond-ptsd, obs-phq9 (score=8.0).",
"needTags": ["mental_health", "outpatient"],
"citationElementIds": ["cond-ptsd", "obs-phq9", "med-001", "need-declared-mental_health"]
},
"requestTemplate": {
"templateId": "tmpl-harbor-mh-min-v1",
"providerId": "00000000-0000-4000-8000-000000000101",
"label": "Harbor MH minimum coordination share",
"categories": ["demographics", "mental_health", "medications", "coordination_notes"],
"accessLevel": "read",
"durationDays": 90,
"purpose": "care_coordination",
"authoredBy": "provider",
"scopeSource": "provider_template"
},
"requiresVeteranApproval": true,
"shareStatus": "not_shared"
}
]
}
Field rules¶
| Field | Rule |
|---|---|
mode |
"preview" | "live". "live" only when m1Eligible === true and PHI hosting allows. |
requiresVeteranApproval |
Always true. Consumer and producer types must enforce this. |
requestTemplate.authoredBy |
Always "provider". |
requestTemplate.scopeSource |
Always "provider_template". Never "meridian_inferred" or similar. |
requestTemplate.categories |
Must be valid LastVet consent category ids (see CONSENT_CATEGORIES). |
shareStatus |
"not_shared" | "pending_veteran" | "shared" | "declined". Matcher GET never sets "shared". |
rationale.citationElementIds |
Optional additive (Deepen D2). Grant-visible element ids and need-declared-* supporting the summary. |
Ranking note: Matches are produced by a deterministic signal-strength ranker over a provider catalog (not LLM-selected). Lane-priority policy (clinical) is not encoded in the ranker; see Meridian MATCHER_LANE_PRIORITY.md.
Explicit non-endpoints (Gate 2.3)¶
- No
POST /veteran/me/service-matches/:id/sharethat creates a grant in one shot without a veteran-edited scope body. - Future approve flow (separate gate): veteran submits approved/edited categories → consent engine creates grant. Matcher never authors the categories.
Auth¶
Same as other /api/veteran/me/* routes: veteran session (authMiddleware + veteran identity).
Implementation pointers¶
| Artifact | Path |
|---|---|
| This contract | lastvet-gates/docs/architecture/SERVICE_MATCHES_API_CONTRACT.md |
| Zod / TS types | last.vet-api/src/contracts/service-matches.ts |
| Python types | last1-meridian/src/meridian/matcher/types.py |
| Spec lock | last1-meridian/MERIDIAN_SPEC.md (Matcher-0 / Arc) |
| iOS consumer | OperatingSystemShellView Service Matches section (empty shell today) |
Dashboard / iOS agents: consume this schema; do not invent parallel field names.