Define + deliver reproduce semantics for real-data MonteCarlo families (currently synthetic-only) #230
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Carved out of #229 (reproduce over real-data families). The #229 fix reconstructs Sweep/WalkForward members' data sources from the family manifest; MonteCarlo family reproduce still always runs the synthetic seed-driven walk regardless of a real instrument on the manifest.
Not folded into #229 because the semantics are genuinely open: an mc R-bootstrap family's members are seeded resamples of an R-series — "reproduce bit-identically" may mean re-running the bootstrap over the re-derived member R-series (deep) or re-checking the resample aggregation from persisted series (shallow). Decide the contract, then pin it RED-first like #229.
Contract decided (2026-07-10): reproduce for a real-data MonteCarlo family is DEEP — re-derive the member's full chain from the manifest (real data source per the machinery the Sweep/WalkForward fix established, then the base R-series, then the seeded bootstrap resample) and compare metrics bit-identically.
Derivation, three grounds: (1) deep is already the MC reproduce semantic — the current code re-runs the seed-driven walk + bootstrap, merely against a hardcoded synthetic source, so the defect is in the source derivation, not the contract; (2) consistency — Sweep/WalkForward reproduce is a full member re-run from the manifest, and an mc member's primary inputs (base series + seed) re-derive the same way; (3) purpose — reproduce is the determinism audit (same input, same run): the shallow alternative (re-check the resample aggregation from persisted series) only catches storage corruption, not a drifted bootstrap or base run, and is a different, weaker kind of check that would silently narrow the verb's meaning for one family kind.
The shallow option is dropped, not deferred. RED-first delivery follows the established shape: mint a real-data mc family, reproduce it, pin the spurious synthetic-walk behaviour, then thread the manifest-derived source through the mc arm.
Diagnosis finding (2026-07-10): the framed bug is unreproducible — no CLI path mints a real-data
FamilyKind::MonteCarlofamily at all. Evidence: the only non-test producer ofFamilyKind::MonteCarloisrun_blueprint_mc(main.rs:1859), called exactly once (main.rs:3208) withDataSource::Synthetichardcoded, andaura mc --seedsrejects--real(main.rs:3121-3129);aura mc --realroutes to the campaign path, where the MonteCarlo stage is a terminal annotator (aura-campaign/src/exec.rs:401-446,family_id: None, "nothing flows out") that persists no family — it prints themc_r_bootstrapline and records only the Sweep/WalkForward families. For the mc families that can exist (synthetic seed walks), reproduce re-derives correctly (green covering testreproduce_family_re_derives_every_mc_member_bit_identically).The deep contract decided in the comment of 2026-07-10 above therefore has nothing to bind to yet: delivering it is design-bearing feature work, not a bug fix. At least three shapes are open, none clearly default: (A) the campaign MC stage additionally persists an addressable MC family, with a manifest extended by the real instrument, real ms window, the wf pooling parameters that produced the OOS trade-R series, and the bootstrap knobs incl. the bootstrap seed (today's stamped seed is the price-walk seed, the wrong one); (B) the annotator design stays and only the bootstrap knobs + seed are recorded on the already-persisted campaign/wf artifacts, making the annotation re-derivable from reproducible families without a new persistence kind; (C) close as by-design: the campaign document + real data are deterministic, so re-running the campaign IS the deep reproduction of the annotation, and per-annotation addressability is declined. The choice interacts with the deliberately-settled verb-dissolution design (mc-as-annotator, #210/#220) and overlaps the open idea #172 (real-data block-bootstrap Monte-Carlo as a first-class capability).
Status: blocked on that design choice; not deliverable RED-first as framed.
Resolution (2026-07-11): the fork dissolves once the two distinct purposes of Monte-Carlo in trading research are separated.
Purpose 1 — trade-sequence bootstrap. A statistic over an already-produced result: resample the trade-R series to read off expectancy confidence intervals and drawdown/ruin distributions. Members are reshuffled arrays, not runs; no backtest executes. The campaign
std::monte_carlostage is exactly this, and the terminal-annotator design (#210/#220) is correct for it — persisting an addressable family per annotation would be a category error (no family is persisted for a mean or a percentile either).Purpose 2 — data-resample Monte-Carlo. Block-bootstrap/permutation over the price series, each member a full backtest over a different data realization (the overfitting-falsification use, cf. permutation tests / White's Reality Check). That genuinely is a family in the C1 sense with deep reproduce semantics — and its home is #172, not this issue.
Decision, per the option letters laid out in the diagnosis comment of 2026-07-10 in this thread:
campaign_runrecord carries: the campaign and process document content ids (a file target is register-then-run sugar,crates/aura-cli/src/campaign_run.rs:390, so both documents live in the content-addressed store; the process document carriesresamples/block_len), the seed — the very value threaded intor_bootstrap(crates/aura-campaign/src/exec.rs:154→:413/:434) and stamped on the record (exec.rs:214) —, the family ids of the reproducible base families (the Sweep/WalkForward reproduce machinery of the #229 fix), and the bootstrap result itself (StageBootstrapon the stage realization,crates/aura-registry/src/lineage.rs:150-176) to compare a re-derivation against. The "wrong stamped seed" observation in the diagnosis comment applies to the synthetic MC family manifest (whose seed is the member-generating price-walk seed), i.e. to option (A)'s hypothetical manifest — not to the campaign record.The deep contract decided in the comment of 2026-07-10 (reproduce re-derives the full chain — source, base series, seeded resample — and compares bit-identically) stands unrevised for real MC families; it binds to the purpose-2 capability of #172 when that is built, not to the campaign annotator.