# Audit Pr

> >

- **Type:** Skill
- **Install:** `agentstack add skill-gtrabanco-agentic-workflow-audit-pr`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [gtrabanco](https://agentstack.voostack.com/s/gtrabanco)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [gtrabanco](https://github.com/gtrabanco)
- **Source:** https://github.com/gtrabanco/agentic-workflow/tree/main/skills/audit-pr

## Install

```sh
agentstack add skill-gtrabanco-agentic-workflow-audit-pr
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Audit PR

The manager's **"can this ship?"** gate. A read-first audit over the *entire* PR —
its SPEC, all phases, docs, tests, CI, and review axes — that returns a single
verdict: **merge-ready** or a ranked list of **blockers**. **Never edits, never
refactors.** By default it never merges either — the human decides and merges.
The one exception is the **opt-in auto-merge** below: a documented policy (or an
explicit user instruction) plus a fail-closed pre-merge checklist.

## Turn contract — verify before ending the turn

```
✓ The verdict block was printed in the fixed format: `VERDICT: MERGE-READY | BLOCKED` with ranked, evidenced blockers
✓ The PR's FULL URL is printed in the verdict header (the user may be juggling
  several projects and agents without a CI monitor — the link in the chat is
  the contract, never "PR #N" alone)
✓ MERGE-READY verdict? Then the MERGE-READY comment was POSTED on the PR
  (`gh pr comment --body-file` RUN, idempotent by SHA marker) — a comment,
  never a commit-message tag. BLOCKED → no comment posted
✓ Nothing was edited or refactored; nothing was merged UNLESS the auto-merge
  policy applied AND the pre-merge checklist was RUN with its output pasted
✓ The closing `→ Next:` block is printed, then the machine envelope (fenced ```json — see ## Machine envelope) as the ABSOLUTE last output
```

About to end the turn with any box unchecked? The turn is NOT done — complete
the missing box first (weak models drop end-of-document duties; this list is
first on purpose).

## When to use

- After the work is "done" and before merging — the final gate once `review-change`
  is clean and all phases are committed.
- When you want one defensible answer to "is this PR actually ready?" rather than
  trusting that every loose end was tied off.

`review-change` reviews the *diff* for quality; `audit-pr` audits the *PR as a unit
of delivery* — that everything the SPEC promised is present, traceable, and green.

## Scope

The whole pull request: the branch vs. the default base, **plus** its SPEC and
planning artifacts, the roadmap entry, the doc map, the PR body, issue links, and
CI. Default target is the current branch's PR; accept a PR number to target another.

## Step 0 — Discover the project & the PR (always first)

1. **Project contract.** Per the agent guide's **Workflow conventions** +
   **documentation map**, then read what THIS skill needs: the roadmap, the
   feature/fix templates, and the project's verification gate (type-check / tests
   / build / CI).
2. **The PR.** Identify it and read it in full (forge CLI per the project's
   Workflow conventions — examples use `gh`):
   ```sh
   gh pr view  --json number,title,body,baseRefName,headRefName,isDraft,mergeable,mergeStateStatus,files,commits,statusCheckRollup,closingIssuesReferences
   ```
   If no PR number is given, resolve the current branch's PR
   (`gh pr view --json ...`). If none exists yet, audit the branch vs. the default
   base and say "no PR open yet" — the contract still applies.
3. **The SPEC.** Locate the governing SPEC — `docs/features/-/` (feature)
   or `docs/fix/-/` (fix) — and its planning artifacts (`PLAN.md`,
   `TASKS.md`, `progress.md`, `testing.md`, `known-issues.md`, `decisions.md`) when
   present. The SPEC is the source of truth for what "done" means.

## Merge-readiness contract

Check each gate; cite evidence (file:line, criterion, check name, issue number).
A gate that can't be confirmed is a **blocker**, not a pass — never assume green.

| Gate | What it means | Blocker when |
|---|---|---|
| **Acceptance criteria** | Every SPEC acceptance criterion is satisfied, each mapped to concrete evidence (code, test, or doc). | Any criterion unmet, unverifiable, or silently dropped. |
| **All phases complete** | Feature: every phase in `PLAN.md`/`TASKS.md` is done and logged in `progress.md`. Fix: the SPEC is fully implemented. | Any unchecked task or unimplemented phase without an explicit, tracked deferral. |
| **Scope integrity** | The PR implements the SPEC and no more; out-of-scope work was split out. | Undocumented scope creep, or in-scope work missing. |
| **Docs updated** | Every "Affected docs" criterion is satisfied; per-phase docs (`progress`/`testing`/`known-issues`/`decisions`) reflect reality; the doc map still resolves. **Never merge with documentation still pending.** | A doc the map or SPEC requires is stale, missing, pending, or contradicts the code. |
| **Traceability** | `Closes #N` is in the PR body when the work is issue-born (from `plan-feature-from-issue` or `plan-fix`); the roadmap/fix-index entry matches, is **still present** (removed only *after* merge, never before), and carries the linked PR reference (`done · [#]()`). | Issue-born work without `Closes #N`; a roadmap/index entry out of sync; the entry dropped before merge; or a `done` row without its PR link. |
| **Tests** | New behavior is covered at the right layer (prefer integration); acceptance criteria map to tests; no regression-risk tests left red. | New behavior untested, or tests assert nothing meaningful. |
| **Verification gate / CI** | The project's gate passes — type-check, tests, build — and `statusCheckRollup` is green. | Any required check failing, pending, or absent where the project requires one. |
| **Mergeability** | Branch is off the default base, independently mergeable (no conflicts), not stacked on another PR, not draft. | Wrong base, conflicts, stacked dependency, or still draft. |
| **Review axes clean** | The applicable `review-change` axes are clean **or** every remaining finding is *consciously deferred* to a tracked issue with a trigger. | A `fix-now` finding still open, or a deferral with no issue/trigger behind it. |

> Run `review-change` for the axis check if it hasn't been run on the final state,
> or read its latest report. Don't re-litigate findings already classified — verify
> each open one is either resolved or has a real, tracked home.

> **`done` ≠ merge-ready.** A unit flips to `done` when its PR opens (built, not
> merged — merge state lives in the forge). So a `done` roadmap row is *not* evidence
> of merge-readiness: this gate still has to pass on its own. The two things this gate
> most often catches on a `done`-but-unmerged unit are **pending docs** and a
> **prematurely-removed issue/fix-index entry** — both are blockers.

## Process

1. **Gather** — Step 0: project contract, PR, SPEC + artifacts, CI status.
2. **Walk the contract** — evaluate every gate above against evidence. For each,
   record pass / blocker / n-a with the specific artifact or check that proves it.
3. **Confirm deferrals are real** — for anything postponed (an unchecked task, a
   review finding, a known issue), verify a tracked issue + trigger exists. A
   deferral with no destination is a blocker, not a pass.
4. **Decide** — one verdict:
   - **MERGE-READY** — every applicable gate passes; list the few things the human
     should still eyeball (the manual-verification items `review-change` surfaced).
   - **BLOCKED** — one or more gates fail; output the ranked blocker list.
5. **Post the MERGE-READY comment on the PR (MERGE-READY only).** The verdict
   must be visible on the PR itself — as a **comment**, never in a commit
   message (a commit trailing "MERGE-READY" pollutes history and goes stale
   the moment the branch moves). Write the body to a file (Markdown rule —
   see Guardrails) and run
   `gh pr comment  --body-file ` with exactly this body:

   ```markdown
   
   ## ✅ audit-pr: MERGE-READY

   - **Audited head:** `` · CI: 
   - **Date:** 
   - **Before merge, a human should still verify:**
     - 

   Any commit after `` voids this verdict — re-run `audit-pr`.
   ```

   **Idempotent:** first check the existing comments
   (`gh pr view  --json comments`) for the ``
   marker — same SHA already commented → skip (say so); older SHA → post the
   new comment (the newest marker wins). Never post a comment for a BLOCKED
   verdict — blockers go in the chat report only, so the PR page never shows
   a stale green flag.
