Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
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.60",
"version": "0.1.83",
"description": "Codex Security workflows for security scans, analysis, and investigation.",
"author": {
"name": "OpenAI"
Expand Down
31 changes: 31 additions & 0 deletions sdk/typescript/_bundled_plugin/scripts/finalize_scan_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@
"directory_snapshot": {"snapshotDigest"},
}
DISPOSITIONS = {"reported", "no_issue_found", "rejected", "not_applicable", "needs_follow_up"}
NON_COVERAGE_TARGET_WARNINGS = {
"Directory contents changed while the scan was running; "
"results were saved for the original snapshot.",
"The scanned Git repository became unavailable while the scan was running; "
"results were saved for the original revision.",
"Repository HEAD changed while the scan was running; "
"results were saved for the original revision.",
"Working-tree contents changed while the scan was running; "
"results were saved for the original snapshot.",
"The scan target became unavailable while the scan was running; "
"results were saved for the original revision or snapshot.",
}
SARIF_LEVELS = {
"critical": "error",
"high": "error",
Expand Down Expand Up @@ -1023,6 +1035,25 @@ def _recover_unsealed_coverage(
partial = True
if partial:
coverage["completeness"] = "partial"
elif (
completeness == "partial"
and coverage.get("mode") == "deep_repository"
and coverage["surfaces"]
and not coverage["deferred"]
and all(
warning in NON_COVERAGE_TARGET_WARNINGS
or re.fullmatch(
r"Recovered finding [0-9]+: "
r"(?:normalized [a-z, ]+|retained stronger duplicate logical finding)\.",
warning,
Comment on lines +1045 to +1048

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 Allow lossless duplicate warnings during coverage recovery

When an otherwise complete Deep Scan contains duplicate logical findings with the strongest or equal record first, _recover_unsealed_findings safely retains that record but emits Skipped malformed finding N: duplicate logical finding.; this allowlist accepts only the inverse-order retained stronger duplicate warning. Consequently, equivalent findings seal with partial versus complete coverage solely based on their ordering. Treat the lossless duplicate-discard warning as non-coverage-affecting as well.

AGENTS.md reference: sdk/typescript/AGENTS.md:L23-L23

Useful? React with 👍 / 👎.

)
for warning in warnings
)
):
coverage["completeness"] = "complete"
warnings.append(
"Recovered Deep Scan coverage marked partial without deferred review work."
)


def _recover_unsealed_hardening(
Expand Down
54 changes: 43 additions & 11 deletions sdk/typescript/_bundled_plugin/scripts/workbench_saved_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
_PUBLICATION_FOLLOW_UP_WARNING = (
"Saved scan evidence remains on disk; result publication needs follow-up:"
)
_UNVERIFIED_COVERAGE_WARNING = (
"Saved scan source is incomplete or has unverified coverage; coverage remains partial."
)


@dataclass(frozen=True)
Expand Down Expand Up @@ -252,6 +255,11 @@ def merge_saved_results(
}
if not isinstance(parent["findings"], list):
raise ContractError("Saved parent draft has no findings array")
if (
parent_scan.get("complete", True) is not True
and _UNVERIFIED_COVERAGE_WARNING not in warnings
):
warnings.append(_UNVERIFIED_COVERAGE_WARNING)
if not parent_scan.get("sealedAt"):
payload = _encoded(parent)
write_scan_local_bytes(
Expand All @@ -277,6 +285,7 @@ def merge_saved_results(
source_digests.update(parent_preserved_sources)
paths: dict[str, str | None] = {}
current_results: set[str] = set()
required_results: set[str] = set()
reducer_outputs: list[tuple[Any, str, list[str], int]] = []
accepted_reducers = [
worker
Expand All @@ -293,6 +302,7 @@ def merge_saved_results(
try:
latest_reducer = Path(reducer["result_manifest_path"]).relative_to(scan_dir).as_posix()
paths[latest_reducer] = None
required_results.add(latest_reducer)
except ValueError:
warnings.append("Skipped a reducer result outside the scan directory.")

Expand Down Expand Up @@ -351,6 +361,8 @@ def reducer_output(directory: str, attempt: int, reducer_worker: Any) -> None:
current_path = Path(worker["result_manifest_path"]).relative_to(scan_dir).as_posix()
paths[current_path] = worker["id"]
current_results.add(current_path)
if worker["status"] == "succeeded":
required_results.add(current_path)
except ValueError:
warnings.append("Skipped a worker result outside the scan directory.")

Expand Down Expand Up @@ -381,6 +393,8 @@ def reducer_output(directory: str, attempt: int, reducer_worker: Any) -> None:
except (ContractError, OSError, ValueError) as exc:
if (scan_dir / relative).exists():
warnings.append(f"Preserved unreadable checkpoint {relative}: {exc}")
elif relative in required_results and _UNVERIFIED_COVERAGE_WARNING not in warnings:
warnings.append(_UNVERIFIED_COVERAGE_WARNING)
if frozen_source_digests is not None:
if frozen_source_digests.keys() - source_digests.keys():
raise ContractError("Frozen stopped-scan checkpoint set is incomplete.")
Expand Down Expand Up @@ -577,16 +591,30 @@ def valid_finding(value: Any) -> bool:
for saved_path, current, saved_worker in sources
)
)
if (
(relative != "parent" or not parent_manifest)
and not superseded
and (
draft.get("complete") is False
or draft["coverage"].get("completeness") != "complete"
)
and coverage.get("completeness") in {"complete", "unknown"}
):
coverage["completeness"] = "partial"
if (relative != "parent" or not parent_manifest) and not superseded:

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 Preserve incomplete reducer results before promotion

For a successful dedup worker whose result exists but has complete: false or partial coverage, worker_id is None; once the canonical parent has complete: true, the preceding superseded predicate is true, so this verification block never records the unverified-coverage warning. If that parent has the motivating partial coverage with reviewed surfaces and no deferred rows, _recover_unsealed_coverage then promotes it to complete and the CLI reports success despite the reducer explicitly remaining incomplete. Inspect reducer completeness before applying parent supersession.

AGENTS.md reference: sdk/typescript/AGENTS.md:L22-L23

Useful? React with 👍 / 👎.

source_coverage = draft["coverage"]
source_completeness = source_coverage.get("completeness")
source_complete = draft.get("complete", True) is True
Comment on lines +594 to +597

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 malformed parent completion markers before promotion

When the canonical parent manifest contains scan.complete: null, 0, or "false", complete_scan_locked does not reject it because it checks only is False, and this condition exempts that parent from source_complete validation. A Deep Scan with otherwise valid partial coverage, reviewed surfaces, and no deferred rows is therefore promoted to complete, despite an explicit malformed completion marker indicating that the parent result is unverified. Validate the canonical parent's marker here as well so malformed parent drafts remain partial rather than producing a successful scan conclusion.

AGENTS.md reference: sdk/typescript/AGENTS.md:L22-L24

Useful? React with 👍 / 👎.

Comment on lines +594 to +597

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 verified results before superseding checkpoints

When a succeeded discovery worker's current result has a malformed completion marker such as null, 0, or "false", this strict check records a warning only after the earlier supersession predicate has accepted that result via current.get("complete") is not False. A non-stopped merge then skips the worker's older checkpoints entirely, so any valid findings present only in those checkpoints disappear from the sealed partial report. Require complete is True before superseding checkpoint history, or continue merging the older findings.

AGENTS.md reference: sdk/typescript/AGENTS.md:L23-L23

Useful? React with 👍 / 👎.

if (
not source_complete
or (
source_completeness != "complete"
and (
worker_id is not None
or source_completeness != "partial"
or coverage.get("completeness") == "unknown"
)
)
or any(
not isinstance(source_coverage.get(field), list)
for field in ("surfaces", "explicitExclusions", "deferred")
)
) and _UNVERIFIED_COVERAGE_WARNING not in warnings:
warnings.append(_UNVERIFIED_COVERAGE_WARNING)
if (
not source_complete or source_completeness != "complete"
) and coverage.get("completeness") in {"complete", "unknown"}:
coverage["completeness"] = "partial"
if superseded and not stopped:
continue
if "threatModel" not in manifest["scan"] and isinstance(draft.get("threatModel"), dict):
Expand Down Expand Up @@ -813,7 +841,11 @@ def valid_finding(value: Any) -> bool:
used.add(item["id"])
if field == "surfaces":
item.setdefault("receiptRefs", [])
if stopped or any(warning not in initial_warnings for warning in warnings):
if (
stopped
or _UNVERIFIED_COVERAGE_WARNING in warnings
or any(warning not in initial_warnings for warning in warnings)
):
coverage["completeness"] = "partial"
if stopped:
if not isinstance(coverage.get("deferred"), list):
Expand Down
2 changes: 1 addition & 1 deletion sdk/typescript/src/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const PACKAGE_VERSIONS = packageVersions(
export const VERSION = PACKAGE_VERSIONS.package;
export const CODEX_SDK_VERSION = PACKAGE_VERSIONS.sdk;
export const CODEX_EXECUTABLE_VERSION = PACKAGE_VERSIONS.executable;
export const BUNDLED_PLUGIN_VERSION = "0.1.60" as const;
export const BUNDLED_PLUGIN_VERSION = "0.1.83" as const;

const PACKAGE_NAME = "@openai/codex-security";

Expand Down
Loading
Loading