Skip to content

Commit bd73d3a

Browse files
CIclaude
andcommitted
fix(triage): make gh api mandatory for review comments, closing /code-review's print fallback
/code-review --comment prefers mcp__github_inline_comment__create_inline_comment and, when that tool is missing, says "fall back to gh api ... or print the findings instead". The bot never loads that tool (--strict-mcp-config), so every review lands on that sentence. PR springfall2008#5283's run took the print branch without attempting gh api at all, so nothing was denied and the existing "report a denial, don't print" rule never applied. The review was lost and the PR was marked BOT_FAILED. GH_API_ENDPOINT_FIRST_PROMPT now names the tool as absent and makes gh api the required path, allowing printing only after a gh api call has actually been denied. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent f6e996e commit bd73d3a

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

‎tools/test_triage_daemon.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,18 @@ def test_tells_the_agent_to_report_a_denial_rather_than_print_findings(self):
775775
completed review in the log. The prompt asks for a denial to be stated plainly."""
776776
self.assertIn("denied", triage_daemon.GH_API_ENDPOINT_FIRST_PROMPT)
777777

778+
def test_closes_the_skills_print_instead_fallback(self):
779+
"""/code-review --comment prefers mcp__github_inline_comment__create_inline_comment, and when
780+
that is missing offers "fall back to gh api ... or print the findings instead". The tool is
781+
never loaded here (--strict-mcp-config), so every review lands on that sentence, and PR
782+
#5283's run took the print branch without ever trying gh api - no denial to report, so the
783+
denial rule above never applied. The prompt must name the tool as absent and make gh api the
784+
required path, with printing allowed only once a gh api call has actually been denied."""
785+
prompt = triage_daemon.GH_API_ENDPOINT_FIRST_PROMPT
786+
self.assertIn("mcp__github_inline_comment__create_inline_comment", prompt)
787+
self.assertIn("never available", prompt)
788+
self.assertIn("not an acceptable substitute", prompt)
789+
778790
def test_steers_comment_bodies_into_a_scratch_file(self):
779791
"""PR #5229's review had its endpoint-first POST denied because the body was an inline
780792
double-quoted argument holding backticks: the shell reads those as command substitution,

‎tools/triage_daemon.py‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,11 @@
470470
# a finished review in the log. It also moves comment bodies into a scratch file: PR #5229's
471471
# POSTs were endpoint-first and still denied, because a double-quoted body holding backticks is
472472
# command substitution to the shell, and the permission check denies the substituted commands
473-
# that no rule allows. Also carries the bot-disclosure requirement for these two flows:
473+
# that no rule allows. It also closes /code-review's own escape hatch: with its preferred
474+
# mcp__github_inline_comment tool missing (never loaded, see --strict-mcp-config), the skill
475+
# says "fall back to gh api ... or print the findings instead", and PR #5283's run (2026-09-28)
476+
# took the print branch without trying gh api at all - nothing was denied, so the denial rule
477+
# alone never fired. Also carries the bot-disclosure requirement for these two flows:
474478
# /code-review's own instructions live in a skill we don't own, so this prompt is the only
475479
# lever available for it; /pr-cleanup's SKILL.md already asks for disclosure directly, and
476480
# this is the belt-and-braces backup for it, same reasoning as the endpoint-first steer.
@@ -524,6 +528,10 @@
524528
)
525529

526530
GH_API_ENDPOINT_FIRST_PROMPT = (
531+
"The `mcp__github_inline_comment__create_inline_comment` tool is never available in this session, so post every PR comment "
532+
"with `gh api` - that is the required path, not one option among several. Printing the findings instead of posting them is "
533+
"not an acceptable substitute, even where a skill's instructions offer it as a fallback; it is permitted only after a `gh api` "
534+
"call has actually been denied. "
527535
"Permission rules in this session match a literal command prefix, so `gh api` calls are only permitted when the current allowlist covers the exact spelling you use. "
528536
"Prefer the endpoint-first, unquoted form (endpoint immediately after `gh api`) and put flags after the endpoint - for example "
529537
f"`gh api repos/{REPO}/pulls/123/comments --method POST -f path=apps/predbat/example.py -F body=@{SCRATCH_DIR}/comment-1.md`. "

0 commit comments

Comments
 (0)