Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

proef — documentation index

proef (Dutch: test, trial — and tasting) is a declarative, modular, multi-engine end-to-end test runner, mostly Rust. Tests are Gherkin .feature files in business prose; macro packs bind the prose to executable steps; a pluggable engine runs each step batch — embedded Hurl for API testing (the seam admits future engines; none are scheduled).

This folder is the project corpus: the product requirements, the decision log, the normative technical spec, the milestone plan, and the testing strategy. Written 2026-07-28 from a validated research round (a working spike ran 5/5 scenarios green under both a prototype native runner and stock hurl 8.0.1 on identical generated artifacts); implementation has since delivered milestones M0–M5 and everything after them — through v0.19.0 (the 0.18 survey waves, then the gates that could not see what they covered). Only M6 (a second engine) is unscheduled. The repo-root CLAUDE.md carries the live status. This corpus is also published as a website: https://emrecdr.github.io/proef/.

Reading order

#DocumentWhat it answersAudience
0WRITING-SCENARIOS.mdWrite prose against a vocabulary somebody else maintains: see the sentences, the dry-run loop, the two errors you will hitP1 test authors
0GETTING-STARTED.mdYour first suite in ten minutes — including the packs behind itP2 pack maintainers
0AUTHORING.mdThe pack/feature reference from the author’s seatP2 pack maintainers
0EDITORS.mdWiring proef lsp into Neovim/Helix/Emacs for live diagnostics, jump-to-macro, completionP1/P2, whoever sets up the editor
0TROUBLESHOOTING.mdExit codes, glyphs, frequent failures, digging into runseveryone
0CONFIG.mdEvery proef.toml key with defaultsP2 pack maintainers
0DIAGNOSTICS.mdThe greppable index of every diagnostic codeP2 pack maintainers
0EVENTS.mdThe events.jsonl wire schema for CI consumersCI engineers
1PRD.mdWhat are we building, for whom, and how do we know it works?everyone
2adr/ — ADR-0001 onwardWhy is it built this way? Each decision, alternatives, consequencesengineers
3TECH-SPEC.mdHow exactly is it built? Types, pipeline, schemas, verified seam factsimplementers
4IMPLEMENTATION-PLAN.mdIn what order, with what acceptance criteria? M0–M6 task breakdown, risks, runbooksimplementers
5TESTING-STRATEGY.mdHow is every layer verified?implementers
—IMPROVEMENT-PLAN.mdPost-M5 competitive review: the feature roadmap, each item carrying a Status column (14 of 16 shipped)maintainers
—OPEN-FINDINGS.mdThe worklist. Every open defect and gap, whichever review found it, plus what shipped against eachmaintainers
—RELEASING.mdVersioning policy and the release runbookmaintainers
—CONTRIBUTING.mdSetup, gates, and the rules that are easy to trip overcontributors
—SECURITY.mdThreat model and vulnerability reportingeveryone
—CHANGELOG.mdPer-release change log (SemVer)everyone
—../CLAUDE.mdRepo-root guidance for Claude Code: constraints, seam facts, commands, statuscoding agents

Decision log (ADR index)

ADRDecisionStatus
0001Embed hurl’s crates in-process as the API engineAccepted
0002Multi-engine core: EngineFactory/EngineSession seam, step-kind routing, batchingAccepted
0003Exact pins + thin zero-diff fork as patch vehicle + upgrade canaryAccepted
0004Packs = YAML skeleton + embedded raw Hurl blocksAccepted
0005${…} author-time / {{…}} run-time variables; World; secretsAccepted
0006Engine traits are sync + dyn; no async machinery in v1Accepted
0007Cooperative cancellation at batch boundaries + budgets (hurl has none)Accepted
0008Serde event enum = run record; decorator reporter stack; libtest-mimic modeAccepted
0009User/TestFailure/System → exit 2/1/3; miette at the CLI edgeAccepted
0010Emitted .hurl artifacts are the executed input (same bytes) + sidecarsAccepted
0011Fixture server is synchronous tiny_http, not axum (tokio-runtime ban)Accepted
0012Project config & environments in proef.toml ([url]/[vars]/[env.*], --env, deep-merge)Accepted
0013Typed macro parameters (params name→type map; best-effort literal-args lint)Proposed (defer)
0014Suite-level setup/teardown ([run] setup/teardown features, CLI-edge orchestration)Accepted
0015Injected run-relative timestamps + worker id (sink-stamped, sans-IO core) for the HTML timelineAccepted
0016OpenAPI → suite generator: one-shot seed allowed under a bright line; oracle/drift mode permanently rejectedProposed (defer)
0017proef lsp language server: sync lsp-server, whole-suite wholesale recompute, injectable-provider + collect-all front-end refactorAccepted
0018Named hurl fragments: ref: as a second macro body form, # @proef <name> in real .hurl files, explicit bind: scopesAccepted
0019Reserved tags and the authored skip: @skip[:reason] at the CLI edge, reasons in every sink, authored-vs-mechanical split for --rerun, quarantine aligned in JUnitAccepted
0020Run metadata is explicit-injection-only: --meta/[meta]/[env.<name>.meta], run_started gains env/metadata/shuffled, harvested-vs-handed-over is the boundaryAccepted
0021Run discovery and rotation are separate questions: a directory is a record because it holds one, rotation still deletes only uuid-named dirs, ordering follows the uuid-v7 timestamp, then mtimeAccepted

Naming & identifiers

Project/binary proef · crates proef-core, proef-engine-hurl, proef-cli, proef-fixture, proef-harness, proef-lsp · run records .proef-runs/ · persistent World .proef-state.json · config proef.toml. The crates.io names proef, proef-core, proef-engine-hurl, and proef-lsp are published and owned.

Provenance

Grounded in two verified sources: (1) hurl master (Orange-OpenSource) — source-level verification of every library seam used, with file:line citations in TECH-SPEC §5; (2) a working spike proving the front end and artifact contract end to end (the spike predates this repo). Ecosystem practices are drawn from cargo-nextest, cucumber-rs, sqlx, rustls, probe-rs, and current (2026) Rust guidance.