Skip to content

feat(cli): review and apply saved SECURITY.md drafts - #489

Open
mldangelo-oai wants to merge 84 commits into
mdangelo/codex/security-policy-draftsfrom
mdangelo/codex/security-policy-command
Open

feat(cli): review and apply saved SECURITY.md drafts#489
mldangelo-oai wants to merge 84 commits into
mdangelo/codex/security-policy-draftsfrom
mdangelo/codex/security-policy-command

Conversation

@mldangelo-oai

@mldangelo-oai mldangelo-oai commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add offline review and explicit application of saved SECURITY.md drafts. policy --apply <artifact-directory> previews the saved draft and offers to install it; --write applies an already-reviewed draft without another confirmation. This PR remains stacked on #536 at 84a4291514cfcd3f5538562373eab76fa6da03b3.

Changes

  • Keep the existing public syntax and defaults. Interactive generation and saved review offer a write confirmation that defaults to No. --headless or an explicit output format skips that prompt. --write requires --apply; it cannot install an unseen model response.
  • Publish complete new policies through the existing atomic, no-clobber installer. Delete the separate visible-copy path and partial-copy classification. Prepare and verify the final filename's SELinux label, including retries.
  • Remove the staging hard link before verification on Windows as well as Unix. Preserve recovery information when cleanup fails after installation.
  • Check inherited guidance after permission verification and detect retained or installed file changes during the final policy traversal. Keep the existing alias, exact-content, concurrent-save, and recovery contracts.
  • Include Smack labels in Linux metadata preservation and verification. Reject existing EFS-encrypted Windows policies before writing staging contents or displacing the original; automatic application does not attempt to change encryption recipients.
  • Clarify generation, offline preview, confirmation, explicit write, cancellation, and artifact paths in help and docs. Show SDK callers when to reload an edited draft. Document the existing-policy replacement gap and encrypted-file limitation.
  • Include the refreshed drafting parent and current main without adding public commands, flags, environment variables, SDK exports, or defaults during this audit pass.

Testing

CI repair at c843a876ba614158bc4d2920d43a5d5bf0d02636 against mdangelo/codex/security-policy-drafts at 84a4291514cfcd3f5538562373eab76fa6da03b3:

  • Budget the Windows installed-package smoke for both npm installation and subsequent verification after CI showed successful commands being interrupted by the overall deadline. Individual command limits are unchanged.
  • All four package-smoke timeout tests passed.
  • JavaScript syntax, changed-file formatting, and git diff checks passed.
  • The full test suite was left to CI.

Earlier validation recorded for prior heads:

Merge conflict resolution at 238973cb37b9e8c58887c71c59f1ee5f4001ad8a against mdangelo/codex/security-policy-drafts at 84a4291514cfcd3f5538562373eab76fa6da03b3:

  • Merge the updated feat(cli): draft SECURITY.md for owner review #536 parent while preserving the policy --apply option, severity-classification value options, and both sets of package-export checks. Keep the PR stacked on its existing parent branch.
  • Focused policy and severity-classification CLI tests: 49 passed.
  • SDK TypeScript check, plugin bundle generation, package smoke-script syntax, changed-file formatting, and git diff --check passed.
  • The full test suite was left to CI.

Earlier validation recorded for prior heads:

At 017d163f724b92f3a85d2a59eacb1212d7917f52:

  • Type/model checks, MCP typecheck, formatting, SDK build, and git diff --check: passed.
  • Synthetic Linux label contracts: three passed, covering final-name SELinux preparation/verification, retry, denial, and rejected Smack/SELinux preservation. The Smack regression incorrectly succeeded before its fix. Native SELinux and Smack enforcement were not exercised locally.
  • The EFS regression passed on native GitHub-hosted Windows at 866a086c, alongside descriptor, audit-rule, and resource-attribute tests. It is restricted to disposable runners because fixture encryption can create a certificate. Current-head CI is requested separately.
  • Preceding commit 866a086c: 2,302 SDK tests passed, 59 skipped, in both fixed and random order. Both installed-target regressions failed before their fix; the focused final-verification set then passed eight tests, with three platform skips. The combined policy/API suites at preceding c2d84a5d passed 146 tests, with 15 platform skips. The inherited framework follow-up passed 99 focused Homebrew Python 3.14 checks and four native standalone Python 3.12 checks. Installed-package smoke and current CI/review results will be recorded in a validation comment.
  • Built-CLI walkthrough: 23 synthetic scenarios passed across both PRs, including saved review without Codex, confirmation, decline, edited drafts, explicit write, and cancellation. No live model calls were made.
  • Portable plugin source checks and Ruff lint/format passed; canonical plugin sources are unchanged by these fixes.

Risk and rollout

