Files
deepseek-harness/docs/rfc/001-property-based-testing.md
T
Tianyi Cui 066f94c7e0 docs: unwrap hard-wrapped Markdown to one line per paragraph
Hard line breaks mid-paragraph make docs harder to edit and diff — a
one-word change reflows and re-diffs the whole paragraph. Reflow all
tracked non-vendor Markdown (plus vendor/AGENTS.md) so each prose
paragraph is a single line; soft-wrapping is the editor's job. Fenced
code, tables, and list structure are preserved (wrapped list items fold
to one line per bullet). Documents the convention in AGENTS.md.
2026-06-13 20:27:04 +08:00

2.1 KiB
Raw Blame History

RFC 001: Property-based testing for protocol-shaped code

Status: proposed

Problem

Example-based tests pin the cases we thought of. The harness's core is protocol-shaped — chunk streams, event logs, schema conversion — where the input space is combinatorial and the interesting bugs live in interleavings nobody wrote an example for (the streamBlocks ordering bug survived 100% line coverage of the happy paths).

Proposal

Adopt fast-check (vitest integration) with generators for our vocabulary:

  • BlockAssembler: arbitrary chunk sequences (valid and malformed — duplicate indices, stragglers after block-end, missing block-start). Invariants: flushReady() + flushRemaining() ≡ blocks() in order; streamBlocks ≡ generate().message.content; memory bounded (partials map size ≤ distinct indices); idempotent re-assembly.
  • Session: arbitrary event logs (seeded generators over SessionEventMap). Invariants: deriveMessages deterministic; replay-from-seed produces identical derivation; seq strictly monotonic; derived history unaffected by non-message events.
  • Schema DSL: arbitrary SchemaSpecs. Invariants: generated JSON Schema's required array equals the required: true keys at every nesting level; conversion is total (never throws); generated args satisfying InferArgs validate against the generated schema (once RFC 005's validator exists — the two RFCs compose).
  • Inbox/loop: arbitrary send/steer/abort schedules against a scripted adapter. Invariants: no message lost (every send/steer appears in the log exactly once), turn numbers strictly increase, status transitions follow idle→running→idle/disposed.

Plan

One tests/properties.spec.ts per package; fast-check as devDependency; numRuns tuned so the suite stays under ~10s locally, with a nightly CI job running 100× the iterations. Failures persist their seed in the report so agents can reproduce deterministically.

Risks

Generator quality determines value — invest in generators that produce realistic-but-adversarial streams, not uniform noise. Property flake from timeouts must be treated as a finding, not retried away.