Local-first maintainer automation for open-source CI triage
Project description
PatchRail
Local-first CI failure triage for open-source maintainers. Paste a failing CI log, get the failure class, the reproduction command, and a suggested fix strategy — in seconds, fully offline.
The recording above is real output from the bundled
examples/ci-triage/typescript-import-type-drift.log fixture. No model calls,
no network, no telemetry: the classifier is a curated rule engine that runs
entirely on your machine.
Why maintainers use it
- 40 failure classes backed by real log signatures — dependency
resolution, flaky network, OOM-killed runners, Docker builds, lint,
type checks, docs-site builds, and test failures across Python, Node,
TypeScript, Go, Rust, Java, .NET, Ruby, PHP, C++, and Swift/Xcode. Run
patchrail ci classesto list them all (add--format jsonto check coverage from a script). - 169 sanitized CI log fixtures keep the classifier honest: every rule is
benchmarked against the public fixture zoo in
examples/ci-triage/on every test run. - 23 secret-redaction patterns (GitHub/GitLab/npm/PyPI/AWS tokens, private keys, JWTs, emails, home paths) so logs can be shared safely.
- Local-first by design: no network access, no billing, no external model, no telemetry. Nothing leaves the machine.
- Markdown for humans, JSON for automation — pipe the same result into a PR comment or a workflow step.
Quickstart
PatchRail is published on PyPI:
pipx install patchrail
Classify any failed CI log:
patchrail ci explain --log failed-ci.log
Or try it on a bundled fixture from a clone of this repo:
git clone https://github.com/patchrail/patchrail
cd patchrail
patchrail ci explain --log examples/ci-triage/dependency-failure.log --format markdown
Real output:
# PatchRail CI Report
- Root cause: `python_dependency_resolution`
- Confidence: `0.89`
- Subsystem: Python dependency installation
- Reproduce: `python -m pip install -r requirements.txt`
- Suggested action: Pin or relax the conflicting dependency range, then rerun the same install command and the affected tests.
## Evidence signals
- `Could not find a version that satisfies the requirement`
- `Cannot install .*because these package versions have conflicting dependencies`
- `ResolutionImpossible`
It also reads from stdin, so you can pipe a log straight in:
tail -n 200 failed-ci.log | patchrail ci explain
Every failure class has a step-by-step remediation write-up in docs/fix/.
GitHub Action
Run the same triage on every red CI run with
patchrail/ci-triage-action
(also on the
GitHub Marketplace).
It classifies the log locally on the runner — no PR, no comment, nothing
leaves the job:
- name: PatchRail CI triage
if: failure()
uses: patchrail/ci-triage-action@v1
with:
log-path: test.log
The @v1 drop-in exposes failure-class, confidence, and guide-url, plus a
run annotation and job summary. See
docs/using-the-action.md for its full inputs and
outputs, or examples/ci-triage-action for
the artifact shapes of both @v1 and the richer in-repo composite.
Features
| Feature | Status | Notes |
|---|---|---|
CI failure triage (ci explain, ci classify, ci classes) |
Beta | 40 failure classes for GitHub Actions-style logs and common toolchains |
Secret redaction (redact, ci explain --redact) |
Beta | 23 patterns for tokens, keys, emails, and home paths |
| Reports | Beta | Markdown, JSON, and plain text |
Fixture benchmark (ci benchmark) |
Beta | Scores the classifier against all 153 public fixtures |
| GitHub Action | Beta | Read-only triage artifact on failed workflows |
Local queue / control plane (queue) |
Experimental | SQLite-backed work items with human approval states |
Funded issue discovery (funded-issues) |
Experimental (read-only) | Safe-only defaults, no claiming or commenting; see docs/funded-issues-ethics.md |
Local-first & safety
PatchRail never phones home. The classifier needs no API key, no GitHub App, no repo write permission, and no external model call. Write actions (PRs, comments, claims) are out of scope; anything that could become one sits behind an explicit human approval state.
Secret redaction is a first-class feature, not an afterthought. Redact a log before sharing it anywhere:
patchrail redact --log failed.log > failed.redacted.log
patchrail ci explain --redact --log failed.log
The redaction pass covers GitHub, GitLab, npm, PyPI, AWS, Stripe, Slack,
Google, Hugging Face, and SendGrid credentials, private key blocks, JWTs,
bearer tokens, URL-embedded credentials, *_TOKEN/*_SECRET environment
assignments, email addresses, and user home paths.
See ETHICS.md, SECURITY.md, and docs/threat-model.md.
Roadmap
- v0.3 — public demo of the local agent control plane: SQLite-backed work queue, approval gates, and audit export.
- v0.4 — ethical funded-maintenance workflow: read-only discovery with human-gated follow-up, no automated claiming.
Details in docs/roadmap.md.
Documentation
- Quickstart
- jq cookbook for the JSON classifier output
- Fix guides per failure class
- CI Failure Zoo
- GitHub Actions CI triage
- Using the action in your own repository
- Agent Control Plane
- API reference
- Threat model
- Funded issue ethics
Contributing
The fastest way in is adding a CI fixture — it takes about 10 minutes:
grab a failed log, redact it, trim it to the smallest excerpt that still shows
the root cause, and add it with its expected classification under
examples/ci-triage/. The full path is in
CONTRIBUTING.md, and the
CI failure fixture issue template
works if you are not ready to open a pull request.
Issues labeled
good first issue
are scoped for first-time contributors.
Run the checks locally before opening a PR:
uv run --extra dev pytest -q
uv run --extra dev ruff check .
uv run --extra dev patchrail ci benchmark examples/ci-triage --format json
License
Apache-2.0.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file patchrail-0.3.0.tar.gz.
File metadata
- Download URL: patchrail-0.3.0.tar.gz
- Upload date:
- Size: 262.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dee1719aafa2f0038b0cf2f5b9e2c40e15262569549057e42a06c83e312c9ee0
|
|
| MD5 |
8d7831747cdebc928af715ba07a9d831
|
|
| BLAKE2b-256 |
3ac99ee97f97a666f21efa97ea98039bb9c94161e3e82256d97f6a62f6737a05
|
Provenance
The following attestation bundles were made for patchrail-0.3.0.tar.gz:
Publisher:
release.yml on patchrail/patchrail
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
patchrail-0.3.0.tar.gz -
Subject digest:
dee1719aafa2f0038b0cf2f5b9e2c40e15262569549057e42a06c83e312c9ee0 - Sigstore transparency entry: 2125380713
- Sigstore integration time:
-
Permalink:
patchrail/patchrail@fee0f118a2e268712c374856ed0339c12878cee7 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/patchrail
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fee0f118a2e268712c374856ed0339c12878cee7 -
Trigger Event:
release
-
Statement type:
File details
Details for the file patchrail-0.3.0-py3-none-any.whl.
File metadata
- Download URL: patchrail-0.3.0-py3-none-any.whl
- Upload date:
- Size: 194.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5119a7141c59ccbb3a818c8f12758b28321c96e2f0b6ff0635a2cf53d939dad
|
|
| MD5 |
e7730ae2603a01db547026f9018470f9
|
|
| BLAKE2b-256 |
02bace48542d2c3e469cceb34e1947fc1960d5376c9e350d1eb6c439ea264dd5
|
Provenance
The following attestation bundles were made for patchrail-0.3.0-py3-none-any.whl:
Publisher:
release.yml on patchrail/patchrail
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
patchrail-0.3.0-py3-none-any.whl -
Subject digest:
d5119a7141c59ccbb3a818c8f12758b28321c96e2f0b6ff0635a2cf53d939dad - Sigstore transparency entry: 2125380732
- Sigstore integration time:
-
Permalink:
patchrail/patchrail@fee0f118a2e268712c374856ed0339c12878cee7 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/patchrail
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fee0f118a2e268712c374856ed0339c12878cee7 -
Trigger Event:
release
-
Statement type: