Test Cases and Acceptance Criteria¶
- Date: 2026-08-02
- Status: Approved (2026-08-02, ADR-0009)
These cases are the Phase 4 unit/contract-test targets and map to the Phase 5 validation scenarios (Roadmap.md). Acceptance = every case below passes with the documented output, including the negative (privacy) cases.
Test cases¶
| # | Scenario | Input state | Expected output |
|---|---|---|---|
| 1 | No resolved route yet | stdin payload present; transcript has no assistant message | auto/cheap (requested label) |
| 2 | Normal resolved route | last assistant message message.model = "big-pickle"; mapping has big-pickle → opencode |
opencode/big-pickle |
| 3 | Provider unknown | last assistant message model not in the mapping; SQLite off | big-pickle (model-only) |
| 4 | Schema drift (top-level model) |
assistant message has top-level model but no message.model |
resolves from top-level model (ADR-0008) |
| 5 | Malformed transcript line | last line is invalid JSON; previous line is a valid assistant message | skips the bad line; uses the previous assistant message |
| 6 | Transcript missing/unreadable | transcript_path points to a nonexistent/unreadable file |
auto/cheap; no crash |
| 7 | Stale route | last assistant message timestamp older than the 5-minute threshold | opencode/big-pickle [stale] |
| 8 | Fresh route past model change | consecutive assistant messages with different models | displays the latest one (re-read per event) |
| 9 | Long model string | provider/model exceeds 32 chars |
truncated route segment with …, provider prefix kept |
| 10 | Unparseable stdin | stdin is not JSON | empty string; exit 0 |
| 11 | Empty stdin | no line written | empty string |
| 12 | SQLite enrichment enabled but unavailable | Docker down / no matching call_logs row |
model-only display; no crash |
| 13 | Missing context fields | context_window absent |
only the present segments render; others omitted |
| 14 | Negative: no secrets in output | transcript contains the session prompt, tokens, and request bodies | none of that content appears in the output |
| 15 | Negative: no writes | statusline runs against the real transcript and volume | neither file is modified (compare checksums/hashes) |
| 16 | Classifier gating | Bash-gated environment (auto/cheap classifier down) | default path (file reads) still renders; no dependency on gated commands |
Acceptance criteria¶
- Correctness: the route segment equals the last assistant message's resolved model (+ provider when known), for all cases 1–9.
- Determinism: identical inputs produce byte-identical output (case 2 repeated N times).
- Latency: the default path (transcript + mapping) completes in < 50 ms wall time on the target machine (Phase 2 measured sub-ms reads).
- Boundedness: output is always a single line of bounded length (case 9).
- Privacy: cases 14–15 pass — no sensitive content in output, no writes.
- Resilience: cases 5–7, 11–13, 16 never crash or emit an error line.
- Cancellation tolerance: the script can be killed at any point without corrupting any file (it never writes).
Phase 5 scenario mapping¶
| Phase 5 scenario | Covered by |
|---|---|
| Direct model selection | Cases 2, 8 |
| Automatic routing | Cases 2, 8, 12 |
| Provider/model changes during a session | Case 8 |
| Missing, malformed, or delayed metadata | Cases 1, 4, 5, 6, 13 |
| OmniRoute unavailable | Cases 6, 12, 16 |
| Slow or failing statusline execution | Cases 10, 11, 16 |
| Different terminal widths / display environments | Case 9 + truncation rules in 01-display-requirements.md |
Gate¶
Phase 3 is approved when this case list and the acceptance criteria are reviewed and recorded in Decisions.md (Phase 3 ADR). Phase 4 then implements against these cases; Phase 5 validates the real scenarios.