Back to home@Akimiya-z

codex-guard

Quality gate for AI/Codex-generated pull requests: blocks TODO leftovers, leaked secrets, sloppy commits and red CI before they reach main.

Stars
44
Language
JavaScript
Created
Aug 20, 2026
Updated
Aug 22, 2026

Introduction

🤖 Codex Guard

GitHub release (latest by SemVer) GitHub stars License CI Docs Marketplace

Docs site: https://akimiya-z.github.io/codex-guard

An automatic quality gate for AI-generated pull requests. Stop TODO leftovers, leaked secrets, sloppy commits and red CI from reaching main — with zero review bandwidth spent on the obvious stuff.

Works with OpenAI Codex (cloud & CLI), Claude Code, Copilot, and any other agent that opens PRs against your repo.

🐕 Dogfooding: this repo gates its own AI-generated PRs. See a real failing example on PR #6 and the workflow behind it in .github/workflows/codex-guard.yml.


Why

AI coding agents are great at writing code and terrible at cleaning up after themselves. In practice, agent-written PRs tend to arrive with the same handful of problems:

  • // TODO: handle this comments that were never meant to stay
  • Hardcoded API keys and connection strings copied from a chat transcript
  • Commit trails like WIP, fix stuff, more changes — squashed versions of a messy session
  • A green-looking PR that actually has failing CI on the head commit

You shouldn't need a human reviewer to catch those every single time. Codex Guard checks the boring, deterministic things automatically, and only on PRs that look AI-generated — so human attention goes where it matters.

How it works

Codex Guard runs on pull_request, figures out whether the PR looks agent-generated (via label, branch prefix, or title), and then:

CheckWhat it flags
🧹 TODO scanTODO / FIXME / XXX / HACK / WIP markers on added lines only
🔐 Secret scanAWS (access + secret keys), GitHub, Google, OpenAI, Anthropic, Slack, Stripe, npm, SendGrid, Telegram, Azure connection strings, JWTs, hardcoded credentials, connection strings (values are redacted in reports)
💬 Commit hygieneSubjects that don't match conventional commits, empty subjects
🧪 CI statusFailing status checks or check runs on the PR head commit

Each finding is posted as a GitHub check-run annotation at the exact file and line, plus a human-readable summary comment on the PR.

The output below is verbatim from a real run on this repo (PR #6) — an open PR from a codex/ branch that left a TODO, a hardcoded AWS key, a live connection string and two sloppy commits:

## 🤖 Codex Guard

❌ **Checks failed — review the findings before merging.**

| Check | Result |
| --- | --- |
| TODO / FIXME scan | ⚠️ 2 |
| Secret scan | ⚠️ 3 |
| Commit hygiene | ⚠️ 2 |
| CI status | ✅ |

**Unfinished work**
- `scripts/sync.js:4` — `FIXME`: const aws = 'AKIAIOSFODNN7EXAMPLE'; // FIXME: move this to a secret store
- `scripts/sync.js:2` — `TODO`: // TODO: wire up real retry with exponential backoff.
**Potential leaked secrets**
- `scripts/sync.js:4` — AWS Access Key ID `AKIA...MPLE`
- `scripts/sync.js:5` — Connection string `post...prod`
- `scripts/sync.js:7` — OpenAI API Key `sk-p...6789`
**Commit hygiene**
- `7c84ae1` — _WIP stuff_ (by Akimiya-z)
- `1affcf8` — _tmp_ (by Akimiya-z)

> Detected as an AI-generated PR (branch prefix "codex/").

Quick start

Add a workflow file, e.g. .github/workflows/codex-guard.yml:

name: Codex Guard
on:
  pull_request:

permissions:
  contents: read
  pull-requests: write
  checks: write

jobs:
  codex-guard:
    runs-on: ubuntu-latest
    steps:
      - uses: Akimiya-z/codex-guard@v1

That's it. The PR fails the required status check until the findings are resolved (or the PR is marked with an ignore label — see "Opting out").

One-click from the GitHub Actions Marketplace.

Block merges on it like any other required check: Settings → Branches → Require status checks → Codex Guard.

Detecting agent PRs

By default Codex Guard only gates PRs it believes were written by an agent, so human-authored PRs are never slowed down:

  • Label matches one of codex-generated, agentic, ai-generated
  • Branch starts with codex/, claude-auto, gh-codex/
  • Title contains Generated by Codex, Generated by Claude, Generated by Copilot

All of these are configurable — or set gate-agents-only: false to gate every PR.

Opting out of a specific PR

Add a label named codex-guard-ignore (configurable) to a PR and Codex Guard will pass it without running checks. Useful when a human has already reviewed and accepted the changes.

Inputs

InputDefaultDescription
github-token${{ github.token }}Token with write access to checks and PRs.
gate-agents-onlytrueOnly gate PRs detected as agent-generated.
agent-labelscodex-generated,agentic,ai-generatedLabels marking an agent PR.
agent-branch-prefixescodex/,claude-auto,gh-codex/Branch prefixes marking an agent PR.
agent-keywordsGenerated by Codex,Generated by Claude,Generated by CopilotTitle keywords marking an agent PR.
ignore-labelcodex-guard-ignorePR label that skips all checks.
check-todostrueScan added lines for unfinished-work markers.
todo-patternsTODO,FIXME,XXX,HACK,WIPMarkers to flag.
todo-blockingtrueFail on TODO findings (false = warn only).
check-secretstrueScan added lines for hardcoded secrets.
secret-exclude-paths(empty)File path substrings to skip (e.g. README,test/fixtures).
check-commitstrueValidate commit subjects.
commit-patternconventional commit regexRegex subjects must match.
check-citrueFail on failing CI for the head commit.
ignore-check-run-names(empty)Check/context names to ignore when assessing CI.
post-commenttruePost a report comment on failures.
comment-modereplacereplace updates the previous report in place (one comment per PR), append posts a new one each run, none never posts.
request-changesfalseAlso submit a formal REQUEST_CHANGES review on blocking findings (opt-in; needs pull-requests: write).
notify-users(empty)Comma-separated usernames to @-mention in the report comment on blocking findings.
soft-failfalseReport findings but never fail the workflow.
config-path.github/codex-guard.ymlOptional per-repo policy file (on the default branch) overriding workflow inputs.
fail-on(empty)Comma-separated blocking checks: todos,secrets,commits,ci. Empty = legacy behavior; a subset makes excluded checks non-blocking.
sweepfalseScan every open agent PR instead of a single one (use with workflow_dispatch).
sweep-label(empty)Only sweep PRs carrying this label.
sweep-basemainOnly sweep PRs targeting this base branch.

Configuration file

Every input above can be overridden per-repo with a .github/codex-guard.yml file on the default branch — so agents can't just loosen the policy in their PR. Unknown keys are ignored (typo tolerant).

# .github/codex-guard.yml
gate-agents-only: true
agent-labels:
  - codex-generated
  - agentic
todo-patterns:
  - TODO
  - FIXME
  - XXX
secret-exclude-paths:
  - README.md
  - docs/
# Only these checks block merges; TODOs below fail the run, not the merge.
fail-on:
  - secrets
  - commits
  - ci
comment-mode: replace
request-changes: true

A copy-paste template lives at examples/codex-guard.yml.

Local dry-run (CLI)

Preview the same checks locally before CI — no repo, no token, no waiting. Point it at a unified diff, get the identical findings and blocking rules:

# from npm — no install needed (v1.7.0+)
npx -y codex-guard --diff <(git diff origin/main)

# from this repo's source
git diff origin/main > /tmp/patch.diff
node src/cli.js --diff /tmp/patch.diff

# or straight against a ref (bare `--git` scans uncommitted changes)
npx -y codex-guard --git --commits
node src/cli.js --git origin/main --commits

Exit codes: 0 = no blocking findings, 1 = blocking findings, 2 = usage error. --json prints the raw report (same shape as the findings-json output) for scripts; --warn-todos and --fail-on todos,secrets,commits mirror the action's blocking rules. Commit hygiene is checked only in --git mode when you pass --commits.

Agent skill (pre-submit self-check)

Same checks, one level further up: packed as a skill, so Codex or Claude Code run them themselves before opening a PR — the CI gate then never sees a dirty diff that the agent didn't already spot locally. This repo ships the skill in skills/codex-guard/SKILL.md; install it with:

bash skills/install.sh              # installs for Codex and Claude Code
# or copy skills/codex-guard/ into ~/.codex/skills/ or ~/.claude/skills/

The skill tells the agent to run node src/cli.js --git --commits before submitting, fix TODO/secret/commit findings, and only open the PR once the checks pass (or the exception is documented in the description).

Codex plugin

The same skill is packaged as an official Codex plugin (skill-only form, schema follows openai/plugins): plugins/codex-guard/.codex-plugin/plugin.json plus a marketplace manifest at .agents/plugins/marketplace.json. Codex users can add this repository as a plugin marketplace from the Codex app or CLI — install steps are in OpenAI's plugin docs: https://developers.openai.com/codex/plugins/build.

plugins/codex-guard/.codex-plugin/plugin.json
plugins/codex-guard/skills/codex-guard/SKILL.md
.agents/plugins/marketplace.json

Once installed, Codex runs the pre-submit checks itself before opening or updating a PR — same behavior as the standalone skill, one packaging step closer to discoverable on GitHub (see the codex-plugin topic).

DeepSeek Harness plugin (dsh)

A DSH bundle lives in dsh/: it declares a dsh.bundle manifest and registers a codex_guard tool that DeepSeek Harness agents can call to pre-flight an agent-authored diff before it becomes a PR.

dsh/
├── package.json        # dsh.bundle manifest (name: dsh-codex-guard)
├── cordis.patch.yml    # the layer a profile applies
└── index.js            # registers the codex_guard tool (dsh-tools API)

The tool shells out to the published CLI (npx --yes codex-guard --git) in the current working directory, so it gets the same deterministic report the CI gate uses. Node API compatibility is tested against the real @deepseek-ai/dsh-tools registry packages (see test/dsh.test.js), including an end-to-end run in a throwaway git repo.

Outputs

OutputDescription
resultpass, fail, or skipped.
detected-agenttrue / false — whether the PR looked agent-generated.
failed-checksComma-separated list of failed checks (todos,secrets,commits,ci).
todo-count / secret-count / commit-countFindings per category.
ci-failure-countNumber of failing CI checks.
findings-jsonJSON of the full report — pipe it into later steps to gate more or build dashboards.
sweep-scanned / sweep-failedSweep mode: agent PRs inspected / with blocking findings.
sweep-report / sweep-jsonSweep mode: markdown report (also in the run summary) / per-PR JSON.

Sweeping existing PRs

Adopting Codex Guard doesn't have to be retrospective — run a sweep to inspect every currently-open agent-generated PR in one go:

on:
  workflow_dispatch:
# … uses: Akimiya-z/codex-guard@v1 with: { sweep: 'true' }

The report is written to the run summary and sweep-report output (per-PR numbers in sweep-json). No per-PR comments or check-runs are posted. Copy-paste at examples/sweep.yml.

Examples

Gate everything, and skip secrets scanning on docs:

steps:
  - uses: Akimiya-z/codex-guard@v1
    with:
      gate-agents-only: 'false'
      secret-exclude-paths: 'README.md,docs/'

Observe first, enforce later:

steps:
  - uses: Akimiya-z/codex-guard@v1
    with:
      soft-fail: 'true'

Integrate with a tool that adds the agent label automatically:

If your agent has a GitHub App or a bot that labels PRs, current Codex Guard will respect whatever label you configure — and fails open (passes) when a PR has no signal at all.

Keep gating agent PRs from forks:

Use pull_request_target so the check runs with your repo's write token. The action reads the fork PR's files, commits and head SHA from the event payload — no extra config. Copy-paste at examples/forks.yml.

How it compares

ToolWhat it doesWhy you'd also want Codex Guard
Branch protectionBlocks merges without required reviews/checksIt's the policy; Codex Guard is the check that enforces agent-hygiene rules on a PR.
Secret scanners (gitleaks, TruffleHog)Deep secret detection across historyUse in addition — ours is a cheap diff-scoped regex pass, not a replacement.
Linters / formattersStyle and static-analysis gatesWe catch workflow issues agents leave behind (TODO, secrets, commit hygiene, red CI) that linters don't.
AI review bots (CodeRabbit, etc.)LLM-powered PR reviewGreat — and slow/opinionated with per-review token cost. Codex Guard is deterministic, fast, free to run in CI, and gate-able without debate.
Agent self-review hooksAgent checks its own outputDefaults fail; a neutral deterministic gate doesn't nod along.

Development

npm install
npm test          # node:test — no framework required
npm run check     # syntax-check every source file

Consult CONTRIBUTING.md before opening a PR — it covers the release process (commit node_modules, tag v1.x). See CHANGELOG.md for release history. Copy-paste workflows live in examples/, and docs/ explains how to record the demo GIF and smoke-test locally.

Limitations

  • Secret detection is regex-based on purpose — it catches the obvious mistakes cheaply, but it is not a replacement for a real secret scanner (use gitleaks or zizmor in addition).
  • The TODO scan only sees lines added by this PR — it won't nag you about pre-existing comments.
  • Runs on pull_request events; for fork contributions use pull_request_target (see examples/forks.yml) and supply a token with the right scope.

Roadmap

  • Auto-request changes instead of only failing the check (opt-in)
  • Replace/update the report comment in place across runs
  • Config file support (.github/codex-guard.yml) for per-repo policy
  • Agent skill (SKILL.md) for pre-submit self-checks
  • workflow_dispatch sweep of existing agent PRs
  • Published to npm (npx codex-guard)

Dropped by design: AI whole-PR summary gates — per-token LLM costs contradict the project's free, deterministic positioning. Codex Guard stays zero-cost.

License

MIT