Skip to content

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-ID copies, MODSEQ/VANISHED, JMAP cannotCalculateChanges).
  • Store reconciliationSyncBatch application 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.

  1. Unit/integration contracts (Rust) prove domain, store, sync, API logic.
  2. Frontend logic contracts (Bun) prove cache invalidation, routing, adapters.
  3. Built-web automation (Playwright) proves the rendered client against a lab daemon.
  4. Linux Tauri automation proves the real desktop app via a feature-gated bridge.
  5. Agent-driven full-app scenarios (planned) prove multi-step, multi-message convergence through posthastectl and 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