Skip to content

feat(threat-model)!: save models with results and support offline export - #1133

Merged
mldangelo-oai merged 42 commits into
mainfrom
mdangelo/codex/save-and-export-threat-models
Oct 3, 2026
Merged

mldangelo-oai merged 42 commits into
mainfrom
mdangelo/codex/save-and-export-threat-models

Conversation

@mldangelo-oai

@mldangelo-oai mldangelo-oai commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Save threat models with scan results and export them without rerunning inference, including when a scan stops or its Markdown document cannot be written.

Changes

  • Retain canonical model content and provenance across Standard, Deep, Diff, and security-policy workflows. Expose verified model paths in SDK, history, component, and bulk results.
  • Add export [result-dir] --artifact threat-model with the alternative source selector --scan IDPREFIX. Threat-model export defaults to Markdown in ./threatmodel.md; --output - writes to stdout. Findings export retains its SARIF default. Add SDK exportArtifact and nullable threatModelPath fields.
  • Preserve artifact seals, source identity, legacy structured models, cancellation, and completed scan snapshots. Treat Markdown generation as optional while retaining canonical content and warnings.
  • Recover the selected worker checkpoint model, including a newer terminal checkpoint saved before result.json is replaced. Preserve a newer completed result and freeze the selected model with source digests so publication retries cannot change it.
  • Merge current main, update the embedded workflow hash and snapshot metadata source, and remove the unused relaxed saved-scan resolver.

Testing

  • All five portable plugin checks passed: Ruff lint and formatting, SDK build:ci, source compatibility, and its 9 regression tests.
  • SDK and MCP types, SDK formatting, and bundled plugin build passed with the pinned dependencies.
  • The terminal-model ordering regression passed all 5 cases, including explicit and default completion. The expanded saved-model publication retry checks passed all 15 cases.
  • All 30 focused MCP checks passed across storage, projection, state fallback, and Deep stdio lifecycle (the lifecycle check was rerun with a standard umask).
  • The local npm archive validated all 536 entries. Installed-package smoke could not complete because the registry returned ETARGET for the pinned @linear/sdk@96.0.0 dependency.
  • Saved-model and report-projection suites passed: 73 tests and 53 subtests.
  • Focused SDK coverage passed 408 tests (1 platform skip) across 14 files with seed 12345. Three Python workbench suites passed all 166 tests.
  • Three independent native code reviews and a fresh verification pass found no remaining actionable issues.
  • Full SDK suites completed: seed 12345 had 3,471 passed and 5 failed; normal order had 3,473 passed and 3 failed (53 skipped in each). Four workflow cases hit the 30s timeout and one TUI case resolved the wrong local dependencies. All five distinct failing cases passed focused reruns with the pinned dependencies and a 120s workflow-test timeout.

Risk and rollout

This adds public export syntax and SDK fields. SecurityPolicyDraft.threatModelPath can be null when its convenience document cannot be written; canonical model content remains exportable. Historical structured models remain readable. Saved-artifact export does not run model inference. No migration or deployment step is required.

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.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 30, 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-10-03T19:06:45.351578Z 70ac5e6 New commits
🔒 Security Review ✅ Completed 2026-10-03T19:05:40.904245Z 70ac5e6 New commits

Security findings

Blocking findings (1)

ℹ️ 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 chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3180210421

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

Comment thread sdk/typescript/src/security-policy.ts
Comment thread plugins/codex-security/scripts/finalize_scan_contract.py
Comment thread plugins/codex-security/schemas/tools/scan-draft.schema.json Outdated
@github-actions github-actions Bot added the breaking-change Breaking change called out in generated release notes label Sep 30, 2026
Comment thread plugins/codex-security/tests/test_threat_model_projection.py Fixed
Comment thread plugins/codex-security/scripts/finalize_scan_contract.py Fixed
Comment thread plugins/codex-security/scripts/workbench_saved_results.py Fixed

@soyeon-oai soyeon-oai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Withholding approval: package validation currently fails, and the existing cancellation, stale-projection and blank-Markdown issues remain applicable after tracing their callers (discussion_r4150025654, discussion_r4150025660, discussion_r4150025667). Reviewed changed hunks and integration paths via source and hosted CI; no local execution. The package/container failure below is confirmed in hosted logs, not inferred from the PR description.

Comment thread sdk/typescript/src/index.ts
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3180210421

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

Comment thread sdk/typescript/src/component-scan.ts Outdated
Comment thread plugins/codex-security/scripts/workbench_saved_results.py Outdated
Comment thread plugins/codex-security/schemas/scan-manifest.schema.json Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Cancellation can be swallowed, completed policies can expose stale provisional documents, and legacy model paths can escape through symlinked parent directories.

Review effort: Balanced
Findings: 1 High severity · 2 Medium severity

Open (3)
What changed in this PR

Adds durable threat-model retention and offline export across scans, policy generation, CLI, SDK, and workbench workflows.

Changes:

  • Saves canonical models and generated threatmodel.md documents at checkpoints and completion.
  • Adds CLI/SDK/workbench threat-model export support.
  • Extends schemas, result APIs, documentation, and tests for structured and Markdown models.
File Description
sdk/​typescript/​tests-ts/​security-policy.test.ts Tests policy model retention.
sdk/​typescript/​tests-ts/​result.test.ts Tests result model accessors.
sdk/​typescript/​tests-ts/​custom-validation.test.ts Tests revised prompts.
sdk/​typescript/​tests-ts/​component-scan.test.ts Tests component model links.
sdk/​typescript/​tests-ts/​compact-diff-scan.test.ts Tests canonical diff models.
sdk/​typescript/​tests-ts/​cli.test.ts Updates export help tests.
sdk/​typescript/​tests-ts/​cli-policy.test.ts Updates policy path expectations.
sdk/​typescript/​tests-ts/​cli-export.test.ts Tests CLI model exports.
sdk/​typescript/​tests-ts/​artifact-export.test.ts Tests offline export API.
sdk/​typescript/​tests-ts/​api-post-scan.test.ts Tests model restoration.
sdk/​typescript/​tests-ts/​api-policy.test.ts Tests policy checkpoints.
sdk/​typescript/​src/​security-policy.ts Retains and projects policy models.
sdk/​typescript/​src/​security-policy-cli.ts Exposes policy models in output.
sdk/​typescript/​src/​saved-scan.ts Resolves incomplete saved scans.
sdk/​typescript/​src/​result.ts Adds model content and path accessors.
sdk/​typescript/​src/​multiscan.ts Links bulk-scan models.
sdk/​typescript/​src/​models.ts Expands threat-model types.
sdk/​typescript/​src/​index.ts Exports artifact API.
sdk/​typescript/​src/​custom-validation-prompt.ts Adapts checkpoint instructions.
sdk/​typescript/​src/​component-scan.ts Links component models.
sdk/​typescript/​src/​cli.ts Adds artifact-aware export CLI.
sdk/​typescript/​src/​artifact-export.ts Implements offline artifact export.
sdk/​typescript/​src/​api.ts Propagates model settings and paths.
sdk/​typescript/​README.md Documents model export contracts.
README.md Adds export usage overview.
plugins/​codex-security/​tests/​test_workbench_standard_deep_results.py Tests recovered Deep models.
plugins/​codex-security/​tests/​test_workbench_db_exports.py Tests provisional workbench exports.
plugins/​codex-security/​tests/​test_threat_model_projection.py Tests rendering and compatibility.
plugins/​codex-security/​tests/​test_report_projection.py Tests Markdown preservation.
plugins/​codex-security/​skills/​threat-model/​SKILL.md Defines model checkpoint behavior.
plugins/​codex-security/​skills/​security-scan/​SKILL.md Adds early model checkpoints.
plugins/​codex-security/​skills/​security-scan/​references/​desktop-scan.md Updates desktop checkpoint guidance.
plugins/​codex-security/​skills/​security-diff-scan/​SKILL.md Retains diff-scan models.
plugins/​codex-security/​scripts/​workbench_saved_results.py Publishes model metadata and documents.
plugins/​codex-security/​scripts/​workbench_publication.py Exports workbench models.
plugins/​codex-security/​scripts/​workbench_db.py Exposes model result fields.
plugins/​codex-security/​scripts/​workbench_cli.py Adds artifact export arguments.
plugins/​codex-security/​scripts/​threat_model_projection.py Renders model documents.
plugins/​codex-security/​scripts/​report_projection.py Reuses model rendering in reports.
plugins/​codex-security/​scripts/​finalize_scan_contract.py Saves and exports model projections.
plugins/​codex-security/​schemas/​tools/​scan-draft.schema.json Supports Markdown model drafts.
plugins/​codex-security/​schemas/​scan-manifest.schema.json Supports expanded model manifests.
plugins/​codex-security/​references/​threat-model.md Documents canonical model retention.
plugins/​codex-security/​references/​scan-contract.md Defines model contract variants.
plugins/​codex-security/​references/​scan-artifacts.md Documents canonical model paths.
plugins/​codex-security/​references/​final-report.md Updates report model guidance.
plugins/​codex-security/​references/​core-scan.md Requires early model checkpoints.
plugins/​codex-security/​references/​artifact-storage.md Updates model storage rules.
plugins/​codex-security/​plugin-files.json Packages the model renderer.
plugins/​codex-security/​mcp-app/​tests/​test_workbench_state_fallback.mjs Updates standalone filenames.
plugins/​codex-security/​mcp-app/​tests/​test_threat_model_document.mjs Tests worker model projection.
plugins/​codex-security/​mcp-app/​tests/​test_artifact_storage.mjs Tests model storage and export.
plugins/​codex-security/​mcp-app/​tests/​test_artifact_storage_regressions.mjs Tests compatibility and restrictions.
plugins/​codex-security/​mcp-app/​src/​types.ts Adds model result fields.
plugins/​codex-security/​mcp-app/​src/​threat-model-document.ts Generates worker model documents.
plugins/​codex-security/​mcp-app/​src/​server/​compact-artifact-tools.ts Updates artifact tool contracts.
plugins/​codex-security/​mcp-app/​src/​scan-handoff.ts Adds handoff checkpoint guidance.
plugins/​codex-security/​mcp-app/​src/​artifact-storage.ts Supports new model filename.
plugins/​codex-security/​mcp-app/​src/​artifact-scan-draft.ts Projects models from drafts.
plugins/​codex-security/​mcp-app/​src/​artifact-deep-reducer.ts Projects reduced Deep models.
plugins/​codex-security/​mcp-app/​server.ts Exposes artifact-aware MCP export.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread sdk/typescript/src/result.ts Outdated
Comment thread sdk/typescript/src/security-policy.ts
Comment thread sdk/typescript/src/security-policy.ts Outdated
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Manifest fallback can associate an unrelated policy threat model with a scan that has no saved model.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
Resolved since last review (3)

Comment thread plugins/codex-security/scripts/finalize_scan_contract.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e126a7909f

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

Comment thread plugins/codex-security/scripts/finalize_scan_contract.py
Comment thread plugins/codex-security/scripts/threat_model_projection.py
Comment thread plugins/codex-security/scripts/threat_model_projection.py Outdated
Comment thread sdk/typescript/src/cli.ts Outdated
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

@mldangelo-oai
mldangelo-oai requested a balanced review from Copilot October 1, 2026 21:40
@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: b29de81516

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

@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

Addressed the projection-warning item in this review in 3622cf8. Final projection warnings now use the existing completion and recovery warning lists, including repeated completion and sealed-result refresh. Saved history and SDK responses retain the warning once. The regression tests verify successful completion and unchanged canonical content when the optional Markdown document cannot be written.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3622cf84c4

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

Comment thread sdk/typescript/src/artifact-export.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Stopped-worker recovery can publish a stale valid result model instead of the newer recorded checkpoint head.

Review effort: Balanced
Findings: 1 High severity

Open (1)

Comment thread plugins/codex-security/scripts/workbench_saved_results.py Outdated
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The broad cross-runtime changes affect public APIs, artifact integrity, recovery, and concurrent publication paths that warrant final human review.

Review effort: Balanced
Findings: None

Resolved since last review (1)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7251dbf86f

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

Comment thread plugins/codex-security/scripts/workbench_saved_results.py
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 0d68206b85

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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Failed post-scan recovery can leave a newly created model projection that supersedes the completed snapshot.

Review effort: Balanced
Findings: None

Previously missed (1)

In code that hasn't changed since last review

Medium severity Remove newly created threatmodel.md after failed post-scan

sdk/​typescript/​src/​api.ts:2184

A failed post-scan turn can leave a newly created threatmodel.md outside the restored snapshot. This list only records a model document when one existed before the turn. If a completed legacy/no-model scan starts with threatModelPath === null, the follow-up can write a canonical model/projection and then fail; the manifest is restored, but the new root document remains. The legacy fallback then treats that file as the scan's saved model, so later history/export no longer reflects the completed snapshot. Track the absent state for threatmodel.md and remove a file created by a failed follow-up (while retaining the existing safe-path restoration checks).

@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

Reviewed the “Previously missed 1” rollback concern in this review.

Follow-up instructions start after complete-scan seals the result. A successful rollback restores that manifest and its recorded artifacts. The saved-model reader returns no model for a sealed manifest without a canonical model or recorded legacy path, before inspecting a newly created threatmodel.md. Recorded legacy documents are already included in the artifact snapshot, even when threatModelPath is null. Canonical models remain authoritative; a mismatching projection returns a null path.

The existing test_sealed_scan_does_not_expose_unrecorded_legacy_models covers all four unrecorded legacy filenames and verifies that lookup and export remain unavailable. See the sealed reader and regression. The proposed model adoption does not occur under this contract, so no deletion behavior was added.

@soyeon-oai soyeon-oai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Source review focused on simplification; no tests were run.

Comment thread sdk/typescript/src/saved-scan.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a34da8c784

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

Comment thread plugins/codex-security/mcp-app/src/threat-model-document.ts
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

Updated through 70ac5e62 to include current main, preserving saved-model export and recovery behavior. Terminal Deep drafts now retain an omitted canonical model while replacing older findings and coverage.

All five portable plugin checks, SDK/MCP types, SDK formatting, and the bundled plugin build passed. The MCP suites passed 189 tests, and the affected Python publication/recovery suites passed 342 tests. Both complete SDK runs passed 3,565 tests with 53 skips and zero failures (seeds 12345 and 3811945789). Three independent native reviews plus fresh verification found no actionable issues.

All required checks passed for 70ac5e62 (CI run). All 38 review threads are resolved.

@alandelong-oai alandelong-oai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 70ac5e628df8d73dde495b958f7a4084baee9cfa against 3642a76a53173e012f579737d1b6cf4096379af2 with exactly three independent full-diff passes, including all changed tests, and independent root verification. No serious introduced findings remain. The inline P3 is a test portability issue; all four legacy export controls preserve the original bytes and resolve to the same physical file.

Validation on macOS arm64: both full SDK runs (seeds 12345 and 2571051859) had 3,553 passes, 64 skips and the same single sandbox-denied ps check; that unchanged test passed with permission. Touched Python tests had 524 passes and 52 passing subtests, with only the inline filename-spelling assertion failing. All 36 distinct touched MCP outcomes passed after one watcher-permission rerun. Fresh native build, plugin/SDK builds, types, formatting, Ruff 0.16.9 and portable checks passed.

The 540-entry package archive check passed; full installed-package smoke could not reach its assertions because npm returned ETARGET for @types/node@26.6.3. No model execution or local Windows run. All reviewed source files still match the head.

path.write_text(body)
self.assertEqual(FINALIZER.build_threat_model_export(source), body.encode())
self.assertEqual(path.read_text(), body)
self.assertEqual(FINALIZER.describe_threat_model(source)["path"], str(path))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Compare file identity for legacy names on case-insensitive filesystems

The threat_model.md subtest fails on a case-insensitive macOS volume: discovery checks THREAT_MODEL.md first and returns that spelling for the same physical file, so this exact string comparison fails even though export succeeds. I reproduced the assertion failure and separately verified all four legacy variants export identical bytes without changing the source. Compare Path(returned_path).samefile(path) here, while keeping the byte-preservation assertions.

@mldangelo-oai
mldangelo-oai merged commit 775e48f into main Oct 3, 2026
60 checks passed
@mldangelo-oai
mldangelo-oai deleted the mdangelo/codex/save-and-export-threat-models branch October 3, 2026 20:30
@github-actions github-actions Bot mentioned this pull request Oct 3, 2026
3 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change Breaking change called out in generated release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants