Skip to content

fix(collector): exclude one-sided startup books - #282

Merged
proerror77 merged 1 commit into
mainfrom
codex/cex-l2-static-checkpoints-224
Jul 23, 2026
Merged

proerror77 merged 1 commit into
mainfrom
codex/cex-l2-static-checkpoints-224

Conversation

@proerror77

@proerror77 proerror77 commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Change contract

Exclude initially one-sided Binance books with explicit manifest evidence, restart the capture session on runtime catalog exclusion, and accept only fully bridged post-warmup shadow segments.

Acceptance evidence

  • Red/green test proves a one-sided initial snapshot emits symbol_excluded rather than a replay-complete snapshot.
  • Red/green test proves runtime exclusion requires a new capture session.
  • Collector binary tests: 42 passed, 0 failed.
  • bash -n and shellcheck pass for the modified gate scripts.
  • deployment/aliyun/test-rust-lob-control-plane.sh passes, including nanosecond warmup cutoff, actual 600-second shadow cadence, zero post-observation reconnect boundaries, and policy rejection of a pre-observation reconnect marker.
  • rustfmt --check and git diff --check pass.
  • Two independent read-only code reviews approved after fixes.

Live failing proof that motivated this rollout:

  • Candidate: 09524e9034a3504f518a10573dd7fb239bb02a6ca7f28cd6f34a27fd15b8d6a1
  • Gate evidence: /data/monday/evidence/shadow-gates/09524e9034a3504f518a10573dd7fb239bb02a6ca7f28cd6f34a27fd15b8d6a1/36ec1715c91519ec68185c427958b7818622a2d095e71d471fcf8b663e5af99a/runs/20260723T164013Z-348370/run.json
  • Final failure was a Spot manifest with snapshot/checkpoint but no diff for SCRIDR; the live book was one-sided. No production cutover occurred.

Out of scope

  • Production cutover before a new full shadow gate passes.
  • agg_trade or reference collector behavior.
  • Snapshot, cohort, evaluator, MCTS, and research logic.
  • Historical gap reconstruction or fabrication.

Dependency or merge order

Depends on merged PR #277 (08456949104a64756703e439b3718915135b5a98). Merge this PR before building the next exact-main collector candidate and rerunning the full gate.

Focused validation

cargo test --manifest-path rust_hft/Cargo.toml -p hft-collector --bin binance-lob-archiver
bash -n deployment/aliyun/host-rust-lob-shadow-gate.sh deployment/aliyun/test-rust-lob-control-plane.sh
shellcheck deployment/aliyun/host-rust-lob-shadow-gate.sh deployment/aliyun/test-rust-lob-control-plane.sh
bash deployment/aliyun/test-rust-lob-control-plane.sh
rustfmt --edition 2021 --check rust_hft/tools/collector/src/bin/binance-lob-archiver.rs
git diff --check

Rollout and rollback impact

Rollout: merge, build an exact-main artifact, install it as an isolated release, and run the full Spot plus USD-M shadow gate. Cut over only if canonical OSS readback, LOB continuity, agg_trade > 0, manifest SHA, and _SUCCESS all pass.

Rollback: do not adopt the candidate, or repoint the shadow release to the prior artifact. Production remains on its current binary until the gate passes.

Refs #224

Summary by CodeRabbit

  • Reliability Improvements

    • Improved deployment validation by waiting longer for service health to stabilize before observation.
    • Strengthened checks for complete symbol coverage and uninterrupted market-data continuity.
    • Updated catalog verification to validate manifests captured during the observation window.
  • Data Quality

    • One-sided initial order-book snapshots are now excluded from archived data and trigger a fresh capture session.
    • Tightened reconnect-boundary validation to prevent incomplete or discontinuous evidence from being accepted.
  • Testing

    • Expanded coverage for observation timing, symbol completeness, and invalid continuity evidence.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 52 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 Plus

Run ID: 0da5e523-d6a8-4969-9561-4089db6a5214

📥 Commits

Reviewing files that changed from the base of the PR and between d6c7c50 and 6e27a19.

📒 Files selected for processing (6)
  • deployment/aliyun/README.md
  • deployment/aliyun/host-rust-lob-shadow-gate.sh
  • deployment/aliyun/rust-lob-shadow-gate-policy.jq
  • deployment/aliyun/test-rust-lob-control-plane.sh
  • deployment/aliyun/test-rust-lob-release-adoption.sh
  • rust_hft/tools/collector/src/bin/binance-lob-archiver.rs
