Skip to content
Back to skills

Check Pr Quality

ASecurity

Diff-bounded single-pass quality evaluation for PR review. Classifies every changed path by ARTIFACT TYPE first (runtime code / deployable config / tests / docs-planning / garura prose / ProductOS model / STM evidence / wireframes — pure globs, first match wins), then evaluates standard-ID checks against the diff using mechanical match rules from the PR severity taxonomy — grep-based rules fire only on runtime-code/deployable-config/tests (a keyword in prose is not a security defect, #438); p...

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
testingpythonbashsqlapisecurity

Works with

  • api

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned November 7, 2026

npx -y skills add intent-driven-ai/garura --skill check-pr-quality --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Check Pr Quality?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Check Pr Quality
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/intent-driven-ai-check-pr-quality/badge)](https://www.skillsdirectory.com/skills/intent-driven-ai-check-pr-quality)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: check-pr-quality
description: Diff-bounded single-pass quality evaluation for PR review. Classifies every changed path by ARTIFACT TYPE first (runtime code / deployable config / tests / docs-planning / garura prose / ProductOS model / STM evidence / wireframes — pure globs, first match wins), then evaluates standard-ID checks against the diff using mechanical match rules from the PR severity taxonomy — grep-based rules fire only on runtime-code/deployable-config/tests (a keyword in prose is not a security defect, #438); pure path rules respect the same prose guard on prose artifacts unless the matched glob is docs-targeting (#454). Matching runs in a bundled deterministic script (scan_taxonomy.py) — real glob/regex, no inference. Every finding carries artifact_type. Emits findings.yaml. Reuses /check-quality KB data — NOT its 11-subagent execution model. Use only from check-change play; never invoke standalone for full-repo audits.
user-invocable: false
model: sonnet
allowed-tools: Read, Write, Bash, Glob, Grep
---

# Quality Check (Scoped)

Single-pass diff-bounded evaluation. Reuses the KB used by `/check-quality` but evaluates only standards relevant to files in `changed_paths`. **Diff scope invariant: NEVER reads files outside `changed_paths`.**

## Purpose vs `/check-quality`

| | `/check-quality` | `check-pr-quality` |
|---|---|---|
| Scope | Full repo | Diff only |
| Execution | 11 parallel subagents | Single deterministic script (`scan_taxonomy.py`) |
| Output | Spider chart + scored audit | `findings.yaml` |
| Invocable | User | Play only (review-pr) |
| KB usage | All standards in all domains | Only standards whose taxonomy match rule fires on the diff |

## Input

The skill is invoked with a JSON payload from `quality-auditor`:

```yaml
diff_path: "{stm_base}/{issue}/evidence/review-pr/diff.patch"   # unified diff
changed_paths:                                                    # array; absolute repo-relative paths
  - src/api/users.ts
  - src/db/migrations/0042_add_email.sql
standards_order:                                                  # short-term copies: the taxonomy copy first, then any quality standards, in the tier order of config review-pr.standards_order
  - "{stm_base}/{issue}/context/memory/knowledge/quality/"
severity_taxonomy_path: "{stm_base}/{issue}/context/memory/standards/rules/pr.md"  # the short-term copy quality-auditor fetched
intent_summary: "Add email verification flow"                     # 1–3 sentences from spec/intent.yaml or PR body
output_path: "{stm_base}/{issue}/evidence/review-pr/findings.yaml"
```

**Pre-flight (hard halts):**

| Check | Action on Failure |
|---|---|
| `severity_taxonomy_path` exists (the short-term copy of `standards/rules/pr.md`) | HALT — "PR severity taxonomy missing at {path}" |
| `diff_path` exists and non-empty | HALT — "Empty or missing diff" |
| `changed_paths` non-empty | HALT — "No changed paths supplied" |
| At least one entry of `standards_order` resolves to a short-term copy (the path exists in the issue's short-term memory) | HALT — "No standards source resolvable" |

## Process

The whole mechanical scan is one deterministic script — `scripts/scan_taxonomy.py` (#454).
It is a real glob/regex engine, **not inference**: the agent runs it and returns its output,
and never hand-matches rules against files. Hand-matching an 800-file diff against a 330-row
table was the old slow path AND the source of loose-substring false positives (a name-glob
`**/schema*` "matching" `finding-schema.md`); a real glob engine makes both problems
structurally impossible.

### Step 1 — Run the scan
Write the contract's `changed_paths` (one path per line) to a file and pass it as `--paths`,
so the scan is bounded by the contract's authoritative list — the Diff Scope Invariant, not a
list the script re-derives:
```
printf '%s\n' "${changed_paths[@]}" > "{working}/changed-paths.txt"
python3 <skill-dir>/scripts/scan_taxonomy.py \
    --taxonomy "{severity_taxonomy_path}" \
    --diff "{diff_path}" \
    --paths "{working}/changed-paths.txt" \
    --out "{output_path}"
```
`--paths` is authoritative when supplied; only when the caller omits it does the script fall
back to deriving `changed_paths` from the diff's own file headers. The added lines used for
`grep:` rules always come from the diff. In one pass the script:

1. **Classifies** every changed path by artifact type — the taxonomy's Artifact-Type
   Scoping table, first-match glob (`garura-prose`, `productos-model`, `stm-evidence`,
   `wireframe`, `tests`, `deployable-config`, `docs-planning`, `runtime-code` default).
2. **Evaluates** every severity row's match rule with real glob/regex:
   - `grep:` / `grep+path:` grep-half — eligible only on the CODE artifact types
     (`runtime-code`, `deployable-config`, `tests`); dropped on any prose type (#438).
   - `path:` / `grep+path:` path-half — on a prose artifact type it fires only when the
     matched glob is docs-targeting; otherwise the match is dropped (#454 prose guard).
   - `CODE-20` `**/*` catch-all — rolled into `meta.catchall.CODE-20` as a single count,
     never per-file findings (#454).
   - A path under `docs/adr/`, or of artifact type `stm-evidence`, gets no finding (#851;
     the reason is in the taxonomy's Artifact-Type Scoping section).
   - A `--paths` entry that does not look like a path (it starts with `+`, `-` or a space,
     or holds `": `) is dropped and listed in `meta.rejected_paths`.
3. **Emits** `findings.yaml` (schema below), stable-sorted, byte-identical across runs.

### Step 2 — Verify and return
Confirm the script exited `0` and `{output_path}` exists. If `meta.errors` is non-empty a
taxonomy row failed to compile (FS-5) — surface it; do not work around it. Return the
`findings.yaml` path to the caller. Do **not** re-derive, re-classify, or "double-check" any
finding by inference — the script's output is authoritative and complete. KB description
files are consulted (via `standards_order`) only when a human reads a finding back, not to
gate emission — the taxonomy row IS the standard.

### Output ordering
`findings.yaml` is written with a stable sort (`severity → file → line → standard_id`), so
two invocations on the same `(diff, taxonomy)` produce byte-identical output bar
`meta.generated_at`.

```yaml
meta:
  generated_at: "{ISO-8601}"
  diff_path: "{diff_path}"
  taxonomy_path: "{severity_taxonomy_path}"
  changed_paths_count: {N}
  scan_coverage: {0.0–1.0}
  standards_relevant: {count}
  catchall:
    CODE-20: {count of files the **/*​ catch-all covered}   # count, not findings (#454)
findings:
  - standard_id: SEC-19
    severity: P1
    file: src/config/secrets.ts
    line: 14
    evidence: 'const apiKey = "sk_live_abc..."'
    artifact_type: runtime-code
    taxonomy_rule_id: SEC-19
  - ...
counts:
  P1: {n}
  P2: {n}
  P3: {n}
  P4: {n}
```

## Output

The schema of `findings.yaml`:

| Field | Type | Required | Notes |
|---|---|---|---|
| `meta.generated_at` | string | yes | ISO-8601 |
| `meta.diff_path` | string | yes | echoed from input |
| `meta.scan_coverage` | float | yes | 0.0–1.0 |
| `meta.standards_relevant` | int | yes | count of taxonomy rows whose match rule fired |
| `meta.catchall.CODE-20` | int | yes | count of files the `**/*` catch-all covered — a count, never per-file findings (#454) |
| `meta.errors[]` | list | no | taxonomy rows that failed to compile (FS-5); empty/absent when clean |
| `findings[].standard_id` | string | yes | MUST exist in taxonomy |
| `findings[].severity` | enum P1\|P2\|P3\|P4 | yes | sourced from taxonomy, never inferred |
| `findings[].file` | string | yes | repo-relative path from `changed_paths` |
| `findings[].line` | int | yes | line in the diff hunk |
| `findings[].evidence` | string | yes | matched substring or path |
| `findings[].artifact_type` | enum | yes | from the Artifact-Type Scoping table; grep findings only on `runtime-code`/`deployable-config`/`tests` |
| `findings[].taxonomy_rule_id` | string | yes | same as `standard_id` |
| `counts.P1`–`P4` | int | yes | counts by severity |

## Diff Scope Invariant

The skill MUST NOT:
- Read files outside `changed_paths`.
- Walk the full repository tree.
- Invoke `/check-quality` or any of its subagents.
- Use heuristic/LLM reasoning to classify severity — severity is read from the taxonomy table, not inferred.

## Determinism

Two back-to-back invocations on the same `(diff_path, changed_paths, taxonomy_path)` MUST produce a byte-identical `findings.yaml` (after stripping `meta.generated_at`). Stable sort order: `severity asc → file asc → line asc → standard_id asc`. This is guaranteed by `scan_taxonomy.py` being pure glob/regex — there is no inference step to vary between runs.

## Failure Modes

| Code | Condition | Action |
|---|---|---|
| FS-1 | Taxonomy missing | HALT + structured failure |
| FS-2 | Diff empty/missing | HALT |
| FS-3 | A finding lacks `standard_id` | DROP finding + log error to evidence |
| FS-4 | No entry of `standards_order` resolves to a short-term copy | HALT |
| FS-5 | Match rule regex invalid | HALT — taxonomy is malformed |

## Reference

- Scanner: `scripts/scan_taxonomy.py` (the deterministic match engine — #454)
- Input contract: `reference/input-contract.md`
- Output schema: `reference/finding-schema.md`
- Taxonomy: the memory rule `standards/rules/pr.md`, read only through the short-term copy at `severity_taxonomy_path`

Files in this skill

  • SKILL.md9.3 KB
  • reference/finding-schema.md2.5 KB
  • reference/input-contract.md2 KB
  • scripts/scan_taxonomy.py16.5 KB
  • scripts/test_scan_taxonomy.py7.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.