hpr_validate/lib.rs
1//! The validation harness: case files, oracle references, metrics and reports.
2//!
3//! **Guide:** [Accuracy][guide-accuracy] gives every validation result, and [Checking a
4//! claim][guide-claim] traces a number to its source, its test and its validation.
5//!
6//! [guide-accuracy]: https://nrdptel.github.io/hpr-sim/accuracy.html
7//! [guide-claim]: https://nrdptel.github.io/hpr-sim/checking-a-claim.html
8//! [lessons]: https://github.com/nrdptel/hpr-sim/blob/main/docs/research/loft-lessons.md
9//! [validation]: https://github.com/nrdptel/hpr-sim/blob/main/docs/VALIDATION.md
10//! [adr-015]: https://github.com/nrdptel/hpr-sim/blob/main/docs/DECISIONS.md#adr-015-the-validation-harness-cases-references-tolerances-and-reports-2026-09-17
11//!
12//! A **case** ([`Case`]) is a TOML file under `validation/cases/`: what to fly, how, and which
13//! metrics to compare against which reference, each with its own tolerance. A **reference**
14//! ([`Reference`]) is a JSON file under `validation/fixtures/`, written by a generator script
15//! under `validation/oracles/`, carrying the oracle's name, the command that produced it and a
16//! source for every value. Running a case gives a [`Comparison`] per metric, and the run gives a
17//! [`Report`] in Markdown and JSON.
18//!
19//! Five [lessons from Loft][lessons], mistakes found in the project that came before hpr-sim, shape
20//! the rules:
21//!
22//! - **[Loft lesson L75][lessons]:** an oracle's inputs come from the case file, never from hpr's
23//! own output.
24//! - **[L76][lessons]:** a reference is never regenerated to make a comparison pass; it moves only
25//! when its generator runs, which is a separate, deliberate step.
26//! - **[L77][lessons]:** every reference value carries provenance, so no number is a hand-written
27//! "stored result".
28//! - **[L78][lessons]:** the cases that must run are locked, so a suite that silently skips one
29//! fails instead of reporting green.
30//! - **[L79][lessons]:** every metric a case reports has a tolerance; nothing is "ungated".
31//!
32//! The method is in [the validation plan][validation], and the design in the decision record
33//! [ADR-015][adr-015], the validation harness.
34
35#![allow(
36 clippy::disallowed_methods,
37 clippy::disallowed_types,
38 reason = "the validation harness reads case and reference files; it is not part of the pure core"
39)]
40
41pub mod case;
42pub mod census;
43pub mod committed;
44pub mod flight_metrics;
45pub mod metrics;
46pub mod report;
47pub mod rocketpy;
48pub mod run;
49pub mod summary;
50
51pub use case::{Case, CaseLock, DragMode, Metric, Tolerance, committed_cases};
52pub use metrics::{Measured, Reference, ReferenceValue};
53pub use report::{Comparison, Gap, NotReproduced, Report, Source, Verdict};
54pub use run::{CaseRun, ValidateError, run_case, run_lock};
55
56pub mod openrocket;
57pub mod real_flight;
58#[cfg(test)]
59mod tests;