Skip to content

Commit 3da5d25

Browse files
ci: deploy lean4repo-utils@0.3 review+summary from the README example
Regenerate both AI PR workflows as fresh copies of the canonical example workflows in the action READMEs, pinned @0.3, using default models: - review: ChatOps-only (/review from a repo member), review@0.3, OPENROUTER_KEY. - summary: every-PR pull_request_target, summary@0.3, OPENROUTER_KEY, default model. Supersedes the earlier per-repo migration so this repo runs the identical, current, example-based workflow as the rest of the fleet. NOTE: this replaces the bespoke review workflow that auto-resolved KB paper citations (docs/kb/_generated/lean-citations.json) into spec_refs. That auto-grounding is intentionally dropped for the clean example baseline; re-add it on top of this if wanted (the consolidated action still accepts spec_refs and auto-extracts refs from the /review comment text). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 6841289 commit 3da5d25

2 files changed

Lines changed: 42 additions & 110 deletions

File tree

.github/workflows/review.yml

Lines changed: 28 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,23 @@
11
name: PR Review
22

3-
# Trusted CHATOPS-ONLY deployment of the consolidated OpenRouter review action
4-
# (lean4repo-utils/review@main). Invoked by a maintainer commenting `/review` on a PR.
5-
# The auto pull_request trigger is intentionally dropped for now.
3+
# Review runs ONLY on demand, via a `/review` comment from a repo member. It is
4+
# deliberately NOT run on PR open: the review path builds and elaborates the
5+
# PR's Lean code with the OpenRouter secret and a write token in scope, so until
6+
# the two-stage secret-free split (S2) lands, running it is safe only for code a
7+
# trusted maintainer has chosen to review. See the review action README.
68
on:
79
issue_comment:
810
types: [created]
911

1012
concurrency:
1113
group: ${{ github.workflow }}-${{ github.event.issue.number }}
12-
cancel-in-progress: false
13-
14-
# Least privilege: the reviewer's lean_tools execute model-directed Lean IO and the
15-
# action builds the PR-head code, so a token exfiltrated there must not be able to push
16-
# or merge. Only what posting a review needs.
17-
permissions:
18-
contents: read
19-
pull-requests: write
20-
issues: write
14+
cancel-in-progress: true
2115

