Skip to content

Repository files navigation

agentci

CI checks written in plain English, run by an AI coding agent.

Drop a markdown file into .agentci/:

---
model: gpt-5.6-luna
effort: low
---
Fail if the changes add anything that looks like a real credential: API keys,
access tokens, passwords, private keys. Obvious placeholders are fine.

Run it:

$ agentci -j 2
agentci: 2 rules, codex, auth: local login (Logged in using ChatGPT), scope: diff origin/HEAD...HEAD (1 file)
agentci: running obvious-bugs (gpt-5.6-luna/medium)
agentci: running no-secrets (gpt-5.6-luna/low)
FAIL no-secrets (16s): I inspected the changes between origin/HEAD and HEAD. telemetry.go adds a GitHub personal access token literal used as a telemetry credential, so the check fails.
telemetry.go:6: Hard-coded GitHub personal access token (ghp_...) added as telemetryToken. (no-secrets)
FAIL obvious-bugs (52s): The change introduces a nil-pointer panic when OpenFile fails, overwrites that error, and leaks the opened file descriptor on every call. Tests could not run because dependencies were unavailable offline.
telemetry.go:11: The OpenFile error is ignored and f is dereferenced unconditionally; any failure to open /tmp/cobra-usage.log causes a nil-pointer panic instead of returning the error. (obvious-bugs)
telemetry.go:11: The opened file is never closed, leaking a file descriptor on every ReportUsage call. (obvious-bugs)
RED: 0 passed, 2 failed, 0 errored (52s)

The agent reads the diff on its own; you read its explanation. Findings come out as file:line: message (rule), the shape of a compiler error, so editors, CI annotations and other agents pick them up without parsing. Exit code 0 when every rule passes, 1 when any fails. One Go binary, standard library only, no config beyond the markdown.

GitHub Actions

# .github/workflows/agentci.yml
name: agentci
on: pull_request
permissions:
  contents: read
  checks: write
jobs:
  run:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: sadfun/agentci@main
        env:
          CODEX_ACCESS_TOKEN: ${{ secrets.CODEX_ACCESS_TOKEN }}

That is the whole workflow. The action builds agentci, installs the agent CLI, fetches the base branch and reviews the pull request. Every rule becomes its own check on the pull request, listed as agentci / no-secrets next to the agentci / run job, with the agent's explanation on its details page and the findings as annotations on the changed lines. checks: write is what allows the per-rule checks; without it you still get the job log and the annotations. Pass flags with with: { args: "-j 4 -effort low" }. This repository runs it on itself: .github/workflows/agentci.yml.

CODEX_ACCESS_TOKEN is a Codex access token from the Access tokens page of your ChatGPT workspace's Codex settings. Without a workspace, use OPENAI_API_KEY instead; it bills the API.

Locally

go install github.com/sadfun/agentci@latest
agentci init                  # writes .agentci/obvious-bugs.md to start from
agentci                       # review HEAD against the base branch
agentci -full                 # review the whole repository
agentci -only no-secrets -v   # one rule, streaming the agent's transcript
agentci -json                 # the same run as one JSON object

agentci needs the codex CLI and offers to install it when missing (-y skips the question). Credentials: CODEX_ACCESS_TOKEN or OPENAI_API_KEY in the environment, or your existing codex login.

Rules

Everything after the front matter is the check. The agent gets it together with the diff range and the list of changed files, has read-only access to the repository, and must finish with a verdict: pass or fail, a plain-language summary, and file:line findings.

Front matter keys, all optional: name (default: file name), model, effort (low medium high xhigh), timeout (default 15m). Files starting with _ are skipped.

This repository's own .agentci/ is a good starting set: no-secrets, obvious-bugs, tests-follow-behaviour.

Details

  • Base detection tries $AGENTCI_BASE, origin/$GITHUB_BASE_REF, origin/HEAD, origin/main, origin/master, main, master, then HEAD~1. Override with -base and -head. An empty diff is green without calling the agent.
  • -j N runs rules in parallel. -model, -effort and -timeout are defaults for rules that set none. Parallelism and timeouts must be positive.
  • Output: stdout carries only results, one line per rule (FAIL rule (time): summary, PASS rule (time), ERROR rule (time): why), one line per finding and the GREEN/RED verdict last. Progress and diagnostics go to stderr. -json prints the run as a single object instead.
  • Exit codes: 0 green, 1 red, 2 setup problem (no rules, no agent CLI, no credentials, bad ref).
  • GitHub Actions: the action hands agentci the workflow's GITHUB_TOKEN, and agentci opens one check run per rule, closes it with the verdict, the summary and the findings as annotations, and writes the job summary. A missing permission is reported once on stderr and the findings fall back to plain job annotations. -github=false turns the reporting off. The token is removed from the agent's environment before it runs.
  • The agent is pluggable. -provider or $AGENTCI_PROVIDER selects it; codex is the only one today. To add one, implement providers.Provider in providers/<name>/ and register it from init. Use providers.Env() for child processes to keep the GitHub reporting token out of the agent's environment.
  • The codex provider runs codex exec in a read-only sandbox with the verdict pinned by --output-schema. Environment credentials (OPENAI_API_KEY, CODEX_API_KEY, CODEX_ACCESS_TOKEN, in that order, then the local login) are loaded into a throw-away CODEX_HOME, so your own login is never touched.

About

CI checks written in plain English, powered by OpenAI Codex

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages