Inspector — Review and Merge Automated PRs #66
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Inspector — Review and Merge Automated PRs | |
| # Triggered when the self-improvement workflow finishes. A second local model | |
| # (Inspector Clementine Zestworth) investigates the resulting PR and merges it | |
| # only if it passes scrutiny AND touches nothing outside src/. | |
| on: | |
| workflow_run: | |
| workflows: ["Recursive Repository Self Improvement"] | |
| types: [completed] | |
| # Like the first workflow, the token is NOT granted `workflows` permission. | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| concurrency: | |
| group: inspector | |
| cancel-in-progress: false | |
| jobs: | |
| inspect: | |
| # Only act when the improve run actually succeeded. | |
| if: ${{ github.event.workflow_run.conclusion == 'success' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| REVIEW_MODEL: "qwen3.5:0.8b" | |
| # The improve workflow named its branch auto/improve-<run_id>, and that | |
| # run_id is exactly this event's workflow_run.id. | |
| PR_BRANCH: "auto/improve-${{ github.event.workflow_run.id }}" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Find the PR for this run | |
| id: find | |
| run: | | |
| set -euo pipefail | |
| PR=$(gh pr list --head "$PR_BRANCH" --state open \ | |
| --json number --jq '.[0].number // empty') | |
| if [ -z "$PR" ]; then | |
| echo "No open PR found for branch $PR_BRANCH; nothing to review." | |
| echo "found=0" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "Found PR #$PR for branch $PR_BRANCH" | |
| echo "found=1" >> "$GITHUB_OUTPUT" | |
| echo "pr=$PR" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Independent safety check — PR must touch only src/ | |
| if: steps.find.outputs.found == '1' | |
| id: scope | |
| env: | |
| PR: ${{ steps.find.outputs.pr }} | |
| run: | | |
| set -euo pipefail | |
| outside="$(gh pr diff "$PR" --name-only | grep -v '^src/' || true)" | |
| if [ -n "$outside" ]; then | |
| echo "::warning::PR #$PR touches files outside src/; refusing to merge:" | |
| echo "$outside" | |
| gh pr comment "$PR" --body \ | |
| "🚫 Inspector aborted: this PR modifies files outside \`src/\`, which is not permitted for automated changes. Leaving it open for a human." | |
| echo "ok=0" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "ok=1" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Set up Python | |
| if: steps.scope.outputs.ok == '1' | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Install and start Ollama | |
| if: steps.scope.outputs.ok == '1' | |
| run: | | |
| curl -fsSL https://ollama.com/install.sh | sh | |
| nohup ollama serve >/tmp/ollama.log 2>&1 & | |
| for i in $(seq 1 30); do | |
| if curl -fsS http://127.0.0.1:11434/api/version >/dev/null 2>&1; then | |
| echo "ollama is up"; break | |
| fi | |
| sleep 2 | |
| done | |
| - name: Pull model | |
| if: steps.scope.outputs.ok == '1' | |
| run: ollama pull "$REVIEW_MODEL" | |
| - name: Run the Inspector | |
| if: steps.scope.outputs.ok == '1' | |
| env: | |
| PR_NUMBER: ${{ steps.find.outputs.pr }} | |
| REVIEW_VERDICT_FILE: ${{ runner.temp }}/review_verdict.txt | |
| REVIEW_BODY_FILE: ${{ runner.temp }}/review_body.md | |
| run: python .github/scripts/review.py | |
| - name: Comment the Inspector's reasoning, then merge if APPROVE | |
| if: steps.scope.outputs.ok == '1' | |
| env: | |
| PR: ${{ steps.find.outputs.pr }} | |
| REVIEW_VERDICT_FILE: ${{ runner.temp }}/review_verdict.txt | |
| REVIEW_BODY_FILE: ${{ runner.temp }}/review_body.md | |
| run: | | |
| set -euo pipefail | |
| VERDICT="$(cat "$REVIEW_VERDICT_FILE" 2>/dev/null || echo reject)" | |
| echo "Inspector verdict: $VERDICT" | |
| # Post the full reasoning as a plain comment. (Formal pr reviews from | |
| # the token that opened the PR are blocked by GitHub, so we skip them.) | |
| gh pr comment "$PR" --body-file "$REVIEW_BODY_FILE" | |
| if [ "$VERDICT" = "approve" ]; then | |
| gh pr merge "$PR" --squash --delete-branch | |
| echo "Merged PR #$PR. 🍊" | |
| else | |
| echo "PR #$PR left open for a human. The Inspector was not convinced." | |
| fi |