2216
jobs:
2317
review:
24-
# Chatops only, gated to trusted members. NOTE: `/review` here is a coarse prefix
25-
# match — a member typing `/reviewer` would also match; harmless under the member
26-
# gate, tighten to a word boundary if this ever opens to untrusted commenters.
18+
# The COMMENT author (not the PR author) is the trust boundary.
2719
if: >-
20+
github.event_name == 'issue_comment' &&
2821
github.event.issue.pull_request &&
2922
startsWith(github.event.comment.body, '/review') &&
3023
(
@@ -33,99 +26,35 @@ jobs:
3326
github.event.comment.author_association == 'COLLABORATOR'
3427
)
3528
runs-on: ubuntu-latest
36-
timeout-minutes: 240
29+
timeout-minutes: 120
30+
permissions:
31+
contents: read
32+
pull-requests: write
3733
steps:
38-
# Parse the /review comment: `Internal:` lines → manual spec/KB refs, everything
39-
# under `External:`/`Comments:` → free-text instructions (the action auto-extracts
40-
# any URLs it mentions). Comment body is passed via env, never interpolated into
41-
# the run: body (GHA expression-injection guard).
42-
- name: Extract arguments from comment
34+
# Everything after `/review` is freeform focus text; URLs and existing
35+
# repo paths it mentions become review context automatically.
36+
- name: Extract instructions from /review comment
4337
id: get_args
4438
env:
4539
COMMENT_BODY: ${{ github.event.comment.body }}
46-
shell: bash
4740
run: |
4841
EOF=$(openssl rand -hex 8)
49-
awk -v eof="$EOF" -v gh_out="$GITHUB_OUTPUT" '
50-
BEGIN { spec=""; com=""; section="" }
51-
/^External:/ { section="com"; next }
52-
/^Internal:/ { section="spec"; next }
53-
/^Comments:/ { section="com"; next }
54-
{
55-
gsub(/\r/, "", $0); gsub(/^[ \t]+|[ \t]+$/, "", $0);
56-
if ($0 == "" || $0 == "/review") { next }
57-
if (section == "spec") { sub(/^- +/, ""); spec = (spec=="" ? $0 : spec "," $0) }
58-
else if (section == "com") { com = (com=="" ? $0 : com "\n" $0) }
59-
}
60-
END {
61-
printf "manual_spec_refs=%s\n", spec >> gh_out
62-
printf "additional_comments<<%s\n%s\n%s\n", eof, com, eof >> gh_out
63-
}
64-
' <<< "$COMMENT_BODY"
65-
66-
# Unguided KB grounding: map the PR''s changed .lean files to the papers they cite
67-
# (docs/kb/_generated/lean-citations.json) and pass those KB pages as spec_refs, so
68-
# a plain /review is grounded in the right paper summaries with no manual guidance.
69-
# Read the citation JOIN from the BASE ref (data-only, fork-safe); do NOT execute
70-
# any checked-out repo script. (The KB page CONTENT is read by the action from the
71-
# PR head — acceptable for this trusted, manually-inspected pilot; base-ref content
72-
# reading is part of the S2/S7 hardening.)
73-
- name: Resolve KB context (base-ref citation join)
74-
id: kb
75-
env:
76-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77-
PR_NUMBER: ${{ github.event.issue.number }}
78-
MANUAL_SPEC_REFS: ${{ steps.get_args.outputs.manual_spec_refs }}
42+
{
43+
echo "instructions<<$EOF"
44+
printf '%s\n' "$COMMENT_BODY" | sed -E '1s|^/review[[:space:]]*||'
45+
echo "$EOF"
46+
} >> "$GITHUB_OUTPUT"
7947
shell: bash
80-
run: |
81-
set -euo pipefail
82-
BASE_SHA="$(gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER" --jq '.base.sha')"
83-
gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" --paginate --jq '.[].filename' > /tmp/changed.txt
84-
if gh api "repos/$GITHUB_REPOSITORY/contents/docs/kb/_generated/lean-citations.json?ref=$BASE_SHA" \
85-
--jq '.content' 2>/dev/null | base64 -d > /tmp/citations.json; then :; else
86-
echo "No lean-citations.json on base ref; proceeding without KB spec_refs."
87-
echo '{}' > /tmp/citations.json
88-
fi
89-
# Join is pure data: filenames + JSON read from files, never interpolated.
90-
spec_refs="$(python3 - <<'PY'
91-
import json, os
92-
try:
93-
cites = json.load(open('/tmp/citations.json')).get('files', {})
94-
except Exception:
95-
cites = {}
96-
changed = [l.strip() for l in open('/tmp/changed.txt') if l.strip().endswith('.lean')]
97-
keys = []
98-
for f in changed:
99-
for k in cites.get(f, []):
100-
if k not in keys:
101-
keys.append(k)
102-
refs = [f"docs/kb/papers/{k}.md" for k in keys]
103-
# Merge any manual `Internal:` refs from the /review comment (dedup, keep order).
104-
for r in (os.environ.get("MANUAL_SPEC_REFS", "") or "").split(","):
105-
r = r.strip()
106-
if r and r not in refs:
107-
refs.append(r)
108-
print(",".join(refs))
109-
PY
110-
)"
111-
echo "spec_refs=$spec_refs" >> "$GITHUB_OUTPUT"
112-
echo "Resolved KB spec_refs: ${spec_refs:-(none)}"
11348

114-
- name: AI review
115-
uses: alexanderlhicks/lean4repo-utils/review@main
49+
- uses: alexanderlhicks/lean4repo-utils/review@0.3
11650
with:
11751
github_token: ${{ secrets.GITHUB_TOKEN }}
11852
api_key: ${{ secrets.OPENROUTER_KEY }}
11953
pr_number: ${{ github.event.issue.number }}
120-
# Auto-pulled KB paper pages for the changed files + any manual Internal: refs.
121-
spec_refs: ${{ steps.kb.outputs.spec_refs }}
122-
additional_comments: ${{ steps.get_args.outputs.additional_comments }}
123-
# Coverage-first budget control: this sizes/trims prompts for large PRs,
124-
# but advisory mode does not stop later files from being reviewed.
125-
# Source these from workflow config, never PR content.
126-
# llm_max_run_tokens: "400000"
127-
# llm_budget_mode: advisory
128-
# model: omitted → the action's default OpenRouter slug. Set an explicit slug
129-
# here if you want a specific model for the pilot.
130-
# lean_tools defaults true (full-quality, compiler-grounded review — trusted
131-
# pilot). enable_web_search defaults false (web-search fees are not token-bounded).
54+
# URLs and repo paths mentioned in the /review comment are extracted
55+
# into external/spec/repo context automatically.
56+
additional_comments: "${{ steps.get_args.outputs.instructions }}"
57+
# Everything else uses the action defaults (deep agents on z-ai/glm-5.2,
58+
# verification on deepseek/deepseek-v4-pro, lean_tools + verify_findings
59+
# on). See the review action README to override models or tune
60+
# spec_refs / escape_hatch_allowlist / dependent_impact_max.

.github/workflows/summary.yml

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
name: 'PR Summary'
22

3+
# Summary runs on every PR update (open + each new commit). It is SAFE under
4+
# pull_request_target — where the OpenRouter secret and a write token are in
5+
# scope even for fork PRs — because it never builds or executes PR code: it
6+
# reads the diff and committed source as data, and reads its policy file from
7+
# the BASE ref (S4). See the summary action README.
38
on:
49
pull_request_target:
510
types: [opened, synchronize, reopened]
@@ -9,25 +14,23 @@ concurrency:
914
cancel-in-progress: true
1015

1116
permissions:
12-
contents: read # required: the action checks out the PR head to read the diff
13-
pull-requests: write # required: post/update the summary comment
14-
issues: read # optional: link affected sorries to `proof wanted` issues
17+
contents: read
18+
pull-requests: write
19+
issues: read
1520

1621
jobs:
1722
summarize:
1823
runs-on: ubuntu-latest
19-
timeout-minutes: 20
2024
steps:
2125
- name: Generate PR Summary
22-
uses: alexanderlhicks/lean-summary-workflow@main
26+
uses: alexanderlhicks/lean4repo-utils/summary@0.3
2327
with:
2428
github_token: ${{ secrets.GITHUB_TOKEN }}
2529
api_key: ${{ secrets.OPENROUTER_KEY }}
26-
# model: inherits the action default (deepseek/deepseek-v4-flash).
27-
# Set `model: <openrouter-slug>` here to override for this repo only.
2830
github_repository: ${{ github.repository }}
2931
pr_number: ${{ github.event.pull_request.number }}
30-
additional_instructions_path: 'CONTRIBUTING.md'
31-
validate_title: 'true'
32-
upstream_path: 'ArkLib/ToMathlib/'
33-
# Other optional knobs (reasoning_effort, max_*_diff_chars): see the action README.
32+
# Uses the default model (deepseek/deepseek-v4-flash). Optional knobs:
33+
# model: <any OpenRouter slug> # e.g. google/gemini-3-flash-preview
34+
# additional_instructions_path: 'CONTRIBUTING.md' # default; read from the base ref
35+
# validate_title: 'true' # enforce conventional-commit PR titles
36+
# upstream_path: 'ToMathlib/' # remind on changes under this prefix

0 commit comments

Comments
 (0)