Skip to content

fix(deep-scan): page reducer inputs by serialized size - #1025

Merged
daneschneider-oai merged 2 commits into
mainfrom
codex/deep-reducer-paging
Sep 24, 2026
Merged

daneschneider-oai merged 2 commits into
mainfrom
codex/deep-reducer-paging

Conversation

@daneschneider-oai

@daneschneider-oai daneschneider-oai commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Deep Scan reducers can exceed the code-mode IPC frame limit when reading all worker findings and the previous aggregate in one duplicated tool response. Page these inputs by serialized response bytes and keep retained provenance on the host so reducers can read large inputs without repeating the same oversized request.

Changes

  • Return one text payload from the reducer input tool, with a required caller byte budget and continuation cursor. JSON fragments support both large collections and a single oversized field, including escaped and Unicode text.
  • Page new findings and the previous aggregate together. Fetch complete originals and prior synthesized findings by reference; preserve full source payloads and history during host reconciliation. Cache the immutable input snapshot across pages.
  • Preserve the exact known numeric IPC error when exposed by SDK events, alongside downstream artifact validation errors. Initial and recovery prompts direct reducers to retry the failed page with a smaller budget while retaining its cursor and reference. Retry caps and scan-fatal classification are unchanged.
  • Add a single-reducer eval through the real Codex code-mode IPC transport and production artifact handlers. The normal MCP suite runs the deterministic local-provider version; an opt-in model version uses the production reducer prompt. Both grade complete pagination, smaller-request recovery, independent findings, and lossless source retention.

Testing

  • Node 24 / Codex SDK 0.156.1: reducer, paging, executor, and coordinator regression suites passed.
  • Real MCP compact-artifact tests passed against both source and freshly built bundled runtimes, including byte accounting and lossless reference retrieval.
  • SDK/plugin typechecks, SDK/MCP formatting checks, CI-script build, plugin source compatibility check and its nine tests passed.
  • Synthetic 75,499,053-byte input: projected inputs and full original detail each traversed in 37 pages within a 1 MiB caller budget, about 1.2 seconds per traversal; reassembled original content matched its SHA-256 digest.
  • The real-IPC eval rejected a 119,844,697-byte legacy response and recovered with a smaller page budget. Deterministic and model runs both saved all three independent findings, matched every original's hash, and retained the prior identity and history. Negative grading checks reject incomplete page traversal and invalid merges.
  • The SDK reducer-recovery harness passes all four tests after including the new helper dependencies.
  • Python checks are left to CI; the pinned Ruff version is unavailable locally. No Python files changed.

Local reducer eval results

Run locally on 2026-09-24 with Node 24.19.0 and Codex CLI/SDK 0.156.1. Scanbench was not run. These are one deterministic run and one live-model run of a single synthetic reducer assignment, not a repository-wide scan or a repeated statistical eval.

Path exercised: synthetic persisted worker findings and a previous aggregate → real Codex external code-mode IPC host (in-process fallback disabled) → production reducer input/recording handlers → persisted reduction. The fixture contains two new independent findings and one prior finding with retained original data and synthesized history, including one 33,554,432-byte (32 MiB) semantic field with JSON escaping and Unicode. The first input call deliberately returns the legacy duplicated full response; subsequent calls use production pagination. This reproduces a real transport rejection rather than mocking the error string.

Measurement / assertion Deterministic local provider Live model + production reducer prompt
Result PASS PASS
IPC frame ceiling (bytes) 67,108,864 67,108,864
Injected legacy response (bytes) 119,844,697 119,844,697
Initial → recovery page budget (bytes) 1,048,576 → 524,288 16,000 → 8,000
Successful page responses (including detail reads) 231 15,139
Independent findings saved 3 / 3 3 / 3
Sources accounted for exactly once 3 / 3 3 / 3
Complete originals matching SHA-256 3 / 3 3 / 3
Prior identity and synthesized history retained PASS PASS

The trace grader requires retrying with a smaller byte budget at the same cursor/reference, every successful response within its requested byte budget, complete assigned-input pagination before recording, and exactly one successful result submission. Negative tests reject missing pages and collapsing unrelated findings into one. The deterministic run additionally asserts the exact numeric IPC error in actual tool output. The model run receives the shipped reducer prompt without scripted recovery code; because SDK events do not expose every code-mode error, its grade uses the oversized response, changed request, and saved artifacts.

The live model selected an 8,000-byte recovery budget, resulting in 15,139 successful page reads for this deliberately large fixture. This validates recovery and retention; it is not a throughput benchmark. That run used the locally configured model without an explicit override; the report did not capture its resolved model ID.

Reproduce from the repository root after the normal locked dependency setup:

# Deterministic provider, real IPC/tools; no model credentials or external model requests.
node plugins/codex-security/mcp-app/evals/deep-reducer-paging.mjs deterministic

# Live model using the production reducer prompt; consumes model usage.
# Append a model ID to select it explicitly.
node plugins/codex-security/mcp-app/evals/deep-reducer-paging.mjs model

The deterministic eval runs in the normal MCP test suite; the live model mode is opt-in. Each command prints its local report directory containing report.json, a compact tool trace, and generated artifacts. The table above transcribes the saved local reports; there is no hosted run page. See the eval README, runner and trace grader, and regression/negative tests.

Risk and rollout

The worker-local input tool now requires maxBytes and returns JSON fragments; its prompt and recovery instructions ship together with the implementation. The budget measures the encoded MCP response, so callers leave room for transport framing and lower the budget after a transport-size failure. Size diagnostics can only be retained when the SDK exposes them. Aggregate submission keeps its existing contract; this change addresses input retrieval and retained provenance growth.

Public disclosure review

  • No customer, partner, prospect, or user identities, data, or identifying details are included.
  • No credentials, personal data, private source, scan findings, or nonpublic links or tickets are included.
  • I reviewed the branch name, title, description, commits, changes, comments, logs, screenshots, attachments, and links for public disclosure.

@daneschneider-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

@github-actions github-actions Bot added the bug Something isn't working label Sep 24, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-24T17:06:42.320572Z 2a32bfa Manual request
🔒 Security Review ✅ Completed 2026-09-24T17:16:49.762287Z 2a32bfa Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 8e1e0a47fb

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

@daneschneider-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 2a32bfa938

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

@daneschneider-oai
daneschneider-oai marked this pull request as ready for review September 24, 2026 17:13
@daneschneider-oai
daneschneider-oai merged commit 203d299 into main Sep 24, 2026
111 of 135 checks passed
@daneschneider-oai
daneschneider-oai deleted the codex/deep-reducer-paging branch September 24, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants