Meridian Field Services: instructional example, not project evidence
The scope boundary first: what stays OUTSIDE tenancy is recorded like what is inside. Then the model, on all five dimensions.
Scope boundary: the dispatch core (board, assignments, positions) is SINGLE-ORG internal tooling and stays OUTSIDE tenancy; the claim is recorded. Tenancy enters with the phase-two CUSTOMER PORTAL: enterprise customers tracking their own service requests (the contract's portal commitment, schedule 21). Activation trigger: the portal commitment's phase-two date confirmed at the contract renewal (elected regimes[1]). Designed now: the isolation model is the retrofit that hurts most.
| Dimension | Pool (chosen) | Silo | Bridge |
|---|---|---|---|
| Blast radius | Bounded: read-only job status per customer; no write path, no RESTRICTED classes (positions never reach the portal, labels[2]) | Strongest | Per-service mix |
| Cost / tenant | Lowest | Database-per-customer: disproportionate for a read-only status view | Mixed |
| Noisy neighbor | Quotas, §4 | Solved at the data tier | Mixed |
| Compliance | No residency divergence at phase two | n/a | n/a |
| Ops | One schema, one migration run | N of everything | Escape hatch |
Bridge noted: if a customer contract ever demands dedicated storage, that customer silos while the pool remains (portal isolation model[3]).
Tenancy context: customer_id as a verified top-level claim in the portal token (a separate audience from staff SSO, identity model[4]); routing, scoping, and storage all derive from it; RLS policies on every portal-visible table as the backstop; a forgotten WHERE clause must not become a breach (SR-004's isolation face[5]).
Tenancy isolation: the scope boundary under the specificity law. Fallback text: inside the Meridian boundary (AWS ca-central-1, Canada residency, infrastructure register[7]), the DISPATCH CORE stays OUTSIDE tenancy (single-org, no tenant key): staff sign in to dispatch-board over OIDC + PKCE + MFA (SR-001); dispatch-api writes jobs and assignments (CONFIDENTIAL) and positions (RESTRICTED · 30-day purge · never leaving the core) to the RDS instance. The TENANT SCOPE holds the phase-two customer portal (POOL + RLS): enterprise customers reach the portal over HTTPS :443 authenticated by a verified customer_id claim (a separate audience), rate-limited per tier; the portal reads the job-status model WHERE customer_id = caller only, RLS the backstop against a forgotten WHERE. The one projection crossing the boundary carries CONFIDENTIAL job status per customer and never a RESTRICTED position (labels[2]). The tenant zone's control is the RLS policy plus continuous cross-tenant leak tests, not a threat-model row; the portal is phase-two, and its threat-model coverage lands when it ships.
Every onboarding step has its mirror; automation theatre is the named failure mode.
| Onboard | Mirror (offboard) |
|---|---|
| Create the customer tenant record | Archive it |
| Issue the portal identity binding | Revoke and invalidate sessions |
| Scope the job visibility view | Drop the scope |
| Apply the tier's quotas | Release them |
| Stamp the observability tag | Close the cost rollup |
Extraction on exit: the customer's job history as a dated export within 30 days. Deletion: gated on legal hold (retention rules[2]), with the assignment records' seven-year contract retention surviving customer offboarding (the precedence stated); the audit trail survives per the audit rule (audit events[4]).
Consequences of the pool: migrations are ONE run (the pooled advantage, stated); cross-tenant queries are forbidden BY POLICY: the RLS backstop plus the query-review rule that keeps cross-customer joins out of the portal codebase. The road not taken: silo would have meant per-customer migration fan-outs with per-tenant tracking and production-scale rehearsal; the bridge escape hatch inherits that cost only for a silo'd customer. Tenant key: customer_id on every portal-visible row, indexed with the query patterns; the dispatch core carries NO tenant key, the scope boundary made operational. Observability: customer_id stamped at the capture site on portal spans and logs (instrumentation[6]); the per-customer usage rollup rides the infrastructure cost tags (environments[7]) and feeds the tier review.
| Tier | Rate | Concurrency | Export jobs |
|---|---|---|---|
| Standard | 120 req/min | 10 | 1 / day |
| Premium | 300 req/min | 25 | 4 / day |
The limits EXTEND the API contract's rate tiers (limits[8]), one limit system, not two. Enforcement: rate at the gateway; concurrency at the pool budget; export jobs at the scheduler; the throttled customer receives rate_limited with Retry-After (error registry[8]). Priority rule: dispatch traffic outranks portal traffic at the shared read model; the portal degrades first, by design, and says so. Leak-test law: the continuous suite authenticates as customer A and asserts zero visibility of customer B across every portal endpoint; registered by id (register[9]), running per release candidate and nightly; a one-time audit is not the control (cross-tenant rows[5]).
| Question | Owner | Answer by | Blocks |
|---|---|---|---|
| Does schedule 21's portal commitment include customer-side user management (which adds an identity-admin surface to the lifecycle table)? | Product owner with the sponsor | At the contract renewal | The provisioning table's identity rows only |