Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ccef883
refactor(pipeline): script board and PR helpers
GiggleLiu Mar 15, 2026
415eff5
refactor(pipeline): add worktree and review checks
GiggleLiu Mar 15, 2026
a8adbef
refactor(pipeline): add completeness checks
GiggleLiu Mar 15, 2026
1093793
refactor(pipeline): extend board helper coverage
GiggleLiu Mar 15, 2026
4df2b3e
refactor(pipeline): enrich board next selection output
GiggleLiu Mar 15, 2026
f98280e
refactor(pipeline): forward board-next selection options
GiggleLiu Mar 15, 2026
6a84b57
refactor(pipeline): script review candidate selection
GiggleLiu Mar 15, 2026
5568cdf
refactor(pipeline): list ready board items
GiggleLiu Mar 15, 2026
ffad2a1
refactor(pipeline): drive run-review from board queue
GiggleLiu Mar 15, 2026
3269ab3
docs(pipeline): align review implementation workflow
GiggleLiu Mar 15, 2026
4efffda
refactor(pipeline): drive run-pipeline from board queue
GiggleLiu Mar 15, 2026
2b23ac5
refactor(pipeline): script issue preflight helpers
GiggleLiu Mar 15, 2026
701c886
refactor(pipeline): script current PR context
GiggleLiu Mar 15, 2026
07ca567
refactor(pipeline): script issue branch and prompt context
GiggleLiu Mar 15, 2026
c7fd536
Merge remote-tracking branch 'origin/main' into pipeline-automation-r…
GiggleLiu Mar 15, 2026
4473f88
refactor(pipeline): bundle PR review context
GiggleLiu Mar 15, 2026
6426b34
refactor(pipeline): bundle deterministic review context
GiggleLiu Mar 15, 2026
bfee0f2
refactor(pipeline): bundle review worktree preparation
GiggleLiu Mar 15, 2026
563c913
refactor(pipeline): bundle queue claiming
GiggleLiu Mar 15, 2026
78fb3e6
refactor(pipeline): standardize issue context loading
GiggleLiu Mar 15, 2026
a8f21f8
refactor(pipeline): scaffold skill context bundles
GiggleLiu Mar 15, 2026
59f56d1
refactor(pipeline): bundle review-pipeline context
GiggleLiu Mar 15, 2026
f331e76
refactor(pipeline): simplify review pipeline entrypoint
GiggleLiu Mar 15, 2026
0fc89f1
refactor(pipeline): bundle final-review context
GiggleLiu Mar 15, 2026
3fb31fb
refactor(pipeline): simplify final-review skill entry
GiggleLiu Mar 15, 2026
f1204d3
docs(pipeline): record skill-scoped context bundle plan progress
GiggleLiu Mar 15, 2026
95f1561
refactor(pipeline): add review context reports
GiggleLiu Mar 15, 2026
54524d2
refactor(pipeline): bundle project and implementation context
GiggleLiu Mar 15, 2026
6ba9cdc
refactor(pipeline): improve final-review skill with full context bund…
GiggleLiu Mar 15, 2026
78c84d8
chore: remove completed plan files
GiggleLiu Mar 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 127 additions & 78 deletions .claude/skills/final-review/SKILL.md

Large diffs are not rendered by default.

103 changes: 30 additions & 73 deletions .claude/skills/fix-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,80 +9,50 @@ Resolve PR review comments, fix CI failures, and address codecov coverage gaps f

## Step 1: Gather PR State

**IMPORTANT:** Do NOT use `gh api --jq` for extracting data — it uses a built-in jq that
chokes on response bodies containing backslashes (common in Copilot code suggestions).
Always pipe to `python3 -c` instead. (`gh pr view --jq` is fine — only `gh api --jq` is affected.)
Step 1 should be a single report-generation step. Use the shared scripted helper to produce one skill-readable PR context packet. Do not rebuild this logic inline with `gh api | python3 -c` unless you are debugging the helper itself.

```bash
# Get repo identifiers
REPO=$(gh repo view --json nameWithOwner --jq .nameWithOwner) # e.g., "owner/repo"
REPORT=$(python3 scripts/pipeline_pr.py context --current --format text)
printf '%s\n' "$REPORT"
```

# Get PR number
PR=$(gh pr view --json number --jq .number)
The report should already include:
- repo, PR number, title, URL, head SHA
- comment counts
- CI summary
- Codecov summary
- linked issue context

