Skip to content

feat(codex): add Codex CLI governance hooks package - #3409

Open
Josh (thatjosh) wants to merge 26 commits into
microsoft:mainfrom
thatjosh:thatjosh/codex-integration
Open

feat(codex): add Codex CLI governance hooks package#3409
Josh (thatjosh) wants to merge 26 commits into
microsoft:mainfrom
thatjosh:thatjosh/codex-integration

Conversation

@thatjosh

@thatjosh Josh (thatjosh) commented Jul 21, 2026

Copy link
Copy Markdown

Description

Adds agent-governance-codex-cli, a new package bringing AGT governance to the OpenAI Codex CLI. It's a thin host adapter over the existing Claude Code governance core: Codex's hooks (SessionStart, UserPromptSubmit, PreToolUse) mirror Claude Code's contract, so the governance logic is reused unchanged and only host wiring is new approach used for the OpenCode integration #2658. Tested with sandbox and live.

Enforcement map

Codex event AGT behavior
SessionStart inject governance context
UserPromptSubmit prompt inspection, fail-closed block
PreToolUse allow / deny / ask via policy; audit every decision

Proposed via RFC #3408.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Maintenance (dependency updates, CI/CD, refactoring)
  • Security fix

Package(s) Affected

  • agent-os-kernel
  • agent-mesh
  • agent-runtime
  • agent-sre
  • agent-governance
  • docs / root

Checklist

  • My code follows the project style guidelines
  • I have added tests that prove my fix/feature works
  • All new and existing tests pass
  • I have updated documentation as needed
  • I have signed the Microsoft CLA

Attribution & Prior Art

  • This contribution does not contain code copied or derived from other projects without attribution
  • Any external projects that inspired this design are credited in code comments or documentation
  • If this PR implements functionality similar to an existing open-source project, I have listed it below

Prior art / related projects:
Adapted from the in-repo agent-governance-claude-code package (credited in the README), following the same copy-approach used for the OpenCode CLI integration #2658 and the Antigravity CLI integration #2554. Codex's hook contract mirrors Claude Code's.

AI Assistance

  • I can explain every meaningful change in this PR: what it does, why, and what tradeoffs were considered
  • I have run tests and verification appropriate for this change
  • No part of this PR was autonomously submitted by an AI agent without my review
  • I have not used AI to generate review comments on others' PRs

If AI tools materially shaped this change, briefly note what was used:

Built with AI assistance (Claude Code): the host adapter, installer, tests, and
drafted from the existing Claude Code package pattern, then reviewed, tested
(sandbox + live), and adversarially verified by me.

IP, Patents, and Licensing

  • This contribution does not implement patent-pending or patent-encumbered techniques
  • This contribution does not require an NDA or licensing agreement to understand or use
  • Any AI tools used have terms compatible with the MIT License

Related Issues

Implements RFC #3408

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jul 21, 2026
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
🤖 AI Agent: docs-sync-checker — Docs Sync

AI-generated review output. Treat it as untrusted analysis and verify before acting.

Docs Sync

Documentation is in sync.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
🤖 AI Agent: security-scanner — View details

AI-generated review output. Treat it as untrusted analysis and verify before acting.

No security issues found.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
🤖 AI Agent: breaking-change-detector — API Compatibility

AI-generated review output. Treat it as untrusted analysis and verify before acting.

API Compatibility

No breaking changes detected.

@github-actions github-actions Bot added the size/XL Extra large PR (500+ lines) label Jul 21, 2026
@github-actions

Copy link
Copy Markdown
🤖 AI Agent: contributor-guide — View details

AI-generated review output. Treat it as untrusted analysis and verify before acting.

Welcome, and thank you for your contribution! Great job on providing detailed documentation and tests for the new agent-governance-codex-cli package.

Before merging, please address the following:

  1. Ensure the Microsoft CLA is signed, as indicated in the checklist.
  2. Verify that the hooks/hooks.json and config/default-policy.json files referenced in the code are included in the PR.

For guidance, please refer to CONTRIBUTING.md. Let us know if you need any help!

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
🤖 AI Agent: code-reviewer — View details

AI-generated review output. Treat it as untrusted analysis and verify before acting.

TL;DR: 0 blockers, 1 warning. The change introduces a new governance package with reused logic, but lacks explicit validation for Codex-specific edge cases.

# Sev Issue Where
1 Warn Codex-specific edge case validation missing agent-governance-codex-cli

Action items:

  1. Add explicit tests for Codex-specific edge cases (e.g., permissionDecision schema handling, fail-closed scenarios).

Warnings are fine as follow-up PRs.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
🤖 AI Agent: test-generator — View details

AI-generated review output. Treat it as untrusted analysis and verify before acting.

Test coverage looks good. No gaps identified.

@github-actions

Copy link
Copy Markdown

PR Review Summary

Check Status Details
🔍 Code Review ⚠️ Missing No current-run comment
🛡️ Security Scan ⚠️ Missing No current-run comment
🔄 Breaking Changes ⚠️ Missing No current-run comment
📝 Docs Sync ⚠️ Missing No current-run comment
🧪 Test Coverage ⚠️ Missing No current-run comment

Verdict: ⚠️ AI review incomplete; ready for human review

AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims.

@thatjosh

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@thatjosh
Josh (thatjosh) marked this pull request as draft July 21, 2026 12:14
@thatjosh
Josh (thatjosh) force-pushed the thatjosh/codex-integration branch 2 times, most recently from dc1e617 to f36e748 Compare July 21, 2026 12:36
@thatjosh
Josh (thatjosh) marked this pull request as ready for review July 21, 2026 12:38
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@MohammadHaroonAbuomar MohammadHaroonAbuomar 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.

  • Hardening sequencing: this package is a byte-faithful copy of main's claude-code governance core, which means it re-introduces the pre-#3251 fail-open rm option-cluster allow-list and pre-#3295 secret-read patterns in a fifth location that no open fix covers (#3251/#3295 predate this package and won't patch it). Add agent-governance-codex-cli to #3251's scope, rebase onto the hardened patterns, or get explicit maintainer ordering.
  • audit.mjs carries the pre-#3250 rollover-brick bug: MAX_ENTRIES not exported, no seam verification, slice(-MAX_ENTRIES) truncates the chain head from GENESIS so verification fails permanently after 10k entries and fail-closed appends deny every subsequent decision. Adopt the #3250 seam-based fix.
  • server/agt-mcp.mjs (233L) ships unreachable: installer never wires it into Codex config, README never says how to connect it, no mcp-server.test.mjs (claude-code has one). Also default-policy.json allowlists mcp__agt_governance__* which is Claude Code's MCP tool-naming convention, unverified for Codex.
  • Confirm Codex 0.144.x emits Claude-style tool_name values (Bash/Read/WebFetch/MultiEdit); non-matching names silently downgrade the Bash-specific deny rules to generic review.
  • .gitignore: add !agent-governance-codex-cli/bin/* negation per opencode/antigravity precedent (**/[Bb]in/* matches; current files tracked but future bin/ files silently ignored).
  • Fix 'Codex shim' -> 'Claude Code shim' comment slips in the three hook files; 'anchor to CODEX_HOME rather than ~/.codex' is self-contradictory (default IS ~/.codex).
  • (follow-up ok) registration-surface per #2658 precedent: root README row, docs page, dependency-audit doc for the new lockfile, package AGENTS.md.
  • (maintainer) 18 action_required; reserve @microsoft/agent-governance-codex-cli on npm before merge (name now asserted in REGISTERED_NPM_PACKAGES); decide whether RFC #3408 acceptance precedes the reference implementation.

@MohammadHaroonAbuomar MohammadHaroonAbuomar 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.

  • Remaining from round 1 (asks on unwired MCP server, .gitignore negation, and comment slips are addressed at 10779a9 — thanks): (1) hardening sequencing vs #3251/#3295 — this package still copies the pre-#3251 fail-open rm option-cluster allow-list and pre-#3295 secret-read patterns; add the package to #3251's scope, rebase onto the hardened patterns, or get explicit maintainer ordering.
  • (2) audit.mjs still carries the pre-#3250 rollover-brick bug (verification fails permanently after 10k entries; fail-closed appends then deny everything). Adopt the #3250 seam-based fix or track it explicitly for this package.
  • (3) confirm Codex 0.144.x emits Claude-style tool_name values (Bash/Read/WebFetch/MultiEdit); non-matching names silently downgrade Bash-specific deny rules to generic review.
  • (maintainer) 18 action_required; npm name reservation before merge; RFC #3408 ordering decision.

@thatjosh

Josh (thatjosh) commented Jul 21, 2026

Copy link
Copy Markdown
Author

(1) and (2) addressed via 23f3bc6, rebasing on the changes in the open PRs.

Working on (3).

@MohammadHaroonAbuomar MohammadHaroonAbuomar 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.

  • Round-3 verified: hardening adoption is faithful and complete — policy.mjs shared body byte-identical to #3251's opencode head incl. normalizeCommandNameToken, letters-only cluster, recursive-without-force deny; #3295's dropCopyDestinationToken + readTokens + all 4 default-policy.json secret-read hunks verbatim; audit.mjs + rollover test byte-identical to #3250's head incl. the limit+2 e2e test. 18/18 package tests pass locally. Remaining: (1) Codex tool_name vocabulary evidence (author self-declares in progress); (2) CI node-test job has not executed on 23f3bc6 (needs workflow approval); (3) re-sync guard: #3250/#3251/#3295 still open — commit to re-syncing if their merged form differs, or sequence after they land.
  • (minor, non-blocking) port the broader #3251/#3295 test matrices (PowerShell remove-item, backtick/brace invocation, .env template-copy allow, source/redirect denies) to the codex test file.

Signed-off-by: thatjosh <learningcs1711@gmail.com>
…emove unwired MCP server

Signed-off-by: thatjosh <learningcs1711@gmail.com>
…over, microsoft#3251 recursive-delete, microsoft#3295 secret-read)

Signed-off-by: thatjosh <learningcs1711@gmail.com>
…_patch/webrun, view_image)

Signed-off-by: thatjosh <learningcs1711@gmail.com>
…erShell/quoted rm, source/redirect secret reads, .env template allow)

Signed-off-by: thatjosh <learningcs1711@gmail.com>
@thatjosh
Josh (thatjosh) force-pushed the thatjosh/codex-integration branch from 7125037 to 534ef2e Compare July 21, 2026 18:11
@thatjosh

Copy link
Copy Markdown
Author

Amended commits to include DCO signoff.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 33 out of 42 changed files in this pull request and generated 1 comment.

Files not reviewed (5)
  • agent-governance-antigravity-cli/package-lock.json: Generated file
  • agent-governance-claude-code/package-lock.json: Generated file
  • agent-governance-codex-cli/package-lock.json: Generated file
  • agent-governance-copilot-cli/package-lock.json: Generated file
  • agent-governance-opencode/package-lock.json: Generated file
Suppressed comments (1)

agent-governance-codex-cli/lib/policy.mjs:1202

  • isSafeEnvTemplateReadCommand() relies on containsCommandControlOperator() to decide when the .env.* template bypass is allowed, but containsCommandControlOperator() currently ignores I/O redirection and single pipelines. This enables a bypass like cat .env.example < ~/.ssh/id_rsa: the secret-read rule matches id_rsa, but the bypass returns true because it only checks for .env tokens and doesn’t treat < as a control operator, so the deny is skipped.
function containsCommandControlOperator(commandText) {
  return /(?:&&|\|\||[;`]|[\r\n])/.test(commandText);
}

Comment thread agent-governance-codex-cli/test/policy.test.mjs
Comment-staleness pass over the round-5 changes. Codex keeps listing a
known marketplace plugin as "not installed" after removal, and the read-back
gates on the status column, so comments saying "still lists the plugin"
overstated the failure condition:

- uninstall() JSDoc and the matching installer test title now say "still
  reports the plugin as installed", matching the gate and its error message.
- policy test isolation comment now states loadPolicy's actual lookup order
  (explicit policyPath, then $AGT_CODEX_POLICY_PATH, then
  ~/.codex/agt/policy.json, then the bundled default) instead of the
  abbreviated form, and the bundled-failure test reuses isolatedPolicy()
  rather than hand-rolling the same path.

Signed-off-by: thatjosh <learningcs1711@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 31, 2026 14:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 33 out of 42 changed files in this pull request and generated no new comments.

Files not reviewed (5)
  • agent-governance-antigravity-cli/package-lock.json: Generated file
  • agent-governance-claude-code/package-lock.json: Generated file
  • agent-governance-codex-cli/package-lock.json: Generated file
  • agent-governance-copilot-cli/package-lock.json: Generated file
  • agent-governance-opencode/package-lock.json: Generated file
Suppressed comments (2)

.github/dependabot.yml:125

  • The new npm Dependabot entry for agent-governance-codex-cli is missing the commit-message prefix configuration that the other npm entries use. Without it, Dependabot will likely open PRs with default titles (e.g. "Bump …"), which can fail the repo’s PR-title/conventional-commit checks.
  - package-ecosystem: "npm"
    directory: "/agent-governance-codex-cli"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5
    labels:
      - "dependencies"

agent-governance-codex-cli/test/policy.test.mjs:21

  • This comment overstates loadPolicy’s precedence: if $AGT_CODEX_POLICY_PATH is set (even to a missing path), loadPolicy does not fall back to ~/.codex/agt/policy.json; it falls back to the bundled default. Please adjust the comment so future maintainers don’t infer an unsupported fallback behavior.

Copilot AI review requested due to automatic review settings July 31, 2026 15:04
@thatjosh

Copy link
Copy Markdown
Author
  • looksLikeUrlField is dead code within this PR's own additions; remove or wire it.

looksLikeUrlField: removed rather than wired (6431ec7). Wiring it would reintroduce the key-gated URL detection that #2541 deliberately removed on main.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 33 out of 42 changed files in this pull request and generated no new comments.

Files not reviewed (5)
  • agent-governance-antigravity-cli/package-lock.json: Generated file
  • agent-governance-claude-code/package-lock.json: Generated file
  • agent-governance-codex-cli/package-lock.json: Generated file
  • agent-governance-copilot-cli/package-lock.json: Generated file
  • agent-governance-opencode/package-lock.json: Generated file

Copilot AI review requested due to automatic review settings August 1, 2026 16:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 33 out of 42 changed files in this pull request and generated no new comments.

Files not reviewed (5)
  • agent-governance-antigravity-cli/package-lock.json: Generated file
  • agent-governance-claude-code/package-lock.json: Generated file
  • agent-governance-codex-cli/package-lock.json: Generated file
  • agent-governance-copilot-cli/package-lock.json: Generated file
  • agent-governance-opencode/package-lock.json: Generated file

Copilot AI review requested due to automatic review settings August 3, 2026 21:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 33 out of 42 changed files in this pull request and generated no new comments.

Files not reviewed (5)
  • agent-governance-antigravity-cli/package-lock.json: Generated file
  • agent-governance-claude-code/package-lock.json: Generated file
  • agent-governance-codex-cli/package-lock.json: Generated file
  • agent-governance-copilot-cli/package-lock.json: Generated file
  • agent-governance-opencode/package-lock.json: Generated file
Suppressed comments (1)

agent-governance-codex-cli/lib/audit.mjs:110

  • Use American English spelling in user-facing error messages for consistency ("recognized" instead of "recognised").
    throw new Error(`Audit log at ${auditPath} is not a recognised audit format.`);

Copilot AI review requested due to automatic review settings August 4, 2026 14:52
@thatjosh

Copy link
Copy Markdown
Author

liamcrumm and MohammadHaroonAbuomar, could you take another look?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 33 out of 42 changed files in this pull request and generated no new comments.

Files not reviewed (5)
  • agent-governance-antigravity-cli/package-lock.json: Generated file
  • agent-governance-claude-code/package-lock.json: Generated file
  • agent-governance-codex-cli/package-lock.json: Generated file
  • agent-governance-copilot-cli/package-lock.json: Generated file
  • agent-governance-opencode/package-lock.json: Generated file
Suppressed comments (1)

.github/dependabot.yml:125

  • The new Dependabot config for agent-governance-codex-cli is missing the commit-message prefixes that all the other npm entries use, which can cause generated PR titles/commits to fail the repo’s conventional-commit / PR-title checks. Mirror the existing npm entries by adding commit-message.prefix and commit-message.prefix-development.
  - package-ecosystem: "npm"
    directory: "/agent-governance-codex-cli"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5

@thatjosh

Copy link
Copy Markdown
Author

liamcrumm and MohammadHaroonAbuomar, could you take another look?

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

Labels

documentation Improvements or additions to documentation scripts/ci/cd size/XL Extra large PR (500+ lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants