Just shippedBest skills for each job.See the picks β†’

CodexScheduleNot executedΒ· 1 caveat

Jitsu: weekly Codex run that fixes security vulnerabilities and opens PRs

Runs weekly. Codex finds dependency security vulnerabilities, fixes those above a severity threshold, and opens pull requests. It supports a dry-run mode that only reports.

schedule: weekly (cron) + workflow_dispatch

How it works

From event to result

1
Trigger
GitHub starts a run when the schedule "0 8 * * 1" is due, or you run it by hand.
2
Agent
Codex, via openai/codex-action.
3
What it does
Runs weekly. Codex finds dependency security vulnerabilities, fixes those above a severity threshold, and opens pull requests. It supports a dry-run mode that only reports.
4
What you get
This listing does not state a pull request or a comment. Read the prompt, and treat the result as not executed.

Setup

Where to paste this

  1. Create .github/workflows/jitsu-security-fix.yml
  2. Paste the workflow below into that file. The notes beside the YAML are not part of the file.
  3. Add these repository secrets: DEPENDABOT_TOKEN, OPENAI_API_KEY. The file reads them as secrets.NAME. Do not paste the key into the YAML.
  4. Steps that call gh with github.token use the token Actions already provides. You do not create that secret.

Let your agent do it

Copy a prompt for Claude Code, Codex, or Cursor.

Paste it into your coding agent in this repo. It does the setup and asks before anything leaves your machine.

Runs the same job in your agent session, on the plan you are signed in with. No API key, no Action.

