CDX-301c · Module 1

Headless Execution & PR Automation

3 min read

Headless execution means Codex runs without a human in the loop — no approval prompts, no interactive confirmations, no "are you sure?" dialogs. This requires the full-auto approval mode and a carefully scoped AGENTS.md that constrains what Codex can do. In headless mode, every rule in AGENTS.md becomes a hard constraint because there is no human to catch mistakes. The rule "prefer functional components" in interactive mode is a suggestion; in headless mode, it is the only guidance Codex has.

PR automation is the highest-value CI pattern for Codex. When a PR is opened, Codex reviews the diff, checks for rule violations, suggests improvements, and posts structured comments on the PR. This gives authors instant feedback — often within 30 seconds — while human reviewers focus on architecture and business logic. The key to effective PR automation is structured output: Codex should produce JSON or markdown that a script can parse and post as GitHub review comments, not free-form text that requires manual reading.

name: Codex PR Review
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm install -g @openai/codex
      - name: Run Codex Review
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        run: |
          codex review \
            --base origin/${{ github.base_ref }} \
            --json \
            > review-output.json
      - name: Post Review Comments
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const review = JSON.parse(fs.readFileSync('review-output.json', 'utf8'));
            if (review.comments && review.comments.length > 0) {
              await github.rest.pulls.createReview({
                ...context.repo,
                pull_number: context.payload.pull_request.number,
                body: review.summary,
                event: 'COMMENT',
                comments: review.comments.map(c => ({
                  path: c.file,
                  line: c.line,
                  body: c.message,
                })),
              });
            }

Do This

  • Use full-auto mode with a tightly scoped CI-specific AGENTS.md
  • Require structured JSON output for automated parsing and comment posting
  • Set a timeout for the review job — kill it if it exceeds 5 minutes
  • Post review comments as suggestions, not blocking reviews

Avoid This

  • Use interactive approval mode in CI — it will hang waiting for input
  • Let Codex post free-form text comments — they are inconsistent and hard to parse
  • Run Codex review on every commit — run on PR open and synchronize events only
  • Block PR merges on Codex review — it is advisory, not authoritative