Repository navigation
Releases: p5ych0/watch-pr-skill
Release list
watch-pr-skill 2.13.0
The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. It also ships a cold reviewer, a subagent that
reads each change the way the reviewers will before a round is bought, and a hooks module
that sets the model and effort of the loop's subagents from the size of the work. No daemon,
and one install serves every project.
In 2.13.0
-
A round's edits run in a subagent, at a tier the session names. 2.12.0 sized a fix
pass only where the session chose to delegate one, and sized it by a count of findings. A
count is a weak measure of the work: one finding can need a redesign, and a pass of five
wordings is an afternoon's nothing. And a session that made every edit itself got no
tiering at all.SKILL.mdnow has the session decide the answer to each finding and then
hand the edits to a subagent by default, where the harness has subagents and the operator
has not said otherwise. It marks the callreview-fix:and names the tier,small,
mediumorlarge, by the hardest finding in the pass, as in
review-fix: large, 2 findings. The hooks module reads the tier where it comes first
after the marker and takes the rung for it; where no tier is named, the stated count
decides as before, so the 2.12.0 form keeps working. The commit, the self-check, the
thread replies, the round summary and every judgment call stay with the session, and the
subagent is told to commit, push, post and resolve nothing and to report, for each
finding, the mutation it ran and what failed. What an operator gains is the delegation
itself, a word to the session that keeps the edits there, and a tier the module reads.No model call sits in the hook to judge the size: the session has already read the
findings, and a second judgment would add cost and delay to every pass. Twenty cases
undertests/hold the module, the two new ones proved against a module that ignores a
named tier, one that reads a tier anywhere in the description, and one that takes a word
that only starts like a tier, a hyphenated one included.test-hooks.shholds that the
marker and the three tiersSKILL.mdtells the session to write are the ones the module
reads. Closes #370.
Also since 2.11.4: 2.12.0
2.12.0 was not released on its own; this release carries it.
-
The loop's subagents are sized to the work. A cold read of a ten-line fix and one of a
five-hundred-line change ran at whatever model and effort the session happened to pass,
and so did a fix pass handed to a subagent, whether it answered one finding or eight. The
plugin now ships the hooks module
docs/decisions/2026-10-13-plugin-ships-one-hooks-module.mdadmits,hooks/tiering.ts,
which setsefforton two kinds of Agent call before the subagent starts and logs one
line saying what it picked and from what. Acold-reviewerrun, the plugin's or a
project's, is sized by the lines added and deleted against the merge base with the
remote-trackingorigin/…ref the prompt names first, else withorigin/HEAD; which
names are refs is git's answer, the longest listed one written at that place, so no
pattern decides where a name ends; a base the checkout has not fetched is not listed,
and a fetched ref whose name begins it is taken in its place. A fix pass is sized by the number
of findings the session states, by starting the call's description withreview-fix:and
that number, as inreview-fix: 3 findings. Each kind has three rungs and two bounds
between them, ten options inplugin.jsonthat/plugin configure watch-pr-skillsets.
The small bound is read first, so where an operator's two bounds overlap a size both
cover is small. A rung is<model>/<effort>,
and the shipped default namesdefaultfor the model on every rung, which leaves the
call's model as it was: out of the box only effort moves, medium, high, then xhigh, and no
install is sent to a model its account may lack. A rung that names a model replaces the
call's. The last twelve merged changes here ran from 18 to 258 changed lines, and the
bounds of 60 and 200 split them six small, four medium and two large.The module gates nothing. A call it cannot size goes through as the session made it: a
merge base git fails to compute, a checkout holding untracked files, which the reviewer
reads and the measure does not count, agitthat fails or outlives its ten-second
bound, a fix pass that states no number. So does every other subagent and every fork. A Claude Code
build without function hooks reads the empty command-hook record beside the module and
runs nothing.SKILL.mdsays how a fix pass is
marked and thatmodelandeffortare left unset on both kinds of call. Eighteen cases
undertests/hold the behaviour underclaude plugin test, each proved against its
mutant, andtest-hooks.shholds what the suite can: the module and its cases are
present, every rung's default names no model, and the options the module reads are
exactly the onesplugin.jsondeclares. Closes #366.
The hooks module needs a Claude Code build with function hooks, measured on 2.1.296. An
older build does not run it, and the loop runs as before. Its ten options are set with
/plugin configure watch-pr-skill: see Subagent model and effort in the README.
Install
/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools
To update an existing install:
/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins
Coming from 1.x
2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.
The full history is in CHANGELOG.md.
watch-pr-skill 2.11.4
The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. It also ships a cold reviewer, a subagent that
reads each change the way the reviewers will before a round is bought. No daemon, and one
install serves every project.
In 2.11.4
- No session could start on a stock Mac.
pr-origin.shrefused any component on the way
to setup's directory whosels -ldmode field ended in+or@, reading the mark and
never what it stood for, and stock macOS marks both parents setup can use: the system
TMPDIRunder/var/folderscarries an extended attribute and no ACL entry, and every home
directory carries one ACL entry,group:everyone deny delete. Measured on a GitHub macOS 26
runner, the first attempt was refused under the systemTMPDIR, the attempt under
~/.watch-prwithTMPDIRunset was refused at the home directory, and so was the retry,
each with terminal status 1. A marked component now has its entries listed withls -led
and passes only when every entry is a deny, inherited or not, since a deny can only take
access away; anallowentry, a line that does not parse, a+with no entry listed and a
listing that fails all refuse as before. GNUlshas no-e, so on Linux every mark still
refuses. The same runner, on this change, reachedstatus=readyin all three cases.
test-pr-origin.shstages each shape through a stubbedls: the home's single deny and the
TMPDIR's bare xattr accepted, a deny list with an inherited deny accepted, and an allow, an
inherited allow, a deny then an allow behind@, an unparseable line, a+with no entry
and a failed listing under either mark refused; the existing@case now lists the allow it
guards against. Each was proved against its mutant. Closes #361.
Also since 2.11.2: 2.11.3
2.11.3 was not released on its own; this release carries it.
-
Every session left a directory in the operator's home. Where
TMPDIRwas unset or
relative — most Linux desktops, and a Claude Code session there — setup reserved
~/watch-pr-setup.<pid>.<random>, and its retry was~/watch-pr-setup-2.…whatever
TMPDIRwas. Nothing under a setup directory is removed, so they piled up in~itself,
seventeen in two weeks on one workstation. Setup now works under~/.watch-prin both
places, created mode 700 where missing but never with a missing home directory above it,
which is refused as before; aTMPDIRthe system sets to an absolute path is
still used first. The no-removal rule is unchanged, and directories earlier releases left
in~stay where they are (#360).The parent sits directly under
HOMEso the ancestrypr-origin.shwalks gains one
component, the one the fence creates: a parent under~/.cachewould have refused every
session on a machine whose~/.cachesome other tool had created group-writable. A parent
that cannot be created stops setup with anABORT:naming it, on the first attempt before
any helper runs and on the retry before a second one does.test-pr-skill-contract.shruns
the setup fence withTMPDIRunset underumask 002and asserts the session lands in
~/.watch-prwith nothing else inHOME, and withHOMEread-only asserts the abort on
each path; the retry and relative-TMPDIRcases now expect~/.watch-pr, and an absolute
TMPDIRis asserted to leaveHOMEuntouched, a missingHOMEto stop setup with nothing
created, and a~/.watch-prleft by an earlier session to be reused by either attempt.
Closes #359.
The setup directories earlier releases left directly in your home can be moved under
~/.watch-pr with one command: see Setup directories from before 2.11.3 in the README.
Install
/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools
To update an existing install:
/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins
Coming from 1.x
2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.
The full history is in CHANGELOG.md.
watch-pr-skill 2.11.2
The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. It also ships a cold reviewer, a subagent that
reads each change the way the reviewers will before a round is bought. No daemon, and one
install serves every project.
In 2.11.2
- The request comment carried the mention twice. On the manual path the opening request
and a Codex round's summary are posted under a@codex reviewline this loop writes, and a
body that already quoted the mention — out of a finding, a PR description or a previous
round — was posted underneath it unchanged. One comment is one trigger, so the pass was
never doubled; what doubled was what the operator reads, a request that says itself twice,
reported twice from one repository before anyone traced it. Quoting stays allowed, because
quoting a finding is most of what a round summary does: the mention is written only when
the body carries none, so the loop never writes a second one above it. The drop rests on
the same measurement the refusals do — the trigger matches case-insensitively anywhere in
the body, so a quoted mention, indented or fenced, requests the pass by itself.test-pr-request-review.sh
andtest-pr-close-round.shcount the mentions in what was posted, for a body that quotes
one and for a body that does not; both cases fail against the unfixed helpers.
rb_review_triggeranswers from a case pattern rather than folding the text withtr, so the
question runs no command and cannot come back indeterminate.gateasks it before the threads
are resolved andpostasks it again afterwards, where a refusal would have left the round
half-closed with nothing posted;test-recordlib.shruns both answers with an emptyPATH,
which the folding version could not survive.
Install
/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools
To update an existing install:
/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins
Coming from 1.x
2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.
The full history is in CHANGELOG.md.
watch-pr-skill 2.11.1
The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. It also ships a cold reviewer, a subagent that
reads each change the way the reviewers will before a round is bought. No daemon, and one
install serves every project.
In 2.11.1
- A link one level up is a link. The cold reviewer probed a changed path with
test -L <root>/<path>, which answers for the component it names. Where a tracked
directory had been replaced by a symlink to a directory outside the checkout holding the
same child path, the child printednot-a-link,test -eprintedpresent, and the Read
tool followed the symlinked parent out — while the brief says a link is read through
readlinkand never opened, which is why the probe exists at all. The pattern is ordinary:
a framework that links a public directory at its own storage outside the tree. The probe is
asked of every prefix from the root down now, and a path under one that printslinkis
reported as reached through it and nothing under it is opened.test-hooks.shbuilds a
directory that is a link to one outside the probe root and asserts what made the gap: the
child answersnot-a-linkandpresent, while the prefix answerslink. The old
single-component sentence is refused beside it.
Install
/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools
To update an existing install:
/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins
Coming from 1.x
2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.
The full history is in CHANGELOG.md.
watch-pr-skill 2.11.0
The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. It also ships a cold reviewer, a subagent that
reads each change the way the reviewers will before a round is bought. No daemon, and one
install serves every project.
In 2.11.0
- A project can add its own checks and paths to the cold reviewer. The brief the plugin
ships is the same everywhere: it reads the root's policy files, applies one secrets rule,
and judges the change against the PR body. Everything a project knew beyond that — checks
distilled from rounds it had already paid for, rules kept below the root, credential names
the rule does not cover — lived in whatever the caller remembered to type, which is the
failure 2.10.3 fixed for the step itself. A.cold-review.mdat the root, read from the
base like every other policy input so a pull request cannot widen its own review, now
carries two headings and nothing else:## Checks, points to raise, which say what to
look for and change nothing about what may be read or run; and## Paths, lines
policy:,secret:andopen:. Apolicy:path is listed and read from the base under
the same mode rule as every other policy file, taken as a policy file and only as one, and
only where the listing prints exactly one entry for it; one the secrets rule still marks —
the file's ownsecret:andopen:lines counted — is reported as named and left unread,
so the project's own file cannot route a credential into the read. That line is how a rule
below the root reaches the read after 2.10.0 stopped guessing at subtree scope. Asecret:name joins the secrets rule. Anopen:name unmarks the name
half of that rule alone, so a marked directory still marks everything under it and a path
the policy forbids stays unopened. A path that is absolute or climbs with..is reported
and ignored. A project without the file is reviewed exactly as before.test-hooks.sh
pins each bound against the brief flattened.
Also since 2.10.3
2.10.4
- A committed
.exampletemplate is not a secret. The cold reviewer's secrets rule marks a
path named.envor.env.*, which takes a tracked.env.exampleor
<dir>/.env.examplewith it: the pre-read reported such a file as changed and left it
unread, though its contents are committed and both reviewers read them once the PR is
pushed. A project keeping three of those templates had every change to one reviewed cold
without it. A name ending.exampleis exempt now, and is marked only where a directory
above it is. The exemption is by name, so a*.pem.exampleor*.key.exampletemplate is
read on the same argument, and a marking directory still marks every template under it.
Another spelling —.env.sample,.env.template— stays unread, which is for a project
to exempt itself once it can (#351).test-hooks.shpins the exemption beside the rest of
the rule.
Install
/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools
To update an existing install:
/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins
Coming from 1.x
2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.
The full history is in CHANGELOG.md.
watch-pr-skill 2.10.3
The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. From 2.10 it also ships a cold reviewer, a
subagent that reads each change the way the reviewers will before a round is bought. No
daemon, and one install serves every project.
In 2.10.3
SKILL.mdruns the cold reviewer. 2.10.0 shipped thecold-revieweragent to installing
projects, but the driver never named it, so a session in such a project had the agent and
no step that ran it, and bought review rounds a minute's cold read would have saved. Step 1
now has it read the change before the first request, and before the PR is opened where
automatic review is on, with its fixes committed, self-checked and pushed before the
request. Step 5's procedure has it read each round's fixes after the self-check and before
the round boundary and the push, given the base ref, the PR body, the newest round summary
and the earlier findings with their replies; its fixes carry the phase trailer and are
written into the round summary. The session fixes what it names as a defect the change
introduced and files the rest. It stays a pre-read, not a gate, and not a reviewer. The
contract test pins both placements, the name the plugin loads it under and the commit
instructions; README's session description says the same.
Also since 2.9.3
2.10.2
- The cold reviewer's path probes print their answers. Its brief decided what a changed
path is withtest -Land thentest -e, which answer only through their exit status,
and a subagent's tool output may not show one. A downstream cold read reported that
test -L"printed nothing even on a file I know is regular" and fell back toreadlink
and the modes git records, though the brief says the probes decide. Each probe is now
test -L <path> && echo link || echo not-a-linkand
test -e <path> && echo present || echo absent,echois allowed for that purpose
only, and a probe's exit status no longer reads as a failed command.test-hooks.sh
takes both probes from the brief and runs them on a dangling link, a file and a missing
path.
2.10.1
- The cold reviewer sees both ends of a move. Its brief listed what changed with
git diff --name-only, and rename detection is on by default, so a commit that moves a
file listed only the destination: the per-path diff then showed a new file and never the
deletion at the source, and what a move left behind went unread, which is what a
"location only" claim needs checked. Measured on a downstream commit with a rename, the
default listing gave only the destination. The listing is
git diff --no-renames --name-onlynow, which names the source as deleted and the
destination as added.test-hooks.shpins the flag and runs it on a commit that moves a
file.
2.10.0
- The cold reviewer ships with the plugin. The subagent that reads a branch against its
base the way Codex and Copilot will, before a round is bought, lived in this checkout's
.claude/agents/, which Claude Code does not load from a plugin. A project that installed
watch-pr-skill got the review loop without the pre-read that makes a round cheaper, and
one measured downstream session spent rounds on four findings a cold read of the diff would
have made first. It isagents/cold-reviewer.mdat the plugin root now, loaded as
watch-pr-skill:cold-reviewer. Its brief readAGENTS.mdandCLAUDE.mdoff the base and
stopped where either was missing. It now asks the base which of
.github/copilot-instructions.mdand the root'sAGENTS.override.md(read, unless empty,
in place ofAGENTS.md),AGENTS.mdandCLAUDE.mdit has, reads those first and says which it
found, and leaves unopened a path that policy says not to open; the same files below the
root are not read. Its secrets rule now also covers anything under a.envor.env.*
directory, and a.sshdirectory at any depth; its other safety rules are unchanged. This checkout keeps a link to the brief in.claude/agents/, so that a
session here uses the branch's brief, not the installed release's.test-hooks.shpins the
shipped file, its name, its read-only tool list, its secrets rule and its policy read in
every copy, and the link in this checkout.
Install
/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools
To update an existing install:
/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins
Coming from 1.x
2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.
The full history is in CHANGELOG.md.
watch-pr-skill 2.9.3
The plugin drives a pull request through GitHub's own reviewers, Codex and Copilot, works
the fix → reply → resolve → re-request loop to a clean signoff, and stops for you before the
second reviewer's phase and before the merge. No daemon, and one install serves every
project.
In 2.9.3
- The manifests name the generation. Both descriptions carried one sentence, which said
what the plugin does and nothing about which of the two incompatible generations it is, so
a reader who knew the 1.x file bus could not tell from a marketplace listing that the
daemons and thecodex execreviewer are gone. They say 2.x and no daemon now.
Install
/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools
To update an existing install:
/plugin marketplace update p5ych0-tools
/plugin update watch-pr-skill
/reload-plugins
Coming from 1.x
2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.
The full history is in CHANGELOG.md.
watch-pr-skill 2.9.2
The first tagged 2.x release. The plugin drives a pull request through GitHub's own
reviewers, Codex and Copilot, works the fix → reply → resolve → re-request loop to a clean
signoff, and stops for you before the second reviewer's phase and before the merge. No
daemon, and one install serves every project.
In 2.9.2
- A hex class is spelled out, not ranged. On bash 3.2 under a non-C locale a bracket
range collates by locale, so[0-9a-f]takesAthroughEand a value git never emits
read as a full sha inrecordlib.sh'scase, and in the driver's read-back of the Codex
signoff. Both spell the sixteen characters out. The mac-shaped CI job runs underC.UTF-8
and did not see it; a Mac in a user's locale would.
The tag also carries README.md's Upgrading from 1.x section, which landed after the
release commit and changed no installed file.
Install
/plugin marketplace add p5ych0/watch-pr-skill
/plugin install watch-pr-skill@p5ych0-tools
Coming from 1.x
2.0.0 replaced the plugin rather than extending it: the file bus, its two systemd --user
daemons, the codex exec reviewer and the SessionStart hook are gone, and both reviewers
are GitHub apps now. Stop and remove the old bus before you update, and mind the renamed
knobs. The steps are in Upgrading from 1.x in the README.
The full history is in CHANGELOG.md.