Review Watch
Review Watch monitors pull requests that requested your review, notifies you when a new head SHA appears, and lets the active Claude Code or Codex session review the queue until every PR is clean. The background daemon is deliberately lightweight: it queries, de-duplicates, queues, and notifies; it never runs the model or posts a GitHub review by itself.
How it works
Section titled “How it works”flowchart LR GitHub[GitHub review request] --> Daemon[Review Watch daemon] Daemon -->|new repo + PR + SHA| Queue[Local JSONL queue] Daemon --> Requested[Desktop notification] Queue --> Skill[Claude /review-watch<br/>Codex $review-watch] Skill --> Tier1[Linters + known issues] Tier1 -->|clean| Tier2[Review agent fan-out] Tier1 -->|blocking| Changes[REQUEST_CHANGES] Tier2 -->|blocking| Changes Tier2 -->|clean| Approved[APPROVE or COMMENT] Approved --> Brief[Self-contained change brief] Brief --> Ready[Ready-for-merge notification]The daemon uses one GraphQL request shared with Notifications. Its optional
review-request alias returns up to 50 open PRs with review-requested:@me. An optional repository
filter adds repo:owner/name. Each result includes repository, PR number, title, URL, author, and
headRefOid, so the same SHA is never announced twice.
Quick start
Section titled “Quick start”Enable the opt-in setting in the project:
reviewWatch: enabled: true intervalSeconds: 60 linters: auto knownIssues: references/known-issues.md
notifications: sound: GlassCheck the installation without querying PRs or changing GitHub:
/review-watch --doctor # Claude Code$review-watch --doctor # CodexAsk the skill for the absolute daemon command:
/review-watch --daemon-command # Claude Code$review-watch --daemon-command # CodexPaste the returned command into a spare terminal. The daemon polls until stopped with Ctrl-C.
The command can accept these daemon-only options:
--interval <seconds> Override the configured poll interval--once Poll once and exit--repo owner/name Watch one repository--force Bypass the enabled gate for an intentional manual runWhen a notification arrives, review one PR or drain the queue:
/review-watch https://github.com/owner/repo/pull/42 # Claude Code$review-watch https://github.com/owner/repo/pull/42 # Codex
/review-watch --drain$review-watch --drainUse --comment-only when the workflow must never post REQUEST_CHANGES or APPROVE:
/review-watch 42 --comment-only$review-watch 42 --comment-onlyNotifications
Section titled “Notifications”The title always identifies the repository and PR. The message identifies the author and change:
owner/repo · PR #42@alice — Fix login redirectAfter a clean review, the same identity is preserved:
owner/repo · PR #42@alice — Ready for merge: Fix login redirectIf GitHub returns a deleted or missing author, the label is unknown author rather than an empty
handle.
| Review requested | Ready for merge |
|---|---|
![]() |
![]() |
These are real macOS banners emitted by the packaged notifier. Linux uses the active desktop’s
native notify-send appearance. Sound is best effort; notification failure never fails a review.
Review decisions
Section titled “Review decisions”Review Watch uses two tiers:
- Project linters and the configured known-issues ruleset catch deterministic blockers cheaply.
- When Tier 1 is clean, the normal review agents inspect correctness, silent failures, types, tests, and comments as relevant to the diff.
Only findings with confidence of at least 80 survive aggregation. Blocking or high-severity
findings produce REQUEST_CHANGES; otherwise the event is APPROVE. Two safeguards can force a
non-blocking COMMENT instead:
--comment-onlywas requested.- The PR belongs to the authenticated GitHub user, because GitHub does not permit self-approval or self-requested changes.
Posting still follows review.postToGitHub:
| Value | Behavior |
|---|---|
ask |
Show the drafted review and request confirmation before posting. |
always |
Post the resolved event without another confirmation. |
never |
Keep the result local. |
When the result is clean, Review Watch generates a Change Brief and sends the
ready-for-merge notification even when safe mode or self-authorship changes the GitHub event to
COMMENT.
State and compatibility
Section titled “State and compatibility”Daemon discovery state is user-local:
${XDG_STATE_HOME:-$HOME/.local/state}/git-workflow/├── review-watch-seen├── review-watch-queue.jsonl└── pr-activity-seen # present when notifications.prActivity is enabledEach new queue record has this shape:
{ "repo": "owner/repo", "number": 42, "headRefOid": "abc123", "author": "alice", "title": "Fix login redirect", "url": "https://github.com/owner/repo/pull/42", "queuedAt": 1770000000}author may be null; older records without the field remain valid. Records without repository,
PR number, or head SHA are discarded. The seen ledger keeps the latest 500 keys in observation
order.
Completed review SHAs are project-local in .git-workflow/.review-watch-reviewed, with the legacy
.claude/.review-watch-reviewed file accepted as a read-only fallback. A new commit changes the
head SHA and makes the PR eligible for another review round.
Configuration
Section titled “Configuration”| Setting | Default | Purpose |
|---|---|---|
reviewWatch.enabled |
false |
Explicitly opts the project into the daemon and worker flow. |
reviewWatch.intervalSeconds |
60 |
Poll interval used when the CLI does not override it. |
notifications.sound |
Glass |
macOS system sound name shared by all banners. |
reviewWatch.linters |
auto |
Auto-detect project linters or run an explicit command. |
reviewWatch.knownIssues |
references/known-issues.md |
Project or skill-local deterministic ruleset. |
review.postToGitHub |
ask |
ask, always, or never. |
review.postEvent |
auto |
Derive REQUEST_CHANGES/APPROVE, or force comment. |
Canonical configuration lives in .git-workflow/config.yaml; .claude/config.yaml is a legacy
read-only fallback. CLI interval and repository arguments take precedence over configuration.
Testing and safety
Section titled “Testing and safety”--doctorchecks paths, Bash, Python, Node, Git,gh, authentication, and parsed configuration. It does not query PRs, publish reviews, or create queue state.- Automated tests replace the notifier through
GIT_WORKFLOW_NOTIFY_SCRIPTor the compatible internalREVIEW_WATCH_NOTIFY_SCRIPToverride, so validation never emits real desktop notifications. - The live query asks GitHub only for metadata required to identify and de-duplicate PRs.
- Review posting uses the same permission and self-review guards as the regular review skill.
Troubleshooting
Section titled “Troubleshooting”- Doctor reports missing files: reload or reinstall the plugin; never substitute a root
/scriptspath. - No PRs appear: verify
reviewWatch.enabled: true,gh auth status, and that GitHub requested a review from the authenticated user. - No desktop banner: allow notifications for the terminal/AppleScript host on macOS, or verify
notify-sendand the desktop notification service on Linux. - A PR is skipped: drafts and already-reviewed head SHAs are intentionally ignored. Push a new commit to create a new SHA.
- Duplicate skill names in Codex: use either the installed plugin or checkout-local
.agents/skillsdiscovery in a session, not both.
See Installation, Commands, and Configuration for the package-wide reference.