📝 Walkthrough

Walkthrough

The shadow gate now settles health longer, starts manifest eligibility at observation time, enforces complete bridging and reconnect-free evidence, and adds deterministic tests. The Binance archiver excludes one-sided initial snapshots and restarts capture sessions after exclusions.

Changes

Shadow gate validation

Layer / File(s) Summary
Observation timing and evidence checks
deployment/aliyun/host-rust-lob-shadow-gate.sh, deployment/aliyun/README.md
Health settling, nanosecond observation cutoffs, manifest selection, bridging invariants, and continuity checks are updated.
Reconnect policy and contract tests
deployment/aliyun/rust-lob-shadow-gate-policy.jq, deployment/aliyun/test-rust-lob-control-plane.sh, deployment/aliyun/test-rust-lob-release-adoption.sh
Spot and USDM evidence now require zero reconnect boundaries, with fixtures and tests covering the revised policy and cutoff behavior.

Snapshot session control

Layer / File(s) Summary
Snapshot exclusion and session restart
rust_hft/tools/collector/src/bin/binance-lob-archiver.rs
One-sided initial snapshots emit exclusion events, exclusions restart capture sessions, and related sequencing and predicate tests are updated.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ShadowGate
  participant HealthChecks
  participant OSSManifests
  ShadowGate->>HealthChecks: wait for health-settle deadline
  HealthChecks-->>ShadowGate: bridged symbol validation
  ShadowGate->>ShadowGate: record observation_started_ns
  ShadowGate->>OSSManifests: select manifests after observation start
  OSSManifests-->>ShadowGate: manifest data and SHA-256 evidence
Loading
sequenceDiagram
  participant InitialSnapshotProducer
  participant RESTSnapshotServer
  participant run_session
  InitialSnapshotProducer->>RESTSnapshotServer: request initial depth snapshot
  RESTSnapshotServer-->>InitialSnapshotProducer: one-sided snapshot
  InitialSnapshotProducer->>run_session: emit ExcludeSymbol
  run_session->>run_session: restart capture session
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: excluding one-sided startup books in the collector.
Description check ✅ Passed The description covers the contract, out-of-scope, dependency, validation, and rollout details; the Scope exception section is missing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/cex-l2-static-checkpoints-224

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.

@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: 8a1ab55dd2

