From 6fe4cb6629d36e87d532419fce051002b4abbdbf Mon Sep 17 00:00:00 2001 From: Elmehdi Aitbrahim Date: Wed, 2 Sep 2026 07:03:58 -0400 Subject: [PATCH] docs(experiments): every flat-priced record points at the cost correction Recommended by #335's own restatement and not done at the time. Sixteen records report profit factors priced at the flat 5bp slippage floor; one document -- the restatement itself -- knows that no asset in keel's universe reaches that floor. WHY A POINTER AND NOT A RE-RUN. The correction is conservative-only: real cost is higher, so a corrected profit factor can only fall, and every one of the 120 measured deltas was negative or zero. Re-running thirteen documents to move numbers that were already null spends real compute to reach the same conclusion. What changes is not any document's VERDICT but what a reader may conclude by comparing ACROSS documents -- a 0.9 in one and a 1.06 in another are not on the same scale when both were priced at a rate neither asset trades at, and nothing on the page says so. NOTHING IS REWRITTEN. `docs/experiments` is an append-only account of what was run; editing a measured number would falsify it. Every change here is an addition, and `git diff` against main contains no removed line that is not part of a note being reflowed. THE INDEX GOT ITS OWN NOTE, because the blanket one was FALSE there. Applied uniformly, the note told `docs/experiments/README.md` that "the figures below are priced at the flat floor" -- and the index has no figures. It now says what is true of it: that every record dated before 2026-09-01 is flat-priced. A note that misdescribes the page it sits on is worse than no note. TEST FIRST, and the third assertion is the one worth having. A bare link would read as "this result is retracted", which would be a worse error than the one being corrected -- so the pin requires the word "verdict" within 600 characters of the link, and a mutation replacing the qualification with "These numbers are wrong." fails it. Tests: `tests/test_experiment_cost_pointers.py` (3 tests). 3 mutants, 3 killed: a record losing its pointer, a pointer that reads as a retraction, and a discovery regex matching nothing -- the last because every assertion here passes vacuously if the scan finds no records. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01NzuKAe2RVrPt9acVAWjRyL --- ...0-adx-ablation-and-random-entry-control.md | 8 ++ .../2026-07-20-exit-lookback-ratio.md | 8 ++ .../2026-08-08-between-family-independence.md | 8 ++ ...6-08-11-hourly-backtest-turtle-breakout.md | 8 ++ ...8-11-hourly-param-sweep-turtle-breakout.md | 8 ++ .../2026-08-12-fee-curve-and-rsi-meanrev.md | 8 ++ ...-08-12-rsi-meanrev-scale-vs-selectivity.md | 8 ++ ...026-08-12-shipped-defaults-intersection.md | 8 ++ ...ated-under-a-production-faithful-engine.md | 8 ++ ...onest-cost-restatement-and-dca-ablation.md | 8 ++ .../2026-08-22-trailing-vs-static-exits.md | 8 ++ ...-27-external-strategy-evaluation-hazard.md | 8 ++ .../2026-08-30-slippage-cap-options.md | 8 ++ ...026-09-01-cusum-event-first-measurement.md | 8 ++ ...-09-01-triple-barrier-first-measurement.md | 8 ++ docs/experiments/README.md | 7 ++ tests/test_experiment_cost_pointers.py | 80 +++++++++++++++++++ 17 files changed, 207 insertions(+) create mode 100644 tests/test_experiment_cost_pointers.py diff --git a/docs/experiments/2026-07-20-adx-ablation-and-random-entry-control.md b/docs/experiments/2026-07-20-adx-ablation-and-random-entry-control.md index 1cdd1303..c70bda1f 100644 --- a/docs/experiments/2026-07-20-adx-ablation-and-random-entry-control.md +++ b/docs/experiments/2026-07-20-adx-ablation-and-random-entry-control.md @@ -1,5 +1,13 @@ # ADX Ablation + Random-Entry Control Arm — 2026-07-20 +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Status:** in-sample measurement on full cached history. **NOT out-of-sample. NOT a promotion decision.** Motivated by two findings in KB `source-58` (Katz & McCormick, *The Encyclopedia of Trading Strategies*): diff --git a/docs/experiments/2026-07-20-exit-lookback-ratio.md b/docs/experiments/2026-07-20-exit-lookback-ratio.md index 1a932d23..740936ae 100644 --- a/docs/experiments/2026-07-20-exit-lookback-ratio.md +++ b/docs/experiments/2026-07-20-exit-lookback-ratio.md @@ -1,5 +1,13 @@ # `exit_lookback` ratio test — §79.6's monotone prediction does NOT replicate +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Date:** 2026-07-20 **Status:** in-sample sensitivity characterisation on cached daily history. **Not a promotion decision.** **Ledger session:** `exit-lookback-2026-07-20` (5 diagnostic columns + 1 decision row) diff --git a/docs/experiments/2026-08-08-between-family-independence.md b/docs/experiments/2026-08-08-between-family-independence.md index d70d10a9..429f1c25 100644 --- a/docs/experiments/2026-08-08-between-family-independence.md +++ b/docs/experiments/2026-08-08-between-family-independence.md @@ -1,5 +1,13 @@ # Between-family independence — the §80.16 harness exists, and it is calibrated +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Date:** 2026-08-08 **KB basis:** §80.16 (the measurement), §73.5 (why it is non-optional), §74.3/§58.10a (why arm B is refuted), §80.10/§80.14 (who the real candidate is) diff --git a/docs/experiments/2026-08-11-hourly-backtest-turtle-breakout.md b/docs/experiments/2026-08-11-hourly-backtest-turtle-breakout.md index c5049281..654daf8c 100644 --- a/docs/experiments/2026-08-11-hourly-backtest-turtle-breakout.md +++ b/docs/experiments/2026-08-11-hourly-backtest-turtle-breakout.md @@ -1,5 +1,13 @@ # `turtle_breakout` clears `min_trades=100` on hourly bars — and loses on all 19 of them +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Date:** 2026-08-11 **Issue:** none — nobody asked for this. It fell out of the 2026-08-11 scout run (`~/keel/proposals/2026-08-11-shortlist.json`), which carried DOGE forward on a daily diff --git a/docs/experiments/2026-08-11-hourly-param-sweep-turtle-breakout.md b/docs/experiments/2026-08-11-hourly-param-sweep-turtle-breakout.md index 27869dd9..1855da23 100644 --- a/docs/experiments/2026-08-11-hourly-param-sweep-turtle-breakout.md +++ b/docs/experiments/2026-08-11-hourly-param-sweep-turtle-breakout.md @@ -1,5 +1,13 @@ # Re-tuning `turtle_breakout` to the hourly clock buys 51% and still loses on everything — 0 of 144 parameter sets +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Date:** 2026-08-11 **Issue:** none. This is the experiment `docs/experiments/2026-08-11-hourly-backtest-turtle-breakout.md` §9.4 recommended someone file, run on the same day instead of filed. That document identified its diff --git a/docs/experiments/2026-08-12-fee-curve-and-rsi-meanrev.md b/docs/experiments/2026-08-12-fee-curve-and-rsi-meanrev.md index 4e9a67ce..fb76622d 100644 --- a/docs/experiments/2026-08-12-fee-curve-and-rsi-meanrev.md +++ b/docs/experiments/2026-08-12-fee-curve-and-rsi-meanrev.md @@ -1,5 +1,13 @@ # At zero fee `turtle_breakout` makes money and `rsi_meanrev` does not — two failure modes that were one inference away from being pooled +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Date:** 2026-08-12 **Issue:** none. Two threads meet here. One is `docs/experiments/2026-08-11-hourly-param-sweep-turtle-breakout.md` §10.3(b) — *the execution-cost diff --git a/docs/experiments/2026-08-12-rsi-meanrev-scale-vs-selectivity.md b/docs/experiments/2026-08-12-rsi-meanrev-scale-vs-selectivity.md index 77f489a8..07d106bc 100644 --- a/docs/experiments/2026-08-12-rsi-meanrev-scale-vs-selectivity.md +++ b/docs/experiments/2026-08-12-rsi-meanrev-scale-vs-selectivity.md @@ -1,5 +1,13 @@ # `rsi_meanrev`'s edge is selectivity, not alpha — and the search for it found a simulator defect +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + > **⚠️ AMENDED 2026-08-13 — read alongside > [`2026-08-13-restated-under-a-production-faithful-engine.md`](2026-08-13-restated-under-a-production-faithful-engine.md).** > diff --git a/docs/experiments/2026-08-12-shipped-defaults-intersection.md b/docs/experiments/2026-08-12-shipped-defaults-intersection.md index fd325119..70fc1da5 100644 --- a/docs/experiments/2026-08-12-shipped-defaults-intersection.md +++ b/docs/experiments/2026-08-12-shipped-defaults-intersection.md @@ -1,5 +1,13 @@ # Three rules, 24 assets, zero free parameters — the viable intersection is empty, and one of the three fails for the opposite reason we recorded +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + > **⚠️ AMENDED 2026-08-13 — read alongside > [`2026-08-13-restated-under-a-production-faithful-engine.md`](2026-08-13-restated-under-a-production-faithful-engine.md).** > diff --git a/docs/experiments/2026-08-13-restated-under-a-production-faithful-engine.md b/docs/experiments/2026-08-13-restated-under-a-production-faithful-engine.md index 4a614ada..f329c988 100644 --- a/docs/experiments/2026-08-13-restated-under-a-production-faithful-engine.md +++ b/docs/experiments/2026-08-13-restated-under-a-production-faithful-engine.md @@ -1,5 +1,13 @@ # Two engine defects, both invisible to 2,712 passing tests — and what the conclusions become without them +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Date:** 2026-08-13 **Amends:** `2026-08-12-shipped-defaults-intersection.md` (#252) and `2026-08-12-rsi-meanrev-scale-vs-selectivity.md` (#255) diff --git a/docs/experiments/2026-08-17-honest-cost-restatement-and-dca-ablation.md b/docs/experiments/2026-08-17-honest-cost-restatement-and-dca-ablation.md index 92e23aab..6c39aa44 100644 --- a/docs/experiments/2026-08-17-honest-cost-restatement-and-dca-ablation.md +++ b/docs/experiments/2026-08-17-honest-cost-restatement-and-dca-ablation.md @@ -1,5 +1,13 @@ # 2026-08-17: The honest-cost simulate re-run, and the DCA dip-bonus ablation +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + Two measurements, one date, both enabled by Phase 9: the first `keel simulate` run under per-product slippage (#334, v0.9.0), and the first-ever measurement of the DCA family in a fee-explicit harness. Recorded together because they answer the two questions Phase 10's diff --git a/docs/experiments/2026-08-22-trailing-vs-static-exits.md b/docs/experiments/2026-08-22-trailing-vs-static-exits.md index 8a589669..3c0cf7ce 100644 --- a/docs/experiments/2026-08-22-trailing-vs-static-exits.md +++ b/docs/experiments/2026-08-22-trailing-vs-static-exits.md @@ -1,5 +1,13 @@ # Trailing vs static exits: does the ratchet-only exit policy help, at the fee actually paid? +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Issue #442.** Driver: [`2026-08-22-trailing-vs-static-exits.py`](2026-08-22-trailing-vs-static-exits.py) (pre-registered in its docstring before the run). Artifact: every number below is a row of [`2026-08-22-trailing-vs-static-exits.jsonl`](2026-08-22-trailing-vs-static-exits.jsonl) — 240 diff --git a/docs/experiments/2026-08-27-external-strategy-evaluation-hazard.md b/docs/experiments/2026-08-27-external-strategy-evaluation-hazard.md index 39922d34..1f1e20bd 100644 --- a/docs/experiments/2026-08-27-external-strategy-evaluation-hazard.md +++ b/docs/experiments/2026-08-27-external-strategy-evaluation-hazard.md @@ -1,5 +1,13 @@ # The fill-model hazard in externally-sourced strategies: what to establish before a foreign number means anything here +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Date:** 2026-08-27 · **Issue:** #529 · **Origin:** [`docs/superpowers/specs/2026-08-23-strategy-api-expressiveness-prd.md`](../superpowers/specs/2026-08-23-strategy-api-expressiveness-prd.md) §4.2 ("a warning worth encoding, not a feature"). diff --git a/docs/experiments/2026-08-30-slippage-cap-options.md b/docs/experiments/2026-08-30-slippage-cap-options.md index 38f62647..b39ace53 100644 --- a/docs/experiments/2026-08-30-slippage-cap-options.md +++ b/docs/experiments/2026-08-30-slippage-cap-options.md @@ -1,5 +1,13 @@ # The 50 bp slippage cap: all three of #523's options, measured on one cohort by one method +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Issue #523.** Driver: [`2026-08-30-slippage-cap-options.py`](2026-08-30-slippage-cap-options.py) (pre-registered in its docstring before the run). Artifact: every number below is a row of [`2026-08-30-slippage-cap-options.jsonl`](2026-08-30-slippage-cap-options.jsonl) — 210 cells diff --git a/docs/experiments/2026-09-01-cusum-event-first-measurement.md b/docs/experiments/2026-09-01-cusum-event-first-measurement.md index 16ebdca7..6a6fc5b2 100644 --- a/docs/experiments/2026-09-01-cusum-event-first-measurement.md +++ b/docs/experiments/2026-09-01-cusum-event-first-measurement.md @@ -1,5 +1,13 @@ # CUSUM event gating, first measurement — feasible, and without a gross edge +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Date:** 2026-09-01 · **Issue:** [#341](https://github.com/CodeGateSoftware/keel/issues/341) · **Rule:** `cusum_event` · **Driver:** `2026-09-01-cusum-event-first-measurement.py` · **Ledger row:** `cusum-event-first-measurement-2026-09-01` (168 trials disclosed) diff --git a/docs/experiments/2026-09-01-triple-barrier-first-measurement.md b/docs/experiments/2026-09-01-triple-barrier-first-measurement.md index f9641383..8c44b5fb 100644 --- a/docs/experiments/2026-09-01-triple-barrier-first-measurement.md +++ b/docs/experiments/2026-09-01-triple-barrier-first-measurement.md @@ -1,5 +1,13 @@ # Triple-barrier exits: a real gross improvement, worth exactly nothing after friction +> **Cost note (added 2026-09-02).** The figures below are priced at the flat 5bp +> slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) later measured that **no +> asset in keel's universe reaches that floor** — the range is 1.1× to 36.8× — so every +> profit factor here is optimistic by roughly 0.09 at the median. **The verdict is +> unaffected:** the correction only ever moves a number *down*, and every result here was +> already negative. Nothing on this page has been rewritten; records are appended to, not +> revised. + **Date:** 2026-09-01 · **Issue:** [#342](https://github.com/CodeGateSoftware/keel/issues/342) · **Rule:** `triple_barrier` · **Control:** `cusum_event` ([measured the same day](2026-09-01-cusum-event-first-measurement.md)) · diff --git a/docs/experiments/README.md b/docs/experiments/README.md index 51e05845..1412bee1 100644 --- a/docs/experiments/README.md +++ b/docs/experiments/README.md @@ -1,5 +1,12 @@ # Experiment records — index +> **Cost note (added 2026-09-02).** Every record here dated before 2026-09-01 prices fills +> at the flat 5bp slippage floor. [the per-product restatement](2026-09-01-per-product-slippage-restatement.md) +> measured that **no asset in keel's universe reaches that floor** — 1.1× to 36.8× — so +> those profit factors are optimistic by roughly 0.09 at the median. **No verdict in this +> directory changes:** the correction only ever moves a number *down*, and they were +> already null. Records are appended to, never revised. + This directory is keel's experiment log: **pre-registered, reproducible records** of measurements, feasibility studies, and engine-defect findings. Every document states its own scope and status up front (in-sample vs out-of-sample, "not a promotion decision", "amends diff --git a/tests/test_experiment_cost_pointers.py b/tests/test_experiment_cost_pointers.py new file mode 100644 index 00000000..ed2394a7 --- /dev/null +++ b/tests/test_experiment_cost_pointers.py @@ -0,0 +1,80 @@ +"""An experiment record priced at the flat slippage floor must say where the correction is. + +`2026-09-01-per-product-slippage-restatement.md` measured what that floor costs: the model +reaches it only at a $500M/day anchor and **no asset in keel's universe reaches it**, so every +figure produced under it overstates the profit factor — by a median of 0.090 across 120 cells. + +That does not change any document's VERDICT. The correction is conservative-only: real cost is +higher, so a corrected profit factor can only fall, and every one of the 120 deltas was negative +or zero. Re-running thirteen documents to move numbers that were already null would be spending +compute to reach the same conclusion. + +What it does change is what a reader may conclude by comparing ACROSS documents. A profit factor +of 0.9 in one and 1.06 in another are not on the same scale if both were priced at a rate neither +asset trades at, and a reader has no way to know that from the page. So each such record carries +one line saying so. + +**Records are never rewritten** — `docs/experiments` is an append-only account of what was run, +and editing a measured number would falsify it. A pointer is an addition, not a revision. +""" + +from __future__ import annotations + +import re +from pathlib import Path + +_ROOT = Path(__file__).resolve().parent.parent +_EXPERIMENTS = _ROOT / "docs/experiments" + +#: The correction every flat-priced record must point at. +RESTATEMENT = "2026-09-01-per-product-slippage-restatement.md" + +#: Records that report a profit factor AND state a slippage assumption are in scope. A document +#: that reports neither has nothing to qualify. +_REPORTS_PF = re.compile(r"profit factor|\bPF\b", re.I) +_STATES_SLIPPAGE = re.compile(r"slippage", re.I) + + +def flat_priced_records() -> list[Path]: + """Every record whose figures rest on a slippage assumption, excluding the correction.""" + return [ + path + for path in sorted(_EXPERIMENTS.glob("*.md")) + if path.name != RESTATEMENT + and _REPORTS_PF.search(text := path.read_text(encoding="utf-8")) + and _STATES_SLIPPAGE.search(text) + ] + + +def test_there_are_records_in_scope() -> None: + """A guard on the guard: if the discovery ever matches nothing, every assertion below + passes vacuously and this file stops meaning anything.""" + assert len(flat_priced_records()) >= 10 + + +def test_every_flat_priced_record_points_at_the_correction() -> None: + """The pin. A reader comparing profit factors across records has no way to know from the + page that both were priced at a rate neither asset trades at.""" + missing = [ + path.name + for path in flat_priced_records() + if RESTATEMENT not in path.read_text(encoding="utf-8") + ] + assert not missing, ( + f"{len(missing)} experiment record(s) report a profit factor under a slippage " + f"assumption without pointing at {RESTATEMENT}:\n " + "\n ".join(missing) + ) + + +def test_the_pointer_says_the_verdict_is_unchanged() -> None: + """A bare link would read as "this result is wrong". It is not — the correction is + conservative-only and every verdict here survives it. A pointer that let a reader conclude + otherwise would be a worse error than the one it corrects. + """ + for path in flat_priced_records(): + text = path.read_text(encoding="utf-8") + window = text[max(0, text.find(RESTATEMENT) - 600) : text.find(RESTATEMENT) + 600] + assert "verdict" in window.lower(), ( + f"{path.name}: the pointer does not say the verdict is unaffected, so it reads as " + "a retraction of a result that still stands" + )