Application is optional and never stages, commits, or publishes the policy. Retain reported recovery files until concurrent editor writes are reconciled. EFS-encrypted targets require a tool that preserves their encryption settings. Native Windows and labeled-Linux behavior must be assessed separately from macOS testing.

Blocking design finding: updating an existing policy temporarily removes its final path while the displaced file is checked. A concurrent scan can observe missing guidance, and abrupt termination can leave only the recovery file. The guide now states this limitation; documenting it does not fix it. Closing the gap while retaining the current concurrent-save contract requires a broader replacement design.

Repeated apply/restore/apply cycles can also leave multiple matching recovery snapshots and cause a safe but unnecessary retry rejection. That recovery-association issue remains open. A proposed staging-only SELinux label removal has not been adopted without a native reproduction; the current code rejects mismatched labels before displacing the original.

The parent's comparative generation-quality/cost question and documented macOS temporary-directory sandbox limitation remain open. This pass does not approve, merge, or release the feature.

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.

Preexisting commit metadata and access-restricted automated review links prevent a clean second attestation. They are not reproduced here, and published history has not been rewritten. New examples and fixtures are synthetic; new commits use GitHub noreply metadata.

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the current head, b1de4d9394c8c8ef7a155d0246735405186c9a11.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: b1de4d9394

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

@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 Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: b1de4d9394

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment thread sdk/typescript/src/security-policy.ts

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the current head, 5c0acd8.

@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: a4014d9fe0

ℹ️ 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-cli.ts
Comment thread sdk/typescript/src/security-policy.ts Outdated
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review
@codex security review

Please review exact current head 967a1ebe51f2db7c6740f49283dedc10dfdccb4f, including atomic new-policy publication, SELinux filename labels, staging cleanup, inherited-policy rechecks, and recovery behavior. Focused regressions, built-CLI scenarios, types, formatting, and builds passed; full local suites and fresh platform CI are running. The description records the remaining validation limits.

@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: 967a1ebe51

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

@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: fee8290552

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

if ((await readSecurityPolicy(candidate)) === draft.previousContent)
candidates.push(candidate);
}
if (candidates.length !== 1) {

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 Track the exact recovery file across retries

When the same saved draft has been applied more than once—for example, A→B, the user restores A while reconciling an editor save, and then reapplies B—the artifact directory can legitimately contain two recovery-SECURITY-*.md files whose contents both equal draft.previousContent. Both are added as candidates, so this uniqueness check rejects a subsequent --apply ... --write verification even though the recovery reported by the latest application still exists. Persist or select the exact reported recovery path instead of treating duplicate-content snapshots as unverifiable.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Current head: 866a086cfda8c322dfa59796b2140a988c39ac45. Confirmed as an unresolved retry limitation. An apply/restore/reapply sequence can leave multiple valid original snapshots, so a later exact-content retry rejects safely. Selecting by identical contents would not establish which retained inode belongs to the latest application. I have left this open for the recovery-association design rather than adding another receipt format during this simplification pass.

Comment thread sdk/typescript/src/security-policy.ts Outdated
Comment on lines +1893 to +1894
if (sourceContext !== null && sourceContext !== destinationContext)
arguments_.push("--preserve=context");

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 Clear a staging-only SELinux context

On SELinux Linux, when the existing SECURITY.md has no security.selinux xattr but the newly created temporary file inherits a label from its directory, sourceContext is null and destinationContext is non-null, so this branch neither passes --preserve=context nor clears the destination-only label. GNU cp -p preserves only mode, ownership, and timestamps, with context as a separate attribute (GNU cp documentation); the label therefore remains and verifyUnixSecurityMetadata rejects every update before displacement even when the account could preserve the unlabeled state. Fresh evidence beyond the earlier non-default-context finding is that the current branch only acts when a source label is present.

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

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Current head: 866a086cfda8c322dfa59796b2140a988c39ac45. No label-removal change has been made. The current mismatch rejects before displacement and leaves the original file unchanged. I have not reproduced a native source-without-context/destination-with-context case on an enforcing SELinux filesystem. I am leaving this open rather than removing a security label based only on the synthetic null case.

Comment thread sdk/typescript/src/security-policy.ts
Comment thread sdk/typescript/src/cli.ts

@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: fee8290552

ℹ️ 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 Outdated
Comment thread sdk/typescript/src/security-policy.ts
try {
signal?.throwIfAborted();
// Check the displaced file, then install without replacing a newer save.
await rename(targetPath, recoveryPath);

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 Keep the existing policy visible during replacement

When updating an existing policy, this rename removes SECURITY.md before content, Unix metadata, or the potentially slow Windows descriptor checks finish and before the staged inode is installed. A concurrent scan during that interval resolves no component policy (or falls back to different ancestor guidance), and an abrupt process termination leaves the checkout in that state with only a hidden recovery file. Retain a recovery reference while atomically replacing the target so readers always observe either the old or reviewed policy.

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

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Current head: 866a086cfda8c322dfa59796b2140a988c39ac45. Confirmed and left open as a blocking design finding. The move/check/install sequence leaves the final path absent, including during the Windows descriptor check. The guide now warns about it, but documentation is not a fix. Simply hard-linking the original and renaming over the target can overwrite a newer save; an exchange can preserve that inode while still removing the newer save from the active path. Closing this gap requires choosing and implementing the concurrent-save contract, so I have not substituted another non-atomic verification loop.

@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

@codex security review

Please review current head 866a086cfda8c322dfa59796b2140a988c39ac45, including the retained recovery checks, Linux labels, and rejection of EFS-encrypted replacement. The PR description records completed checks and the unresolved existing-policy replacement design; neither PR is approved or merged by this update.

@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: 866a086cfd

ℹ️ 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
@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review current head c2d84a5d8664a57cf7a9498a43be3ea6576a7aed, including the refreshed drafting parent and installed-file verification after the final traversal. Validation and unresolved design questions are recorded in the PR description; this update does not approve or merge either PR.

@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

const policyGuidance = await resolveSecurityPolicyGuidance(
{ ...target, targetPath },

P2 Badge Revalidate host-resolved policy guidance

When a selected component contains a nested or linked SECURITY.md and that file changes after this one-time host resolution—or during the subsequent multi-stage generation—the model continues using the stale contents because it can no longer read or resolve those policies itself. The following requireUnchangedSecurityPolicy call validates only the selected target and its ancestor snapshot, not descendant/reporting policies from inputs.policyPaths, and there is no later inventory check, so generation can successfully return a draft based on guidance that no longer exists. Snapshot and revalidate every host-resolved policy before accepting the generated draft.

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

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

@codex review

Please review current head 017d163f724b92f3a85d2a59eacb1212d7917f52, including macOS framework Python launch compatibility. Native tests reproduced the CI failure with Homebrew Python 3.14 and now pass while preserving the selected environment and denying sibling reads. The existing replacement-design findings remain open.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: 017d163f72

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

Validation for 017d163f724b92f3a85d2a59eacb1212d7917f52:

  • The installed Node.js 24 package checks passed, including public SDK imports, TypeScript consumers, CLI, MCP, nested workers, and native lifecycle.
  • The final CLI walkthrough passed all 23 scenarios across this PR and feat(cli): draft SECURITY.md for owner review #536. Saved preview, confirmation, explicit write, edited-draft preview, and cancellation constructed no model runtime.
  • Code and security reviews completed on this exact head without new findings; the security check passed. This does not resolve the existing replacement-design findings.

Current-head CI is green: Node CI, container checks, and PR release validation passed. Cancelled duplicate runs are excluded.

The native Windows policy shard passed 544 tests, with 18 platform skips and zero failures; its separate machine-wide PowerShell policy check also passed. This includes EFS, audit-rule, descriptor, and resource-attribute regressions. Both duplicate EFS reports are resolved with this evidence. Native SELinux and Smack enforcement are still unverified; the synthetic label tests are not reported as native coverage.

The existing-policy replacement gap remains blocking: the final path can be absent while the displaced inode is checked. The ambiguous recovery association and staging-only SELinux report also remain open. The latter still needs native reproduction; current mismatch handling rejects before displacing the original. Full local suite results and their tested predecessor commits remain listed in the PR description. This pass does not approve, merge, or release the feature.

@mldangelo-oai

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review head 238973cb37b9e8c58887c71c59f1ee5f4001ad8a against mdangelo/codex/security-policy-drafts at 84a4291514cfcd3f5538562373eab76fa6da03b3. Merge the updated #536 parent while preserving the policy --apply option, severity-classification value options, and both sets of package-export checks. Keep the PR stacked on its existing parent branch.

Focused policy and severity-classification CLI tests: 49 passed. SDK TypeScript check, plugin bundle generation, package smoke-script syntax, changed-file formatting, and git diff --check passed. The full suite is left to CI.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: 238973cb37

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

@codex review

Please review head c843a876ba614158bc4d2920d43a5d5bf0d02636 against mdangelo/codex/security-policy-drafts at 84a4291514cfcd3f5538562373eab76fa6da03b3. Budget the Windows installed-package smoke for both npm installation and subsequent verification after CI showed successful commands being interrupted by the overall deadline. Individual command limits are unchanged.

All four package-smoke timeout tests passed. JavaScript syntax, changed-file formatting, and git diff checks passed. The full suite is left to CI.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: c843a876ba

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants