Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
155 commits
Select commit Hold shift + click to select a range
cd4423c
feat(plugin): add patch risk assessment
mldangelo-oai Aug 25, 2026
4db1564
fix(plugin): tighten patch-risk invariants
mldangelo-oai Aug 26, 2026
910847b
fix(plugin): validate patch-risk evidence consistently
mldangelo-oai Aug 26, 2026
3ade0ac
fix(plugin): reject contradictory merge evidence
mldangelo-oai Aug 26, 2026
ab56e56
fix(plugin): keep established defects out of evidence holds
mldangelo-oai Aug 26, 2026
d44ffe6
fix(plugin): preserve evidence-hold states
mldangelo-oai Aug 26, 2026
002d799
fix(plugin): bind failed checks to evidence
mldangelo-oai Aug 26, 2026
78cdd37
fix(plugin): preserve terminal risk evidence
mldangelo-oai Aug 26, 2026
276276e
fix(plugin): enforce decisive risk evidence
mldangelo-oai Aug 26, 2026
982bade
fix(plugin): align patch-risk decisions
mldangelo-oai Aug 26, 2026
9497314
fix(plugin): require terminal risk evidence
mldangelo-oai Aug 26, 2026
5855442
fix(plugin): preserve applicability hold evidence
mldangelo-oai Aug 26, 2026
1505d53
feat(cli): add deterministic patch reviews
mldangelo-oai Aug 25, 2026
8d972bf
fix(cli): harden patch review boundaries
mldangelo-oai Aug 26, 2026
d4b2e44
fix(cli): close patch review publication gaps
mldangelo-oai Aug 26, 2026
14cb37d
fix(cli): preserve hidden candidate changes
mldangelo-oai Aug 26, 2026
a0db49a
fix(cli): normalize reviewed paths for publication
mldangelo-oai Aug 26, 2026
42d7b40
fix(cli): bind approvals to final patch state
mldangelo-oai Aug 26, 2026
b978845
fix(cli): isolate deterministic review boundaries
mldangelo-oai Aug 26, 2026
9984cd0
fix(cli): confine independent review context
mldangelo-oai Aug 26, 2026
d0092a8
fix(cli): harden deterministic patch reviews
mldangelo-oai Aug 26, 2026
e8ad6d5
fix(plugin): align patch-risk terminal evidence
mldangelo-oai Aug 26, 2026
48f0052
fix(cli): harden deterministic review boundaries
mldangelo-oai Aug 26, 2026
d83261d
Merge patch-risk contract fixes
mldangelo-oai Aug 26, 2026
f4ea2e3
fix(cli): parse nested include sections
mldangelo-oai Aug 26, 2026
a4ea5f4
fix(plugin): bind patch-risk evidence outcomes
mldangelo-oai Aug 26, 2026
974d73d
fix(cli): preserve local review instructions
mldangelo-oai Aug 26, 2026
e903b67
Merge patch-risk evidence fixes
mldangelo-oai Aug 26, 2026
69057bf
test(plugin): bind applicability evidence fixtures
mldangelo-oai Aug 26, 2026
737b6df
Merge applicability evidence fixtures
mldangelo-oai Aug 26, 2026
16e1dcb
fix(cli): preserve complete review boundaries
mldangelo-oai Aug 26, 2026
3c0f323
fix(plugin): structure patch-risk applicability evidence
mldangelo-oai Aug 26, 2026
c25a4e8
Merge structured applicability evidence
mldangelo-oai Aug 26, 2026
de37c32
fix(cli): restage reviewed ignored restorations
mldangelo-oai Aug 26, 2026
07cb8c0
fix(plugin): close remaining evidence-plan gaps
mldangelo-oai Aug 26, 2026
47f53b7
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
c78e747
fix(cli): seal patch review snapshot inputs
mldangelo-oai Aug 26, 2026
0871a3d
fix(plugin): count failed checks as executed
mldangelo-oai Aug 26, 2026
6907542
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
14956c4
fix(cli): preserve sparse review baselines
mldangelo-oai Aug 26, 2026
f31b1d8
fix(plugin): bind patch-risk evidence outcomes
mldangelo-oai Aug 26, 2026
bd21619
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
eaefdd2
fix(cli): bind reviewed patches to repository state
mldangelo-oai Aug 26, 2026
0aed06e
fix(cli): normalize buffered directory entries
mldangelo-oai Aug 26, 2026
fcedfa7
fix(plugin): validate every evidence branch
mldangelo-oai Aug 26, 2026
01edd99
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
37e1e64
fix(cli): seal hidden patch review state
mldangelo-oai Aug 26, 2026
7533543
fix(cli): bind hidden worktree state
mldangelo-oai Aug 26, 2026
c3a484d
test(plugin): align unknown-impact confidence
mldangelo-oai Aug 26, 2026
56ad21c
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
e6941ef
fix(plugin): close residual evidence branches
mldangelo-oai Aug 26, 2026
ee7ce9d
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
f5748aa
Merge remote-tracking branch 'origin/main' into mdangelo/codex/port-p…
mldangelo-oai Aug 26, 2026
96d7c97
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
ed65e01
fix(plugin): preserve Unicode diagnostics
mldangelo-oai Aug 26, 2026
4ea38f2
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
0e8d59d
fix(cli): seal Git snapshot metadata
mldangelo-oai Aug 26, 2026
47e526b
test(plugin): align exact-head fixtures
mldangelo-oai Aug 26, 2026
b897e7a
Merge remote-tracking branch 'origin/mdangelo/codex/port-patch-risk-a…
mldangelo-oai Aug 26, 2026
e56be59
fix(plugin): close evidence outcome gaps
mldangelo-oai Aug 26, 2026
b041d65
Merge remote-tracking branch 'origin/mdangelo/codex/port-patch-risk-a…
mldangelo-oai Aug 26, 2026
1792e01
fix(cli): verify cumulative reviewed patches
mldangelo-oai Aug 26, 2026
0b469a9
test(plugin): align protection fixtures
mldangelo-oai Aug 26, 2026
fddc035
Merge remote-tracking branch 'origin/mdangelo/codex/port-patch-risk-a…
mldangelo-oai Aug 26, 2026
1a073ff
fix(cli): preserve Git review boundaries
mldangelo-oai Aug 26, 2026
9bf388e
fix(plugin): distinguish required validation
mldangelo-oai Aug 26, 2026
709046c
Merge remote-tracking branch 'origin/mdangelo/codex/port-patch-risk-a…
mldangelo-oai Aug 26, 2026
c2cfc70
fix(cli): preserve sparse review index state
mldangelo-oai Aug 26, 2026
52a04eb
fix(plugin): tighten block evidence semantics
mldangelo-oai Aug 26, 2026
62c57eb
fix(cli): preserve remaining review state
mldangelo-oai Aug 26, 2026
4ddcaa2
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
11ec94a
fix(cli): preserve nested review state
mldangelo-oai Aug 26, 2026
3c00ba6
fix(plugin): align patch risk evidence contract
mldangelo-oai Aug 26, 2026
653d82e
Merge patch-risk evidence contract
mldangelo-oai Aug 26, 2026
1e77f4c
fix(cli): allow reviewed path shape changes
mldangelo-oai Aug 26, 2026
c7cd9a1
fix(cli): capture file directory replacements
mldangelo-oai Aug 26, 2026
4002517
fix(plugin): align evidence outcomes with safety
mldangelo-oai Aug 26, 2026
0cd2e22
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
d2ea6a2
fix(cli): preserve reviewed patch state
mldangelo-oai Aug 26, 2026
73d88a5
fix(plugin): validate branch likelihood outcomes
mldangelo-oai Aug 26, 2026
9ffb290
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
f9a6f99
fix(cli): preserve cumulative reviewed files
mldangelo-oai Aug 26, 2026
83df522
fix(plugin): align evidence branch outcomes
mldangelo-oai Aug 26, 2026
2e78c16
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
998eeeb
fix(cli): preserve normalized publication trees
mldangelo-oai Aug 26, 2026
6fcc607
fix(plugin): close patch-risk contract gaps
mldangelo-oai Aug 26, 2026
c4092b7
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
5426e1b
fix(cli): review beside unmerged index entries
mldangelo-oai Aug 26, 2026
6f4f3fd
fix(plugin): validate evidence branch terminal states
mldangelo-oai Aug 26, 2026
dd42c35
Merge remote-tracking branch 'origin/mdangelo/codex/port-patch-risk-a…
mldangelo-oai Aug 26, 2026
83078e9
fix(plugin): keep evidence branches internally consistent
mldangelo-oai Aug 26, 2026
46b609d
Merge remote-tracking branch 'origin/mdangelo/codex/port-patch-risk-a…
mldangelo-oai Aug 26, 2026
7d496c6
fix(cli): bind nested repository snapshot identity
mldangelo-oai Aug 26, 2026
f8dab5c
fix(cli): accept Git directory records in nested snapshots
mldangelo-oai Aug 26, 2026
9984124
fix(cli): reject Git config includes during review
mldangelo-oai Aug 26, 2026
6b4d66f
fix(cli): reject new empty review directories
mldangelo-oai Aug 26, 2026
9d512db
fix(cli): close remaining review integrity gaps
mldangelo-oai Aug 26, 2026
320fee8
fix(plugin): align established safety risk severity
mldangelo-oai Aug 26, 2026
2be4f7d
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
967067e
fix(cli): bind Git lock state during review
mldangelo-oai Aug 26, 2026
edc51ad
fix(plugin): validate effective evidence branches
mldangelo-oai Aug 26, 2026
f215195
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
76fd1c9
fix(plugin): complete patch-risk evidence contract
mldangelo-oai Aug 26, 2026
46bd9fe
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
d58b42c
fix(cli): seal review filesystem context
mldangelo-oai Aug 26, 2026
e916748
fix(plugin): enforce branch confidence parity
mldangelo-oai Aug 26, 2026
d95f0e3
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
3220ea5
fix(plugin): preserve established branch evidence
mldangelo-oai Aug 26, 2026
fafb8b3
Merge branch 'mdangelo/codex/port-patch-risk-assessment' into mdangel…
mldangelo-oai Aug 26, 2026
0d7aaaa
fix(cli): preserve patch review invariants
mldangelo-oai Aug 26, 2026
bae272e
fix(cli): seal patch reviewer state
mldangelo-oai Aug 26, 2026
e016729
fix: protect nested linked-worktree metadata
mldangelo-oai Aug 26, 2026
18390c0
fix: seal sibling worktree metadata
mldangelo-oai Aug 26, 2026
3b8f9f1
fix: revalidate patch file confinement
mldangelo-oai Aug 26, 2026
2eb9937
fix: seal patch review object and module state
mldangelo-oai Aug 26, 2026
f312d19
test: allow patch review integration setup
mldangelo-oai Aug 26, 2026
a3cf658
fix: preserve raw submodule metadata paths
mldangelo-oai Aug 26, 2026
ec31053
fix: disable clean filters during patch publication
mldangelo-oai Aug 26, 2026
07adb6d
fix: seal reviewer context and nested empty paths
mldangelo-oai Aug 26, 2026
362c4bd
fix: seal patch review object and metadata boundaries
mldangelo-oai Aug 26, 2026
254fec5
fix: preserve sealed review boundaries
mldangelo-oai Aug 26, 2026
4554f5b
fix: stabilize patch review gates
mldangelo-oai Aug 26, 2026
bd12588
fix(plugin): sync patch-risk assessment skill
soyeon-oai Aug 26, 2026
a140cf5
Merge remote-tracking branch 'origin/mdangelo/codex/port-patch-risk-a…
mldangelo-oai Aug 26, 2026
b1b9712
fix(plugin): make patch-risk validation self-contained
soyeon-oai Aug 26, 2026
754f6b4
Merge remote-tracking branch 'origin/mdangelo/codex/port-patch-risk-a…
mldangelo-oai Aug 27, 2026
19a3c86
fix(plugin): align patch-risk terminal validation
mldangelo-oai Aug 27, 2026
5d9eb2d
Merge branch 'mdangelo/codex/port-patch-risk-assessment' of https://g…
mldangelo-oai Aug 27, 2026
f980e7f
fix(plugin): align patch-risk response contract
mldangelo-oai Aug 27, 2026
20fd7e8
Merge branch 'mdangelo/codex/port-patch-risk-assessment' of https://g…
mldangelo-oai Aug 27, 2026
7030efe
fix(plugin): compare JSON numbers by value
mldangelo-oai Aug 27, 2026
7b66b7d
Merge branch 'mdangelo/codex/port-patch-risk-assessment' of https://g…
mldangelo-oai Aug 27, 2026
dcdbc3d
fix(plugin): enforce terminal risk outcomes
mldangelo-oai Aug 27, 2026
dd03814
Merge branch 'mdangelo/codex/port-patch-risk-assessment' of https://g…
mldangelo-oai Aug 27, 2026
711c48c
Merge branch 'main' into mdangelo/codex/port-patch-risk-assessment
soyeon-oai Aug 27, 2026
832c11b
fix(plugin): reuse shared schema validator
soyeon-oai Aug 27, 2026
bcd0a46
fix(plugin): complete patch-risk decision gates
mldangelo-oai Aug 27, 2026
18e3c80
Merge branch 'mdangelo/codex/port-patch-risk-assessment' of https://g…
mldangelo-oai Aug 27, 2026
f566f8e
fix(cli): avoid filters while creating patch branches
mldangelo-oai Aug 27, 2026
7d1d9b1
test(cli): report clean filter caller
mldangelo-oai Aug 27, 2026
37a9e6b
fix(cli): disable filters while writing patch tree
mldangelo-oai Aug 27, 2026
fda3f8b
Merge branch 'main' into mdangelo/codex/port-patch-risk-assessment
soyeon-oai Aug 27, 2026
b687180
fix(plugin): tighten patch-risk evidence validation
mldangelo-oai Aug 27, 2026
ef05f7d
Merge remote-tracking branch 'origin/mdangelo/codex/port-patch-risk-a…
mldangelo-oai Aug 27, 2026
fda227f
fix(cli): ignore repository diff order files
mldangelo-oai Aug 27, 2026
568fd5e
Merge commit 'ef05f7dbe4a355baab3713d646e91d2d0ab05d21' into mdangelo…
mldangelo-oai Aug 27, 2026
5671925
fix(plugin): bind patch-risk evidence relationships
mldangelo-oai Aug 27, 2026
9ae8590
Merge commit '56719259697338d0aa726887158f73e6a3226399' into mdangelo…
mldangelo-oai Aug 27, 2026
8e84947
fix(plugin): align material exclusions with impact
mldangelo-oai Aug 27, 2026
91a5cc8
Merge commit '8e84947e' into mdangelo/codex/refresh-deterministic-pat…
mldangelo-oai Aug 27, 2026
9913486
fix(cli): invalidate patches after interrupted writes
mldangelo-oai Aug 27, 2026
0fbbed0
fix(plugin): align recovery and validation gates
mldangelo-oai Aug 27, 2026
d619dab
Merge commit '0fbbed03' into mdangelo/codex/refresh-deterministic-pat…
mldangelo-oai Aug 27, 2026
a1b0270
fix(cli): simplify and bind independent patch reviews
mldangelo-oai Aug 27, 2026
af2c4fe
chore: merge final release packaging updates
mldangelo-oai Aug 27, 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
2 changes: 1 addition & 1 deletion .github/workflows/node-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ jobs:
run: ./sdk/typescript/scripts/prepare-windows-test-root.ps1