Do the job of the "Jitsu: weekly Codex run that fixes security vulnerabilities and opens PRs" workflow from AgentFlows (https://agentflows.sh/flows/jitsu-security-fix) right here, in this session, using the plan I'm signed in with. No API key and no GitHub Action.

Install these agent skills first. Download each SKILL.md from its source (respect its license) into .claude/skills/<name>/SKILL.md, or wherever this agent loads skills from:
- Security and hardening: audit inputs, auth and secrets: https://github.com/addyosmani/agent-skills/tree/main/skills/security-and-hardening (MIT), notes at https://agentflows.sh/skills/addyosmani-security-and-hardening

What it does: Runs weekly. Codex finds dependency security vulnerabilities, fixes those above a severity threshold, and opens pull requests. It supports a dry-run mode that only reports.

The workflow normally runs on: schedule: weekly (cron) + workflow_dispatch. Instead, ask me which pull request, issue, or branch to work on, then follow these instructions:

```text
Runs weekly. Codex finds dependency security vulnerabilities, fixes those above a severity threshold, and opens pull requests. It supports a dry-run mode that only reports.
```

Use the gh CLI for anything on GitHub, and show me what you plan to post or change before you do it.

The file

Workflow YAML

Copy the file as-is. The notes beside each block explain it.

.github/workflows/jitsu-security-fix.yml

Name

The name GitHub shows in the Actions tab. The file path is under Where to paste this.

name: πŸ”’ Security Vulnerability Fix

Trigger

GitHub starts a run when the schedule "0 8 * * 1" is due, or you run it by hand.

on:  schedule:    - cron: "0 8 * * 1" # Every Monday at 8:00 UTC  workflow_dispatch:    inputs:      dry_run:        description: "Dry run (report only, no PRs)"        required: false        type: boolean        default: false      severity:        description: "Minimum severity to fix"        required: false        type: choice        options:          - low          - moderate          - high          - critical        default: moderateconcurrency:  group: security-fix  cancel-in-progress: false

Jobs

Each job is one runner. The steps inside it run top to bottom.

jobs:  scan-and-fix:    name: πŸ” Scan & Fix Vulnerabilities    runs-on: ubuntu-latest    timeout-minutes: 30

Permissions

This token may push commits, comment on pull requests and open them, and security-events: read. Anything not listed is not granted.

    permissions:      contents: write      pull-requests: write      security-events: read

Steps

These steps run in order on that job.

    steps:      - name: πŸ“₯ Checkout code        uses: actions/checkout@v6        with:          fetch-depth: 1          ref: newjitsu      # setup-node MUST run before setup-pnpm: pnpm/action-setup@v4 binds its      # CLI shim to whichever Node is active at install time, so if pnpm goes      # first, every later `pnpm` call still runs on the runner's default      # Node 20 (triggers "Unsupported engine: wanted {node:>=22}") even after      # setup-node bumps the PATH to Node 22.      - name: πŸ”§ Setup Node.js        uses: actions/setup-node@v4        with:          node-version: 22      # No `version:` β€” pnpm/action-setup reads `packageManager` from      # package.json (pnpm@10.22.0). Specifying both conflicts and fails the step.      - name: πŸ”§ Setup pnpm        uses: pnpm/action-setup@v4      - name: πŸ”§ Setup Go        uses: actions/setup-go@v6        with:          go-version: "1.26"          cache-dependency-path: "bulker/**/*.sum"      - name: πŸ“¦ Install dependencies        if: false        run: pnpm install --frozen-lockfile        continue-on-error: true      - name: πŸ” Run npm audit        id: npm-audit        if: false        run: |          pnpm audit --json > .npm-audit.json 2>/dev/null || true          echo "npm audit complete"          # Summary for logs          jq -r '.advisories // {} | length' .npm-audit.json 2>/dev/null || echo "0"      - name: πŸ” Run govulncheck        id: go-vuln        if: false        run: |          go install golang.org/x/vuln/cmd/govulncheck@latest          mkdir -p .go-vulns          for moddir in bulker/*/; do            if [ -f "${moddir}go.mod" ]; then              modname=$(basename "${moddir}")              echo "Scanning ${moddir}..."              govulncheck -C "${{ github.workspace }}/${moddir}" -json ./... > ".go-vulns/${modname}.json" 2>/dev/null || true            fi          done          jq -s 'flatten' .go-vulns/*.json > .go-vulns.json 2>/dev/null || echo '[]' > .go-vulns.json          echo "govulncheck complete"      - name: πŸ” Fetch Dependabot alerts        id: dependabot        env:          GH_TOKEN: ${{ secrets.DEPENDABOT_TOKEN }}        run: |          set -euo pipefail          gh api repos/${{ github.repository }}/dependabot/alerts --paginate \            --jq '[.[] | select(.state == "open") | {              number: .number,              ghsa: .security_advisory.ghsa_id,              cve: .security_advisory.cve_id,              severity: .security_advisory.severity,              summary: .security_advisory.summary,              published_at: .security_advisory.published_at,              package: .security_vulnerability.package.name,              ecosystem: .security_vulnerability.package.ecosystem,              vulnerable_range: .security_vulnerability.vulnerable_version_range,              fixed_version: .security_vulnerability.first_patched_version.identifier            }]' > .dependabot-alerts.json          echo "Dependabot alerts: $(jq length .dependabot-alerts.json)"      - name: πŸ“ Write Codex prompt        env:          DRY_RUN: ${{ inputs.dry_run || 'false' }}          MIN_SEVERITY: ${{ inputs.severity || 'moderate' }}          REPO: ${{ github.repository }}        run: |          set -euo pipefail          mkdir -p .github/codex          # Runtime context goes through an UNQUOTED heredoc so $REPO/$DRY_RUN/          # $MIN_SEVERITY expand. The static prompt body below uses a QUOTED          # heredoc ('PROMPT_EOF') so backticks, $vars, and glob chars inside          # the markdown pass through literally instead of being interpreted.          cat > .github/codex/security-fix.prompt.md <<EOF          ## Runtime context          - Repository: ${REPO}          - Base branch: newjitsu          - Dry run mode: ${DRY_RUN}          - Minimum severity: ${MIN_SEVERITY}          EOF          cat >> .github/codex/security-fix.prompt.md << 'PROMPT_EOF'          You are a security engineer fixing dependency vulnerabilities in a monorepo.          ## Operating mode (read first)          You are running non-interactively inside a GitHub Actions job. There is          no human to answer questions. Do not ask for confirmation, do not stop          to request clarification, do not print plans and wait β€” just execute.          When a step is ambiguous, pick the option described in the Rules          section below; if there is no matching rule, skip that vulnerability          and move on. Finish by printing a short summary of what you did.          ## Repo layout          - Node.js/pnpm workspace rooted at repo root (libs/, services/, webapps/, cli/, types/).          - Go workspace rooted at bulker/ (bulker/go.work). All Go modules are members of this workspace β€” do NOT treat them as independent repos. Workspace members are listed in bulker/go.work.          - pnpm-workspace.yaml has an `overrides:` block for pinning transitive versions.            (It used to live in root package.json under `pnpm.overrides`; pnpm >=10.22            no longer reads that field and ignores it silently.)          ## Input          The primary source of work is .dependabot-alerts.json (already produced          by an earlier step). It is a JSON array; each entry has: number, ghsa,          cve, severity, summary, published_at, package, ecosystem,          vulnerable_range, fixed_version.          Read it with: cat .dependabot-alerts.json | jq .          `published_at` is when the ADVISORY was published, not when the package          was fixed. It matters because a patch released after that date may not          be reflected in vulnerable_range / fixed_version β€” see "Major version          bumps" below.          .github/security-fix-exceptions.yml records alerts a human has already          resolved in a way the advisory database does not recognise. It is          checked in and may be absent or empty.          ## Procedure          IMPORTANT: All examples below use PLACEHOLDER names in ALL_CAPS          (ACTUAL_PKG_NAME, FIXED_VER, ACTUAL_MODULE). Substitute real values          from the alerts before running any command. Never run a command that          still contains a placeholder.          1. List existing security PRs to avoid duplicates:             gh pr list --search "security" --state open             Skip any alert whose fix is already covered by an open PR.          2. Filter alerts by MIN_SEVERITY (severity order: critical > high > moderate > low).          3. Drop alerts already settled by a human. If             .github/security-fix-exceptions.yml exists, read its `exceptions:`             list and look for an item matching the alert on ALL THREE of `ghsa`,             `package` and `ecosystem`. One advisory can cover several packages,             and a deviation accepted for one of them says nothing about the             others β€” matching on ghsa alone would skip unrelated alerts that are             still genuinely vulnerable. More than one item may share a ghsa;             that is expected, so keep looking until all three fields match             rather than taking the first ghsa hit.             When an entry matches, judge every resolved copy of that package             separately. A copy is settled if EITHER it satisfies the entry's             `satisfied_by` semver range (the human vouched for it) OR it already             falls outside the alert's vulnerable_range (it is fixed on the             advisory's own terms, e.g. at or above fixed_version). SKIP the             alert only if EVERY resolved copy is settled under one of those two;             list it in the run summary under "Skipped (accepted deviation)" with             the recorded reason. If even one copy is settled by neither, the             exception does NOT apply β€” treat the alert normally.             Both tests are needed because a pnpm lockfile routinely holds             several copies of a package. A tree carrying a backport-fixed 7.x             copy alongside an already-fixed 8.x one is fully patched, but             `satisfied_by` alone would reject it and re-propose the very major             bump the exception exists to prevent.             Checking vulnerable_range rather than just widening the range keeps             the bound meaningful. `satisfied_by` is bounded on both sides on             purpose: a bare lower bound would keep matching after a major             migration, so a repo that later moved to a still-vulnerable version             on the next major line would have the alert silently suppressed by             an exception written for the old one. Versions between the two β€” on             the newer major but below its fix β€” satisfy neither test and are             still reported, which is the point.             Never edit this file yourself: it records decisions only a human can             make. An entry does not expire, so an alert can stay open forever             with the repo deliberately not on the advisory's fixed_version.          4. For EACH remaining alert, determine ALL versions of the package             actually resolved in this repo, then SKIP the alert only if every             one of them is already fixed:             - A package can be resolved at MULTIPLE versions at once: a pnpm               lockfile routinely contains several copies of the same package,               and each Go workspace member (bulker/*/go.mod) resolves the               module independently. Collect every resolved version β€” e.g.               `pnpm why -r ACTUAL_PKG_NAME` / grep pnpm-lock.yaml for npm, and               `go -C bulker/ACTUAL_MODULE list -m ACTUAL_PKG` for each               workspace member for Go.             - Only if EVERY resolved version is >= the alert's fixed_version               (or outside the vulnerable_range) is the repo already patched β€”               skip it. If even one resolved copy is still vulnerable, the               alert applies; fix that copy (without downgrading the others).               Do NOT touch the manifest just to match fixed_version exactly;               that is a no-op at best and a downgrade at worst.             - Go major versions are distinct modules. An alert for               `github.com/foo/bar` (the v0/v1 module path) does NOT apply to               imports of `github.com/foo/bar/v2` (or higher) β€” that is a               different, newer module. But both majors can be in use at once:               check `grep -rE 'github.com/foo/bar[[:space:]]' bulker/*/go.mod`               (the trailing whitespace class matches the space or tab `go mod               tidy` uses, while still excluding /v2+ paths) before skipping. Skip               the alert only when NO workspace member still requires the               v0/v1 path; never "fix" a v0/v1 alert by pinning the older               major-version path in a module that only uses v2+.             - NEVER downgrade. Compare versions semantically: if applying the               fix would move any package to a LOWER version than it currently               resolves to (directly or transitively), skip the alert and note it               in the PR body under "Skipped (already satisfied / would downgrade)".          5. Group the remaining alerts into AT MOST TWO PRs β€” one per stack:             - All npm / Node.js fixes β†’ a single PR on branch security/fix-npm-YYYY-MM-DD             - All Go fixes β†’ a single PR on branch security/fix-go-YYYY-MM-DD             This is mandatory: pnpm-lock.yaml, go.sum, and bulker/go.work.sum             otherwise cause merge conflicts if two concurrent PRs touch them.             If a fix is risky (major version bump, breaking change), still include             it in the per-stack PR but flag it prominently in the PR body so a             reviewer can split it out manually.          6. Apply every ecosystem-specific step below for all alerts in that             stack BEFORE creating the PR. Do NOT push incremental commits per             alert β€” one branch, one commit per stack, one PR per stack.          7. After applying fixes, verify nothing regressed before opening the PR:             - npm: `pnpm install --no-frozen-lockfile` must succeed.             - Go: `go -C bulker work sync` and `go -C bulker/ACTUAL_MODULE build ./...`               for each touched module must succeed.             If verification fails for an alert, revert that alert's change and             move it to the "Skipped" list. Never open a PR that does not build.          8. If after all of the above NO alerts remain to fix, do NOT create a             branch or PR β€” just print a summary saying everything is already             satisfied.          9. If DRY_RUN is true, output a report of what would be done and do NOT             create branches, commits, or PRs.          ### npm / Node.js packages          #### Major version bumps          Do this BEFORE writing any override or version bump whose fixed_version          is on a HIGHER major than the version currently resolved.          An advisory is usually filed the day the first patch ships. If that          patch was on the newest major and a backport to an older line landed          later, the advisory frequently keeps the merged range it was created          with (e.g. ">= 7.12.0, < 8.3.0", fixed 8.3.0) and is never amended.          The backport is then invisible in vulnerable_range and fixed_version,          and taking fixed_version literally forces a major bump that was never          necessary. Do not assume the alert knows about every fix.          The upstream advisory is the authority, not the release dates. Work          from it first and use dates only to explain what you find.          1. Read the upstream advisory's own patched-versions list:               gh api /advisories/ACTUAL_GHSA_ID             If it names a patched version on the SAME major as the currently             resolved version, that is the backport β€” use it, and stop here.          2. If it shows only the merged range, the entry may predate the             backport. Widen the search: read the advisory page at             https://github.com/OWNER/REPO/security/advisories/ACTUAL_GHSA_ID             (its "Patched versions" field is often correct when the API entry is             stale), then list candidate releases:               npm view ACTUAL_PKG_NAME versions --json               npm view ACTUAL_PKG_NAME time --json             Consider EVERY release on the current major above the resolved             version. Do not filter by date: `published_at` is a hint about why             the advisory might be stale β€” a candidate published after it is a             likely backport β€” but under coordinated disclosure a fix can ship             before the advisory, so an earlier date does not rule a release out.          3. Publication order is never proof of a fix. Use a candidate only if             the advisory page, the release notes, or the changelog explicitly             names it as containing this fix. If nothing says so, treat it as no             backport rather than guessing.          4. If a confirmed backport exists, use it as FIXED_VER instead of the             alert's. The alert will NOT close, because the advisory range still             covers the backport β€” that is expected, not a failure. Record it in             the PR body under "Deviations" (see "Creating PRs") so a human can             add it to .github/security-fix-exceptions.yml; do not add it             yourself.          5. If no backport exists, the major bump is the only fix. Apply it, and             flag it under "Risks" in the PR body.          #### Applying the fix          - Determine if the package is a direct dependency:              grep -r '"ACTUAL_PKG_NAME"' package.json */package.json libs/*/package.json webapps/*/package.json cli/*/package.json services/*/package.json types/*/package.json          - Transitive-only: add an entry to the `overrides:` block in pnpm-workspace.yaml            (NOT package.json - pnpm >=10.22 ignores `pnpm.overrides` there, so an            override written to package.json silently does nothing).            Pattern (YAML, quote both sides): "ACTUAL_PKG_NAME@<FIXED_VER": "^FIXED_VER"            The override floor (^FIXED_VER) must never be lower than the version            already resolved in pnpm-lock.yaml β€” an override that caps a package            below its current version is a downgrade; skip it instead.          - Companion packages that pin each other EXACTLY must move together.            Sibling packages from one project (e.g. react-router / react-router-dom)            routinely depend on each other at an exact version, so overriding one            of the pair alone leaves the other demanding a version it will never            get. Before installing, list every package that pins it, by tracking            the enclosing snapshot header:              awk -v dep="ACTUAL_PKG_NAME" '                /^  [^ ].*:$/ { pkg = $0; gsub(/\047/, "", pkg); next }                { line = $0; sub(/^ +/, "", line); gsub(/\047/, "", line)                  if (index(line, dep ": ") == 1) {                    ver = substr(line, length(dep) + 3)                    if (ver ~ /^[0-9]/) print pkg " -> " line                  } }' pnpm-lock.yaml            Pass the name via -v and compare it as a plain string. Interpolating            it into an awk regex literal breaks on scoped packages, because the            slash in `@scope/pkg` closes the /.../ and awk dies with a syntax            error β€” which would look like "no companion packages" and let a            broken lockfile through. The gsub calls strip the single quotes that            YAML puts around scoped keys ('@scope/pkg': 1.2.3); \047 is an            apostrophe, written as an escape so the program can stay inside            single quotes in the shell. The `ver ~ /^[0-9]/` test is what selects            exact pins: range specifiers start with ^ or ~.            Any package depending on ACTUAL_PKG_NAME at an exact version (no ^ or ~)            needs its own override to a release that depends on FIXED_VER β€” add it            in the same commit. If no such release exists, skip the alert rather            than ship a lockfile whose two halves disagree.          - Direct dependency: bump the version in the package.json that declares            it β€” only ever UP. If the declared/resolved version is already >=            FIXED_VER, leave it untouched (already satisfied).          - MANDATORY after any change to package.json OR pnpm-workspace.yaml            (root or any workspace member): run `pnpm install --no-frozen-lockfile`            at the repo root. Omitting --no-frozen-lockfile breaks in CI because pnpm            defaults to --frozen-lockfile when CI=true and refuses to update            pnpm-lock.yaml when overrides / catalog / workspace config has changed.            This step updates pnpm-lock.yaml. Commit the manifest changes            (package.json and/or pnpm-workspace.yaml) together with pnpm-lock.yaml.          - If pnpm install fails, revert the changes and skip that vulnerability.          ### Go packages (Go workspace at bulker/)          - Find every workspace member that depends on the package:              grep -l 'ACTUAL_PKG' bulker/*/go.mod          - Confirm the EXACT module path in go.mod matches the alert's package,            including the major-version suffix (e.g. `/v2`). If the repo uses a            higher major version than the alert references, the alert does not            apply β€” skip it; never add or pin the older major-version path.          - Check the current version in go.mod/go.sum. If it is already >= vFIXED,            skip β€” `go get ACTUAL_PKG@vFIXED` would DOWNGRADE it, which is forbidden.          - For EACH matching member whose version is below vFIXED, run inside its            module directory:              go -C bulker/ACTUAL_MODULE get ACTUAL_PKG@vFIXED          - After updating all affected members, sync the workspace:              go -C bulker work sync          - Manually drop hashes for old vulnerable versions from the affected            go.sum files and bulker/go.work.sum (leaving unrelated entries alone).          - Commit the changed go.mod/go.sum of each affected member together            with bulker/go.work.sum.          - Do NOT modify bulker/go.work β€” the use(...) list must not change for            a security fix.          - If `go get` or `go work sync` fails, revert and skip.          ### Creating PRs          There are at most two PRs per run β€” one per stack β€” so the structure is:          - Branch name:              security/fix-npm-YYYY-MM-DD   (all npm fixes)              security/fix-go-YYYY-MM-DD    (all Go fixes)          - Single commit per branch:              fix(security): batch npm dependency security fixes   (or batch go ...)          - Push and open PR:              git push -u origin HEAD              gh pr create --base newjitsu --title "fix(security): <stack> security fixes (YYYY-MM-DD)" --body "..."          - PR body must enumerate every included fix, one bullet per CVE:              - CVE_ID (SEVERITY): short vuln description β€” ACTUAL_PKG FROM_VER β†’ FIXED_VER            Plus a final "Risks" section calling out any major version bumps or            breaking changes that a reviewer should split into a separate follow-up PR.          - If any fix used a backport instead of the alert's fixed_version, add a            "Deviations" section naming the alert, the version used, why the            advisory does not list it, and the evidence that it is patched. State            plainly that the alert will stay open until a human either dismisses it            or adds an entry to .github/security-fix-exceptions.yml β€” otherwise the            next scheduled run reopens the same major bump this PR avoided. Suggest            the exact entry to add.          - After creating the first PR, reset before starting the other stack:              git checkout newjitsu && git reset --hard origin/newjitsu          ## Rules          - NEVER modify the newjitsu branch directly β€” always use a new branch.          - NEVER run a command that still contains an ALL_CAPS placeholder.          - NEVER force-push.          - NEVER downgrade a dependency. Every change must move a version up or            leave it unchanged β€” directly and transitively. If a "fix" would lower            any resolved version, it is wrong: skip it.          - A fixed_version from an alert is a FLOOR, not a target. If the repo is            already at or above it, there is nothing to do β€” skip the alert.          - An alert describes the fixes known when it was written, not every fix            that exists. Never cross a major version boundary without first            checking for a backport on the current line.          - Closing the alert is not the goal; removing the vulnerability is. Prefer            the smallest upgrade that is genuinely patched, even when it leaves the            alert open, over a major bump that merely satisfies the range.          - Prefer opening NO PR over opening one that downgrades, is a no-op, or            does not build.          - If any command fails, revert the working tree to clean state and skip that vulnerability.          - When in doubt between overriding vs. bumping a direct dependency, prefer the smaller change (override).          - When in doubt between one PR or many, prefer many small PRs.          PROMPT_EOF      - name: 🧰 Reinstall Codex CLI (workaround)        # openai/codex-action@v1 relies on a globally-installed @openai/codex.        # On GitHub-hosted runners the platform-specific optional dep        # (@openai/codex-linux-x64) sometimes gets skipped, producing:        #   "Missing optional dependency @openai/codex-linux-x64"        # Force a clean reinstall with --include=optional before the action.        # Pinned to the same CLI release as `codex-version` below (and as        # ai-review.yml in jitsucom/github-workflows) so the workaround can't        # pull a newer CLI than the action itself installs.        run: |          set -euo pipefail          npm uninstall -g @openai/codex >/dev/null 2>&1 || true          npm install -g --include=optional @openai/codex@0.149.0          codex --version      - name: πŸ”’ Fix vulnerabilities with Codex        id: run-codex        # Pinned to the v1.11 commit, not the floating v1 tag β€” same pin as        # ai-review.yml in jitsucom/github-workflows: v1.12 (2026-08-20)        # rewrote the Linux launch path and the step never returns after a        # heavy turn (openai/codex-action#150). Bump both places together        # once upstream ships a fix.

Agent

Runs Codex with openai/codex-action@52fe01ec70a42f454c9d2ebd47598f9fd6893d56. Inputs: openai-api-key (the OpenAI API key secret); prompt-file; output-file; model; effort; codex-version; sandbox; codex-home.

        uses: openai/codex-action@52fe01ec70a42f454c9d2ebd47598f9fd6893d56 # v1.11        env:          GH_TOKEN: ${{ github.token }}          GITHUB_TOKEN: ${{ github.token }}          # Belt-and-suspenders: if codex-action or the underlying codex CLI          # ever reads these, they force headless behaviour.          CODEX_NON_INTERACTIVE: "1"          CI: "true"        with:          openai-api-key: ${{ secrets.OPENAI_API_KEY }}          prompt-file: .github/codex/security-fix.prompt.md          output-file: .github/codex/security-fix.output.md          model: gpt-5.6-terra          effort: high          # Same CLI release as ai-review.yml in jitsucom/github-workflows β€”          # verified clean with v1.11; keeps a CLI release from changing          # behaviour under us.          codex-version: 0.149.0          # danger-full-access: no approval gating β€” required because the agent          # needs to run `pnpm install`, `go get`, `git commit`, `gh pr create`          # without waiting for a human to approve each one.          sandbox: danger-full-access          codex-home: .github/codex/home  # Note: AI review for the security PRs opened by this workflow is no longer  # dispatched manually. The PRs are opened by github-actions[bot], and  # ai-review.yml now auto-reviews bot-opened PRs (the reusable workflow passes  # allow-bots: true to codex-action, so its write-access check no longer aborts  # on the bot actor). A manual dispatch here would produce a duplicate review.

Keep going

More workflows

All workflows
  • CodexPull request
    12

    Codex PR review posted as a comment

    Two-job split keeps the API key job read-only (README example pattern). `:read-only` profile per README Permission profiles.

    pull_request: opened

    Est. cost per run~$0.03 runner + OpenAI tokens (UNVERIFIED)Checked Oct 16, 2026

    Not executedΒ· 3 caveats
  • CodexLabel
    13

    Codex implements an issue on label

    `:workspace` profile lets Codex edit the checkout (README). PR creation is plain git/gh, not an action input.

    issues: labeled == codex

    Est. cost per run~$0.09 runner + OpenAI tokens (UNVERIFIED)Checked Oct 16, 2026

    Not executedΒ· 2 caveats
  • CodexIssue opened
    14

    Codex triage with JSON output schema

    `output-schema` is forwarded to `codex exec --output-schema` (README inputs table).

    issues: opened

    Est. cost per run~$0.01 runner + OpenAI tokens (UNVERIFIED)Checked Oct 16, 2026

    Not executedΒ· 3 caveats