Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7abcd73
fix: report completion for the requested scan scope
mldangelo-oai Aug 20, 2026
1c10d36
fix: synchronize scoped coverage projections
mldangelo-oai Aug 20, 2026
84574be
fix: keep scan history coverage consistent
mldangelo-oai Aug 20, 2026
7732b90
fix: include exclusions in scan scope summaries
mldangelo-oai Aug 20, 2026
2c6cfa9
Merge main into scoped scan completion
mldangelo-oai Aug 20, 2026
e9c6170
fix: preserve large native scan histories
mldangelo-oai Aug 20, 2026
2d22c4d
Merge main scan summary updates
mldangelo-oai Aug 20, 2026
db135fe
fix: preserve exact paths in scan history
mldangelo-oai Aug 20, 2026
8b9b93c
fix: disambiguate scan scope summaries
mldangelo-oai Aug 20, 2026
f7ca16c
fix: preserve exact paths in scan reports
mldangelo-oai Aug 20, 2026
9fbd2fe
Merge main into scoped scan completion
mldangelo-oai Aug 21, 2026
e63efdb
fix: simplify requested-scope presentation
mldangelo-oai Aug 21, 2026
4c13fef
fix: refresh bundled guidance and preserve large scan details
mldangelo-oai Aug 21, 2026
d384888
Merge main workbench updates
mldangelo-oai Aug 21, 2026
855e95a
fix: escape default-ignorable scope path characters
mldangelo-oai Aug 21, 2026
4a377d5
Merge main into scoped scan completion
mldangelo-oai Aug 21, 2026
428f664
fix: escape Unicode format controls in scope paths
mldangelo-oai Aug 21, 2026
696d996
Merge main into scoped scan completion
mldangelo-oai Aug 21, 2026
6caa6ed
fix: make Unicode path escaping version-stable
mldangelo-oai Aug 21, 2026
66954ac
Merge main into scoped scan completion
mldangelo-oai Aug 21, 2026
6f8b8bb
Merge remote-tracking branch 'origin/main' into HEAD
mldangelo-oai Aug 21, 2026
0396b99
Merge remote-tracking branch 'origin/main' into HEAD
mldangelo-oai Aug 21, 2026
5e7a0de
test: stream scoped history probe through stdin
mldangelo-oai Aug 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions sdk/typescript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,13 @@ overrides, without starting Codex or contacting the network.
`core.hooksPath`, does not replace an existing hook, and blocks high-severity
findings or failed scans. Set `--fail-on-severity` to change the threshold.

`--path` scopes a scan to one or more paths, `--diff` scans committed changes,
and `--working-tree` scans staged and unstaged changes. Deep scans support
repository and path targets. The output directory must be outside the scanned
directory and any enclosing Git worktree. When SARIF is produced, it is written
to
`--path` selects one or more files or directories. A completed scoped scan
covers those paths, not the rest of the repository. Human-readable output
JSON-quotes ambiguous path names; JSON results retain the original strings.
`--diff` scans committed changes, and `--working-tree` scans staged and
unstaged changes. Deep scans support repository and path targets. The output
directory must be outside the scanned directory and any enclosing Git worktree.
When SARIF is produced, it is written to
`<scan-dir>/exports/results.sarif`.

Working-tree snapshots include files from untracked nested Git repositories.
Expand Down Expand Up @@ -340,10 +342,17 @@ the destination without moving files.

Scans are report-only by default. Use `--fail-on-severity` in CI to exit 1 when
a completed scan contains a finding at or above the selected severity.
Incomplete coverage and CLI/runtime errors exit 2 so they cannot be mistaken
for a passing policy. Incomplete scans still write the available human or JSON
result to stdout and a coverage warning to stderr, including in report-only
mode.
Incomplete or unknown coverage of the requested scope and CLI/runtime errors
exit 2. A completed `scan . --path src/parser` exits 0 in report-only mode,
even if other paths were not selected. `coverage.deferred` records unfinished
requested work; `coverage.openQuestions` records optional follow-up. A
static-only review can be complete without live reproduction.

Exit 2 can still include a valid partial report. Incomplete scans write the
available human or JSON result to stdout and a coverage warning to stderr,
including in report-only mode. Automation should check the manifest status,
`coverage.mode`, `coverage.completeness`, scope paths, and deferred work
instead of treating every exit 2 as a missing report.

Use `--patch` to fix and verify confirmed findings after a complete scan.
`--patch-severity high` selects high and critical findings; the default is low
Expand Down
2 changes: 1 addition & 1 deletion sdk/typescript/_bundled_plugin/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codex-security",
"version": "0.1.22",
"version": "0.1.23",
"description": "Codex Security workflows for security scans, analysis, and investigation.",
"author": {
"name": "OpenAI"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The scan reviewed the canonical include paths and exclusions listed below.
- Revision: deadbeef
- Snapshot digest: codex-security-snapshot/v1:sha256:ed88f96a4c1a06603a41b3f261f59c3de2555c367ef6ad3bb8b9e483495d34eb
- Inventory strategy: repository
- Included paths: .
- Included paths: `.`
- Excluded paths: none
- Runtime or test status: not recorded

Expand All @@ -21,7 +21,7 @@ The scan reviewed the canonical include paths and exclusions listed below.
| Reportable findings | 1 |
| Severity mix | high: 1 |
| Confidence mix | high: 1 |
| Coverage | complete |
| Coverage | complete for requested scope |
| Validation mode | not recorded |

Canonical artifacts: `scan-manifest.json`, `findings.json`, and `coverage.json`. This report is a deterministic projection of those files.
Expand Down
Binary file modified sdk/typescript/_bundled_plugin/mcp/server.mjs.br.part-000
Binary file not shown.
Binary file modified sdk/typescript/_bundled_plugin/mcp/server.mjs.br.part-001
Binary file not shown.
4 changes: 2 additions & 2 deletions sdk/typescript/_bundled_plugin/references/core-scan.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Perform one complete, evidence-backed security audit of the exact supplied repos
3. While the baseline runs, read `threat-model.md` once and obtain its independent architecture review within the available worker allowance. Verify its resource rows against their actual consumers, use the returned canonical `threatModel` as the generated model, and build source-backed investigation packets from it. Carry that object and its evidence into the final result instead of reconstructing a shorter summary. Preserve any user-supplied threat model unchanged as the authoritative security assumptions; map its real surfaces and controls without replacing it.
4. Group related source-backed security questions into investigation packets. Each group shares its plausible attacker, protected asset, entry points, expected controls, sensitive operations, component relationships, and actual repository-relative source anchors. Keep each question concrete, preserve distinct attacker boundaries and security mechanisms, and let investigators establish the detailed dataflow.
5. Launch focused investigator subagents with `fork_turns: "none"` as soon as useful packet groups exist. Choose their number and assignments from the amount, complexity, and independence of source-backed work, bounded by the supplied available subagent allowance; use fewer for related packets and more only when distinct surfaces justify them. Keep mapping other surfaces while they run. Send each only its focused-investigator prompt below, assigned packets, investigator perspective, repository path, authorized scope, any supplied scoped-source inventory, exact user context, supplied threat model, applicable packet-specific security guidance and its resolver command, the optional authoritative knowledge-base location, and verified search command. Do not include this reference or another worker's prompt. Supporting code may be outside a requested path, but an affected entry point, control, or operation must be in scope.
6. Reconcile source coverage before combining findings. Union only the baseline and focused investigators' `fully_reviewed_files` with files the parent fully security-audited, then intersect that set with the supplied authorized inventory or an inventory of the selected current scope. Architecture mapping alone and supporting files outside that inventory do not count toward completed audit coverage. Finish the remaining in-scope files in coherent groups, reusing available investigators within the same allowance. Inspect implementation-owning generated or compressed code as data. Do not add overlapping worker counts or claim that a search hit completed a file. Keep this one transient set; do not create a separate progress ledger or receipt format. If a user limit or unavailable source prevents completion, identify the actual remaining paths and report partial coverage. Then combine baseline and investigator findings once. Group observations only when they share the same broken security control and effective remediation; preserve every affected route, operation, sink, and supporting source location. Never merge different security failures solely because they share a CWE.
6. Reconcile source coverage before combining findings. Union only the baseline and focused investigators' `fully_reviewed_files` with files the parent fully security-audited, then intersect that set with the supplied authorized inventory or an inventory of the selected current scope. Architecture mapping alone and supporting files outside that inventory do not count toward completed audit coverage. Finish the remaining in-scope files in coherent groups, reusing available investigators within the same allowance. Inspect implementation-owning generated or compressed code as data. Do not add overlapping worker counts or claim that a search hit completed a file. Keep this one transient set; do not create a separate progress ledger or receipt format. If a user limit or unavailable source prevents review of the requested inventory, identify the actual remaining paths and report partial coverage. Then combine baseline and investigator findings once. Group observations only when they share the same broken security control and effective remediation; preserve every affected route, operation, sink, and supporting source location. Never merge different security failures solely because they share a CWE.
7. Independently validate each unique finding against local source once. Establish its attacker, entry point, trust boundary, attacker-controlled dataflow, transformations, broken control, sensitive operation, prerequisites, effective mitigations, strongest counterevidence, and concrete impact. Record concise, source-backed `rootCause.summary`, `validation.summary`, `attackPath.dataflow.summary`, and `attackPath.reachability.summary` alongside their supporting facts; determine impact, likelihood, and severity from those established facts. State optional configuration, dependency-version, or deployment prerequisites; do not require proof of a real deployment or runtime reproduction. A public library or parser boundary is sufficient when callers control the input. Reject only with source-backed counterevidence, preserve valid baseline findings, record material unresolved proof gaps, and apply the severity rules below.
8. Assemble complete semantic `scope`, `threatModel`, `findings`, and `coverage` using the plugin's `examples/completed-scan/` and `schemas/` as shape references, never as values to copy. Use the canonical field mapping and scenario reconciliation in `threat-model.md`, preserving supplied models unchanged and retaining source-backed architecture, capability, deployment, and uncertainty facts. Give each finding a stable lowercase vulnerability-family `ruleId`, its precise `taxonomy.category` and `taxonomy.cwe` values, genuine `provenance.source`, an instance when separately reported findings would otherwise collide, a `root_control` location when identifiable, all materially affected locations, calibrated severity and rationale, confidence and rationale, verified nonempty source evidence, attacker-to-sink reachability, and practical remediation. Use actual coverage surface labels and dispositions; report reviewed surfaces, explicit exclusions, deferred work, and unresolved questions honestly, and mark coverage `complete` only when the requested source scope was actually reviewed. Preserve every genuine finding, evidence item, user-supplied assumption, and unresolved proof gap in the caller's complete semantic result.
8. Assemble complete semantic `scope`, `threatModel`, `findings`, and `coverage` using the plugin's `examples/completed-scan/` and `schemas/` as shape references, never as values to copy. Use the canonical field mapping and scenario reconciliation in `threat-model.md`, preserving supplied models unchanged and retaining source-backed architecture, capability, deployment, and uncertainty facts. Give each finding a stable lowercase vulnerability-family `ruleId`, its precise `taxonomy.category` and `taxonomy.cwe` values, genuine `provenance.source`, an instance when separately reported findings would otherwise collide, a `root_control` location when identifiable, all materially affected locations, calibrated severity and rationale, confidence and rationale, verified nonempty source evidence, attacker-to-sink reachability, and practical remediation. Use actual coverage surface labels and dispositions. Coverage is `complete` when the requested source was reviewed and no essential in-scope proof gap remains. Unselected source does not make a scoped review partial. Put unfinished requested work in `coverage.deferred` or a `needs_follow_up` surface. Put optional deployment checks, broader investigations, and additional assurance in `coverage.openQuestions`; record the agreed validation method and limitations in `scope`. Never reclassify a real blocker as optional to claim completion. Preserve every genuine finding, evidence item, user-supplied assumption, and unresolved proof gap in the caller's complete semantic result.

Keep discovery, validation, and attack-path reasoning within this one self-contained audit; do not invoke separate phase skills. Do not create ranking phases, per-file or per-candidate ledgers, separate phase worker pools, repeated phase reports, or receipt files.

Expand Down
6 changes: 3 additions & 3 deletions sdk/typescript/_bundled_plugin/references/final-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Every scan mode uses the same final report pipeline. Workbench-owned Standard an

For each finding, supply an evidence-supported lowercase vulnerability-family `ruleId`; `taxonomy: { category, cwe }` using its exact known CWEs; verified locations; and `provenance.source`, using `"local_plugin"` only when this plugin actually discovered the finding. Preserve genuine worker or source provenance and any existing canonical candidate identity in the finding extensions. A finding with no known CWE retains `cwe: []`; never invent a classification. Include optional `codeEvidence` only when its actual code is nonempty and every referenced evidence ID is present.

Supply semantic coverage as `{ completeness, surfaces, explicitExclusions, deferred }`, with each surface using the actual `label` and one existing `disposition`. Mark coverage `partial` when a deferred item or `needs_follow_up` surface remains; preserve its real reason and supporting context. Each deferred item needs a meaningful reason; preserve any existing `id` or `candidateId`. The workbench derives a missing ID from its candidate identity or stable deferred-work details. Open questions may be nonempty strings or `{ question, followUpPrompt? }` objects. The workbench derives target and scope metadata, scope include and exclude paths, coverage mode and inventory strategy, finding identities and fingerprints, and surface IDs. Do not put those workbench-owned values or top-level coverage receipt references into the semantic draft.
Supply semantic coverage as `{ completeness, surfaces, explicitExclusions, deferred, openQuestions? }`, with each surface using the actual `label` and one existing `disposition`. Completeness applies to the authorized requested review. A finished path-scoped review is complete for those paths. Deferred items and `needs_follow_up` surfaces mean requested work or an essential in-scope proof gap remains, so coverage must be `partial`. Preserve their reasons and supporting context. Record optional follow-up, such as deployment confirmation or a broader review, in `openQuestions`. Record the agreed validation method, runtime status, and limitations in `scan.scope`. Do not invent exclusions or move blockers to `openQuestions` to claim completion. Each deferred item needs a meaningful reason; preserve any existing `id` or `candidateId`. The workbench derives a missing ID from its candidate identity or stable deferred-work details. Open questions may be nonempty strings or `{ question, followUpPrompt? }` objects. The workbench derives target and scope metadata, scope include and exclude paths, coverage mode and inventory strategy, finding identities and fingerprints, and surface IDs. Do not put those workbench-owned values or top-level coverage receipt references into the semantic draft.

After a workbench-owned Standard or workbench-backed diff draft is accepted, or the Deep coordinator returns its parent scan's canonical manifest, call `complete_codex_security_scan({ scanId, handoffClaimToken? })` and use its returned completion metadata. An SDK-owned scan returns its unsealed canonical files without calling a completion tool or finalizer; the SDK owns completion and report generation. Read full canonical results only when explicitly requested. For a terminal/chat workflow without a `scanId` or completion tool, retain `python <plugin_dir>/scripts/finalize_scan_contract.py --scan-dir <scan_dir> --source-root <repo_root>` after writing the canonical JSON. Outside the SDK path, do not mark the scan goal complete until finalization succeeds and the generated report exists.

Expand Down Expand Up @@ -150,11 +150,11 @@ Recommended outcomes:
- `No issue found`: reviewed and no credible issue survived.
- `Rejected`: plausible-looking candidate was ruled out with specific counterevidence.
- `Not applicable`: the risk class does not apply to that surface.
- `Needs follow-up`: plausible but not fully closed because of a concrete blocker or proof gap.
- `Needs follow-up`: essential in-scope review remains unresolved because of a concrete blocker or proof gap; this blocks complete coverage.

Write the same content, or a slightly more detailed version, to `<coverage_dir>/reviewed_surfaces.md`.

For broad scans where the completed coverage is useful for triage but too large for high-precision review, include a concise `## Open Questions And Follow Up` section near the end of the report. Use concrete, copyable prompt ideas that narrow the next review to individual commits from the current scan. Do not include this section for precise scans where the requested scope was already sufficient.
The generated `## Incomplete Requested Work` section lists deferred work and unresolved in-scope surfaces. Put optional investigations in `## Open Questions And Follow Up`, including for an otherwise complete scoped scan. Use concrete, copyable prompts grounded in the selected source and findings. Do not invent follow-ups or broaden the current scan.

Follow-up prompts should be tailored to the actual scan results:

Expand Down
15 changes: 10 additions & 5 deletions sdk/typescript/_bundled_plugin/schemas/coverage.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@
"complete",
"partial",
"unknown"
]
],
"description": "Completion of the requested review within the authorized scope, not whole-repository coverage or proof that no vulnerabilities exist. Use partial when requested work or an essential in-scope proof gap remains; use unknown when completion cannot be established."
},
"inventoryStrategy": {
"enum": [
Expand Down Expand Up @@ -92,7 +93,8 @@
"rejected",
"not_applicable",
"needs_follow_up"
]
],
"description": "The evidence-supported result for this in-scope surface. Use needs_follow_up only when an essential part of its requested review remains unresolved."
},
"receiptRefs": {
"type": "array",
Expand Down Expand Up @@ -131,7 +133,8 @@
"minLength": 1
}
}
}
},
"description": "Source excluded by the requested scope or applicable authorization and policy. Do not invent exclusions to hide unfinished requested work."
},
"deferred": {
"type": "array",
Expand Down Expand Up @@ -165,7 +168,8 @@
}
}
}
}
},
"description": "Unfinished requested work or an essential unresolved in-scope proof gap. Every item blocks complete coverage. Put optional additional assurance in openQuestions instead; never move a real blocker there to claim completion."
},
"openQuestions": {
"type": "array",
Expand All @@ -184,7 +188,8 @@
"minLength": 1
}
}
}
},
"description": "Optional additional assurance or later investigations that do not block completion of the requested review. Preserve essential unresolved in-scope proof gaps in deferred instead."
}
},
"allOf": [
Expand Down
Loading
Loading