Meridian Field Services: instructional example, not project evidence
The earn-its-place rationale, stated once: the privacy assessment and the customer audit both need per-flow data-class annotation the architecture's embedded flow view does not carry (assessment[1], audit requirements[2]); the architecture's view is the SOURCE, cited (data flow & privacy[3]).
Level 0: one process, externals at the edges, NO data stores at this level. The single process is a deliberate abstraction, so the node rule binds the BOUNDARY here: everything inside runs in AWS ca-central-1 under the Canada residency rule (PIPEDA + contract clause 13). The arrows still name their fields, because they cross trust boundaries at this level too. Fallback text: the telematics vendor sends vehicle_id, lat, lon and observed_at (RESTRICTED) over HTTPS 443, authenticated by an HMAC-SHA256 signature (SR-021) across PB-1; the legacy scheduler sends the nightly job master (CONFIDENTIAL) over SFTP with key auth, sunset at cutover; the HR directory syncs technician_id, name, skills and status (CONFIDENTIAL); Meridian SSO asserts identity via OIDC code with PKCE; the platform pushes each technician's own assignment (CONFIDENTIAL) to the notification gateway under a vendor API key (SR-027), and anonymized ranking codes only (no identity, no coordinates; INTERNAL) to the model provider under a provider key (SR-014) across PB-2; technician mobiles confirm arrivals and receive only their own assignments.
The stores appear for the first time at level one, and nothing goes deeper. The table owns the facts; the diagram owns the shape.
Level 1: where the node rule binds, because every node here is a real deployed system. The application tier runs dispatch-api, telematics-adapter (fixed at one instance for ordering), dispatch-board, notification-worker, and the embedding hook that runs in-process inside dispatch-api. The data tier holds the dispatch-events SQS queue and one RDS PostgreSQL 16.3 instance, meridian-ops, which contains all four logical stores: positions (RESTRICTED, purged at 30 days), jobs and assignments (CONFIDENTIAL, 7 years), the append-only audit stream (2 years), and the pgvector note index. They are drawn inside that one instance deliberately: four separate boxes would claim four separate systems, and an auditor scopes (and a team budgets) against what the picture claims. Fallback text: the flow list is the annotation table below.
| Flow | Payload: the actual fields | Class (cites) | Protocol · auth | Direction · trigger | Resolves to |
|---|---|---|---|---|---|
| Positions inbound | vehicle_id, lat, lon, observed_at | RESTRICTED (labels[4]) | HTTPS 443 · HMAC-SHA256 + timestamp, 300s window (SR-021) | Vendor → adapter · webhook delivery | INT-1[5] |
| Job master nightly | the nightly job master file | CONFIDENTIAL | SFTP · key auth | Legacy → adapter · the 02:00 timer | INT-3[5] (sunset) |
| Assignment push | assignment_id, technician_id | CONFIDENTIAL | HTTPS 443 · vendor API key (SR-027) | Worker → gateway · assignment.created | INT-2[5] |
| Anonymized ranking codes | ranking codes ONLY; no identity, no coordinates | INTERNAL | HTTPS 443 · provider key (SR-014) · gateway-only | API → model provider · suggestion request | INT-4[5] |
| Roster sync | technician_id, name, skills, status | CONFIDENTIAL | HTTPS 443 · directory sync | HR → API · directory sync | INT-5[5] |
| Auth assertions | identity assertions | n/a | HTTPS 443 · OIDC code + PKCE | SSO → board · sign-in | INT-6[5] |
| Override notes to the index | reason_code, note → 384-dim vector | CONFIDENTIAL worker-conduct | in-process · PostgreSQL 5432 · TLS 1.3 | API → embedding hook · override.recorded | the override.recorded seam[6] |
Every arrow above has a row; every row resolves; the reconciliation ran at generation, zero orphans.
| Crossing | Highest class | Threat model (cross-cited) |
|---|---|---|
| PB-1: vendor → adapter | RESTRICTED | TM-01[7] |
| PB-2: API → model provider | INTERNAL by design: the anonymization happens BEFORE the crossing | TM-04[7] |
| The mobile edge | CONFIDENTIAL (own assignments) | TM-05, TM-06[7] |
| The INT-3 legacy edge | CONFIDENTIAL | Waived with expiry (coverage[7]) |
Reconciliation: these crossings and the threat model's analyzed-or-waived set are THE SAME SET, checked both directions; signed by the security owner.
Sensitive path, narrated for the auditor, a position's life: observed at the vehicle (vendor custody) → crosses PB-1 under signature verification (SR-021[8]) → the adapter validates bounds (VR-01[9]) → the store holds it 30 days (retention rules[4]) → the board renders it band-masked off dispatch surfaces (labels[4]) → the purge hard-deletes on schedule. It never reaches the model provider (the anonymized-code boundary), never enters logs (logging[10]), and never leaves the residency region (data flow & privacy[3]). Handling rules cited at every hop; restated at none.
| Question | Owner | Answer by | Blocks |
|---|---|---|---|
| Does the customer audit's scope include the note-index store (which would add the embedding path to the narrated set)? | N. Duval with the security owner | At the audit scoping call | The narrative's second path only |