ℹ️ 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 +1333 to +1335
let event = Event::ExcludeSymbol {
symbol: symbol.clone(),
reason: "one-sided initial snapshot is not replay-complete".to_owned(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep exclusion segments consistent with their recorded catalog

When a one-sided symbol emits a depth update before its REST snapshot—possible because every websocket connects before snapshot production—this event causes process_event to remove the symbol from the active catalog even though its diff is already archived. On session close, close_segment_at updates the segment catalog to exclude that symbol, after which summarize_lob_continuity rejects the recorded diff as outside the declared scope; the resulting .jsonl.part remains in the spool and assert_spool_drained makes the shadow gate fail. Preserve the segment's original catalog or explicitly discard/quarantine this unsafe segment, with a diff-before-exclusion counterexample test.

AGENTS.md reference: AGENTS.md:L95-L96

Useful? React with 👍 / 👎.

}

match pending_action {
action if action.restarts_capture_session() => break,

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 Disarm the watchdog while restarting an excluded session

When an exclusion triggers, this new break stops websocket activity and enters task draining plus close_segment while the process watchdog remains armed. The deployed environments allow only 180 seconds of market-data silence but permit compression to run for 300 seconds, and publish_global_shutdown explicitly disarms the watchdog for this same drain/compression path; therefore a slow close can invoke process::exit(75), lose the in-memory exclusion, and repeat the exclusion after systemd restarts the process. Disarm and re-arm around the internal session transition, or otherwise report watchdog progress during the close.

AGENTS.md reference: AGENTS.md:L95-L96

Useful? React with 👍 / 👎.

start_ns=$(jq -er '.start_received_at_ns' "$manifest")
end_ns=$(jq -er '.end_received_at_ns' "$manifest")
((end_ns < gate_started_ns)) && continue
((start_ns < observation_started_ns)) && continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Seed strict verification before filtering warm-up segments

Filtering out every segment that started before observation also removes the session's only real snapshot seeds. The first retained segment is opened by scheduled rotation with segment_open checkpoints, but verify_binance_market_tape_with_requirements explicitly rejects a first-segment checkpoint unless that segment previously contained a snapshot; consequently the --require-lob-continuity invocation at the end of this function fails for an otherwise stable post-warm-up session, so the production gate cannot pass. Include a trusted pre-observation seed segment in strict verification (without counting it as observation evidence), or teach the verifier an equivalent anchored-checkpoint contract and test the real verifier path.

AGENTS.md reference: AGENTS.md:L95-L96

Useful? React with 👍 / 👎.

Comment on lines +1333 to +1335
let event = Event::ExcludeSymbol {
symbol: symbol.clone(),
reason: "one-sided initial snapshot is not replay-complete".to_owned(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove excluded symbols from the security-token subset

When a one-sided symbol also appears in security_token_symbols, this event only adds it to excluded_symbols; Config::segment_config continues copying it into each manifest's security-token list while active_symbols removes it from symbols. The strict artifact validator requires every security_token_symbols entry to remain in symbols, so every otherwise clean segment produced after the capture-session restart is rejected and the shadow gate cannot pass. Filter the security-token subset when applying runtime exclusions and cover this catalog combination with a counterexample test.

AGENTS.md reference: AGENTS.md:L95-L96

Useful? React with 👍 / 👎.

@proerror77
proerror77 force-pushed the codex/cex-l2-static-checkpoints-224 branch from 8a1ab55 to d6c7c50 Compare July 23, 2026 18:21

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rust_hft/tools/collector/src/bin/binance-lob-archiver.rs`:
- Around line 1327-1343: Update the one-sided snapshot exclusion branch in the
symbol-processing flow so that after `SendOutcome::Sent`, it invokes the
existing `wait_or_shutdown` rate-limit delay before continuing. Preserve the
`SendOutcome::Shutdown` handling and ensure excluded symbols still respect the
configured `snapshot_requests_per_second` request rate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2aa17181-16ab-4ef7-8774-09051ce36c3e

📥 Commits

Reviewing files that changed from the base of the PR and between 7fecb9d and d6c7c50.

📒 Files selected for processing (6)
  • deployment/aliyun/README.md
  • deployment/aliyun/host-rust-lob-shadow-gate.sh
  • deployment/aliyun/rust-lob-shadow-gate-policy.jq
  • deployment/aliyun/test-rust-lob-control-plane.sh
  • deployment/aliyun/test-rust-lob-release-adoption.sh
  • rust_hft/tools/collector/src/bin/binance-lob-archiver.rs

Comment thread rust_hft/tools/collector/src/bin/binance-lob-archiver.rs
@proerror77
proerror77 force-pushed the codex/cex-l2-static-checkpoints-224 branch from d6c7c50 to 6e27a19 Compare July 23, 2026 18:28
@proerror77

Copy link
Copy Markdown
Owner Author

CI disposition for final head 6e27a1903b33827be1d39b59b711d228d25c7e34:

  • All focused collector and deployment checks pass in CI: Rust collector control-plane, Rust LOB release adoption, Polymarket raw-ops, collector fast lane, strict Clippy, Semgrep, security, and image contracts.
  • The only red check is Rust Workspace after those focused checks pass, when Linux runs test-trading-ecs-host-contract.sh.
  • Current main run 30029374579 fails at the identical point after the same three preceding control-plane tests pass: https://github.com/proerror77/monday/actions/runs/30029374579/job/89281833163
  • PR final-head run: https://github.com/proerror77/monday/actions/runs/30033881329/job/89296889915
  • Root baseline drift: .github/workflows/acr-publish.yml now has three pinned actions/upload-artifact uses, while the unrelated trading-host contract asserts exactly two. This PR does not modify that workflow or trading-host test.

This baseline red is tracked separately from #224 and is not being represented as a passing check.

@proerror77
proerror77 merged commit b0050e0 into main Jul 23, 2026
17 of 18 checks passed
@proerror77
proerror77 deleted the codex/cex-l2-static-checkpoints-224 branch July 24, 2026 08:44
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