fix: preserve Deep Scan findings across terminal failures - #617
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f0b08a2406
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b48eda5b97
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 84b4501dff
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 51a3f01d65
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: deb89a8153
ℹ️ 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".
Summary
Deep Scan could lose accepted worker output when reduction or terminal publication did not complete, and the CLI could replace a stored terminal failure with a completion-state error. This change checkpoints and reconciles partial results so incomplete scans remain inspectable without being reported as complete.
Changes
Testing
bun test --timeout 30000 ./tests-ts --seed 12345— 1,646 passed, 30 platform/integration skips, 0 failedpnpm run typespnpm run formatpnpm run buildRisk and rollout
The change affects Deep Scan orchestration, recovery, and persisted workbench state. Database migrations are append-only, recovered scans retain partial coverage, and no public CLI arguments or defaults change. Release validation should verify both successful completion and terminal recovery from an existing database.
Public disclosure review
Change impact
Preserve canonical completion findings and freeze checkpoint evidence for explicitly incomplete terminal Deep Scan results.
flowchart LR subgraph column_0["Scan input"] direction TB node_0["Original scan instructions<br/><code>CodexSecurity.scan</code>"] end subgraph column_1["Terminal recovery"] direction TB node_1["Fail or interrupt Deep Scan<br/><code>fail_deep_scan_locked</code>"] node_2["Reconcile saved checkpoints<br/><code>merge_saved_results</code>"] end subgraph column_2["Stored result"] direction TB node_4["Canonical completed result<br/><code>merge_saved_results</code>"] node_3["Immutable partial result<br/><code>preserve_scan_results_locked</code>"] end node_0 -->|"registered with scan"| node_1 node_1 -->|"starts recovery"| node_2 node_2 -->|"freezes and seals"| node_3 node_2 -->|"ignores superseded drafts"| node_4 class node_0 context class node_1 changed class node_2 changed class node_3 affected class node_4 affected classDef changed fill:#d7f5e5,stroke:#237a4b,color:#111 classDef affected fill:#e6f0ff,stroke:#3569a8,color:#111 classDef context fill:#f2f3f5,stroke:#6e7781,color:#111Source evidence (13)
sdk/typescript/src/api.ts:L927-L945— The SDK registers the scan recipe and original scan prompt together, so Deep workers can recover the caller's instructions.sdk/typescript/_bundled_plugin/scripts/deep_scan_workbench.py:L2030-L2063— The workbench records the Deep and parent terminal states under the completion lock, then invokes stopped-result preservation.sdk/typescript/_bundled_plugin/scripts/workbench_saved_results.py:L298-L385— Recovery discovers worker and reducer checkpoints, then limits rereads to the frozen path-and-digest set when one exists.sdk/typescript/_bundled_plugin/scripts/workbench_saved_results.py:L870-L1034— The first successful terminal publication freezes its source digests, seals partial artifacts, and indexes only that immutable finding set.sdk/typescript/_bundled_plugin/scripts/workbench_schema.py:L686-L692— An append-only migration stores the frozen stopped-scan source digests.sdk/typescript/tests-ts/stopped-scan-results.test.ts:L148-L178— The regression test writes a checkpoint after failed and interrupted seals, then verifies the manifest, findings artifact, and indexed count stay unchanged.sdk/typescript/_bundled_plugin/scripts/workbench_saved_results.py:L579-L593— Successful completion treats the stored canonical draft as authoritative and does not promote findings from superseded checkpoints.sdk/typescript/tests-ts/compact-diff-scan.test.ts:L808-L856— The regression test verifies that completion preserves the canonical draft's nine findings instead of growing to 13 from superseded checkpoints.sdk/typescript/_bundled_plugin/scripts/workbench_saved_results.py:L912-L1030— Stopped-scan source digests are now committed with the successful publication transaction, so failed output writes remain retryable.sdk/typescript/tests-ts/stopped-scan-results.test.ts:L209-L236— The regression test injects a transient publication OSError into a legacy seal and verifies the next refresh recovers its finding.sdk/typescript/_bundled_plugin/scripts/workbench_saved_results.py:L143-L155— Worker-local candidate reconciliation includes identity.instance so distinct reportable occurrences remain separate.sdk/typescript/_bundled_plugin/scripts/workbench_saved_results.py:L873-L887— Canceled scans without a successful seal can retry publication and freeze sources on the first successful transaction.sdk/typescript/tests-ts/stopped-scan-results.test.ts:L263-L308— Behavioral tests preserve two distinct worker instances and recover canceled findings after a transient publication failure.Collection limits