Step-by-step procedure for producing ONE advisory COMMENT review on a Forgejo pull request — clone at the head sha, fetch the diff, apply general and language review criteria, post a single Reviews-API review with inline comments, recover from 422s, then verify and close the kanban card. Use when a kanban card assigns an advisory PR review on git.home.claydon.co.
73
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
You have been handed a kanban card that asks you to review one pull request
on git.home.claydon.co and post advisory feedback. This skill is the
procedure. Your profile carries the rails (advisory only, read-only, one
COMMENT review, git.home.claydon.co is the only host); this skill tells
you how to carry it out.
The whole job is: one Forgejo review of type COMMENT, then a completed
kanban card. Nothing else touches the PR.
The card body is a block of key: value lines:
| key | meaning |
|---|---|
repo | owner/name on git.home.claydon.co |
pr | PR number (<n> below) |
title | PR title |
author | PR author's login |
base | base ref @ base sha |
head | head ref @ head sha |
url | PR web URL |
clone | git clone URL (https://git.home.claydon.co/<owner>/<name>.git) |
changed_files | count, or unknown |
review_skills | comma-separated language reviewer skill names — MAY BE EMPTY |
review_skills lists language-specific reviewers only (for example
shell-script-reviewer, go-review). This workflow skill is separate and
is always loaded for you; it is never listed there.
Work in your scratch workspace:
git clone --depth 50 <clone> repo && cd repo
git fetch --depth 50 origin refs/pull/<n>/head
git checkout FETCH_HEADrefs/pull/<n>/head also covers fork PRs. After checkout, git rev-parse HEAD should equal the card's head sha — if it does not, note the mismatch
in the review body and continue against what you actually checked out.
Read whole files for context. Never review from the diff alone.
If the clone or the checkout fails, kanban_block with the reason and stop.
curl -fsS -H "Authorization: token $FORGEJO_TOKEN" \
"https://git.home.claydon.co/api/v1/repos/<owner>/<name>/pulls/<n>.diff"The diff tells you which files and which lines changed. If the diff fetch
fails, kanban_block with the reason and stop.
Apply these to every changed file, in every language:
CLAUDE.md (read it if present)TODO / FIXME, merge-conflict
markersDo not report:
Keep only findings you are confident are real. A short, correct review beats a long speculative one.
For each name in review_skills (skip this section entirely if it is
empty):
SKILL.md at $HERMES_HOME/skills/<name>/SKILL.md.hermes skills inspect <name>.Apply each language skill only to the file types it covers (for example
shell-script-reviewer to *.sh / *.bash, go-review to *.go).
This is a read-only review. Do not run the project's test suite, build,
nix commands, linters, or formatters — your scratch workspace does not
have the toolchain and a failing command here tells you nothing. If a
finding would normally need a command to confirm, state it as "likely" and
move on.
POST /api/v1/repos/<owner>/<name>/pulls/<n>/reviews
{
"event": "COMMENT",
"commit_id": "<head sha>",
"body": "<summary + only findings with no single changed line>",
"comments": [
{"path": "<file>", "new_position": <line in NEW file>, "body": "<finding>"}
]
}curl -fsS -X POST \
-H "Authorization: token $FORGEJO_TOKEN" \
-H "Content-Type: application/json" \
-d @- \
"https://git.home.claydon.co/api/v1/repos/<owner>/<name>/pulls/<n>/reviews"Rules:
event is always "COMMENT". The API also accepts APPROVED,
PENDING, REQUEST_CHANGES — never send any of them.commit_id is the card's head sha.comments — path plus new_position, the line number in the NEW
version of the file (the + side of the diff). Do not summarise
line-specific findings in body. A review that had line findings but put
them only in body is a failure — redo it.body is for the overall read (what the PR does, your assessment) and for
findings that genuinely have no single changed line: cross-cutting issues,
something missing, a concern spanning several files.comments array and a body
that says nothing blocking was found. There is always a visible artifact
on the PR.PR adds a helper to scripts/backup.sh; the new hunk is:
@@ -10,6 +10,11 @@ set -eu
main() {
+ dest=$1
+ cd $dest
+ rm -rf ./cache/*
+ echo "cleaned $dest"
+}cd $dest is line 13 in the new file, rm -rf ./cache/* is line 14. A
correct multi-comment body:
{
"event": "COMMENT",
"commit_id": "9f3a1c2e5b7d0a4f6c8e1b2d3a5f7c9e0b1d2f3a",
"body": "Adds a cache-cleaning helper to scripts/backup.sh. The logic is small and readable; two robustness issues on the new lines, noted inline. No security or correctness blockers beyond those.",
"comments": [
{"path": "scripts/backup.sh", "new_position": 13,
"body": "`cd $dest` is unquoted and its exit status is unchecked. If `$dest` is empty or has spaces the `cd` fails and, because `set -e` does not trigger on a failed command in this position, the following `rm -rf ./cache/*` then runs against the wrong directory. Use `cd \"$dest\" || exit 1`."},
{"path": "scripts/backup.sh", "new_position": 14,
"body": "`rm -rf ./cache/*` relies on the `cd` above having succeeded; combined with the unchecked `cd` this can delete `cache/` under whatever directory the script was invoked from. Guard the `cd` (see previous comment)."}
]
}Note both line findings are inline; body only carries the overall read.
new_position / old_position are file line numbers, not diff offsets.
Forgejo rejects the whole call with 422 Unprocessable Entity if any
comment points at a line outside the diff hunks.
On a 422:
new_position by counting + and context lines
in the hunk from its @@ -a,b +c,d @@ header — do not guess.body and keep every other finding inline.Never collapse the whole comments array to empty just to get a 2xx.
curl -fsS -H "Authorization: token $FORGEJO_TOKEN" \
"https://git.home.claydon.co/api/v1/repos/<owner>/<name>/pulls/<n>/reviews"Confirm the response contains the review you just posted: its commit_id
matches the card's head sha and its user is your own bot login.
You MUST NOT call kanban_complete unless this check passes. If it does
not — including any case where your only successful output went somewhere
other than git.home.claydon.co — kanban_comment the failure and
kanban_block. Never complete a card over a review that never reached the
Forgejo PR.
kanban_comment the review's html_url.kanban_complete with metadata {changed_files, findings_count, review_url}.The card is terminal. Do not request-review, do not merge, do not post a
commit status.
Before your turn budget runs out, stop analysing and post the review you
have (step 5) — still with each line-specific finding inline, anything
unresolved in body — then run steps 7–8. A posted advisory review beats a
card stuck in progress.
cd15778
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.