diff --git a/.github/pi/pr-review.prompt.md b/.github/pi/pr-review.prompt.md index 952ba4c428..8f46813507 100644 --- a/.github/pi/pr-review.prompt.md +++ b/.github/pi/pr-review.prompt.md @@ -4,3 +4,14 @@ - Return a markdown PR comment starting with `## Pi Review`. - Tag each finding with a severity (P0 / P1 / P2), file path, and line number when known confidently. - Output ONLY the final review markdown — no preamble, no thinking, no tool transcripts. + +# Before you settle on a verdict + +`REVIEW.md` tells you to discard findings you are not confident in. That rule exists to suppress noise, not to license a quick approval. Review in two passes: + +1. Enumerate every candidate defect you notice, without judging any of them yet. +2. Take each candidate and try to prove it is real: read the surrounding code, check the caller, check the error path. Keep it, or dismiss it for a specific reason. + +A "Good to merge" verdict must be accompanied by a "Considered and dismissed" section listing each candidate from pass 1 with the concrete reason it is not a finding. If that section would be empty, pass 1 was skipped: go back and do it. + +Facts cut both ways. If you notice that a cached value can be multiple megabytes, that a lock is held across an await, or that a new parameter is caller-controlled, that observation is a candidate for pass 2 even when the surrounding code looks deliberate. Do not narrate such a fact as evidence that the code is fine without first checking whether it is a bug. diff --git a/.github/workflows/pi-pr-review.yml b/.github/workflows/pi-pr-review.yml index a5d8d6e6f1..9b536b6ed5 100644 --- a/.github/workflows/pi-pr-review.yml +++ b/.github/workflows/pi-pr-review.yml @@ -212,7 +212,9 @@ jobs: - name: Install Pi CLI if: steps.pi_config.outputs.enabled == 'true' && steps.pr.outputs.skip != 'true' - run: npm install --global @mariozechner/pi-coding-agent + # Pinned: this job holds DEEPSEEK_API_KEY and PR write access, and an + # unpinned reviewer also makes verdicts non-reproducible across runs. + run: npm install --global @earendil-works/pi-coding-agent@0.84.1 - name: Pre-fetch base and head refs for the PR if: steps.pi_config.outputs.enabled == 'true' && steps.pr.outputs.skip != 'true' @@ -362,13 +364,14 @@ jobs: # The context file lives in RUNNER_TEMP (outside the checkout); tell the # agent its absolute path. printf '\nReview context file (absolute path): %s\n' "$CTX" >> /tmp/pi-prompt.md - # DeepSeek exposes only two reasoning levels; pi's default (medium) is - # unsupported for this model and silently clamps to reasoning_effort=high. - # xhigh is the only way to reach "max", which is what a review needs. + # DeepSeek's reasoning_effort accepts low/high/max and silently maps both + # medium and xhigh onto high. Set the level explicitly rather than letting + # pi's default clamp onto it, so a change to either the default or the + # clamping is a visible diff here instead of a silent shift in review depth. pi -p \ --provider deepseek \ --model deepseek-v4-pro \ - --thinking xhigh \ + --thinking high \ --tools "$PI_TOOLS" \ "${PI_HARDEN_FLAGS[@]}" \ --mode json \ @@ -403,6 +406,14 @@ jobs: | (.content[]? | select(.type == "text") | .text) ' "$OUT_DIR/pi-events.jsonl" > "$OUT_DIR/pi-final-message.md" + # The final message often opens with chatter ("Now I have all the context + # I need..."), which would land above the verdict in the posted comment. + # Keep the trim conditional: without the heading there is nothing to cut + # and the range expression would empty the file. + if grep -q '^## Pi Review' "$OUT_DIR/pi-final-message.md"; then + sed -i -n '/^## Pi Review/,$p' "$OUT_DIR/pi-final-message.md" + fi + - name: Post Pi review comment if: steps.pi_config.outputs.enabled == 'true' && steps.pr.outputs.skip != 'true' uses: actions/github-script@v7