What the agent does
The agent reads the failed job before anything else. It gets the workflow_run event, runs gh run view <run id> --log-failed, and finds which job and which matrix entry failed. That matters in a Go project like miniflux/v2, whose .github/workflows/tests.yml runs unit tests on ubuntu-latest, windows-latest and macOS-latest: only Ubuntu runs make test, which is go test -cover -race -count=1 ./..., while Windows and macOS run plain go test ./.... A test that fails only on Ubuntu is often a data race the -race flag caught, and the log then shows WARNING: DATA RACE with two goroutine stacks rather than a failed assertion. The agent quotes the relevant block and names the package.
Then it matches the toolchain. go.mod declares module miniflux.app/v2 and go 1.26.0, and the workflow installs go-version: stable, so the agent uses a Go release that satisfies the go line and runs the exact command of the failing matrix entry, flags included. It runs the failing package alone first, such as go test -race -count=1 -run TestRetryDelay ./internal/reader/fetcher/, where response_handler_test.go holds TestIsModified, TestRetryDelay and TestExpiresInMinutes. -count=1 keeps Go from serving a cached pass.
With the failure reproduced, it reads the code the test covers, here internal/reader/fetcher/response_handler.go and request_builder.go, or the reader handler in internal/reader/handler/handler.go, and the commit that broke it. A race is fixed with the synchronization the shared value needs, not by removing t.Parallel() from the test; a failed assertion is fixed in the code unless the test encoded behavior the commit deliberately changed. Before pushing, the agent reruns make test across the whole module and runs go vet ./... and gofmt -l ., the first two checks of the repository's make lint.
When the failing job is integration-tests, the agent sets up what that job sets up: a Postgres service (the workflow uses postgres:11), then make integration-test, which drops and recreates miniflux_test with psql, starts the app with go run main.go (CREATE_ADMIN=1, RUN_MIGRATIONS=1, ADMIN_USERNAME=admin), waits for port 8080, and runs go test -v -count=1 ./internal/api against it. The server's own output goes to /tmp/miniflux.log, and the agent reads that file when an API test fails, since the test log alone shows only the HTTP status.
Start it with one API call
POST https://api.prix.dev/o/{org}/sessions with this body:
{
"agent": "codex",
"input": "The GitHub Actions workflow on this branch failed; the workflow_run event is at the end of this prompt. Read the failed job's log with gh run view <run id> --log-failed, name the job and matrix entry that failed, and quote the failing test or race report. Use a Go version that satisfies go.mod and run the exact command that job runs, with the same flags (-race, -count=1, -cover), on the failing package first with -run. Fix the cause in the code (fix a data race with proper synchronization rather than by disabling parallel tests; change a test only if the test is wrong, and say so), then run go test ./... with the job's flags, go vet ./... and gofmt -l . until they pass, and open a pull request against the failing branch that quotes the error it fixed.\n\nEvent: <workflow_run payload>",
"resources": [
{
"url": "https://github.com/your-org/your-app"
}
]
}- Get an API key. In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
- Send the request. POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
- Read what came back. Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.
What comes back
A pull request against the failing branch, with the fix in the package the failing test covers and the job, matrix entry and quoted error in the description. For a race, the description includes the two stacks from the race report and explains which value was shared and how it is now guarded. It lists every command the agent ran in its sandbox, from the single -run test to the full go test ./..., go vet and gofmt, and the session's trajectory keeps them with their output. The workflow runs again on the pull request across the same matrix.
When the failure appears only on Windows or macOS, the agent says it reproduces on Linux only if it can, reads the code for platform differences such as path separators or line endings, and states in the pull request that the fix is unverified on that platform until the workflow reruns. If it finds no code cause, it opens nothing and its answer explains what the log shows.
A reviewer checks that a race fix does not add a lock on a hot path where a channel or a copy would do, that no t.Parallel() or -race was removed, and that an edited test was truly wrong.
Run it on every failed Go test run
Subscribe a GitHub webhook to workflow_run and, on completed with conclusion: failure, send this request with the event in input and https://github.com/<owner>/<repo>/tree/<head_branch> as the resource. miniflux's tests run on pull requests to main, so most failures arrive on contributors' branches; exclude branches the agent opened so a failed fix does not trigger itself.
A failed matrix produces one workflow_run with several failed jobs, so one run covers all of them and the prompt asks for each. Keep the workflow_run.id with the returned execution_id to skip redeliveries, and use the run.completed webhook from Rush to post the pull request link back on the contributor's pull request.
The use case this job follows, with its automation and trigger: Fix a bug from an alert.
Why run it on Rush?
Race failures are the hard kind to fix on a laptop: they depend on scheduling, need -race and -count=1 to show up, and are easy to dismiss as flaky. The agent runs the exact command the runner ran, as many times as it takes, in its own sandbox with its own clone and module cache, without slowing your machine or touching your checkout.
What it hands back is checkable: the quoted race report or assertion, the trajectory with every go test run and its output, and the full matrix rerunning on the pull request. Failures on several branches each get their own run in parallel, and nothing merges without a reviewer.
Frequently asked questions
Will it make a race go away by removing -race or t.Parallel()?
No. The prompt rules that out, and the pull request has to name the shared value and how it is now synchronized. Any change to the Makefile or workflow flags would show in the diff.
Can it reproduce a Windows-only failure?
Its sandbox runs Linux, so it cannot run the Windows job itself. It reads the code for platform-specific behavior, fixes what it finds, and says in the pull request that the Windows result comes from the workflow rerun, not from its own run.
Does it run golangci-lint?
When the failing workflow is the lint one, yes, with the version that workflow installs. Otherwise it runs go vet and gofmt, which every Go repository can run without extra configuration.
What if the failing test needs Postgres?
It starts Postgres in the sandbox the way the workflow's services block does and runs the same Makefile target, such as make integration-test in miniflux, with the same environment variables.