Skip to content

feat(polymarket): gate quote tape completeness - #239

Merged
proerror77 merged 2 commits into
mainfrom
codex/polymarket-quote-validation-220
Jul 23, 2026
Merged

proerror77 merged 2 commits into
mainfrom
codex/polymarket-quote-validation-220

Conversation

@proerror77

@proerror77 proerror77 commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Change contract: Polymarket raw-tape validation independently recomputes quote classification, coverage, latency, field quality, and collection failures, and only counts complete manifests as canonical.

Out of scope: Production deployment/cutover, snapshot construction, evaluator/MCTS, and research logic are unchanged.

Dependency or merge order: Producer contract merged first in PR #238. This validation PR is rebased directly onto main.

Focused validation: hft-collector Polymarket uploader tests (41 passed); bash syntax; shellcheck; Polymarket raw-ops control-plane test; new-ploy-runner full-feature cargo check; final read-only spec and standards reviews found no blocker.

Rollout/rollback impact: No deployment is performed. Noncanonical raw remains preserved with explicit quality evidence, but canonical upload counts and the shadow gate fail closed for missing context, coverage, timestamps, unexplained fields, or collection failures. Revert this PR independently; producer recording remains intact.

Closes #220.

@coderabbitai

coderabbitai Bot commented Jul 23, 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: 20 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: bd637b5a-1e25-4809-9df0-d8f96518b360

📥 Commits

Reviewing files that changed from the base of the PR and between 9aa1797 and ce27d53.

📒 Files selected for processing (3)
  • deployment/aliyun/polymarket-raw-ops-shadow-gate.sh
  • rust_hft/tools/collector/src/polymarket_research_import.rs
  • rust_hft/tools/collector/src/polymarket_upload.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/polymarket-quote-validation-220

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: 42c195b70c

ℹ️ 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".

let mut manifest = json!({
"schema": "monday.polymarket.raw.v1",
"canonical": reference_context_complete,
"canonical": reference_context_complete && quote_coverage_complete,

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 Require every uploaded segment to be canonical

When an upload contains both complete and incomplete chunks, this correctly marks the latter noncanonical, but the inspected shadow gate at deployment/aliyun/polymarket-raw-ops-shadow-gate.sh:902-906 and :950-957 only requires each canonical count to be greater than zero. Consequently, one complete chunk allows production_eligible to remain true despite any number of chunks failing the new quote checks; compare the canonical count with the total uploaded count so a mixed run is rejected.

AGENTS.md reference: AGENTS.md:L93-L96

Useful? React with 👍 / 👎.

Comment on lines +1091 to +1094
if matches!(kind, "quote" | "quote_collection_failure") {
let token = required_text(update, "token_id", line_number)?;
attempted_quote_token_ids.insert(token.to_owned());
request_attempts += 1;

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 Count a failed collection attempt only once

For each WebSocket failure, send_quote_collection_failure_and_empty emits a QuoteCollectionFailure followed by a synthetic empty Quote for the same actual attempt (ploy-market-data/src/feeds.rs:1149-1177). This block increments request_attempts for both records, while the later request_successes: quote_count also reports the synthetic empty quote as a success, so one failed request is recorded as two attempts—one successful and one failed—corrupting the manifest's collection-reliability metrics.

Useful? React with 👍 / 👎.

Comment on lines +1298 to +1300
let missing_quote_tokens = known_event_tokens
.difference(&quoted_token_ids)
.cloned()

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 Validate both discovered token IDs before computing coverage

When an event_discovered record omits an outcome token, supplies an empty token, or repeats the same token for both outcomes, the earlier population of known_event_tokens silently skips or deduplicates it. This difference therefore has no way to report that outcome in missing_quote_tokens, allowing quotes for only the remaining token to produce quote_coverage_complete=true and a canonical manifest for an incomplete or malformed market; require two nonempty, distinct outcome tokens before using this set as the coverage denominator.

AGENTS.md reference: AGENTS.md:L50-L54

Useful? React with 👍 / 👎.

Comment on lines +1306 to +1309
let quote_quality_complete = incomplete_quotes == 0
&& crossed_quotes == 0
&& out_of_range_prices == 0
&& negative_sizes == 0;

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 Reject depth books that contradict the top quote

A malformed quote can provide a valid noncrossed top level such as bid=0.49, ask=0.51 while its preserved depth contains a tradeable bid at 0.90 and ask at 0.10. The new scan validates each depth level only in isolation and derives crossed_quotes solely from the supplied top fields, so this tape receives quote_quality_complete=true and can become canonical even though replaying its full-depth book yields a crossed market; validate depth ordering and ensure the best tradeable depth levels agree with the top quote.

AGENTS.md reference: AGENTS.md:L50-L54

Useful? React with 👍 / 👎.

Comment on lines +1115 to +1119
if last_quote_source_at
.insert(token.to_owned(), source_at)
.is_some_and(|previous| source_at < previous)
{
bail!("line {line_number}: quote source time moved backwards");

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 Reset source-time ordering after a collection failure

When a WebSocket reconnect returns a fresh snapshot whose exchange timestamp is older than the last snapshot from the failed connection, the producer accepts it because spawn_clob_ws_quote_feed_until clears its per-token timestamp map at the reconnect boundary. The uploader retains last_quote_source_at across the intervening quote_collection_failure, however, so it rejects that producer-valid recovery tape with quote source time moved backwards and leaves the closed segment pending; clear the affected token's ordering state when processing the explicit failure boundary.

Useful? React with 👍 / 👎.

@proerror77
proerror77 force-pushed the codex/polymarket-quote-validation-220 branch 3 times, most recently from 89697e5 to b86a386 Compare July 23, 2026 02:31
@proerror77
proerror77 changed the base branch from codex/polymarket-quote-completeness-220 to main July 23, 2026 02:31
@proerror77
proerror77 force-pushed the codex/polymarket-quote-validation-220 branch from b86a386 to 8e8fa65 Compare July 23, 2026 02:34
@proerror77
proerror77 merged commit 8240c04 into main Jul 23, 2026
18 checks passed
@proerror77
proerror77 deleted the codex/polymarket-quote-validation-220 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.

Polymarket: 标记 quote 可执行性与采集完整性

1 participant