Skip to content

feat(backtest): require evidence-bound executable L2 replay - #65

Merged
proerror77 merged 6 commits into
mainfrom
codex/evidence-bound-l2-replay
Jul 16, 2026
Merged

proerror77 merged 6 commits into
mainfrom
codex/evidence-bound-l2-replay

Conversation

@proerror77

@proerror77 proerror77 commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Change contract

Make a backtest result executable only when it is deterministically materialized from verified, sequence-safe Binance L2 collector evidence. Bind source segments, manifests, success markers, configuration, and result artifacts by SHA-256. The collector materializer and backtest use one shared replay validator in data-pipelines/core.

Out of scope

No live execution, account reconciliation, risk policy, readiness endpoint, alpha promotion, or market-data adapter rollout change.

Dependencies and merge order

Independent; may merge directly to main. It deliberately does not depend on #59 because it validates governed Binance L2 evidence rather than enabling the Prediction venue adapter.

Focused validation

  • cargo test -p hft-data
  • cargo test -p hft-backtest
  • cargo test -p hft-collector --lib
  • cargo test -p hft-collector --bin lob-pit-materializer
  • cargo clippy -p hft-data -p hft-backtest --all-targets --no-deps -- -D warnings
  • cargo tree -p hft-backtest -i hft-collector is absent (verified)

Rollout / rollback

Backtest-only, fail closed: malformed, stale, unbound, or non-deterministic input is rejected before execution. Revert this PR to restore the prior non-executable replay path.

Scope exception

20 files / 2,321 added lines exceed the normal split-assessment threshold, but this is one atomic trust contract: the raw collector evidence, PIT materializer, shared replay validator, and executable backtest must agree on the same schema and sequence semantics. Merging a subset would either publish unconsumed evidence or create a backtest path that cannot verify the evidence it executes. Named reviewer approval required before ready-for-review: proerror77.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@proerror77, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 58 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f13a0c9f-f674-41e2-b8bd-3d4821829c2d

📥 Commits

Reviewing files that changed from the base of the PR and between 53c98f2 and cb1b763.

⛔ Files ignored due to path filters (1)
  • rust_hft/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (19)
  • .gitignore
  • rust_hft/apps/backtest/Cargo.toml
  • rust_hft/apps/backtest/src/config.rs
  • rust_hft/apps/backtest/src/engine.rs
  • rust_hft/apps/backtest/src/event.rs
  • rust_hft/apps/backtest/src/main.rs
  • rust_hft/apps/backtest/src/sweep.rs
  • rust_hft/config/backtest/default.yaml
  • rust_hft/data-pipelines/core/Cargo.toml
  • rust_hft/data-pipelines/core/src/binance_lob_replay.rs
  • rust_hft/data-pipelines/core/src/lib.rs
  • rust_hft/data/backtest/sample.manifest.json
  • rust_hft/data/backtest/sample.ndjson
  • rust_hft/data/backtest/sample.raw.manifest.json
  • rust_hft/data/backtest/sample.raw.ndjson
  • rust_hft/data/backtest/sample.raw.ndjson._SUCCESS
  • rust_hft/tools/collector/Cargo.toml
  • rust_hft/tools/collector/src/bin/lob-pit-materializer.rs
  • rust_hft/tools/collector/src/lob_archiver.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/evidence-bound-l2-replay

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proerror77
proerror77 marked this pull request as ready for review July 16, 2026 07:27
@proerror77
proerror77 merged commit 2f3476b into main Jul 16, 2026
22 checks passed
@proerror77
proerror77 deleted the codex/evidence-bound-l2-replay branch July 16, 2026 07:27

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cb1b763027

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +139 to +140
if self.strategy.volume_factor > 0.0 || self.strategy.cvd_threshold != 0.0 {
bail!("strategy requires trade flow but dataset manifest is LOB-only");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the shipped grid LOB-compatible

When using the checked-in config/backtest/default.yaml with --grid config/backtest/param_grid.yaml, every planned run sets volume_factor to 0.8/1.0/1.2, and sweep::run reaches this validation in both dry-run and execution, so the stock sweep aborts with strategy requires trade flow before any backtest runs. Either update the grid to sweep only LOB-compatible values or provide a trade-flow manifest for those combinations.

Useful? React with 👍 / 👎.

Comment on lines +895 to +901
assert!(Command::new("zstd")
.args(["-q", "-f"])
.arg(&raw_path)
.arg("-o")
.arg(&compressed_path)
.status()
.unwrap()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip zstd compression tests when binary is absent

In environments where the zstd binary is not installed, the newly added compression tests panic at status().unwrap() before exercising the backtest validation logic, so cargo test -p hft-backtest fails for a missing optional system tool. Guard these tests the same way the existing collector zstd tests do, or use an in-process encoder for the fixture.

Useful? React with 👍 / 👎.

Comment on lines +299 to +300
let artifact_rows = parse_ndjson_values(artifact_bytes, "backtest event tape")?;
let mut materialized_rows = Vec::with_capacity(artifact_rows.len());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stream event-tape verification instead of retaining all rows

For realistic L2 backtest artifacts, this builds both artifact_rows and materialized_rows as full Vec<serde_json::Value> collections before replay starts, on top of the earlier fs::read of the entire artifact. A multi-GB tape can therefore OOM in --dry-run or normal backtests even though the previous runner streamed events; compare rows incrementally while hashing/materializing instead of retaining both tapes.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant