Testing domain -- L0¶
Purpose¶
Posthaste tests are executable behavior contracts. They prove that provider observations, local reconciliation, runtime view updates, API invalidation, and frontend state converge to the expected user-visible model. A test must assert expected behavior, not snapshot a current implementation quirk.
This domain exists because Posthaste's hardest bugs — missed view updates, over-broad cache invalidation, sync-convergence races, provider projection mismatches — are difficult to reproduce by hand. A disciplined, layered harness with shared support code is the only economical way to catch them before release and to let coding agents verify fixes reliably. It supersedes the legacy testing-spec framing.
Coverage is by behavior boundary, not file count¶
Tests are organized by the boundary whose behavior they prove, not by source file. The boundaries, from the network edge inward:
- Provider observation — raw remote observations become the canonical local
model (Gmail labels as mailboxes, shared
Message-IDcopies, MODSEQ/VANISHED, JMAPcannotCalculateChanges). - Store reconciliation —
SyncBatchapplication is atomic, account-scoped, projection-safe, and event-complete. - Runtime view update — mutations and sync deltas produce correct, minimal view-diffs; no missed recompute, no over-broad invalidation.
- API boundary — error mapping, pagination, SSE replay, mutation responses.
- Frontend state — React Query invalidation, optimistic visibility, surface routing, overlay stacking.
- Live-provider parity — JMAP and IMAP projections agree on the same seeded real server fixture.
The detailed observation matrix and per-boundary rules live in L1.
Layering stakes¶
Each layer catches a different bug class and costs a different amount to run. Skipping a layer leaves a blind spot; running only the expensive layer is too slow to iterate on.
- Unit/integration contracts (Rust) prove domain, store, sync, API logic.
- Frontend logic contracts (Bun) prove cache invalidation, routing, adapters.
- Built-web automation (Playwright) proves the rendered client against a lab daemon.
- Linux Tauri automation proves the real desktop app via a feature-gated bridge.
- Agent-driven full-app scenarios (planned) prove multi-step, multi-message
convergence through
posthastectland declarative fixtures.
The shared posthaste-testkit crate standardizes the harness, fixtures, and
assertions across the lower layers so each test catches wide and reports
clearly. Its contract is L1; runtime-in-harness, the settlement
recorder, and declarative TOML fixtures have landed — the remaining forward
contract (posthastectl headless driver) is in
docs/eph/PLAN-L2-testkit-roadmap.md.
Assertions¶
| ID | Sev. | Assertion |
|---|---|---|
| behavior-not-current-code | MUST | Tests assert expected protocol/domain behavior, not implementation quirks |
| layered-coverage | MUST | Coverage spans provider, store, runtime, API, frontend, and parity boundaries rather than one layer |
| shared-testkit | MUST | Lower-layer tests share harness, fixtures, and assertions through posthaste-testkit instead of ad-hoc per-crate copies |
| red-first | SHOULD | New behavior coverage is developed red-first or justified as already covered |
| spec-linked-coverage | SHOULD | Tests for SPECial assertions link to the assertion with a spec: comment |