audit-pr
Audit a whole PR against the delivery contract and return MERGE-READY or evidenced blockers with the full URL. Consumes the current review-change REVIEW-PASS receipt instead of re-running review axes; posts a SHA-bound ready comment; never edits or merges. Triggers: "audit-pr", "
Install
npx skills add https://github.com/gtrabanco/agentic-workflow/tree/main/skills/audit-pr
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install gtrabanco-agentic-workflow@llmmart
git clone https://github.com/gtrabanco/agentic-workflow.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole gtrabanco/agentic-workflow collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Audit PR
The manager's "can this ship?" gate. A read-first audit over the entire PR —
its SPEC, all phases, docs, CI status, and review receipt — that returns a single
verdict: merge-ready or a ranked list of blockers. Never edits,
refactors, or merges. The human merges, or an active
ship-roadmap --fullauto invocation consumes the SHA-bound verdict and performs
its separate fail-closed merge step.
audit-pr does not re-review the diff. It consumes the current SHA-bound
review-change receipt (the REVIEW-PASS comment marker) as the review
evidence, blocks on a missing or stale receipt routed to /review-change, and
independently evaluates only the delivery gates below.
Turn contract — verify before ending the turn
✓ The review receipt was consumed from one PR snapshot: `headRefOid` + newest
matching `review-change:pass` marker fetched together; absent or any SHA
mismatch → blocker routed to `/review-change`, current → its scope/axes/
acceptance coverage/manual checks acknowledged without re-review
✓ Upstream lineage was re-verified (current plan receipt + parent spec receipt,
digests recomputed), every obligation row is `verified`/`n/a`, and no planning
finding is open — stale or missing lineage is a blocker, never a formality
✓ 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, refactored, or merged; merge authorization is outside
this skill and cannot be inherited from docs or an earlier session
✓ No review pass was composed or reconstructed: a missing/stale receipt is a
blocker, never a prompt to re-run review axes from this skill
✓ Closure integrity was evaluated and its result stated explicitly: pass /
blocker / warning / n-a (fix-governed PRs are always n-a; never skipped
silently)
✓ Scope integrity (descope) was evaluated and its result stated explicitly:
pass / blocker / n-a (no unit-referencing issues born on the branch → n-a;
never skipped silently)
✓ Architectural-invariant preservation was evaluated and its result stated
explicitly: pass / blocker / n-a (no project document → n-a; never skipped)
✓ The closing `→ Next:` block is printed 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-changeis clean (itsREVIEW-PASSreceipt is posted) 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 and posts its SHA-bound receipt;
audit-pr consumes that receipt and audits the PR as a unit of delivery — that
everything the SPEC promised is present, traceable, and green. A missing or stale
receipt is a blocker routed back to /review-change, never re-litigated here.
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)
- Project contract. Per the agent guide's Workflow conventions + documentation map, then read what THIS skill needs: the roadmap and the project's verification gate (type-check / tests / build / CI). Do not load full feature/fix templates — the SPEC below is the only planning artifact this audit reads (AC 14).
- The PR. Identify it and read it in full (forge CLI per the project's
Workflow conventions — examples use
gh):
If no PR number is given, resolve the current branch's PR (gh pr view <N> --json number,url,title,body,baseRefName,headRefName,headRefOid,isDraft,mergeable,mergeStateStatus,files,commits,statusCheckRollup,closingIssuesReferencesgh pr view --json ...). If none exists yet, audit the branch vs. the default base and say "no PR open yet" — the contract still applies. - The SPEC. Locate the governing SPEC —
docs/features/<NN>-<slug>/(feature) ordocs/fix/<n>-<topic>/(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.
Step 1 — Consume the review receipt (always, before any gate)
The review evidence is the SHA-bound REVIEW-PASS receipt review-change posts
on the PR — never a re-review composed here. Fetch headRefOid and the PR's
comments together, then find the newest comment carrying the marker
<!-- review-change:pass sha=<40-hex> contract=v1 -->:
gh pr view <N> --json headRefOid,comments
- current — marker
shaequals that snapshot'sheadRefOid(the current head SHA). Acknowledge its scope/axes, acceptance coverage, invariant result, and manual checks as the review evidence, then evaluate the delivery gates below. - absent — no matching marker on the PR → BLOCKER: no review evidence at
the head; route to
/review-change. - stale — a marker exists but its
shadoes not equalheadRefOid. Any SHA mismatch voids the receipt → BLOCKER: route to/review-changefor a re-review. Do not use a localgit diffto override the PR-head comparison.
Never compose, reconstruct, or "spot-check" the review from the diff to clear a
missing/stale receipt — that is review-change's turn, and re-litigating axes
here is exactly what the receipt gate removes (AC 13).
Progressive loading — mandatory audit route
The reference allowlist is exactly the six linked paths below. Never invent or
read another references/ path. After discovery and the Step 1 receipt check,
every audit loads and applies exactly these five mandatory resources in order:
- 01 merge gates for delivery, CI, traceability, review-receipt, and mergeability evidence.
- 02 closure and scope gates for capability closure and descope provenance.
- 03 audit process to gather, decide, persist blockers, and post the SHA-bound MERGE-READY comment.
- 04 verdict before output, then
05 routing and guardrails. These
mandatory resources own the
docs/workflow/REPOSITORY_STATE.mdevidence rules and Architectural invariants gate.
Read portability only when the declared forge or
agent actually lacks a named primitive; otherwise skip it. The project artifact
docs/workflow/REPOSITORY_STATE.md is evidence, not a skill reference. All
resources are one hop from this file. Missing evidence or a missing required
resource is a blocker; never infer a pass.
Merge ownership
This skill never merges, including when project docs contain merge: auto,
the user previously approved a merge, or a tool retained an earlier permission.
Those signals cannot change this skill's read-first boundary.
The sole automated merge authority is the AUDIT stage of an actively invoked
ship-roadmap --continue --fullauto run. Its MERGE-READY comment is evidence,
not permission; the repository wrapper independently verifies that comment,
the forge's current head/default base, green checks, and the merge: fullauto
decision fetched at that head. The wrapper owns fresh sync checks, transient
state, merge execution, cleanup, and the automerge PR comment. A standalone/
manual call to this skill always hands the MERGE-READY URL to the human.
Portability
Translate forge commands, never the gate semantics. Use the explicit fallbacks in portability.
Relationship to other skills
execute-phase (all phases done) ─▶ review-change (REVIEW-PASS receipt posted) ─▶ audit-pr ─▶ merge
│
blockers ─┬─ receipt absent/stale ──▶ /review-change ──────┘ (re-review, re-audit)
├─ in-scope ──▶ execute-phase ────────┘ (fold, re-audit)
├─ out-of-scope ──▶ plan-fix
└─ deferral ──▶ triage-issue
- Consumes the
review-changeREVIEW-PASSreceipt (its scope/axes, acceptance coverage, invariant result, manual checks) plus the artifacts ofplan-feature/plan-fix/execute-phase(SPEC, phases, docs,Closes #N). audit-docsis the cross-document coherence check;audit-pris per-PR merge readiness;product-auditis the periodic, product-wide full sweep.
Done when
- The review receipt was consumed: a current marker was acknowledged, or a
missing/stale one became a blocker routed to
/review-change(never re-reviewed here). - Every applicable gate has a pass / blocker / n-a verdict backed by cited evidence.
- A single top-line verdict (MERGE-READY or BLOCKED with ranked blockers) is reported with the PR's full URL in the header, each blocker routed, with the human's manual-verification list explicit.
- On MERGE-READY the merge owner is explicit: a standalone audit hands the URL
to the human; an active
ship-roadmap --fullautoAUDIT stage receives the SHA-bound verdict and owns every later merge check. - The closing
→ Next:block is printed (merge link → then the next unit via/plan-feature --nextor/triage-issue; BLOCKED → the routed fix, then re-audit). - Nothing was edited, refactored, or merged.
Files (agentic-workflow)
-
references
-
01_MERGE_GATES.md 4.4 KB
## 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 coverage** | The receipt's acceptance-coverage field accounts for every SPEC acceptance criterion (review-change verified the mapping). This gate confirms the receipt *names* the criteria — it never remaps diff hunks to criteria itself. | The receipt omits a criterion the SPEC lists, or its coverage field is absent/generic. | | **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 (creep)** | 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 · [#<pr>](<pr-url>)`). | 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. | | **Verification gate / CI** | The project's gate passes — type-check, tests, build — and `statusCheckRollup` is green at the current head. | 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 receipt** | A current `REVIEW-PASS` receipt is posted on the PR: the newest comment carrying `<!-- review-change:pass sha=<40-hex> contract=v1 -->` whose `sha` equals the PR's current head SHA. Its scope/axes, acceptance coverage, invariant result, and manual checks are the review evidence this audit consumes. | Receipt absent, or its marker `sha` predates the current head (any later commit voids it). The blocker routes to `/review-change`; never re-review the diff from here (AC 13). | | **Closure integrity** | The governing **feature** SPEC's capability closure was taken and recorded — `design-feature` was actually run, not bypassed. Fix-governed PRs: `n/a` (no closure block by design). | A present `Capability closure` block has a blank row, or a resolved non-`n/a` row with no matching acceptance criterion. | | **Scope integrity (descope)** | An issue born during this unit that maps to an unmet SPEC acceptance criterion or phase task has a matching, user-approved, dated `## Amendments` entry — descoped scope was recorded, not silently exported. Detection is two-path: a slug/issue-number text match, **or** an issue linked from an `## Amendments` row (`#89`) — either is sufficient to enumerate the issue, so a descoped issue with a generic title/body is not invisible to the gate. | An issue born since branch divergence that references this unit (by either detection path) maps to an unmet criterion/task with no matching `## Amendments` entry, or an `## Amendments` row that is undated, unapproved, or unlinked to an issue. | | **Architectural invariants** | The **receipt** records the invariant result review-change took against the optional project invariant document; this gate confirms that result is explicit (`pass | blocker | n-a`) and does not reclassify it (AC 13). No document → `n/a: no project invariants declared`, not a blocker. | The receipt's invariant result is absent/ambiguous, or a recorded `blocker`/`violates`/`introduces`/`changes` lacks the cited decision the review surfaced. | > The review evidence is the receipt, never a re-review: verify the newest > `review-change:pass` marker's `sha` against the PR's head (Step 1). A current > receipt passes this gate regardless of its axes' content — the audit consumes, > it does not re-litigate. A missing or stale receipt is a blocker routed to > `/review-change`. -
02_CLOSURE_AND_SCOPE_GATES.md 7.4 KB
## Closure and scope gates > **Closure integrity — fixed output.** Detection is purely mechanical: grep the > governing SPEC for a `Capability closure` heading — match the heading text, not > a fixed level (SPECs nest it as `### Capability closure` under `## Product half`; > older ones use `## Capability closure`) — never dates, never versions, never > judgment. > - **Fix-governed PR** (`docs/fix/<n>-<topic>/SPEC.md`) → **n/a**, always. Fix > SPECs carry no closure block by design; never emit a warning for one. > - **Feature SPEC, block present** → evaluate the three boxes, each a blocker > on failure: > 1. the block exists in the SPEC (true whenever this path is reached) > 2. zero blank rows — every entity/capability/role row is either filled > (UI + API + test) or carries an explicit `n/a: <reason>` > 3. every resolved non-`n/a` row maps to a listed acceptance criterion > `n/a: <reason>` is a **fully valid, passing** row — the gate verifies the > decision was *taken and recorded*, never that UI/API surface exists. Never > push a blank row into inventing surface to pass this gate. > - **Feature SPEC, block absent** → the SPEC predates or bypassed > `design-feature`. Never a blocker — emit a dated **warning**, PR still > merges: > ``` > design-debt: closure absent, SPEC predates the rule (dated <YYYY-MM-DD>) > ``` > This warning is itself the **retrofit trigger**: the next unit of work that > touches this feature must fill the closure via `/design-feature <slug>` > (upsert — fills only the missing rows, destroys nothing recorded) *before* > that new work is planned. See `design-feature`'s upsert semantics for the > other half of this contract. > **`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. > **Scope integrity (descope) — fixed output.** A cheap way to look finished is > to quietly convert unfinished SPEC scope into a follow-up issue — the unit > reads as done, the scope silently moved to the backlog. This gate catches it > mechanically, keyed off the same `## Amendments` log `execute-phase`'s > descope guard writes to (single source — see that skill's *Descope guard* > section): > 1. List issues **born since the branch diverged** > (`git log <base>..HEAD --format=%ad --date=short | tail -1` for the > earliest commit date, then `gh issue list --state all --search > "created:>=<date>"`) that **reference this unit**, via **either** of two > detection paths — a hit on either is sufficient, run both, never only the > first: > - **text match** — title/body mentions the feature/fix slug or issue > number, or > - **`## Amendments` link** (`#89`) — the issue is linked from a row in > the governing SPEC's `## Amendments` section (the same log > `execute-phase`'s descope guard writes to — single source, see that > skill's *Descope guard*), **regardless of the issue's own title/body > text**. This closes the coverage gap a generic-titled or slug-unaware > descoped issue leaves in the text-match path alone: an issue linked > from an amendment row is unambiguously about this unit no matter what > it's titled. > 2. For each such issue (from either path), run the per-issue checklist: > - ✓ the SPEC criterion/task it touches is still **met in the PR** — pass, > it's discovered work or already covered, or > - ✓ a matching `## Amendments` entry exists in the governing SPEC > (dated, **user-approved**, and **linked** to this issue's number) — pass, > the descope was properly recorded > - neither holds → **BLOCKER**. > 3. Symmetrically, every `## Amendments` row in the governing SPEC must itself > be dated, user-approved, and link a real, existing issue — an `## Amendments` > row missing any of those is also a **BLOCKER** (a hollow amendment is the > same failure as no amendment at all). > - **Scope:** any SPEC-governed PR — **feature and fix** alike, both carry > acceptance criteria a lazy run could export. No issues born during the unit, > or none referencing it → the gate **passes** (nothing was exported). > - This gate never re-litigates whether the *original* criterion was reasonable > — only whether its descope, if any, was recorded and approved before the > issue was filed. > - **Backstop, not primary.** `execute-phase`'s creation-time descope guard > (`skills/execute-phase/SKILL.md` *Descope guard*) is the **primary** > control — it stops a descope from ever reaching an issue without an > approved `## Amendments` entry first. This gate is the **backstop** that > catches what the primary control missed (a descope-filed issue from a > session that bypassed the guard, or a hand-filed issue). The `## Amendments` > -link detection path (`#89`) widens this backstop's *coverage* only — it > changes nothing about `execute-phase`'s own contract or precedence. ## Pre-execution lineage and obligation closure (feature and fix PRs) This gate sits downstream of both pre-execution reviews, so it verifies their authority **survived the build** — it never re-reviews a plan and never re-judges a verdict: 1. **Upstream lineage is current.** The unit's `progress.md` carries `## Pre-execution review receipt v1 — plan` whose digest re-derives identically (`scripts/pre-execution-snapshot.mjs verify --stage plan --parent <the receipt's Product digest>`; a fix unit binds no parent — `structural.reasonCode`/`changedPaths` name the drifted dimension), and — for a feature unit — its named `— spec` parent re-derives the same way. Bound artifacts are frozen: new implementation-phase files are allowed, edits to a bound artifact are not. Stale, missing, wrong-stage **or impossible-timeline** lineage → **BLOCKED**, `→ Next: /review-plan <unit>` (or `/review-spec <unit>` when the parent is the broken link). A `SPEC-REVIEW-PASS` never satisfies the plan hop, and vice versa. 2. **Obligations are closed.** Every row of the unit's obligation ledger is `verified` — with the validator that ran on this candidate — or an explicit `n/a: <reason>`. Any `planned`, `in-progress`, blank, or `deferred` row is **BLOCKED**, naming the ids. `deferred` is legal only when the user amended the governing SPEC first (cite the amendment); without one it is an open obligation wearing a new name, and it may not be exported to a follow-up issue to clear the gate. 3. **Planning findings are resolved.** `planning-findings.md` holds no open row for the bound snapshot: a PASS may not coexist with an unresolved material finding. 4. **Authority is unchanged.** `audit-pr` remains the only emitter of `MERGE-READY`; a pre-execution PASS is upstream evidence, never a merge verdict, and nothing here merges, closes, comments down, or files an issue. A legacy unit with no ledgers is not exempt: the missing ledgers must be constructed and reviewed through the adoption route (the pre-execution gate in `execute-phase`'s preflight) before MERGE-READY. The audit never coerces old evidence into the new format, never edits `ACCEPTANCE.md`, and never accepts a hand-written table that the plan snapshot does not bind. -
03_AUDIT_PROCESS.md 4 KB
## Process 1. **Gather** — Step 0: project contract, PR, SPEC + artifacts, CI status. 2. **Consume the review receipt** — Step 1: fetch the PR's `headRefOid` and comments in one query (`gh pr view <N> --json headRefOid,comments`) and take the **newest** marker `<!-- review-change:pass sha=<40-hex> contract=v1 -->`. Its `sha` must equal that query's `headRefOid` current head SHA. Any mismatch is stale; do not use a local diff to preserve a receipt for a different PR head. - **current** → acknowledge scope/axes, acceptance coverage, invariant result, manual checks; continue to the gates. - **absent / stale** → **BLOCKER** (no review evidence at the head), routed to `/review-change`; never re-review from here. 3. **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. 4. **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. 5. **Decide** — one verdict: - **MERGE-READY** — every applicable gate passes (including a current receipt); list the few things the human should still eyeball (the manual-verification items the receipt surfaced). - **BLOCKED** — one or more gates fail; output the ranked blocker list. 6. **Persist blockers to the fold ledger (BLOCKED verdict only).** Every blocker on a **BLOCKED** verdict is, by definition, fix-now — merge is gated on it. Append each to the unit's fix-now fold ledger `review-findings.md` (same location and fixed schema `| id | file:line | axis | severity | class | route | folded |` as `review-change`'s persist step) — the **same ledger**, not a separate one (D4: the fold cycle consumes one list). **Merged unit → no write** — check `gh pr view --json state`; `MERGED` skips the persist step entirely. For each blocker: `file:line` = the cited evidence location (the gate name when no single line applies); `axis` = the gate name (e.g. `Review receipt`, `Docs`, `Traceability`); `severity` = `high` (a blocker gates the merge by definition); `class` = `fix-now`; `route` = the routing this skill's own Routing section assigns to that kind of blocker; `folded` starts `no`. Re-runs **dedupe by `file:line` + axis**, identical to `review-change`'s rule — a blocker already on the ledger at that `file:line`+axis is not re-appended; a genuinely new blocker gets the next `Fn` id. 7. **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 <N> --body-file <path>` with exactly this body: ```markdown <!-- audit-pr:merge-ready sha=<head SHA> --> ## ✅ audit-pr: MERGE-READY - **Audited head:** `<head SHA>` · CI: <green|local-gate-green> - **Review receipt:** `REVIEW-PASS` at `<head SHA>` (consumed, not re-reviewed) - **Date:** <YYYY-MM-DD> - **Before merge, a human should still verify:** - <manual-verification item — or "nothing"> Any commit after `<head SHA>` voids this verdict — re-run `audit-pr`. ``` **Idempotent:** first check the existing comments (`gh pr view <N> --json comments`) for the `<!-- audit-pr:merge-ready -->` 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. 8. **Report** — the verdict block below, always headed by the PR's full URL. In an active `ship-roadmap --fullauto` AUDIT stage, return the verdict to the conductor; never run its merge wrapper from this skill. -
04_VERDICT.md 3 KB
## Verdict format ``` PR #<N> — <title> URL: <full PR URL — always printed; the user works across several projects and not every agent shows a CI monitor or PR list> Base: <default> ← Head: <branch> @ <head SHA> CI: <green|failing|pending> VERDICT: MERGE-READY | BLOCKED (<count> blockers) Blockers (ranked): 1. [<gate>] <what's wrong> — evidence: <file:line | check | criterion> → fix: <smallest action to clear it> (<route>) ... Warnings (non-blocking — never change the verdict): - design-debt: closure absent, SPEC predates the rule (dated <YYYY-MM-DD>) Non-blocking nits: - <minor item> — <pointer> Before merge, a human should still verify: - <manual-verification item from the review-change receipt> → Next: Print the ONE verdict bullet that matches, THEN — if a closure warning fired — also print the closure bullet (a warning never blocks, so it co-occurs with a MERGE-READY verdict; the two lines print together, never one instead of the other): · MERGE-READY, standalone/manual audit → you merge: <full PR URL>, then /plan-feature --next (the next roadmap unit) or pick an issue with /triage-issue · MERGE-READY inside active ship-roadmap --fullauto → return this SHA-bound verdict to the conductor; it runs the transient merge wrapper · BLOCKED → clear the top blocker (routed above), then re-run /audit-pr · Receipt absent/stale blocker → /review-change (re-review at the head), then re-run /audit-pr — never re-review from this audit · Closure warning (in addition to the verdict above) or a closure blocker → /design-feature <slug> — fills the missing closure rows (upsert, destroys nothing) before further work on this feature is planned; re-run /audit-pr after · Scope-bleed blocker → record the missing `## Amendments` entry (user-approved, dated, linking the issue) in the governing SPEC, or re-classify the issue as genuinely discovered work via /triage-issue; re-run /audit-pr after ``` 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) ``` -
05_ROUTING_AND_GUARDRAILS.md 3.2 KB
## Routing (blockers, by kind) - **Missing/stale review receipt** → `/review-change` (re-review at the head, then re-run `audit-pr`) — never re-review from here. - **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, refactor, or merge.** Its only forge write is the **MERGE-READY comment** (Process step 7 — idempotent, comment-only, never a commit tag). Fullauto merge execution belongs only to the active `ship-roadmap --fullauto` conductor. - **Never re-review the diff.** The `REVIEW-PASS` receipt is the review evidence; a missing/stale receipt is a blocker routed to `/review-change`. The audit does not compose `review-change`, rescan axes, judge test quality, remap diff hunks to acceptance criteria, or reclassify architectural invariants (AC 13). - **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 <path>` — never inline `--body "…"` or a quoted heredoc. Verify with `gh pr view <N> --json comments` that no literal `` \` `` survived. - **Never imply that MERGE-READY is permission.** It is evidence bound to one SHA; pending work makes it stale, and merge ownership remains external. - Never report MERGE-READY on an unconfirmed gate — absence of evidence is a blocker. - 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). ## Normalized Repository State Audit against frozen NRS facts in `docs/workflow/REPOSITORY_STATE.md` and report conflicts as contradictions. This audit is read-only: only `resolve-repository-state` may update a frozen fact or decision. ## Architectural invariants The invariant result is part of the review evidence the receipt carries (`- Architectural invariants: pass | blocker | n/a`). This audit **does not reclassify** invariants (AC 13) — it confirms the receipt records an explicit result and mirrors it into the verdict: - `n/a: no project invariants declared` (the review recorded no applicable document) → pass, not a blocker. - `pass` (the review evidenced every applicable rule as preserved, or an explicit architectural decision is recorded) → pass. - `blocker` / `violates` / `introduces` / `changes` in the receipt → **merge blocker** routed to the decision the review surfaced; the PR's head cannot be merged until the project's declared authority applies the decision and the review re-runs. State `Architectural invariants: pass | blocker | n/a` in the verdict. A decision record alone does not pass; never accept a SPEC, implementation, or passing test as the missing decision. -
PORTABILITY.md 1 KB
## Portability (agents other than Claude Code) The workflow is the contract; Claude Code features are conveniences. On an agent that lacks one, apply the fallback — never skip the step the feature enables: - **No slash-command menu** — where this skill says `/<skill>`, open that skill's `SKILL.md` (wherever your agent installed the skills) and follow it literally, in a fresh conversation: hand-offs assume a clean context. - **No per-skill `model:`/`effort:`** — on the `#claude` branch the frontmatter pins these tiers; here, pick tiers yourself: the merge gate is the highest-stakes automated verdict — run it on your **strongest** model, never on the cheap tier that wrote the code. - **Receipt consumption is comment-based, not forge-branded.** The `review-change:pass` marker lives in PR comments (`gh pr view <N> --json comments` on GitHub). On a forge without a native comments list, use its closest equivalent (MR notes, review threads); the newest-marker-wins and head-SHA comparison semantics are forge-independent.
-
-
SKILL.md 10.7 KB
--- name: audit-pr user-invocable: true version: 5.1.0 argument-hint: <pr-number> (optional — defaults to the current branch's PR) author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>" license: MIT description: > Audit a whole PR against the delivery contract and return MERGE-READY or evidenced blockers with the full URL. Consumes the current review-change REVIEW-PASS receipt instead of re-running review axes; posts a SHA-bound ready comment; never edits or merges. Triggers: "audit-pr", "is this PR ready", "merge gate". --- # Audit PR The manager's **"can this ship?"** gate. A read-first audit over the *entire* PR — its SPEC, all phases, docs, CI status, and review receipt — that returns a single verdict: **merge-ready** or a ranked list of **blockers**. **Never edits, refactors, or merges.** The human merges, or an active `ship-roadmap --fullauto` invocation consumes the SHA-bound verdict and performs its separate fail-closed merge step. `audit-pr` does **not** re-review the diff. It consumes the current SHA-bound `review-change` receipt (the `REVIEW-PASS` comment marker) as the review evidence, blocks on a missing or stale receipt routed to `/review-change`, and independently evaluates only the delivery gates below. ## Turn contract — verify before ending the turn ``` ✓ The review receipt was consumed from one PR snapshot: `headRefOid` + newest matching `review-change:pass` marker fetched together; absent or any SHA mismatch → blocker routed to `/review-change`, current → its scope/axes/ acceptance coverage/manual checks acknowledged without re-review ✓ Upstream lineage was re-verified (current plan receipt + parent spec receipt, digests recomputed), every obligation row is `verified`/`n/a`, and no planning finding is open — stale or missing lineage is a blocker, never a formality ✓ 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, refactored, or merged; merge authorization is outside this skill and cannot be inherited from docs or an earlier session ✓ No review pass was composed or reconstructed: a missing/stale receipt is a blocker, never a prompt to re-run review axes from this skill ✓ Closure integrity was evaluated and its result stated explicitly: pass / blocker / warning / n-a (fix-governed PRs are always n-a; never skipped silently) ✓ Scope integrity (descope) was evaluated and its result stated explicitly: pass / blocker / n-a (no unit-referencing issues born on the branch → n-a; never skipped silently) ✓ Architectural-invariant preservation was evaluated and its result stated explicitly: pass / blocker / n-a (no project document → n-a; never skipped) ✓ The closing `→ Next:` block is printed 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 (its `REVIEW-PASS` receipt is posted) 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 and posts its SHA-bound receipt; `audit-pr` consumes that receipt and audits the *PR as a unit of delivery* — that everything the SPEC promised is present, traceable, and green. A missing or stale receipt is a blocker routed back to `/review-change`, never re-litigated here. ## 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 and the project's verification gate (type-check / tests / build / CI). Do **not** load full feature/fix templates — the SPEC below is the only planning artifact this audit reads (AC 14). 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 <N> --json number,url,title,body,baseRefName,headRefName,headRefOid,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/<NN>-<slug>/` (feature) or `docs/fix/<n>-<topic>/` (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. ## Step 1 — Consume the review receipt (always, before any gate) The review evidence is the SHA-bound `REVIEW-PASS` receipt `review-change` posts on the PR — **never** a re-review composed here. Fetch `headRefOid` and the PR's comments together, then find the **newest** comment carrying the marker `<!-- review-change:pass sha=<40-hex> contract=v1 -->`: ```sh gh pr view <N> --json headRefOid,comments ``` - **current** — marker `sha` equals that snapshot's `headRefOid` (the current head SHA). Acknowledge its scope/axes, acceptance coverage, invariant result, and manual checks as the review evidence, then evaluate the delivery gates below. - **absent** — no matching marker on the PR → **BLOCKER**: no review evidence at the head; route to `/review-change`. - **stale** — a marker exists but its `sha` does not equal `headRefOid`. Any SHA mismatch voids the receipt → **BLOCKER**: route to `/review-change` for a re-review. Do not use a local `git diff` to override the PR-head comparison. Never compose, reconstruct, or "spot-check" the review from the diff to clear a missing/stale receipt — that is `review-change`'s turn, and re-litigating axes here is exactly what the receipt gate removes (AC 13). ## Progressive loading — mandatory audit route The reference allowlist is exactly the six linked paths below. Never invent or read another `references/` path. After discovery and the Step 1 receipt check, every audit loads and applies exactly these five mandatory resources in order: 1. [01 merge gates](references/01_MERGE_GATES.md) for delivery, CI, traceability, review-receipt, and mergeability evidence. 2. [02 closure and scope gates](references/02_CLOSURE_AND_SCOPE_GATES.md) for capability closure and descope provenance. 3. [03 audit process](references/03_AUDIT_PROCESS.md) to gather, decide, persist blockers, and post the SHA-bound MERGE-READY comment. 4. [04 verdict](references/04_VERDICT.md) before output, then [05 routing and guardrails](references/05_ROUTING_AND_GUARDRAILS.md). These mandatory resources own the `docs/workflow/REPOSITORY_STATE.md` evidence rules and Architectural invariants gate. Read [portability](references/PORTABILITY.md) only when the declared forge or agent actually lacks a named primitive; otherwise skip it. The project artifact `docs/workflow/REPOSITORY_STATE.md` is evidence, not a skill reference. All resources are one hop from this file. Missing evidence or a missing required resource is a blocker; never infer a pass. ## Merge ownership This skill **never merges**, including when project docs contain `merge: auto`, the user previously approved a merge, or a tool retained an earlier permission. Those signals cannot change this skill's read-first boundary. The **sole automated merge authority** is the AUDIT stage of an actively invoked `ship-roadmap --continue --fullauto` run. Its MERGE-READY comment is evidence, not permission; the repository wrapper independently verifies that comment, the forge's current head/default base, green checks, and the `merge: fullauto` decision fetched at that head. The wrapper owns fresh sync checks, transient state, merge execution, cleanup, and the automerge PR comment. A standalone/ manual call to this skill always hands the MERGE-READY URL to the human. ## Portability Translate forge commands, never the gate semantics. Use the explicit fallbacks in [portability](references/PORTABILITY.md). ## Relationship to other skills ``` execute-phase (all phases done) ─▶ review-change (REVIEW-PASS receipt posted) ─▶ audit-pr ─▶ merge │ blockers ─┬─ receipt absent/stale ──▶ /review-change ──────┘ (re-review, re-audit) ├─ in-scope ──▶ execute-phase ────────┘ (fold, re-audit) ├─ out-of-scope ──▶ plan-fix └─ deferral ──▶ triage-issue ``` - Consumes the `review-change` `REVIEW-PASS` receipt (its scope/axes, acceptance coverage, invariant result, manual checks) plus the artifacts of `plan-feature` / `plan-fix` / `execute-phase` (SPEC, phases, docs, `Closes #N`). - `audit-docs` is the cross-document coherence check; `audit-pr` is per-PR merge readiness; `product-audit` is the periodic, product-wide full sweep. ## Done when - The review receipt was consumed: a current marker was acknowledged, or a missing/stale one became a blocker routed to `/review-change` (never re-reviewed here). - Every applicable gate has a pass / blocker / n-a verdict backed by cited evidence. - A single top-line verdict (**MERGE-READY** or **BLOCKED** with ranked blockers) is reported **with the PR's full URL in the header**, each blocker routed, with the human's manual-verification list explicit. - On MERGE-READY the merge owner is explicit: a standalone audit hands the URL to the human; an active `ship-roadmap --fullauto` AUDIT stage receives the SHA-bound verdict and owns every later merge check. - The **closing `→ Next:` block is printed** (merge link → then the next unit via `/plan-feature --next` or `/triage-issue`; BLOCKED → the routed fix, then re-audit). - Nothing was edited, refactored, or merged.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.