Autonomous maintenance agents for your codebase, shipped as a GitHub composite action.
Each mate is a specialized Claude Code agent that runs on a schedule, analyzes your repo, and either files an issue or opens a PR with fixes. Mates never merge — humans decide.
Inspired by AI Daemons, built on Claude Code.
Two classes:
Drift mates — nightly state-query over HEAD. Each is a Claude Code prompt tuned for one concern.
| Mate | Purpose | Default model | Trigger |
|---|---|---|---|
docs |
Documentation quality, staleness, drift | Haiku | nightly |
tests |
Outdated/redundant tests, weak assertions | Haiku | nightly |
dead-code |
Unused symbols, orphaned files | Haiku | nightly |
logic |
TODOs, deprecated APIs, hardcoded values | Haiku | nightly |
Policy gate — PR-scoped, wraps a specialized tool.
| Mate | Purpose | Engine | Trigger |
|---|---|---|---|
security |
Security review, diff-aware, inline PR comments | anthropics/claude-code-security-review (Opus 4.1 default) |
pull_request only |
The security mate is a thin wrapper over Anthropic's specialized scanner: you keep the mate: security interface, the scanner does the analysis. See examples/README.md for the PR-scoped invocation pattern.
Key architectural difference from the drift mates:
| Drift mates | Security mate | |
|---|---|---|
| Findings go to | Job Summary panel (ephemeral, per-run) | Inline PR review comments (during PR lifecycle) |
| Opens a PR? | Yes, when there's a concrete fix | No — detection-only |
| Opens an issue? | No (avoids tracker noise at nightly scale) | Only when a PR merges with residual findings (via optional security-aftermath.yml companion). Rare × high-signal. |
| Blocks merge? | Never (advisory only) | Yes, when security is added as a required status check |
See examples/README.md § Security aftermath for the tracked-issue pattern — recommended for production app repos where a vulnerability landing without remediation is a real risk.
gh secret set CLAUDE_MATES_API_KEY --repo your-org/your-repo
# Paste your Anthropic API keyRepo Settings → Actions → General → Workflow permissions. Without this, the mate can open issues but not PRs.
mates:
docs:
enabled: true
# max_window_hours: 24 # default — review files changed in last 24h
# (override per-mate; e.g. 168 to "catch up
# over a week" after an outage. No upper bound.)
tests:
enabled: true
dead-code:
enabled: true
logic:
enabled: false
security:
enabled: false # Consider PR-scoped claude-code-security-review instead
deny:
- "NEVER merge PRs — always require human approval"
- "NEVER modify .env files or infrastructure config"
labels:
prefix: "claude-mate"Full schema in .claude-mates.yml of this repo.
Pick one pattern from examples/README.md. The matrix-over-mates pattern is the simplest:
name: Mates
on:
schedule:
- cron: '0 6 * * 1-5'
workflow_dispatch: {}
jobs:
mate:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: write
pull-requests: write
issues: write
strategy:
fail-fast: false
matrix:
mate: [docs, tests, dead-code]
concurrency:
group: mate-${{ matrix.mate }}
cancel-in-progress: false
steps:
- uses: actions/checkout@v5
with: { fetch-depth: 100 }
- uses: vlad-ko/claude-mates@v0.9.5
with:
mate: ${{ matrix.mate }}
api-key: ${{ secrets.CLAUDE_MATES_API_KEY }}gh workflow run mates.ymlThe security mate is a PR-scoped wrapper over anthropics/claude-code-security-review. Running it is one thing; blocking merge on it is how you actually prevent vulnerabilities from landing on main.
Add a PR-scoped workflow first (see examples/README.md § The security mate is PR-scoped), then promote its check to required:
Repo Settings → Branches → Branch protection rule for main:
- Enable "Require status checks to pass before merging"
- Add
security(the workflow's job name) to the required-checks list
With this, merge is blocked until the scanner completes AND the PR addresses (or overrides) any findings. Recommended for production application repos where the cost of a vulnerability landing greatly exceeds the occasional false-positive friction.
Escape hatch: repo admins can override the required check on a per-PR basis when the scanner is clearly wrong. Document that override path in your repo's CLAUDE.md / contributing docs.
Skip this for framework / library repos where surface area is small (bash, YAML) and false-positive rate is high — advisory mode is fine.
- uses: vlad-ko/claude-mates@v0.9.5
with:
mate: docs # required: one of docs, tests, dead-code, logic, security
api-key: ${{ ... }} # required: Anthropic API key
config-path: .claude-mates.yml # optional (default shown)
claude-cli-version: 2.1.97 # optional — pin for reproducibility (drift mates only)| Output | Values |
|---|---|
outcome |
none | findings | pr |
status |
ok | clean | error | empty |
issue-url |
Always empty (drift mates write to Job Summary; security mate posts inline PR comments) |
pr-url |
URL of created PR, or empty (drift mates only) |
findings-count |
Number of findings (security mate only; empty otherwise) |
schedule / pull_request / push / workflow_dispatch
│
▼
action.yml (composite)
│ ├─ if mate==security → delegates to anthropics/claude-code-security-review (pinned SHA)
│ └─ else → installs @anthropic-ai/claude-code CLI + invokes runner.sh
▼
runner.sh (drift mates: docs/tests/dead-code/logic)
│ ├─ Phase 0: self-loop guards + bounded delta window
│ │ - self-loop guards: PR branch, HEAD commit patterns, CHANGELOG markers
│ │ - window start = max(cursor, now - max_window_hours), default 24h
│ │ - if 24h window empty AND cursor exists → fall back to cursor
│ │ - review set = window ∩ mate's allowed_paths
│ │ - skip-fast-path: review set empty → exit 0, zero API cost
│ ├─ Phase 1: Claude reviews ONLY the review set (code-enforced in Phase 2)
│ └─ Phase 2: shell validates, commits, opens branch/PR; reverts edits outside window
▼
$GITHUB_OUTPUT surfaces outcome + URLs + findings-count for downstream steps
Trigger shape is your choice:
- Drift mates (docs, tests, dead-code, logic): nightly cron is the default. Can also be invoked on
pull_request— the framework prevents self-loops either way. - Security mate: always
pull_request(enforced by the action). It's a pre-merge policy gate, not a drift scan.
See examples/README.md for both per-mate and matrix patterns, and the PR-trigger variants.
- Mates never merge. They propose (PR or findings comment). Humans decide.
- Code enforces, prompts guide. Hard rules (scope, protected paths, git isolation, self-loop detection) live in
runner.sh. Prompts guide behavior only. - Bounded delta review, never a full scan. Each mate reviews files changed in the last
max_window_hours(default 24, configurable per-mate via.claude-mates.yml), intersected with itsallowed_paths. If the 24h window is empty AND a cursor (last mate contribution) exists, the window extends to the cursor — catches unreviewed bursts that predate the horizon. If both windows are empty, the run skips cleanly (zero API cost). Full-repo scans are forbidden by the framework — even on first run. Historical cleanup is for humans running Claude Code directly. - No file copying. The action IS the integration — no
.claude-mates-framework/checkout, no per-release template bumps. - No self-loops, across any trigger. Framework-level guards fire on schedule, push, AND pull_request events. Mate-originated branches, automation-authored commits, and CHANGELOG PRs all skip cleanly.
workflow_dispatch(manual) bypasses self-loop guards but still applies delta scope. - No issue-tracker noise. Findings without a concrete fix render to the workflow log + Job Summary panel, not auto-filed GitHub issues. Only human-filed issues are tracked long-term.
- Specialized tools for specialized jobs. The security mate is a thin wrapper over Anthropic's
claude-code-security-review— battle-tested, diff-aware, FP-filtered. We don't re-invent; we integrate. - Cost-bounded. Per-mate model selection, per-mate max-turns,
allowed_pathsscope cap,--allowedToolstool cap. Delta scope + self-loop guard skip any run that would produce no signal. - Observable. Every run writes
/tmp/mate-*-summary.json(uploaded as artifact), populates GitHub Job Summary, and surfaces structured action outputs for downstream steps.
Pin uses: vlad-ko/claude-mates@vX.Y.Z to a specific release tag. Check CHANGELOG.md before bumping — patch versions are safe; minor versions may add features; major versions document breaking changes.
| Model | Typical run | Monthly (5 mates, weekdays) |
|---|---|---|
| Haiku 4.5 | $0.08–$0.15 | $8–$15 |
| Sonnet 4.6 | $0.30–$0.50 | $30–$50 |
| Mixed (Haiku default, Sonnet for security) | — | $15–$25 |
The self-loop guard brings real cost down further on quiet repos — mates with no human work to analyze exit in seconds and skip the Claude API entirely.
MIT — see LICENSE.