badgr-agent
v1.0.18
Published
Shared runtime for Badgr Pipeline Check and Badgr Agent products
Maintainers
Readme
badgr-agent
Shared runtime package for Badgr products.
Badgr Pipeline Check is an always-on CI quality gate. It diagnoses failed builds, checks pipeline health, flags security risks, and audits config with local rules by default. AI is used only for ambiguous failures when a Badgr API key is configured.
Product surfaces
| Surface | Product name | Install |
|---------|--------------|---------|
| GitHub Actions | Badgr Pipeline Check | michaelmanly/badgr-ci@v1 |
| Azure Pipelines | Badgr Pipeline Check | BadgrCI@1 |
| GitLab CI | Badgr Pipeline Check | node dist/gitlab.js (download from Releases) |
| Jenkins | Badgr Pipeline Check | node dist/jenkins.js (download from Releases) |
| Kubernetes | Badgr Pipeline Check | node dist/k8s.js (download from Releases) |
| npm CLI | Badgr Agent CLI | npm i badgr-agent |
| Docker | Badgr Agent Infra | ghcr.io/michaelmanly/badgr-agent:infra |
All packages publish under Michael Manley accounts (michaelmanly on GitHub/npm, michaelmanleyx on Docker Hub). Product API and signup remain at aibadgr.com.
Maintainers: publish Badgr Agent Infra (Docker Hub + GHCR)
docker login -u michaelmanleyx
echo "$GITHUB_TOKEN" | docker login ghcr.io -u michaelmanly --password-stdin
npm run publish:badgr-infra:pushLive on Docker Hub as michaelmanleyx/badgr-agent:infra.
Maintainers: publish michaelmanly/badgr-ci@v1
The public GitHub Action is a thin export (no private backend code). From the monorepo root:
npm run export:badgr-ci # writes ../badgr-ci
cd ../badgr-ci && cat PUBLISH.md # tag v1, push, list on MarketplaceAll Badgr Agent runtimes share the same backend, policy, and dashboard controls. Every org/project/runtime has an on/off toggle.
Free vs. paid
Badgr is free to run as a Pipeline Check. No API key required.
| Tier | What you get |
|------|-------------|
| Free | Always-on Pipeline Check: local failure, health, security, and audit checks on every build. Summary/console output. No API key needed. |
| Paid | AI diagnosis for ambiguous failures. Requires BADGR_API_KEY from aibadgr.com. AI only fires when local confidence is low — not on every build. |
| Enterprise (self-hosted) | Run AI diagnosis against your own AWS Bedrock account or other LLM endpoint. No logs leave your infrastructure. |
Simple rule:
if: always()/condition: always()— when Badgr runsBADGR_API_KEY— optional AI diagnosis for ambiguous failures (paid)SYSTEM_ACCESSTOKEN— optional Azure platform token for richer logs and PR comments (free, Azure only)BADGR_LLM_PROVIDER=bedrock— optional direct AWS Bedrock integration (enterprise)
CI Runtime — Quick Start
On every build, Badgr produces a Pipeline Check report: cause, evidence, recommended fix, confidence, plus health, security, and audit findings when relevant.
Example output (high-confidence, no AI):
### Badgr Pipeline Check
**Failure:** Missing dependency `vite`
**Evidence:** Cannot find module 'vite'
**Suggested fix:** npm install --save-dev vite
**Confidence:** high
**Health:** Install step took 4m 12s — consider caching node_modules
**Security:** No issues found
**Audit:** No timeout set on test stepGitHub Actions
Add one step — no credentials needed:
- name: Badgr Pipeline Check
uses: michaelmanly/badgr-ci@v1
if: always()
with:
# Optional: AI diagnosis for ambiguous failures
# badgr_api_key: ${{ secrets.BADGR_API_KEY }}
# Optional: open PR with AI-proposed fix instructions
# badgr_open_pr: "true"
# Optional: override auto-detected GitHub token for richer logs / PR comments
# ci_token: ${{ secrets.BADGR_CI_TOKEN }}
# Optional: output override: summary | console | pr-comment | both
# output_mode: pr-comment
# Optional: self-hosted/private endpoint
# badgr_api_url: https://badgr.your-company.internal/v1Default: runs local Pipeline Check with no Badgr API key. Summary output is default. Add CI token only for richer logs/comments. Add BADGR_API_KEY only for AI on ambiguous failures.
Azure DevOps
Add one task as the final step. Runs best-effort with no inputs. If System.AccessToken is exposed (requires "Allow scripts to access the OAuth token" in pipeline settings), Badgr auto-detects it.
- task: BadgrCI@1
displayName: Badgr Pipeline Check
condition: always()
inputs:
# Optional: richer Azure logs / PR comments
# Requires "Allow scripts to access OAuth token"
# ci_token: $(System.AccessToken)
env:
# Optional: AI diagnosis for ambiguous failures
# BADGR_API_KEY: $(BADGR_API_KEY)
# Optional: output override: summary | console | pr-comment | both
# BADGR_OUTPUT_MODE: pr-comment
# Optional: self-hosted/private endpoint
# BADGR_API_URL: https://badgr.your-company.internal/v1Default: runs local Pipeline Check with no Badgr API key. Summary output is default. Add CI token only for richer logs/comments. Add BADGR_API_KEY only for AI on ambiguous failures.
GitLab CI
Add a job that runs when: always:
badgr_pipeline_check:
when: always
script:
- npx badgr-agent pipeline-check
variables:
# Optional: AI diagnosis for ambiguous failures
# BADGR_API_KEY: $BADGR_API_KEY
# Optional: override auto-detected GitLab token for richer logs / MR comments
# BADGR_CI_TOKEN: $CI_JOB_TOKEN
# Optional: output override: summary | console | pr-comment | both
# BADGR_OUTPUT_MODE: pr-comment
# Optional: self-hosted/private endpoint
# BADGR_API_URL: https://badgr.your-company.internal/v1Default: runs local Pipeline Check with no Badgr API key. Summary output is default. Add CI token only for richer logs/comments. Add BADGR_API_KEY only for AI on ambiguous failures.
Jenkins
Add to your Jenkinsfile:
post {
always {
sh '''
npx badgr-agent pipeline-check
# Optional AI diagnosis:
# BADGR_API_KEY="$BADGR_API_KEY" npx badgr-agent pipeline-check
# Optional richer CI context:
# BADGR_CI_TOKEN="$BADGR_CI_TOKEN" npx badgr-agent pipeline-check
# Optional output override:
# BADGR_OUTPUT_MODE=pr-comment npx badgr-agent pipeline-check
# Optional self-hosted endpoint:
# BADGR_API_URL="https://badgr.your-company.internal/v1" npx badgr-agent pipeline-check
'''
}
}Default: runs local Pipeline Check with no Badgr API key. Summary output is default. Add CI token only for richer logs/comments. Add BADGR_API_KEY only for AI on ambiguous failures.
Kubernetes (runtime diagnosis)
Requires kubectl in PATH with a valid kubeconfig. Run manually or add as a post-deploy step:
Download dist/k8s.js from Releases:
BADGR_API_KEY=<key> node dist/k8s.js --namespace=production --selector=app=apiIn a pipeline (post-deploy failure):
# GitHub Actions
- name: Badgr Pipeline Check
if: always()
env:
BADGR_API_KEY: ${{ secrets.BADGR_API_KEY }}
run: node dist/k8s.js --namespace=productionCollects warning events, pod describe, and container logs (including previous crash output). Prints diagnosis to stdout.
CI Runtime — Examples
Python + pytest (GitHub Actions)
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
permissions:
contents: read
actions: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- run: pip install -r requirements.txt
- run: pytest
- name: Badgr Pipeline Check
uses: michaelmanly/badgr-ci@v1
if: always()
with:
# badgr_api_key: ${{ secrets.BADGR_API_KEY }} # optional: AI for ambiguous failuresGo (GitHub Actions)
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
permissions:
contents: read
actions: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: '1.21'
- run: go test ./...
- name: Badgr Pipeline Check
uses: michaelmanly/badgr-ci@v1
if: always()
with:
# badgr_api_key: ${{ secrets.BADGR_API_KEY }} # optional: AI for ambiguous failuresRust (Azure DevOps)
trigger: [main]
pool:
vmImage: 'ubuntu-latest'
steps:
- script: cargo test
displayName: 'cargo test'
- task: BadgrCI@1
displayName: Badgr Pipeline Check
condition: always()
env:
BADGR_OUTPUT_MODE: summary
# BADGR_API_KEY: $(BADGR_API_KEY) # optional: AI for ambiguous failuresJava + Maven (Azure DevOps)
trigger: [main]
pool:
vmImage: 'ubuntu-latest'
steps:
- script: mvn test
displayName: 'mvn test'
- task: BadgrCI@1
displayName: Badgr Pipeline Check
condition: always()
env:
BADGR_OUTPUT_MODE: summary
# BADGR_API_KEY: $(BADGR_API_KEY) # optional: AI for ambiguous failuresBadgr Agent Infra — Approved Remediation
Approved-only remediation: Only explicitly allowlisted actions run. Defaults to detect-only monitoring.
Watches your containers and services, detects failures, and runs only pre-approved fixes (no arbitrary commands). Emails you when it acts or detects problems.
Key: Starts in detect-only mode (dry-run). After staging validation, toggle auto-fix ON via dashboard per org/project/runtime.
docker run -d \
--name badgr-agent \
--restart unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/badgr-agent:/var/lib/badgr-agent \
-e [email protected] \
-e BADGR_API_KEY=xxxx \
-e WATCH_CONTAINERS=api,worker,redis \
michaelmanleyx/badgr-agent:infraApproved Actions (when enabled)
Default approved actions:
- ✅ Restart stopped containers —
docker restart <name>+ verifies recovery - ✅ Restart inactive services —
systemctl restart <name>+ verifies - ✅ Clean old logs — deletes
/var/log/app/*.logfiles older than 7 days
Optional (disabled by default):
- ⚠️ Kill runaway process — only if
kill_processexplicitly added toACTION_ALLOWLISTAND CPU > threshold
Safe defaults
- Detect-only by default (
DRY_RUN=true) — agent monitors and alerts without making changes - Approved actions only — only actions in
ACTION_ALLOWLISTcan execute;restart_container, restart_service, cleanup_logsare approved by default kill_processoff by default — must be explicitly added toACTION_ALLOWLIST- Safe paths only — log cleanup restricted to
/var/log/app/*.log - Cooldown & escalation — 5-minute cooldown between retries; max 3 attempts per issue, then stops and alerts
Enable auto-fix (optional)
By default, Badgr Infra runs in detect-only mode. To enable auto-fix, set DRY_RUN=false:
docker run -d \
--name badgr-agent \
--restart unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/badgr-agent:/var/lib/badgr-agent \
-e DRY_RUN=false \
-e [email protected] \
-e BADGR_API_KEY=xxxx \
-e WATCH_CONTAINERS=api,worker,redis \
michaelmanleyx/badgr-agent:infraAfter running in detect-only mode for a few days and confirming alerts, you can toggle DRY_RUN=false to enable auto-fix.
Infra configuration
| Variable | Default | Description |
|----------|---------|-------------|
| BADGR_API_KEY | required | Your Badgr account key |
| EMAIL | — | Notification email for fixes and failures |
| WATCH_CONTAINERS | all | Comma-separated container names |
| WATCH_SERVICES | none | Comma-separated systemd services |
| DRY_RUN | true | Monitor without executing (detect-only by default) |
| ACTION_ALLOWLIST | restart_container,restart_service,cleanup_logs | Approved actions only |
| SCAN_INTERVAL_MS | 60000 | How often to scan |
| COOLDOWN_MS | 300000 | Min time between retries on same issue |
| MAX_ATTEMPTS | 3 | Max retries before escalation |
| DISK_LOG_CLEANUP_THRESHOLD | 85 | Disk % to trigger log cleanup |
Events are stored at /var/lib/badgr-agent/events.json.
How CI Diagnosis Works
On every build, Badgr runs as Pipeline Check:
- Collect — Fetches available logs or CI metadata (job logs, build context, pipeline YAML)
- Redact — Removes secrets and tokens before any analysis
- Score — Runs four local rule-based engines: failure, health, security, audit
- Escalate — If the build failed, an API key is configured, and the failure score is low-confidence or unknown, AI is called to refine the fix
- Publish — Results written to summary, console, or PR comment
High-confidence failure (local fix, no AI):
Cause: missing dependency
Evidence: Cannot find module 'vite'
Recommended fix: npm install --save-dev vite
Confidence: highLow-confidence failure (AI escalation):
Cause: ambiguous runtime error
Local score: low confidence → AI escalation
Recommended fix: pin Node 20 and rerun npm ciHealth, security, and audit findings are always local — they never call AI.
Amazon Bedrock (direct LLM provider)
For teams that want AI diagnosis without sending logs to aibadgr.com, Badgr can call Amazon Bedrock directly.
Set BADGR_LLM_PROVIDER=bedrock. Bedrock is used only when the local failure score is low-confidence — same trigger as the hosted path.
BADGR_LLM_PROVIDER=bedrock
AWS_REGION=us-east-1
# AWS credentials (omit if using an IAM role or instance profile)
AWS_ACCESS_KEY_ID=AKID...
AWS_SECRET_ACCESS_KEY=secret...
AWS_SESSION_TOKEN=... # optional: for temporary/assumed-role credentials
# Optional: override the model (default: anthropic.claude-3-5-sonnet-20241022-v2:0)
BADGR_BEDROCK_MODEL_ID=anthropic.claude-3-5-sonnet-20241022-v2:0Requires @aws-sdk/client-bedrock-runtime (optional dependency — install only for Bedrock mode):
npm install @aws-sdk/client-bedrock-runtimeGitHub Actions:
- name: Badgr Pipeline Check
uses: michaelmanly/badgr-ci@v1
if: always()
env:
BADGR_LLM_PROVIDER: bedrock
AWS_REGION: us-east-1
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}Azure Pipelines:
- task: BadgrCI@1
displayName: Badgr Pipeline Check
condition: always()
env:
BADGR_OUTPUT_MODE: summary
BADGR_LLM_PROVIDER: bedrock
AWS_REGION: us-east-1
AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID)
AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)CI Troubleshooting
Step didn't run:
- GitHub: use
if: always()(notif: failure()) - Azure: use
condition: always()(notcondition: failed()) - GitLab: use
when: alwaysin the.poststage - Jenkins: use
post { always { ... } }
No summary or output appeared:
- Expand the Badgr step in the job log and look for errors
- GitHub: token needs
pull-requests: writeandactions: readpermissions - Azure: set
BADGR_OUTPUT_MODE: summary
No PR comment appeared:
- PR comments require a PR to be open; plain branch pushes write to job summary instead
- GitHub: token needs
pull-requests: writepermission - Azure:
SYSTEM_ACCESSTOKENis required for PR thread comments; enable "Allow scripts to access the OAuth token" in pipeline settings - GitLab:
GITLAB_TOKENneedsread_api+ write notes - Jenkins:
GITHUB_TOKEN/GITLAB_TOKENrequired to post to PR/MR; without either, check console output
Kubernetes: no diagnosis printed:
- Verify
kubectlis inPATHandkubeconfigis valid - Check that the namespace contains failed or unhealthy pods (
kubectl get pods -n <ns>) - Run with
--namespace=<ns>to scope the search
Security & Policy
Unified policy across all runtimes:
- Every org/project/runtime has an on/off toggle in the Badgr dashboard
- Detect-only by default (Infra) and diagnosis-only by default (CI)
- All auto-fixes are allowlist-only — no arbitrary command execution
- Logs redacted client-side before sending to backend
- API keys never appear in PR comments, logs, or dashboards
- Infra agent never runs arbitrary shell commands
kill_processis opt-in and requires explicitACTION_ALLOWLISTentry + CPU threshold exceeded- Repeat failures tracked server-side; LLM improvements happen without code changes
Support
- Email: [email protected]
- Get API key: aibadgr.com