# Get PR head SHA (on remote)
HEAD_SHA=$(gh api repos/$REPO/pulls/$PR | python3 -c "import sys,json; print(json.load(sys.stdin)['head']['sha'])")
```
Use the values printed in that report for the rest of this skill. If you absolutely need raw structured data for a corner case, rerun the same command with `--format json`, but do not rebuild Step 1 manually.

### 1a. Fetch Review Comments

**Check ALL four sources.** User inline comments are the most commonly missed — do not skip any.

```bash
# 1. Inline review comments on code lines (from ALL reviewers: users AND Copilot)
gh api repos/$REPO/pulls/$PR/comments | python3 -c "
import sys,json
comments = json.load(sys.stdin)
print(f'=== Inline comments: {len(comments)} ===')
for c in comments:
line = c.get('line') or c.get('original_line') or '?'
print(f'[{c[\"user\"][\"login\"]}] {c[\"path\"]}:{line} — {c[\"body\"][:200]}')
"

# 2. Review-level comments (top-level review body from formal reviews)
gh api repos/$REPO/pulls/$PR/reviews | python3 -c "
import sys,json
reviews = json.load(sys.stdin)
print(f'=== Reviews: {len(reviews)} ===')
for r in reviews:
if r.get('body'):
print(f'[{r[\"user\"][\"login\"]}] {r[\"state\"]}: {r[\"body\"][:200]}')
"
Start from the report's `Comment Summary`. It should tell you whether any source is non-empty before you inspect raw threads.

# 3. Issue-level comments (general discussion)
gh api repos/$REPO/issues/$PR/comments | python3 -c "
import sys,json
comments = [c for c in json.load(sys.stdin) if 'codecov' not in c['user']['login']]
print(f'=== Issue comments: {len(comments)} ===')
for c in comments:
print(f'[{c[\"user\"][\"login\"]}] {c[\"body\"][:200]}')
"
```

**Verify counts:** If any source returns 0, confirm it's genuinely empty — don't assume no feedback exists.
If you need the raw comment arrays for detailed triage, rerun `python3 scripts/pipeline_pr.py context --current --format json` and inspect:
- `comments["inline_comments"]`
- `comments["reviews"]`
- `comments["human_issue_comments"]`
- `comments["human_linked_issue_comments"]`
- `comments["codecov_comments"]`

### 1b. Check CI Status

```bash
# All check runs on the PR head
gh api repos/$REPO/commits/$HEAD_SHA/check-runs | python3 -c "
import sys,json
for cr in json.load(sys.stdin)['check_runs']:
print(f'{cr[\"name\"]}: {cr.get(\"conclusion\") or cr[\"status\"]}')
"
```
Read the report's `CI Summary`. The structured JSON fallback includes:
- `state` — `pending`, `failure`, or `success`
- `runs` — normalized check-run details
- `pending` / `failing` / `succeeding` counts

### 1c. Check Codecov Report

```bash
# Codecov bot comment with coverage diff
gh api repos/$REPO/issues/$PR/comments | python3 -c "
import sys,json
for c in json.load(sys.stdin):
if c['user']['login'] == 'codecov[bot]':
print(c['body'])
"
```
Read the report's `Codecov` section. The structured JSON fallback includes:
- `found` — whether a Codecov comment is present
- `patch_coverage`
- `project_coverage`
- `filepaths` — deduplicated paths referenced by Codecov links
- `body` — the raw latest Codecov comment body

## Step 2: Triage and Prioritize

Expand Down Expand Up @@ -130,23 +100,10 @@ Copilot suggestions with `suggestion` blocks contain exact code. Evaluate each:

### 5a. Identify Uncovered Lines

From the codecov bot comment (fetched in Step 1c), extract:
From the `CODECOV` JSON (fetched in Step 1c), extract:
- Files with missing coverage
- Patch coverage percentage
- Specific uncovered lines (linked in the report)

For detailed line-by-line coverage, use the Codecov API:

```bash
# Get file-level coverage for the PR
gh api repos/$REPO/issues/$PR/comments | python3 -c "
import sys,json,re
for c in json.load(sys.stdin):
if c['user']['login'] == 'codecov[bot]':
for m in re.findall(r'filepath=([^&\"]+)', c['body']):
print(m)
"
```
- Specific uncovered files referenced in `filepaths`

Then read the source files and identify which new/changed lines lack test coverage.

Expand Down
111 changes: 62 additions & 49 deletions .claude/skills/issue-to-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,55 +18,59 @@ For Codex, open this `SKILL.md` directly and treat the slash-command forms above

```
Receive issue number [+ --execute flag]
-> Fetch issue with gh
-> Verify Good label (from check-issue)
-> If not Good: STOP
-> If Good: research references, write plan, create PR
-> Fetch structured issue preflight report
-> Verify Good label and rule-model guards
-> If guards fail: STOP
-> If guards pass: research references, write plan, create or resume PR
-> If --execute: run plan via subagent-driven-development, then review-implementation
```

## Steps

### 1. Parse Input

Extract issue number and flags from arguments:
Extract issue number, repo, and flags from arguments:
- `123` -> issue #123, plan only
- `123 --execute` -> issue #123, plan + execute
- `https://github.com/owner/repo/issues/123` -> issue #123
- `owner/repo#123` -> issue #123 in owner/repo

### 2. Fetch Issue
Normalize to:
- `ISSUE=<number>`
- `REPO=<owner/repo>` (default `CodingThrust/problem-reductions`)
- `EXECUTE=true|false`

### 2. Fetch Issue + Preflight Guards

```bash
gh issue view <number> --json title,body,labels,assignees,comments
ISSUE_JSON=$(python3 scripts/pipeline_checks.py issue-context \
--repo "$REPO" \
--issue "$ISSUE" \
--format json)
```

Present issue summary to user. **Also review all comments** — contributors and maintainers may have posted clarifications, corrections, additional context, or design decisions that refine or override parts of the original issue body. Incorporate relevant comment content when writing the plan.
Treat `ISSUE_JSON` as the source of truth for the deterministic preflight data:
- `title`, `body`, `labels`, and `comments` provide the issue summary and comment thread
- `kind`, `source_problem`, and `target_problem` provide parsed issue metadata
- `checks.good_label`, `checks.source_model`, and `checks.target_model` provide guard outcomes
- `existing_prs`, `resume_pr`, and `action` tell you whether to resume an open PR instead of creating a new one

Present the issue summary to the user. **Also review all comments** — contributors and maintainers may have posted clarifications, corrections, additional context, or design decisions that refine or override parts of the original issue body. Incorporate relevant comment content when writing the plan.

### 3. Verify Issue Has Passed check-issue

The issue must have already passed the `check-issue` quality gate (Stage 1 validation). Do NOT re-validate the issue here.

**Gate condition:** The issue must have the `Good` label (added by `check-issue` when all checks pass).

```bash
LABELS=$(gh issue view <number> --json labels --jq '[.labels[].name] | join(",")')
```

- If `Good` is NOT in the labels → **STOP**: "Issue #N has not passed check-issue. Please run `/check-issue <N>` first."
- If `Good` is present → continue to step 4.
Use `ISSUE_JSON.checks.good_label`:
- If it is `fail` → **STOP**: "Issue #N has not passed check-issue. Please run `/check-issue <N>` first."
- If it is `pass` → continue.

### 3.5. Model-Existence Guard (for `[Rule]` issues only)

For `[Rule]` issues, parse the source and target problem names from the title (e.g., `[Rule] BinPacking to ILP` → source=BinPacking, target=ILP). Verify that **both** models already exist in the codebase on `main`:
For `[Rule]` issues, `ISSUE_JSON` already includes `source_problem`, `target_problem`, and the deterministic model-existence checks.

```bash
grep -r "struct SourceName" src/models/
grep -r "struct TargetName" src/models/
```

- If **both** models exist → continue to step 4.
- If either model is missing → **STOP**. Comment on the issue: "Blocked: model `<name>` does not exist in main yet. Please implement it first (or file a `[Model]` issue)."
- If both `checks.source_model` and `checks.target_model` are `pass` → continue to step 4.
- If either is `fail` → **STOP**. Comment on the issue: "Blocked: model `<name>` does not exist in main yet. Please implement it first (or file a `[Model]` issue)."

**One item per PR:** Do NOT implement a missing model as part of a `[Rule]` PR. Each PR should contain exactly one model or one rule, never both. This avoids bloated PRs and repeated implementation when the model is needed by multiple rules.

