pr-guardian — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited pr-guardian (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
An autonomous cron-based loop that watches your current PR and drives it to merge.
┌─────────────────────────────────────────────────────────────┐
│ PR Guardian Loop │
├─────────────────────────────────────────────────────────────┤
│ 1. Check PR review comments │
│ └─ If unresolved → /rune:resolve-all-gh-pr-comments │
│ 1.5 Local quality gate (lint + typecheck) │
│ └─ Auto-detect stack → run lint/format/typecheck │
│ └─ Runs BEFORE every git push │
│ 2. Check CI/CD status │
│ └─ If red → diagnose & fix → lint gate → push │
│ 3. Check branch freshness vs main │
│ └─ If behind → rebase → lint gate → push │
│ 3.5 Local services & migration health │
│ └─ A: Start Docker Compose / verify dev servers │
│ └─ B: Detect & resolve migration conflicts │
│ (Alembic, Django, Rails, Prisma, Sequelize, etc.) │
│ └─ C: Apply pending migrations + round-trip verify │
│ 4. Run browser tests (if applicable) │
│ └─ Frontend/API changes → test related routes │
│ 5. All green + no comments? │
│ └─ Merge PR (squash + delete branch) │
│ └─ Delete this cron job │
└─────────────────────────────────────────────────────────────┘/rune:pr-guardian # Start the guardian on current branch's PR
/rune:pr-guardian <PR_NUMBER> # Watch a specific PR
/rune:pr-guardian --disable-auto-merge # Watch PR but skip auto-merge (monitor + fix only)
/rune:pr-guardian <PR_NUMBER> --disable-auto-merge # Watch specific PR, skip auto-mergeWhen this skill is invoked, perform these steps in order:
# Parse arguments — extract PR number and flags
PR_NUMBER=""
DISABLE_AUTO_MERGE=false
for arg in $ARGUMENTS; do
case "$arg" in
--disable-auto-merge) DISABLE_AUTO_MERGE=true ;;
[0-9]*) PR_NUMBER="$arg" ;;
esac
done
# If no PR number provided, detect from current branch
if [ -z "$PR_NUMBER" ]; then
gh pr view --json number -q '.number'
fiIf no open PR is found on the current branch, STOP and tell the user:
"No open PR found on this branch. Push your branch and create a PR first."
Use CronCreate with:
*/5 * * * * (every 5 minutes)trueSave the returned job ID — you will need it for self-deletion in Step 5.
Tell the user:
DISABLE_AUTO_MERGE=false:"PR Guardian activated for PR #<NUMBER>. Checking every 5 minutes. I'll auto-merge when everything is green. The cron auto-expires after 7 days if not completed sooner."
DISABLE_AUTO_MERGE=true:"PR Guardian activated for PR #<NUMBER> (monitor-only mode). Checking every 5 minutes. Auto-merge is disabled — I'll fix issues but won't merge. The cron auto-expires after 7 days."
Each cron tick should execute this prompt (adapt the PR number):
You are the PR Guardian. Execute these steps for PR #<PR_NUMBER> in order. Stop at the first step that requires action and re-check on the next tick. Auto-merge is <ENABLED|DISABLED based on DISABLE_AUTO_MERGE flag>.
#### Phase 1: Review Comments
gh pr view <PR_NUMBER> --json reviewDecision,reviews,comments --jq '{
decision: .reviewDecision,
pending_reviews: [.reviews[] | select(.state == "CHANGES_REQUESTED" or .state == "COMMENTED") | {author: .author.login, state: .state}],
comment_count: (.comments | length)
}'/rune:resolve-all-gh-pr-comments skill to resolve all comments#### Phase 1.5: Local Quality Gate (Lint & Typecheck)
Before every git push, run the project's lint and typecheck commands to catch errors locally instead of waiting for a full CI cycle. See local-quality-gate.md for full framework-specific commands.
Summary:
.tsx/.jsx/.vue, backend: .py/.rb/.go/.rs/.php)$PKG run lint / eslint → tsc --noEmit → prettier auto-fixmake check-all / make lint / task lint convenience targetsstyle: auto-fix lint and formatting| Stack | Lint | Typecheck | Format |
|---|---|---|---|
| JS/TS | eslint / $PKG run lint | tsc --noEmit | prettier |
| Python | ruff → flake8 | mypy / pyright | ruff format |
| Ruby | rubocop | — | rubocop |
| Go | golangci-lint → go vet | — | gofmt |
| Rust | cargo clippy | built-in | cargo fmt |
| PHP | phpstan | phpstan | pint / php-cs-fixer |
Key rule: This phase runs BEFORE every git push in the guardian loop — that includes after Phase 1 (comment fixes), Phase 2 (CI fixes), Phase 3 (rebase), and Phase 4 (browser test fixes).
#### Phase 2: CI/CD Status
gh pr checks <PR_NUMBER> --json name,state,conclusion --jq '.[] | select(.state != "COMPLETED" or .conclusion != "SUCCESS")'gh run view <RUN_ID> --log-failedfix: resolve CI failure — <brief description>#### Phase 3: Branch Freshness (Rebase onto Main)
git fetch origin main
BEHIND_COUNT=$(git rev-list --count HEAD..origin/main)
echo "Behind main by: $BEHIND_COUNT commits"BEHIND_COUNT > 0:git rebase origin/mainalembic heads → if multiple, alembic merge headsdb/migrate/ for conflicting timestampsnpx prisma migrate resolvegit rebase --continue after resolvinggit push --force-with-lease (safe force push after rebase)#### Phase 3.5: Local Services & Migration Health
Before running browser tests, ensure local services are up and the database schema is current. See services-and-migrations.md for full framework-specific commands.
##### 3.5A: Service Readiness
docker-compose.yml / compose.yml → docker compose up -d --wait → wait for health checks (max 60s) → rebuild if Dockerfile / dependency lockfiles changednc / curl##### 3.5B: Migration Conflict Detection & Resolution
Auto-detect migration framework and resolve conflicts before applying:
| Framework | Conflict Detection | Auto-Resolution |
|---|---|---|
| Alembic | alembic heads → multiple heads? | alembic merge heads + commit |
| Django | showmigrations --plan → CONFLICT? | makemigrations --merge per app + commit |
| Rails | Duplicate timestamps in db/migrate/ | Flag for manual resolution |
| Prisma | prisma migrate status + drift check | Flag drift for review |
| Sequelize | db:migrate:status | — |
| Knex | migrate:status | — |
| TypeORM | migration:show | — |
Command resolution (Python): uv run alembic → .venv/bin/alembic → alembic (same pattern for Django manage.py).
##### 3.5C: Apply Migrations & Verify Database
downgrade -1 → upgrade head to ensure reversibilitydb/schema.rb if changed after migrationnpx prisma generate after deploypg_isready (PostgreSQL) / mysqladmin ping (MySQL) via Docker#### Phase 4: Browser Tests
Determine if the PR touches frontend or API-facing code:
# Get changed files
gh pr diff <PR_NUMBER> --name-only/rune:test-browser skill was removed in v3.0.0-alpha.2; trigger /rune:arc Phase 7.7 or invoke the e2e-browser-tester agent directly if a fresh harness is available)If browser tests fail:
If browser tests pass → proceed to Phase 5
#### Phase 5: Merge & Cleanup
All conditions met:
If `DISABLE_AUTO_MERGE=true` (monitor-only mode):
"PR #<PR_NUMBER> is fully green — all checks pass, no unresolved comments, branch is up-to-date. Auto-merge is disabled. Merge manually when ready."
If `DISABLE_AUTO_MERGE=false` (default):
Execute the merge:
# 1. Verify gh CLI
command -v gh && gh auth status
# 2. Switch to correct GitHub account
source "${RUNE_PLUGIN_ROOT}/scripts/lib/gh-account-resolver.sh" && rune_gh_ensure_correct_account
# 3. Verify PR is still open and mergeable
gh pr view <PR_NUMBER> --json state,mergeable --jq '{state, mergeable}'
# 4. Squash merge + delete branch
GH_PROMPT_DISABLED=1 gh pr merge <PR_NUMBER> --squash --delete-branch
# 5. Sync local
git checkout main && git pull origin mainAfter successful merge:
"PR #<PR_NUMBER> has been merged successfully! Guardian loop terminated."
--force-with-lease after rebase (never --force)docker compose down — only up -d. Guardian should add services, not destroy themDROP, TRUNCATE). Only migrate forwardgh-account-resolver.sh to ensure correct account before mergeTo stop the guardian manually, the user can say:
"Stop the PR guardian" / "Cancel the loop"
This should trigger CronDelete with the saved job ID.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.