Meridian Field Services: instructional example, not project evidence
Every case cites its technique; every row documents expected behavior, a specification, not a test step. The empty set breaks first.
| Id | Technique | Case → expected behavior | Severity | Disposition | Traces |
|---|---|---|---|---|---|
| EC-01 | zero/one/many | A ready job has ZERO eligible technicians → the panel states the empty result and its reason (no eligible match, not a failure), the full list opens, the job flags for exception review (US-3[1]) | high · possible | handle · A. Reyes | FR-002[2] · tests register |
| EC-02 | BVA · 4 points | Position.observed_at at the 300-s skew bound (299 / 300 / 301 / far-future) → 300 accepted, 301 dropped and counted (VR-02[3]) | moderate · possible | handle · E. Sandoval | VR-02 · tests register |
| EC-03 | state corner · INVALID | A technician confirms an assignment already reassigned away → rejection with the stale_version contract and a board notice (error registry[4]) | moderate · likely | handle · E. Sandoval | FR-004 |
| EC-04 | CRUD × many | Deleting a job with active assignments → forbidden; archive is the only exit while assignments exist (lifecycle[5]) | moderate · rare | handle · A. Reyes | FR-009 |
| EC-06 | equivalence partition | A job addressed outside any hub's service polygon → intake accepts and routes to manual review | low · rare | accept-gap for pilot (rationale: two occurrences/month observed, manual review absorbs it; owner M. Chen; revisit at hub-two) | FR-001 |
The assignment lifecycle earns the matrix (five states × four actions, twenty cells, three forbidden transitions explicit). The matrix surfaced EC-05, shift ends mid-assignment, whose expected behavior was UNDEFINED at analysis. Promoted to an FR revision (the assignment persists and the confirmation window extends into the next shift; FR-016 revision[2]): the analysis records the discovery, the FRD owns the behavior.
| State ↓ · Action → | Assign | Confirm | Override | Complete |
|---|---|---|---|---|
| ready | → assigned | forbidden | forbidden | forbidden |
| assigned | re-assign (reason) | → confirmed | → assigned′ | forbidden |
| confirmed | EC-03 → stale_version | idempotent | → assigned′ (notice) | → complete |
| on-hold | forbidden (BR-04 clock paused) | n/a | n/a | n/a |
| complete | terminal: EC-05's shift-end row promoted to FR-016 | |||
Four parts, every row (what fails, how detected, what the user experiences, recovery), citing designed behavior, never inventing it. Malicious faces live in the threat model.
| Id | What fails | Detected by | User experiences | Recovery | Malicious face |
|---|---|---|---|---|---|
| F-01 | Position feed stops | The gap indicator (INT-1[6]) | Stale-marked positions; manual assignment proceeds | The feed-loss drill (DV-5[7]) | TM-01[8] (poisoned feed) |
| F-02 | Suggestion path degrades | The 2-s boundary timer (FLW-01[9]) | Full list with a degradation notice (suggestions_unavailable[4]) | Automatic on next request | n/a |
| F-03 | Notification gateway fails | Delivery-failure counts | Technician silence: the 10-min confirmation timer catches it, re-notifies, then flags (exception paths[9]) | Manual call tree at 30 min | TM-06[8] (flooding) |
| F-04 | Nightly file truncated: the ISS-2 case | Checksum | None (quarantined before load) | Quarantine-and-rerun (RSK-08[10], ISS-2[11]) | n/a |
Design-time discipline: these rows exist before the race ships. Every row names its window, cites its countermeasure, and specifies what the losing request experiences.
| Id | Pattern | Race window | Countermeasure (cited) | Residual: the loser sees |
|---|---|---|---|---|
| R-01 | double-submit | The assign click retried by the client while the first request is in flight, same job | The Idempotency-Key contract (POST /assignments[4]) | The retry receives the first response (one assignment); signed E. Sandoval |
| R-02 | lost update | Two dispatchers edit the same job between read and save | Optimistic-lock version check (concurrency[5]) | stale_version → re-read (error registry[4]) |
| R-03 | check-then-act | Eligibility checked at suggest time; the technician's shift ends before assign | Eligibility re-checked server-side at assignment write; the suggest-time check is advisory (FR-002[2], BR-01[3]) | validation_failed, with the changed-eligibility reason |
No production-discovered races yet: stated, so the first one arrives into a table that already exists.
The governing posture: degrade before erroring; every row cites its designed degradation.
| Family | Disposition |
|---|---|
| Malformed output | eliminated structurally: constrained output, ranked ids from the eligible set only (ADR-5[12], SR-016[13]); the residual is a schema-valid but empty ranking, which is EC-01's empty-set behavior; one case, one place |
| Latency spike | handle: the 2-s boundary timer degrades to the full list (FLW-01[9]); slow-but-valid responses past the timer are discarded, never late-applied |
| Empty candidate set | handle: distinguished from EC-01; a model returning nothing for an eligible pool is a model FAULT and counts toward the suggestion-quality indicator (RSK-06[10]); a genuinely empty pool is domain truth |
| Hallucination | not applicable · a claim: no free text reaches the board in the constrained design; the eliminating decision cited (ADR-5[12]) |
| Question | Owner | Answer by | Blocks |
|---|---|---|---|
| Does EC-06's accept-gap survive hub-two volumes (the two-per-month observation is Toronto-only)? | M. Chen | At the hub-two go decision | The EC-06 disposition only |