feat: feed the shadow PR reviewer the linked issue body + test-runner facts #442
No reviewers
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
2 participants
Notifications
Total time spent: 2 minutes 7 seconds
Due date
igor
2 minutes 7 seconds
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor!442
Loading…
Reference in a new issue
No description provided.
Delete branch "agent/438-feed-the-pr-reviewer-the-linked-issue-test-runner"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What this PR does
lib/review.sh: parses theCloses #NN(or Fixes/Resolves, any inflection) keyword from the PR body, fetches that issue, and folds its title + body into the review prompt (bounded to 4000 chars, truncated-not-blocked; skips gracefully on no match or a failed fetch)Makefiletesttarget recipe (one hop through a delegated prerequisite, e.g. this repo's owntest: check-sync), the contents of any.shscript that recipe invokes,package.json'stestscript, and a presence-only note forpytest.ini/go.mod/Cargo.toml(each ecosystem's convention-based auto-discovery)review_build_promptcomposes the full user-turn prompt (PR metadata + the two new sections, each collapsing to nothing when empty + the unified diff) and is called fromdo_review_tickinbin/tick.sh, replacing the inline heredoc; confirmed byte-identical output to the pre-#438 prompt shape when a PR closes no issue and touches no test filesbin/lib/review-directive.md-- verdict thresholds and approve criteria are untouched, per the issue's scope discipline--- BEGIN/END UNTRUSTED ISSUE TEXT ---), matching the existing convention inlib/feedback.sh's player-feedback block -- an issue can originate from a lower-trust pipeline (e.g. feedback-triage) than the PR author, and an unfenced body could otherwise try to forge a fake## Unified diffheading to blur the section boundary in the reviewer's promptbin/test-review.sh: unit tests covering the closing-keyword parser, the linked-issue section (fetch, truncation, untrusted-data fencing, graceful skip), the test-file diff filter, the Makefile recipe scraper (incl. the one-hop delegation case), the assembled test-runner-facts section, and an acceptance test asserting both new sections land inreview_build_prompt's output for a PR that closes an issueTest plan
bin/test-review.shpasses (new suite, picked up automatically bybin/check-sync.sh'sbin/test-*.shglob)make testpasses (full suite, allbin/test-*.sh+ the AGENTS.md/tick.sh sync check)make lintpasses (shellcheckonbin/+lib/,mdlclean)Closes #438
WIP: issue #438 checkpoint -- Feed the PR reviewer the linked issue + test-runner facts so it stops punting to the humanto feat: feed the shadow PR reviewer the linked issue body + test-runner facts🤖 Review —
COMMENT(automated)CI for
06c519e6: successAdds
lib/review.sh(linked-issue text + test-runner facts) and routesdo_review_tick's prompt through the newreview_build_prompt. Scope is tight, CI is green, and every checked box maps to real diff content — including the byte-identical-plain-prompt claim, which is genuinely asserted inbin/test-review.sh. Not approving because the one thing that determines whether this feature does anything at all is exactly the thing the tests stub out.Blocking-ish questions (can't resolve from the diff)
forgejo_get_issue/forgejo_repo_get_filesignatures are unverified.lib/review.sh:57and:110callforgejo_get_issue "$repo" "$number"/forgejo_repo_get_file "$repo" "$path", andbin/test-review.shoverrides both with its own stubs. Every call site is wrapped in|| return 0/2>/dev/null || true, so if either helper doesn't exist, or takes a different arity (e.g. a requiredrefarg), the feature degrades to a permanent silent no-op and the test suite still passes green. Please confirm both exist with this arity inlib/forgejo.sh; ideally add a cheap guard to the suite (sourcelib/forgejo.shand assertdeclare -F forgejo_get_issue forgejo_repo_get_filebefore stubbing) so a future rename is caught.forgejo_repo_get_fileread? If it reads the default branch, the Makefile/script contents pasted unfenced into the prompt (lib/review.sh:117-135) are already-merged, trusted content — fine. If it reads the PR head, then a PR can edit its ownMakefile/bin/*.shto inject arbitrary text (including a ``` fence break and a fake## Unified diffheading) into the prompt of the reviewer that gates auto-merge — the exact attack the issue-body fence at:66was added to prevent. Worth stating explicitly in the module comment either way.Non-blocking findings
lib/review.sh:66— the untrusted fence is a delimiter, not an escape: an issue body containing--- END UNTRUSTED ISSUE TEXT ---breaks out. Matches the existinglib/feedback.shconvention, so this is consistency-preserving, but stripping the marker from$bodybefore interpolation is a one-liner.lib/review.sh:29—(close[sd]?|fix(e[sd])?|resolve[sd]?)has no leading word boundary, soprefixes #12/unfixed #3false-positive and would splice an unrelated issue into the prompt.(^|[^[:alnum:]])or\bwould tighten it. Also noteCloses owner/repo#12(cross-repo form) doesn't match — graceful, but silently.lib/review.sh:96—for prereq in $prereqsis unquoted, so a Makefile prerequisite like$(SOURCES)or*.ogets glob-expanded against the agent's cwd, and$(...)then lands insidegrep -E "^${prereq}[[:space:]]*:"where$and()are regex metacharacters. Worst case is prompt noise rather than a bug, butset -f-guarding the loop or skipping prereqs matching[^A-Za-z0-9_./-]would make it deterministic.lib/review.sh:16-18— thelogfallback is defined butlogis never called anywhere in the module. Dead code.review_test_runner_factsfires up to ~9 contents-API calls per review tick (Makefile + 3 scripts + package.json + 3 unconditional ecosystem probes) whenever a test-shaped file changes. The threepytest.ini/go.mod/Cargo.tomlprobes run even in an obviously bash-only repo. Bounded and per-PR, so probably fine — just flagging the added latency on the hot path.Test coverage notes
The suite is genuinely good — parser, truncation-length assertion via the
x-count trick, fence open/close, graceful-skip, the delegation hop, the "no Makefile fabricated" negative, and the byte-identical plain-prompt acceptance test all pull their weight. Two gaps:truncated_noteis""in bothreview_build_promptcalls (the truncated-diff shape is never exercised), and malformed/non-object JSON fromforgejo_get_issueis guarded at:58but not tested.Independent review by the harness on
claude-opus-5(effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.