6. **Auto-merge check (only on MERGE-READY)** — evaluate the opt-in auto-merge
   section below. Policy present + pre-merge checklist green → merge and report
   the merge evidence. Otherwise the human merges — say so explicitly.
7. **Report** — the verdict block below, always headed by the PR's full URL.

## Auto-merge (opt-in — default is the human merges)

By default this skill **never merges**. It merges a MERGE-READY PR only when
**both** keys hold:

1. **Written authorization.** The project's docs state the policy — e.g.
   `merge: auto` / `merge: fullauto` in the agent guide's Workflow conventions
   or the committed decision record (`docs/features/SHIP_DECISIONS.md`) — **or**
   the user explicitly instructed it in this conversation ("merge it if
   merge-ready"). An inferred preference, a past session, or convenience is
   never authorization.
2. **Pre-merge checklist — RUN it fresh, paste the outputs; fail-closed** (any
   box that cannot be evaluated counts as failed):

   ```
   ✓ VERDICT is MERGE-READY, issued in THIS turn, bound to the PR's current
     head SHA (re-check the head via the forge — any later commit voids it)
   ✓ `git status --porcelain` → empty (nothing uncommitted — code or docs)
   ✓ `git fetch` + `git status -sb` (on the PR branch) → neither ahead nor
     behind its remote (nothing unpushed, nothing unpulled)
   ✓ Remote head SHA == the SHA this audit evaluated
   ✓ CI re-checked green on that exact SHA via the forge at merge time (no-CI
     project: a fresh local gate run on that SHA, output pasted)
   ✓ The PR touches no declared sensitive area and contains no destructive
     (data-deleting / schema-destructive) diff
   ✓ The forge accepts the merge (a refusal — branch protection, conflicts —
     parks the PR; never bypass, never force)
   ```

3. **Anything pending → do NOT merge, even with authorization.** Uncommitted or
   unpushed work would make the PR's CI result stale the moment it lands.
   The sequence is fixed: route the pending work (commit + push via
   `execute-phase`'s fold cycle) → wait for CI on the new head → **re-run
   `audit-pr`** → only a fresh MERGE-READY on the new SHA may merge. Never
   merge on a stale verdict.

After a successful merge: print the merged PR URL + merge SHA, and route the
post-merge close-out (pull the default branch; remove/archive the fix-index
entry per the project's convention — only now, never before).

## Verdict format

```
PR # — 
URL: 
Base:  ← Head:  @    CI: 

VERDICT: MERGE-READY | BLOCKED ( blockers)

Blockers (ranked):
  1. []  — evidence: 
     → fix:  ()
  ...

Non-blocking nits:
  -  — 

Before merge, a human should still verify:
  - 

→ Next:
  · MERGE-READY, no auto-merge policy → you merge: , then
    /plan-feature --next (the next roadmap unit) or pick an issue with /triage-issue
  · MERGE-READY, auto-merge authorized → merged (URL + merge SHA above), then
    /plan-feature --next or /triage-issue
  · MERGE-READY but pending commit/push/pull found → NOT merged: commit + push,
    wait for CI, re-run /audit-pr (a fresh verdict on the new SHA decides)
  · BLOCKED → clear the top blocker (routed above), then re-run /audit-pr
```

If MERGE-READY, omit the blocker list and state it plainly: nothing blocks merge.
The `→ Next:` block is always printed — on MERGE-READY it repeats the **full PR
URL** (merge it yourself, or the merged link) and points the user at the next
concrete unit so a finished feature never dead-ends at the merge.

Example (generic — substitute your project's numbers and gates):

```
PR #142 — Add CSV export to the reports view
Base: main ← Head: feat/14-csv-export   CI: green

VERDICT: BLOCKED (2 blockers)

Blockers (ranked):
  1. [Tests] Export handler has no test — acceptance criterion "export
     round-trips the rows" is unverified
     → fix: add an integration test for the handler (fold into the current phase)
  2. [Traceability] PR body is missing `Closes #131` for issue-born work
     → fix: add `Closes #131` to the PR body (execute-phase)

Non-blocking nits:
  - Help text wording diverges from the other commands — docs/USAGE.md

Before merge, a human should still verify:
  - The exported file opens cleanly in a spreadsheet app (visual)
```

## Routing (blockers, by kind)

- **Incomplete in-scope work** → fold into this branch via `execute-phase`
  (the relevant phase or `--fix`); re-run `audit-pr` after.
- **Out-of-scope defect surfaced** → `plan-fix` (new fix entry), not this PR.
- **Deferred finding lacking a home** → `triage-issue` to file + classify it.
- **Stale/missing docs** → update per the doc map (often a quick `execute-phase`
  doc commit), then re-audit.
- **Red CI / failing gate** → report the failing check; the dev fixes on-branch.

## Guardrails

- **Read-first verdict. Never push, edit, or refactor.** The only forge writes
  this skill may perform: (1) the **MERGE-READY comment** (Process step 5 —
  idempotent, comment-only, never a commit tag), and (2) the opt-in
  **auto-merge** — written policy or explicit instruction, MERGE-READY on the
  current SHA, pre-merge checklist green, outputs pasted. One key missing →
  the human ships.
- **Forge bodies are Markdown, not shell — never hand-escape.** The comment's
  backticks are formatting; a `\` before them renders literally. Write the
  body to a file and pass `--body-file ` — never inline `--body "…"` or
  a quoted heredoc. Verify with `gh pr view  --json comments` that no
  literal `` \` `` survived.
- **Never merge with anything uncommitted, unpushed, or unpulled** — even when
  auto-merge is authorized. Pending work makes the CI evidence stale: commit +
  push, wait for CI, re-audit, and only the fresh verdict may merge.
- Never report MERGE-READY on an unconfirmed gate — absence of evidence is a blocker.
- Don't re-run the full review from scratch; compose `review-change` and verify its
  open findings are resolved or tracked.
- Honor the project's **Workflow conventions** (gate, docs-language, evidence —
  every blocker cites file:line/check/criterion/issue — track-don't-inline:
  out-of-scope problems become issues/fix entries, never silent additions here).

## Machine envelope

Every invocation ends with the **machine envelope** — schema, field rules and
placement per the installed `orchestration-envelope` skill: one fenced
```json block, printed **after** the closing block above, as the **absolute
last output** of the turn (external orchestrators parse the LAST fenced json
block; see `docs/workflow/ORCHESTRATION.md`). All top-level keys always
present; values only from verified command output, never invented.

This skill emits:

- **`state`:** `MERGE_READY` (verdict MERGE-READY; the PR comment below was
  posted; `pr.merge_ready: true`), `MERGED` (opt-in auto-merge executed —
  merge SHA in `detail`), `NEEDS_FIXES` (in-scope blockers → fold on-branch,
  re-audit; `blockers[]` mirrors the ranked list), or `BLOCKED` (external
  cause: wrong base, conflicts, a dependency PR).
- **Fields:** `pr` fully filled (number, url, head_sha, ci, merge_ready);
  `gates.audit_pending: false` after a verdict; `findings.issues_filed` =
  issues opened for deferrals lacking a home.
- `detail`: `{"verdict": "MERGE-READY|BLOCKED", "blockers_ranked": [...],
  "manual_verification": [...], "merge_sha": ""}`.

Example (MERGE-READY, default mode — abbreviated):

```json
{"skill": "audit-pr", "state": "MERGE_READY",
 "summary": "PR #14 passes every gate; comment posted; human merges.",
 "unit": {"type": "fix", "id": "43-null-crash", "issue": 43, "branch": "fix/43-null-crash"},
 "phase": {"current": null, "total": null, "completed": null},
 "pr": {"number": 14, "url": "https://github.com/o/r/pull/14", "state": "open",
        "head_sha": "abc123", "merge_ready": true, "ci": "green"},
 "gates": {"verification": "green", "review_pending": false, "audit_pending": false},
 "findings": {"fix_now": [],

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [gtrabanco](https://github.com/gtrabanco)
- **Source:** [gtrabanco/agentic-workflow](https://github.com/gtrabanco/agentic-workflow)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-gtrabanco-agentic-workflow-audit-pr
- Seller: https://agentstack.voostack.com/s/gtrabanco
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
