review-workflow-pr

SkillFiles & storage

Review a workflow-style PR's design, plan, and track files in research-mode Q&A; auto-records observations and submits a line-anchored review via gh api. TRIGGER when: user asks to review a workflow PR or run /review-workflow-pr. SKIP: non-workflow PRs without docs/adr/<dir>/_workflow/.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the review-workflow-pr skill

What this skill tells your AI

The instructions your AI receives, as published by jetbrains/youtrackdb in .claude/skills/review-workflow-pr/SKILL.md and read by ahel’s review.

Reading workflow files (TOC protocol)

When you Read any file under .claude/workflow/ or .claude/skills/, follow the protocol in conventions.md §1.8:

  1. Read the TOC region: from <!--Document index start--> to <!--Document index end--> (read to the closing delimiter, not a fixed line count). If the file has no TOC region (a file whose only ## heading is this bootstrap block carries none, per §1.8(d)), read the file in full.
  2. Match TOC rows where Roles contains any of your roles (or your role is any, or the row's Roles is any) AND Phases contains any of your phases (or your phase is any, or the row's Phases is any).
  3. Use Read(offset, limit) to read only matched sections; if no row matches your role/phase, the file holds nothing for you — do not read further.

Your role: pr-reviewer. Your phase: any (PR review sits outside the phase taxonomy).

Inline refs you find inside workflow files carry the same name:roles:phases suffix; apply file-level filtering before opening: a ref matches when any of your roles is in its roles and any of your phases is in its phases, your own any on either axis matches every ref on that axis, and a ref whose own roles or phases is any matches you. Backtick-wrapped refs carry no suffix; open or skip them at your discretion.

SectionRolesPhasesSummary
§Invocation contractpr-revieweranyThe three accepted argument shapes and the single-turn greeting-then-investigate handshake at invocation.
§Preflightpr-revieweranyResolve the PR argument, fetch head SHA and changed files, verify the local checkout before loading artifacts.
§Artifact discoverypr-revieweranyResolve the plan directory, enumerate canonical and optional artifacts, abort on a missing required file.
§Research modepr-revieweranyReviewer-driven Q&A over loaded artifacts: free-form questions, auto-recorded observations, lazy doc loading.
§Sub-agent dispatch — DR auditpr-revieweranySpawn the DR-audit sub-agent on request, translate its findings into observations, log one entry per spawn.
§Wrap-up and submissionpr-revieweranyRender and prune observations, re-verify the head SHA, compose the payload, confirm, then POST the review.
§Handoff and resumepr-revieweranyReviewer-driven checkpoint to /tmp and resume: write triggers, file format, HEAD re-verification, cleanup.

A reviewer invokes /review-workflow-pr <PR> against a PR they have already checked out, lands in research-mode Q&A against the verified workflow artifacts, and at wrap-up submits a single line-anchored review back to the PR.

House style for chat-scale prose. User-facing prose produced from this file (status updates, observation entries, prune-table rendering, the final stub message) follows the AI-tell subset of house-style.md: ## Banned sentence patterns, ## Banned analysis patterns, ## Orientation, and ## Plain language. Structural rules (§ BLUF lead, the ≤200-word section cap, § Document-shape rules) do not apply to chat-scale prose. See conventions.md:pr-reviewer:any §1.5 for the workflow-level anchor and tier mapping.

Invocation contract

/review-workflow-pr $ARGUMENTS accepts three argument shapes (a PR number such as 42, a PR URL like https://github.com/owner/repo/pull/42, or a branch name such as feature/foo) and defaults to the current branch's PR when $ARGUMENTS is empty. The shape is resolved by ## Preflight; this section is the contract the reviewer sees at invocation time.

The handshake is single-turn. On the same turn that runs preflight and artifact discovery, the skill emits a one-line greeting naming the PR number, head SHA, and resolved <dir>, then asks what to investigate. The reviewer's next message is the first research-mode question; no separate acknowledgment is required. When preflight or discovery fails, the skill emits the error and exits without entering research mode.

See ## Preflight for the mechanical resolution.

Preflight

The skill resolves the PR, fetches its head SHA and changed files, and confirms the local checkout matches before loading any artifact.

Resolve $ARGUMENTS. Accepts a PR number (42), a PR URL, or a branch name. When empty, the skill targets the current branch's PR.

Fetch PR metadata. Run gh pr view <ref> --json headRefOid,number,files to read the head SHA, PR number, and the changed-files array (each element carries path, additions, deletions, changeType; the skill reads .path). Run gh repo view --json nameWithOwner separately to resolve owner/repo for the API path.

Verify local HEAD. Run git rev-parse HEAD and compare against headRefOid. On match, proceed to artifact discovery.

HEAD-SHA mismatch. Abort and print both the expected and local SHAs along with the remediation: gh pr checkout <ref>. The command typically creates a named local branch tracking the PR head; only --detach produces a detached HEAD, and git rev-parse HEAD returns the head SHA in either case.

Non-zero gh pr view exit. When no PR exists for the current branch or the ref does not resolve, surface the command's stderr and tell the reviewer to either pass an explicit PR number or URL as $ARGUMENTS or open a PR first.

Artifact discovery

The skill resolves <dir>, enumerates the canonical workflow artifacts under docs/adr/<dir>/_workflow/, acknowledges any companion files, and aborts when a required file is missing. The skill is read-only against everything it finds: it never edits the artifacts under review.

Resolve <dir>. Default to the current branch name from git branch --show-current, matching the /create-plan default. When docs/adr/<branch>/_workflow/ does not exist in the local checkout, fall back to the list-and-pick path: enumerate every docs/adr/*/_workflow/ directory that contains an implementation-plan.md, present the names, and ask the reviewer to pick one. Use the picked name as <dir>.

Enumerate canonical artifacts. Required under docs/adr/<dir>/_workflow/:

  • implementation-plan.md
  • design.md

Optional, load only when present:

  • design-mechanics.md (length-triggered per .claude/workflow/conventions.md §1.2)
  • plan/track-*.md (one file per planned track)

Acknowledge companion files. List design-mutations.md (present whenever design.md has been mutated) and any transient handoff-*.md for visibility. Do not load them into the review context unless the reviewer asks.

Missing canonical file. When implementation-plan.md or design.md is missing under the resolved <dir>, abort with an error naming both expected paths and pointing the reviewer at the list-and-pick fallback.

Research mode

The skill enters research-mode Q&A driven by the reviewer once preflight and artifact discovery succeed. The reviewer drives the conversation; the skill answers questions about the loaded artifacts, auto-records observations when its own analysis surfaces a gap, and loads workflow rule files on demand.

Session-start prelude. After preflight and artifact discovery, the skill greets the reviewer with a one-line summary naming the PR number, the head SHA, and the resolved <dir>, then asks what to investigate. The prelude carries one warning: Observations live in this conversation only. A /clear mid-session loses them unless you ask the skill to checkpoint. The reviewer triggers a checkpoint with any of checkpoint, save state, or we're about to /clear; the skill writes the handoff file per ## Handoff and resume below and prints the resulting /tmp/claude-code-review-workflow-pr-<N>-$PPID.md path on one line so the reviewer can confirm it landed.

Free-form Q&A. No fixed walkthrough order. The reviewer drives; the skill answers questions about any loaded artifact using Read, Grep, and Bash. The skill asks clarifying questions when a question is ambiguous and answers from artifacts already loaded rather than re-fetching the workflow rubric for routine Q&A.

Observation auto-recording. When the skill's own analysis surfaces an issue mid-conversation, it records a structured observation with path (an artifact path under _workflow/), line (or a start/end range), body (one paragraph naming the gap and grounding it in the cited file or section), and source (skill-analysis). When a sub-agent returns findings, the skill translates each finding into one observation tagged with the sub-agent's name. When the reviewer asks the skill to record something directly, source is reviewer. After each new observation the skill prints a one-line confirmation: index, path:line, source, and the first 80 chars of the body.

Observation list operations. The reviewer can drop an observation by index (drop 3) or by source tag (drop reviewer); the skill confirms the drop with the surviving list size. Observations are immutable in place — to revise one, drop the old entry and record a new one.

The orchestrator also maintains a dispatchLog (defined in ### Sub-agent dispatch — DR audit below): an in-conversation append-only list of {sub-agent name, ISO-8601 UTC timestamp, one-line summary} entries, one per spawn. The observation list and the dispatchLog are the two conversation-state structures the skill carries forward across turns; both live in this conversation by default, and a mid-session /clear discards them unless the reviewer explicitly checkpoints first per ## Handoff and resume below.

Workflow-doc trigger conditions. Load lazily on the named trigger; do not preload.

  • .claude/workflow/conventions.md when the reviewer asks about plan file structure, scope indicators, or naming conventions.
  • .claude/workflow/research.md when the reviewer asks about research-mode conventions or wants the canonical rubric.
  • .claude/workflow/design-document-rules.md when the reviewer asks whether a design section has the right shape (TL;DR, mechanism overview, edge cases, References footer).
  • .claude/workflow/planning.md when the reviewer asks about Decision Record format expectations.

Scope rule for code-file questions. When the reviewer asks about code files in the PR (paths not under docs/adr/<dir>/_workflow/), the skill answers using Read and Grep but does not record observations against those files. For Java symbol-reference questions (callers, overrides, find-usages, "is X still used?"), use mcp-steroid PSI find-usages when reachable; fall back to Grep only when mcp-steroid is unreachable and flag the result as grep-only in the answer. The observation list scope stays workflow-artifact-only.

Sub-agent dispatch — DR audit

The skill spawns the DR-audit sub-agent on the reviewer's request to audit the Decision Records in the loaded implementation-plan.md. The sub-agent returns a structured findings block; the orchestrator translates each finding into one observation and appends an entry to the in-conversation dispatchLog.

Trigger phrases. Treat any of the following from the reviewer as the cue to spawn DR audit: audit the DRs, audit the decision records, check the decision records, check the DRs, run the DR audit. Match case-insensitively against the reviewer's full message, allowing surrounding whitespace and punctuation. Substring matches inside longer prose do not fire; if uncertain, ask one clarifying question.

Spawn call. Dispatch via the Agent tool with subagent_type: "dr-audit". The agent's prompt body lives at .claude/agents/dr-audit.md (registered as a project-scoped sub-agent like every other in-skill dispatch target; the agent's frontmatter declares its model, so do not override model from the dispatch call). Pass plan_path as the first line of the prompt in the form plan_path: <value> so the sub-agent can parse it before any other input. The sub-agent reads design.md on its own when a Decision Record cites **Full design**: design.md §...; the orchestrator does not pre-pass design.md. The literal call shape, with plan_path interpolated:

Agent({
  subagent_type: "dr-audit",
  prompt: "plan_path: docs/adr/<dir>/_workflow/implementation-plan.md"
})

The sub-agent's inputs are Markdown only (implementation-plan.md and optionally design.md); no PSI / Java reference-accuracy questions arise inside this audit, so the grep-vs-PSI rule (.claude/workflow/conventions.md §1.4) does not apply.

Sub-agent dispatch failure. Every outcome other than the sub-agent returning a well-formed ## Summary plus optional ## Findings block is a dispatch failure, not a translation failure. Apply the following rules in order, before the Finding-to-observation translation block runs:

  • The sub-agent returns no parsable ## Summary block, or returns prose without the structured schema: do not append a dispatchLog entry, do not translate any findings, surface a one-line error to the reviewer naming the failure shape (for example dr-audit returned no Summary block; nothing recorded), and offer to retry.
  • ## Summary is present but decisions_audited or findings_count is missing or non-numeric: record as a soft failure. Surface the malformation to the reviewer, do not translate findings, and do not append a dispatchLog entry.
  • An individual ### F<i> block is missing one of the required fields (decision, category, plan_line, quote, body): drop that finding only, append a dispatchLog entry covering the remaining well-formed findings, and warn the reviewer with the dropped finding's available fields (or its raw text when every field is absent).
  • A ### F<i> block carries a non-integer or zero plan_line: fall through to the existing No explicit file citation anchoring rule below.
  • The spawn itself errors (network, tool error, sub-agent crashes mid-stream): record as a dispatch failure, do not append a dispatchLog entry, and offer to retry.

Finding-to-observation translation. Parse the sub-agent's ## Findings blocks. For each ### F<i> block, extract decision, category, plan_line, quote, and body. Build one observation {path, line, body, source} where path is the plan_path echoed in the sub-agent's ## Summary, line is the integer plan_line from the finding, body is the finding's body paragraph (verbatim, no rewrap), and source is the literal string dr-audit. Append each observation to the running list via the auto-recording rules in ## Research mode above; the one-line confirmation prints the same way it does for skill-analysis observations.

Three anchoring edge cases override the verbatim mapping:

  • No explicit file citation. When a finding's plan_line is absent or non-positive, anchor the observation at the artifact the sub-agent was reviewing (the plan_path echoed in ## Summary) at the nearest ## heading line at or above the implied location. The source tag stays dr-audit.
  • Quoted prose edited since the sub-agent's read. When the finding's quote does not match the current content at plan_line, search the artifact for the literal quote string and use the matched line if exactly one match is found. When zero or multiple matches are found, record the observation at the sub-agent's reported plan_line and prepend [STALE: verify line] to the body so the reviewer sees the flag at prune time.
  • Reviewer wants a broader cold-read. A request for design cold-read (as opposed to DR audit) is out of scope here. Tell the reviewer to invoke the existing cold-read flow as a separate skill in the same session; that skill's output does not flow back into this observation list automatically.

dispatchLog structure. The orchestrator maintains a single in-conversation dispatchLog: an ordered list of {sub-agent name, timestamp, summary} entries. sub-agent name is the literal sub-agent identifier (dr-audit); timestamp is the ISO-8601 UTC instant at spawn time (e.g., 2026-05-21T13:45Z), obtained via Bash by running date -u +"%Y-%m-%dT%H:%MZ" immediately before the spawn call so the recorded timestamp reflects the real spawn instant rather than a hallucinated value; summary echoes the sub-agent's ## Summary block as a one-line digest (decisions_audited=<N>, findings_count=<N>). Append one entry on every sub-agent spawn, including spawns that return zero findings. The ## Handoff and resumeDispatch-log re-presentation. sub-block reads dispatchLog on resume to label each sub-agent name as not run, ran, no findings, or ran, <N> findings recorded; the reviewer decides whether to re-spend on the audit. Repeated spawns append a second entry; the same sub-block treats the latest entry per sub-agent name as the authoritative last run, per ## Handoff and resumeResume reload.. Second-spawn findings are appended verbatim to the observation list and may duplicate first-spawn observations; the reviewer is expected to prune duplicates at wrap-up.

Wrap-up and submission

The skill renders the observation list, accepts prune commands, composes the JSON payload for the pulls/{N}/reviews endpoint, asks for one final confirmation, and POSTs the bulk line-anchored review back to the PR. This section documents the wrap-up trigger, the table render and prune commands, the 50-entry pre-flight warning, the head-SHA re-fetch, the one-line confirmation prompt, the POST and review-URL print, the empty observation list branch, the payload composer, and the path / line validation that runs before the POST. On the next wrap-up trigger word the head-SHA re-fetch, 50-entry warning, and confirmation prompt all run again from scratch; cached state from a cancelled attempt is discarded.

Wrap-up trigger words. Treat any one of wrap up, done, submit, or finish from the reviewer as the wrap-up cue. The reviewer's last message must consist of only the trigger word or phrase plus optional surrounding whitespace and punctuation (e.g., wrap up, Done., submit!); match case-insensitively. Substring matches inside longer prose do not fire wrap-up; if uncertain, ask the reviewer to confirm wrap-up before rendering. The trigger word must appear exactly once; multiple trigger words in the same message (e.g., Done. Submit!) trigger the "ask the reviewer to confirm wrap-up" clarification path rather than firing immediately.

Non-empty observation list. Render the list as a numbered Markdown table with four columns: index (1-based), path:line (or path:start-end for range observations), source (the tag set during auto-recording: skill-analysis, reviewer, or the sub-agent name), and body (first 120 chars). Escape |, \, and backticks in cell bodies; replace literal newlines with <br> so the cell stays valid Markdown. Truncate at 120 characters with a trailing ellipsis; do not let a cell exceed one visual line. Observations carrying the [STALE: verify line] prefix are rendered with the prefix visible in the body column; the 120-char truncation preserves the leading prefix. After the table, prompt the reviewer to prune the list or confirm submission.

Prune commands. Accept drop-verb commands operating on the numbered table: drop 3, 7 (drop the entries at the named indices), drop all from dr-audit (drop every entry whose source matches the named tag), and keep all (skip pruning and proceed straight to confirmation). Bare numeric arguments always reference the displayed index column, never a source tag. A sub-agent named with a numeric-looking identifier still resolves through the drop all from <tag> form, not the bare-number form. Reject unrecognized verbs by re-printing the table and reminding the reviewer of the three accepted shapes. After each successful drop, re-render the table with the new indices so subsequent commands refer to the visible list.

Edge-case handling for malformed drop input: out-of-range indices report the offending number and the rest of the drop list still processes; unknown source tags drop zero entries and print a one-line warning naming the unknown tag and the known tags; drop with no arguments is rejected like an unrecognized verb; comma and whitespace separators in the index list are both accepted (drop 3, 7, drop 3 7, and drop 3,7 all parse the same); negative indices are rejected as out-of-range; drop all from <known-tag> when zero observations carry that tag is a no-op with a confirming one-line message.

50-entry pre-flight warning. When the pruned list has more than 50 entries at the point the reviewer signals they are done pruning (any wrap-up trigger word repeated, or an explicit submit), print a warning naming the count (for example 52 observations will be posted as inline comments. Confirm to proceed.) and ask the reviewer to confirm before composing the JSON payload. A negative or unclear answer returns the reviewer to prune mode without re-rendering the table; an affirmative answer proceeds.

Head-SHA re-fetch. Re-fetch the head SHA via gh pr view <ref> --json headRefOid -q .headRefOid immediately before composing the payload. When the re-fetched SHA matches the value cached during ## Preflight, proceed to the confirmation prompt below. When it differs, follow design.md §"HEAD-SHA verification": print the cached SHA and the new SHA and ask the reviewer to choose between (a) refresh and re-verify line numbers against the new content, or (b) abort the submission and re-checkout. The default safe path is abort; on abort, the observation list survives so the reviewer can re-run wrap-up after gh pr checkout <ref> brings the local tree back to the PR head. On option (a), run the refresh procedure step-by-step: re-fetch gh pr view <ref> --json files,headRefOid and the .files[].path cache (re-applying the 100-entry pagination fallback from Path validation below when the cached list has exactly 100 entries); re-run Path validation and Line validation against the new diff for every surviving observation; mark every newly-stale observation by prepending [STALE: verify line] to its body field; update the cached SHA to the re-fetched value; re-render the prune table when any observation flipped to stale; then return to the Confirmation prompt below.

Confirmation prompt. After the head-SHA check clears and the JSON payload has been composed per the Submission payload composer sub-block below, print one line summarizing the submission and asking for confirmation: REQUEST_CHANGES with 12 comments to PR <N>? for the non-empty branch, or APPROVE PR <N> with no inline comments? for the empty branch. A negative or unclear answer cancels and returns the reviewer to prune mode with the observation list intact. An affirmative answer proceeds to POST.

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
433
Forks
16
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
review-workflow-pr
Source
github.com/jetbrains/youtrackdb