Expand Down Expand Up @@ -106,26 +110,23 @@ Include the concrete details from the issue (problem definition, reduction algor

### 6. Create PR (or Resume Existing)

**Check for existing PR first:**
```bash
EXISTING_PR=$(gh pr list --search "Fixes #<number>" --state open --json number,headRefName --jq '.[0].number // empty')
```
Use the `ISSUE_JSON.action` and `ISSUE_JSON.resume_pr` fields from Step 2.

**If a PR already exists** (`EXISTING_PR` is non-empty):
- Switch to its branch: `git checkout <headRefName>`
- Capture `PR=$EXISTING_PR`
**If an open PR already exists** (`action == "resume-pr"`):
- Switch to its branch: `git checkout <resume_pr.head_ref_name>`
- Capture `PR=<resume_pr.number>`
- Skip plan creation — jump directly to Step 7 (execute)

**If no existing PR** — create one with only the plan file:

**Pre-flight checks** (before creating the branch):
1. Verify clean working tree: `git status --porcelain` must be empty. If not, STOP and ask user to stash or commit.
2. Check if branch already exists: `git rev-parse --verify issue-<number>-<slug> 2>/dev/null`. If it exists, switch to it with `git checkout` (no `-b`) instead of creating a new one.
**If no open PR exists** (`action == "create-pr"`) — create one with only the plan file:

```bash
# Create branch (from main)
git checkout main
git rev-parse --verify issue-<number>-<slug> 2>/dev/null && git checkout issue-<number>-<slug> || git checkout -b issue-<number>-<slug>
# Prepare or reuse the issue branch (this enforces a clean working tree)
BRANCH_JSON=$(python3 scripts/pipeline_worktree.py prepare-issue-branch \
--issue <number> \
--slug <slug> \
--base main \
--format json)
BRANCH=$(printf '%s\n' "$BRANCH_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['branch'])")

# Stage the plan file
git add docs/plans/<plan-file>.md
Expand All @@ -134,17 +135,27 @@ git add docs/plans/<plan-file>.md
git commit -m "Add plan for #<number>: <title>"

# Push
git push -u origin issue-<number>-<slug>
git push -u origin "$BRANCH"

# Create PR
gh pr create --title "Fix #<number>: <title>" --body "
# Create PR body
PR_BODY_FILE=$(mktemp)
cat > "$PR_BODY_FILE" <<'EOF'
## Summary
<Brief description>

Fixes #<number>"
Fixes #<number>
EOF

# Capture PR number
PR=$(gh pr view --json number --jq .number)
# Create PR and capture the created PR number
PR_JSON=$(python3 scripts/pipeline_pr.py create \
--repo "$REPO" \
--title "Fix #<number>: <title>" \
--body-file "$PR_BODY_FILE" \
--base main \
--head "$BRANCH" \
--format json)
PR=$(printf '%s\n' "$PR_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin)['pr_number'])")
rm -f "$PR_BODY_FILE"
```

### 7. Execute Plan (only with `--execute`)
Expand Down Expand Up @@ -194,7 +205,8 @@ Post an implementation summary comment on the PR **before** pushing. This commen
- Note any open questions or trade-offs made

```bash
gh pr comment $PR --body "$(cat <<'EOF'
COMMENT_FILE=$(mktemp)
cat > "$COMMENT_FILE" <<'EOF'
## Implementation Summary

### Changes
Expand All @@ -206,7 +218,8 @@ gh pr comment $PR --body "$(cat <<'EOF'
### Open Questions
- [any trade-offs or items needing review — or "None"]
EOF
)"
python3 scripts/pipeline_pr.py comment --repo "$REPO" --pr "$PR" --body-file "$COMMENT_FILE"
rm -f "$COMMENT_FILE"

git push
make copilot-review
Expand Down Expand Up @@ -261,7 +274,7 @@ Run /review-pipeline to process Copilot comments, fix CI, and run agentic tests.
| Generic plan | Use specifics from the issue, mapped to add-model/add-rule steps |
| Skipping CLI registration in plan | add-model still requires alias/create/example-db planning, but not manual CLI dispatch-table edits |
| Not verifying facts from issue | Use WebSearch/WebFetch to cross-check claims |
| Branch already exists on retry | Check with `git rev-parse --verify` before `git checkout -b` |
| Dirty working tree | Verify `git status --porcelain` is empty before branching |
| Branch already exists on retry | Use `pipeline_worktree.py prepare-issue-branch` — it will reuse the existing branch instead of failing on `git checkout -b` |
| Dirty working tree | Use `pipeline_worktree.py prepare-issue-branch` — it stops before branching if the worktree is dirty |
| Bundling model + rule in one PR | Each PR must contain exactly one model or one rule — STOP and block if model is missing (Step 3.5) |
| Plan files left in PR | Delete plan files before final push (Step 7c) |
Loading
Loading