- name: Test shard ${{ matrix.shard }}
timeout-minutes: 10
timeout-minutes: 15
env:
TEMP: ${{ steps.windows-temp.outputs.path }}
TMP: ${{ steps.windows-temp.outputs.path }}
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,22 @@ Requires Node.js 22.13.0 or later and Python 3.10 or later.
npm install @openai/codex-security
codex-security login
codex-security scan /path/to/directory
codex-security scan /path/to/directory --patch --review-minimality --review-style
```

For CI, set `OPENAI_API_KEY` instead of signing in.

Add `--review-minimality` or `--review-style` to `scan --patch` or `patch`
to trigger a deterministic review workflow. The CLI runs each selected review
as a separate, independent, read-only model invocation: minimality first, then
local coding style. Review scope comes from the Git delta observed after the
author run, excluding pre-existing worktree changes. Both reviews are optional
and disabled by default.
Set `--max-review-revisions 5` to allow up to five author revisions across
actionable review findings; later-stage revisions restart earlier reviews, and
blocked reviews still stop immediately. The revision limit requires at least
one selected review stage.

## TypeScript SDK

Codex Security is a Javascript package:
Expand Down
15 changes: 15 additions & 0 deletions sdk/typescript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ npx @openai/codex-security validate "Possible SQL injection" --effort high
npx @openai/codex-security patch OCCURRENCE_ID
npx @openai/codex-security patch --scan SCAN_ID --severity high --json
npx @openai/codex-security patch --scan SCAN_ID --severity high --create-pr
npx @openai/codex-security patch --scan SCAN_ID --review-minimality --review-style
npx @openai/codex-security patch --scan SCAN_ID --assess-patch-risk --create-pr
npx @openai/codex-security patch --linear-issue SEC-123 --assess-patch-risk --create-pr
```
Expand All @@ -878,6 +879,20 @@ existing work is never included. If publication fails, run the printed
`patch --resume-pr BRANCH` command in the same repository. It reuses the saved
commit without rerunning Codex, but refuses to publish if the branch changed.

Add `--review-minimality` or `--review-style` to `patch` or `scan --patch` for
independent, read-only review stages. Minimality runs before style. The CLI
derives each review from the candidate-only delta against a snapshot of the
containing worktree, including after revisions, and excludes pre-existing
changes. Nested Git repositories and submodules are separate patch targets.
Automatic PR creation stops if a reviewed file had pre-existing changes, and a
`verified` result without an observed candidate delta fails. Reviewer findings
are hypotheses that the revision author validates against the repository.

Both stages are off by default. `--max-review-revisions 5` allows up to five
revisions across the selected stages; otherwise each stage permits one. After a
later-stage revision, earlier selected stages run again. Reviewed scan results
also include `patchRepository`, the Git worktree root used for patch paths.

To patch Linear issues, repeat `--linear-issue ISSUE` (ID or URL), or use
`--linear-project "PROJECT"` with an optional native JSON `--linear-filter`.
Completed and canceled issues are excluded unless the filter sets `state`.
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.60",
"version": "0.1.81",
"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 @@ -18,6 +18,9 @@
"statusQuoRisk",
"autoMergeExclusions",
"affectedRuntimeRoots",
"importantCallers",
"riskDrivers",
"protectiveFactors",
"materialBoundaries",
"validation",
"unknowns",
Expand Down Expand Up @@ -48,7 +51,8 @@
"changedFiles": {"$ref": "#/$defs/stringList"},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
"maxLength": 64,
"pattern": "^[0-9a-fA-F]{64}$"
}
}
},
Expand Down Expand Up @@ -137,30 +141,34 @@
"invariant",
"runtimeRoot",
"counterexample",
"counterexampleSource",
"legitimateControl",
"legitimateControlSource",
"result"
],
"properties": {
"id": {"$ref": "#/$defs/identifier"},
"id": {"$ref": "#/$defs/nonEmptyString"},
"invariant": {"$ref": "#/$defs/nonEmptyString"},
"runtimeRoot": {"$ref": "#/$defs/nonEmptyString"},
"counterexample": {"$ref": "#/$defs/nonEmptyString"},
"counterexampleSource": {"$ref": "#/$defs/nonEmptyString"},
"legitimateControl": {"$ref": "#/$defs/nonEmptyString"},
"legitimateControlSource": {"$ref": "#/$defs/nonEmptyString"},
"result": {"enum": ["supported", "contradicted", "unresolved"]}
}
}
},
"validation": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name", "status", "protects"],
"required": ["name", "status", "protects", "relevant"],
"properties": {
"name": {"$ref": "#/$defs/nonEmptyString"},
"status": {"enum": ["passed", "failed", "skipped", "unavailable"]},
"protects": {"$ref": "#/$defs/nonEmptyString"}
"protects": {"$ref": "#/$defs/nonEmptyString"},
"relevant": {"type": "boolean"}
}
}
},
Expand All @@ -169,8 +177,9 @@
"items": {
"type": "object",
"additionalProperties": false,
"required": ["summary", "decisionCritical"],
"required": ["id", "summary", "decisionCritical"],
"properties": {
"id": {"$ref": "#/$defs/nonEmptyString"},
"summary": {"$ref": "#/$defs/nonEmptyString"},
"decisionCritical": {"type": "boolean"}
}
Expand All @@ -182,13 +191,20 @@
"items": {
"type": "object",
"additionalProperties": false,
"required": ["question", "action", "outcomes"],
"required": ["question", "action", "resolvesUnknowns", "outcomes"],
"properties": {
"question": {"$ref": "#/$defs/nonEmptyString"},
"action": {"$ref": "#/$defs/nonEmptyString"},
"resolvesUnknowns": {
"type": "array",
"minItems": 1,
"items": {"$ref": "#/$defs/nonEmptyString"},
"uniqueItems": true
},
"outcomes": {
"type": "object",
"additionalProperties": {"$ref": "#/$defs/recommendation"},
"propertyNames": {"$ref": "#/$defs/nonEmptyString"},
"minProperties": 2
}
}
Expand All @@ -198,11 +214,8 @@
"$defs": {
"nonEmptyString": {
"type": "string",
"minLength": 1
},
"identifier": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9_-]*$"
"minLength": 1,
"pattern": "^[\\s\\S]*\\S[\\s\\S]*$"
},
"stringList": {
"type": "array",
Expand Down
46 changes: 41 additions & 5 deletions sdk/typescript/_bundled_plugin/scripts/finalize_scan_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,31 @@ def _schema_values_equal(left: Any, right: Any) -> bool:
return left == right


def _schema_value_key(value: Any) -> Any:
"""Return a hashable key with the equality used by JSON Schema."""
if isinstance(value, bool):
return ("boolean", value)
if isinstance(value, (int, float)):
if isinstance(value, float) and math.isnan(value):
# NaN is never equal, including to itself.
return ("number", object())
return ("number", value)
if value is None:
return ("null",)
if isinstance(value, str):
return ("string", value)
if isinstance(value, list):
return ("array", tuple(_schema_value_key(item) for item in value))
if isinstance(value, dict):
return (
"object",
frozenset(
(key, _schema_value_key(item)) for key, item in value.items()
),
)
return ("value", type(value), value)


def _resolve_schema_reference(
root_schema: dict[str, Any], reference: str, context: str
) -> dict[str, Any]:
Expand Down Expand Up @@ -1539,6 +1564,8 @@ def _validate_schema_node(
if isinstance(value, str):
if schema.get("minLength", 0) and len(value) < schema["minLength"]:
raise ContractError(f"{context}: string is too short")
if "maxLength" in schema and len(value) > schema["maxLength"]:
raise ContractError(f"{context}: string is too long")
if "pattern" in schema and not re.fullmatch(schema["pattern"], value):
raise ContractError(f"{context}: string does not match schema pattern")
if schema.get("format") == "date-time":
Expand All @@ -1554,12 +1581,12 @@ def _validate_schema_node(
if "maxItems" in schema and len(value) > schema["maxItems"]:
raise ContractError(f"{context}: array has too many items")
if schema.get("uniqueItems") is True:
for index, item in enumerate(value):
if any(
_schema_values_equal(item, candidate)
for candidate in value[:index]
):
seen_items: set[Any] = set()
for item in value:
key = _schema_value_key(item)
if key in seen_items:
raise ContractError(f"{context}: array items must be unique")
seen_items.add(key)
contains = schema.get("contains")
if isinstance(contains, dict):
matches = 0
Expand Down Expand Up @@ -1598,6 +1625,15 @@ def _validate_schema_node(
raise ContractError(f"{context}.{key}: missing required schema property")
if "minProperties" in schema and len(value) < schema["minProperties"]:
raise ContractError(f"{context}: object has too few properties")
property_names = schema.get("propertyNames")
if isinstance(property_names, dict):
for key in value:
_validate_schema_node(
key,
property_names,
f"{context} property name",
root_schema,
)
properties = schema.get("properties", {})
additional_properties = schema.get("additionalProperties", True)
for key, item in value.items():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ Return both a concise Markdown report and a JSON object conforming to [`../../sc
2. recommendation and workflow label;
3. impact, likelihood, regression protection, recoverability, and confidence ratings with evidence, plus any strict auto-merge exclusions;
4. affected production roots, important callers, contracts, and state;
5. strongest counterexample and legitimate control for each material boundary;
6. relevant tests and checks, including whether they ran and what they actually protect;
5. strongest counterexample and legitimate control for each material boundary, with `counterexampleSource` and `legitimateControlSource` locations;
6. tests and checks, including whether they ran, what they protect, and an explicit `relevant` classification;
7. top risk drivers, protective factors, and status-quo risk; and
8. unknowns plus the bounded evidence plan when held.
8. stable ids for unknowns plus the bounded evidence plan when held; each plan action lists the unknown ids it resolves in `resolvesUnknowns`.

This skill lives at `<plugin-root>/skills/assess-patch-risk/SKILL.md`, so
`<plugin-root>` is two directories up. Resolve `<python_command>` to the
Expand Down
Loading
Loading