Problem
plugin/skills/github-review-loop/scripts/reply-resolve.sh is the designated single source for the review-thread reply/resolve mutation contract, but it only knows one reply shape: "Fixed in <SHA>. <summary>.". It requires a fix SHA and always words the reply as a fix.
The remediation doctrine (plugin/governance/remediation-doctrine.md, defer-with-scope / record-with-scope) says an actionable finding left unfixed in the current loop must go to a tracked issue (or a recorded residual) with full scope, and the thread should say so. The script has no sanctioned shape for that reply: "Deferred to . ." with no fix SHA.
Evidence
Twice, the github-reviewer bypassed the script with raw addPullRequestReviewThreadReply / resolveReviewThread GraphQL mutations to post a deferral reply pointing at a tracked issue:
Each bypass skips the script's invariants (reply-before-resolve, fail-closed surface map, non-blocking resolve, question-never-resolves, offline test seam), so the contract drifts outside the one place that owns it.
Proposed direction
Add a sanctioned deferral reply mode to reply-resolve.sh (for example a --defer <tracked-home-url> flag, or a mode positional) that:
- posts a deferral-shaped reply body naming the tracked home instead of a fix SHA;
- keeps every existing invariant (surface map, reply before resolve, resolve only when eligible, never resolve a question thread, non-blocking resolve);
- is covered by
tools/test_reply_resolve.sh through the existing capture seam.
Then route defer-with-scope through it in plugin/agents/github-reviewer.md step 8 (and wherever the github-review-loop skill describes reply delivery), so the reviewer never needs raw mutations.
Open decision
Whether a deferred thread should be resolved (the finding is handed off to a tracked issue) or left open for the human reviewer. This needs a user decision before implementation.
Scope
plugin/skills/github-review-loop/scripts/reply-resolve.sh, its test, plugin/agents/github-reviewer.md step 8, and related github-review-loop prose. Runtime behaviour change to a shipped script, so a version bump is expected.
Problem
plugin/skills/github-review-loop/scripts/reply-resolve.shis the designated single source for the review-thread reply/resolve mutation contract, but it only knows one reply shape:"Fixed in <SHA>. <summary>.". It requires a fix SHA and always words the reply as a fix.The remediation doctrine (
plugin/governance/remediation-doctrine.md, defer-with-scope / record-with-scope) says an actionable finding left unfixed in the current loop must go to a tracked issue (or a recorded residual) with full scope, and the thread should say so. The script has no sanctioned shape for that reply: "Deferred to . ." with no fix SHA.Evidence
Twice, the github-reviewer bypassed the script with raw
addPullRequestReviewThreadReply/resolveReviewThreadGraphQL mutations to post a deferral reply pointing at a tracked issue:Each bypass skips the script's invariants (reply-before-resolve, fail-closed surface map, non-blocking resolve, question-never-resolves, offline test seam), so the contract drifts outside the one place that owns it.
Proposed direction
Add a sanctioned deferral reply mode to
reply-resolve.sh(for example a--defer <tracked-home-url>flag, or a mode positional) that:tools/test_reply_resolve.shthrough the existing capture seam.Then route defer-with-scope through it in
plugin/agents/github-reviewer.mdstep 8 (and wherever the github-review-loop skill describes reply delivery), so the reviewer never needs raw mutations.Open decision
Whether a deferred thread should be resolved (the finding is handed off to a tracked issue) or left open for the human reviewer. This needs a user decision before implementation.
Scope
plugin/skills/github-review-loop/scripts/reply-resolve.sh, its test,plugin/agents/github-reviewer.mdstep 8, and related github-review-loop prose. Runtime behaviour change to a shipped script, so a version bump is expected.