Architecture¶
This page describes the internal structure of lrdbench for contributors and advanced users. If you only want to run benchmarks, the Quickstart is the better starting point.
The benchmark loop¶
Public manifest-driven runs follow this orchestration path. The paper's frozen confirmation engine has a separate execution and archive contract, described below.
Manifest (YAML)
│
▼
Record materialisation ← generators | observational sources
│
▼
Optional preprocessing ← independent raw-to-corrected branches
│
▼
Optional ML training ← ml_training block (data-driven estimators only)
│
▼
Estimation ← estimator registry (+ optional third-party plugins)
│
▼
Evaluation ← mode-specific evaluator (ground_truth / stress_test / observational)
│
▼
Leaderboards ← weighted-rank builder
│
▼
Result store staging ← record arrays, metadata and buffered CSV rows
│
▼
Reports ← HTML / CSV / LaTeX / figures
│
▼
Result store finalisation ← raw CSVs, report/model artefacts, plugin provenance
BenchmarkRunner.run() in runner.py wires these public stages together and expects a
validated BenchmarkManifest. The manifest loaders parse and validate YAML or mappings
before calling it. Each stage is implemented by a dedicated module.
If a manifest declares preprocessing.operators, the runner materializes additional corrected records after source materialization and before estimation. These records keep the original truth target, add preprocessing_* stratum fields, and preserve raw_record_id / pair_group_id annotations for raw-vs-corrected comparisons.
In stress mode, each contamination acts on the clean parent independently. Each preprocessing
operator then acts independently on its source record; operators are not a sequential pipeline.
preprocessing.include_raw controls whether the original records remain in the fitting grid.
Preprocessing precedes optional model preparation. preview() also materialises and preprocesses
records, but does not train models, fit estimators or write reports.
Key modules¶
| Module | Responsibility |
|---|---|
cli.main |
Argparse front-end (run, validate, list-*, validate-output). |
manifest |
Load and parse YAML manifests into BenchmarkManifest dataclasses. |
validation |
Validate manifest structure, metric admissibility and truth compatibility. |
runner |
BenchmarkRunner — orchestrates the full loop and collects plugin_provenance. |
execution |
collect_fit_jobs + run_fit_jobs — manages the (record × estimator) grid, optional thread pools, and on-disk estimate caches. |
evaluator |
GroundTruthEvaluator handles both synthetic modes; ObservationalEvaluator handles truth-free records. |
paired_metrics |
Clean/contaminated and raw/corrected comparisons with record pairing. |
preprocessing, ml_training |
Correction operators and optional run-local model preparation. |
leaderboard |
WeightedRankLeaderboardBuilder — composes metric columns into ranked rows. |
reporter |
SimpleHtmlCsvReporter — renders HTML, CSV, LaTeX, and matplotlib figures. |
result_store |
CsvResultStore — persists signal arrays as .npy, selected fields as CSV, and run metadata as JSON/YAML. |
output_contract |
Required file/header checks and the public export schema. |
registries |
Estimator, generator, contamination and preprocessing look-up tables. |
plugin_loader |
Discovery and ordinary import-failure reporting for trusted third-party estimator plugins. |
schema |
Immutable dataclasses (SeriesRecord, EstimateResult, MetricSpec, …) that form the public data contract. |
interfaces |
Abstract base classes (BaseEstimator, BaseGenerator, BaseContamination, …) that define extension points. |
Extension points¶
Adding a generator¶
- Subclass
BaseGeneratorand implementfamily,version, andgenerate(). - Register it in
defaults.build_default_generator_registry(). - Reference the family name in a manifest
source.generator_gridblock.
Adding a contamination operator¶
- Subclass
BaseContaminationand implementname,family,version, andapply(). - Register it in
defaults.build_default_contamination_registry(). - Reference the operator name in a manifest
contamination.operatorsblock.
Adding a preprocessing or correction operator¶
- Subclass
BasePreprocessingand implementname,family,kind,version, andapply(). - Register it in
defaults.build_default_preprocessing_registry(). - Reference the operator name in a manifest
preprocessing.operatorsblock.
Adding an estimator¶
- Subclass
BaseEstimatorand implementspecandfit(). - Register it in
defaults.build_default_estimator_registry()or use the third-party plugin workflow. - Declare it in a manifest
estimatorsblock withname,family,target_estimand, and optionalparams.
For a complete walkthrough, see Adding estimators.
Provenance and reproducibility¶
Every synthetic record carries a ProvenanceRecord with:
- a stable record_id (SHA-1 hash of manifest id, family, parameters, and replicate index),
- the generator seed derived deterministically from the manifest's global_seed,
- timestamps and software version metadata.
Contaminated records extend this history via contamination_history, preserving the clean parent id, operator name, parameters, and severity label. Preprocessed records extend preprocessing_history so empirical corrections and oracle corrections remain auditable.
Every run writes manifest/environment.json containing Python version, platform, package
versions, seed policy, and execution settings. Reproduction also requires matching inputs,
dependencies, estimator/plugin implementations and relevant numerical backend settings.
Run UUIDs, timestamps and measured runtimes vary; byte-identical report directories are not
promised. Public record IDs do not incorporate the global seed, so an ID alone does not
identify signal content across changed seeds. Estimate cache keys include values and record seed.
Confirmation research workflow¶
The research implementation lives under benchmark_experiment/remediation/ and reuses library
statistics while controlling its own frozen design, batching, resampling and storage:
Frozen protocol → compiled design + runtime/source checks
→ run_confirmation.py / confirmation_batch.py
→ confirmation_intervals.py + confirmation_store.py
→ raw chunks and completion evidence
→ confirmation_analysis.py / summarize_confirmation.py + confirmation_audit/
→ audited exports → manuscript_v3 assets → manuscript verification
The confirmation guide links the protocol, execution specification,
archive audit and reproduction commands. This workflow uses its own run identity and paired
resampling rules. Its raw chunks and summary tables are not CsvResultStore exports and must
not be checked or interpreted using only the public CSV contract. Preserve the original producer
revision and runtime lock; changes to current library code do not retroactively change the study.
Output contract¶
The public machine-readable contract is rendered directly in the output specification.
lrdbench validate-output <run_root> checks that:
- all required files exist,
- all required CSV columns are present,
- optional CSVs that exist contain their declared minimum columns.
It does not check a stored contract version, conditional-file eligibility, row values, hashes or scientific completeness. The Python dataclasses are richer than the CSV projection: for example, raw estimate CSVs do not retain full diagnostics or bootstrap draws. See the output specification for these boundaries and the research audit for stronger study-specific checks.
Review schema, implementation, migration notes and contract version together when changing a stable output requirement. Data-dependent columns already permitted by the contract do not require a version change for each run. The contributor checklist maps architecture and workflow changes to documentation and verification responsibilities.