| name | pr-review-update |
| description | Review dashboard PRs needing your response and generate high-confidence update proposals for PRs where maintainers are waiting |
PR Review & Update Skill
Review PRs from the improveit-dashboard where upstream authors have requested changes (listed in "Needs Your Response"), analyze the feedback to determine if updates can be made with high confidence (≥90%), and generate clear actionable instructions for review and submission.
For codespell PRs requiring rebase, the skill will automatically attempt the rebase and clean up history to maintain a tight, clean commit structure.
Configuration
This skill uses the following values. Adjust for your setup by editing this section:
- DASHBOARD_DIR:
~/proj/improveit-dashboard — path to improveit-dashboard checkout
- REPOS_DIR:
~/proj/misc — path where PR repos are cloned
- GITHUB_USER:
yarikoptic — your GitHub username
- FORK_REMOTE:
gh-yarikoptic — git remote name for your fork
Throughout this document, these names refer to the configured values above.
User Arguments
The user may provide optional arguments:
--repo <pattern>: Filter by repository name (e.g., --repo duckdb)
--pr <number>: Analyze specific PR number
--min-confidence <0-100>: Override default 90% confidence threshold (default: 90)
--limit <N>: Limit to top N PRs by waiting time (default: 10)
--show-all: Show all awaiting PRs, not just top N
--auto-rebase: Automatically perform rebase for high-confidence PRs (default: true for codespell PRs)
Prerequisites
- Dashboard data at
$DASHBOARD_DIR/data/repositories.json
- User's README at
$DASHBOARD_DIR/READMEs/$GITHUB_USER.md
- Repos typically cloned in
$REPOS_DIR/ with PR branch checked out
- GitHub CLI (
gh) authenticated for fetching additional PR details if needed
Execution Steps
1. Load Dashboard Data
Read the pre-collected PR data from $DASHBOARD_DIR/data/repositories.json.
Filter for PRs where:
author == "$GITHUB_USER"
response_status == "awaiting_submitter" (maintainer has responded, waiting for you)
status == "open" (not merged or closed)
Apply any user-provided filters from arguments.
2. Prioritize PRs
Sort filtered PRs by:
- Primary: Days waiting (longest first) - from
days_awaiting_submitter
- Secondary: CI status (failing > pending > passing) - address broken CI first
- Tertiary: Has conflicts (conflicts=true > conflicts=false)
Extract key metadata for each PR:
- Repository full name (e.g.,
readthedocs/readthedocs.org)
- PR number and URL
- Title
- Last developer comment body (the feedback to address)
- CI status:
ci_status field
- Conflicts:
has_conflicts field
- Days waiting:
days_awaiting_submitter
- Tool type:
tool field (codespell, shellcheck, other)
3. Analyze Feedback for Each PR
For each prioritized PR, examine last_developer_comment_body to categorize the request:
Actionable Categories:
-
Merge Conflicts (has_conflicts: true)
- Request: Resolve conflicts with main branch
- Confidence: 95% (rebase is well-defined)
- Action:
git fetch upstream && git rebase upstream/main
-
CI Failures (ci_status: "failing")
- Request: Fix failing tests or checks
- Confidence: Depends on failure type
- Action: Read CI logs, fix issues, push update
-
Code Review Feedback
- Specific file/line changes: 90-100% confidence
- Typo fixes: 100% confidence
- Configuration tweaks: 85-95% confidence
- Architectural changes: <70% confidence (usually needs manual review)
-
Questions/Clarifications
- Request: Answer reviewer questions
- Confidence: 100% (just needs response, not code)
- Action: Comment on PR with answer
-
Approval Pending Action (e.g., "looks good", "yes, please")
- Request: Merge approval pending minor action (rebase, squash, etc.)
- Confidence: 95%
- Action: Perform requested action and notify
Non-Actionable (Skip or Manual Review):
- Vague feedback ("needs improvement")
- Design disagreements
- Requests for major refactoring
- Awaiting third-party decision
4. Repository Availability Check
For each actionable PR, check if repo exists locally:
ls -d $REPOS_DIR/<repo-name>/.git 2>/dev/null
Extract repo name from repository field (e.g., readthedocs/readthedocs.org → readthedocs.org).
If repo exists:
- Get current branch:
git -C $REPOS_DIR/<repo-name> branch --show-current
- Check if it matches expected PR branch (infer from PR metadata or common pattern like
enh-codespell)
- Verify clean working tree:
git -C $REPOS_DIR/<repo-name> status --porcelain
If repo missing:
- Extract clone URL from PR data or construct from repository full_name
- Typically user's fork:
https://github.com/$GITHUB_USER/<repo-name>
- Generate clone command
5. Confidence Assessment
Assign confidence score (0-100%) based on feedback analysis:
100% Confidence:
- Merge conflict resolution (standard rebase workflow)
- Answering questions (no code change)
- Typo fixes in specific files mentioned
- Rebase/squash requests with approval
90-95% Confidence:
- CI failures with clear error messages (linting, formatting)
- Configuration file updates (e.g., add ignore patterns)
- Minor code changes with specific file/line references
- Updating PR branch to target (e.g.,
develop instead of main)
80-89% Confidence:
- CI failures requiring code fixes (test failures)
- Refactoring specific functions with examples
- Documentation improvements with clear guidance
<80% Confidence (Manual Review):
- Architectural changes
- Performance optimization requests
- Security concerns
- Design disagreements
- Vague feedback
Exclude from proposals (<90% unless --min-confidence lowered):
- Anything requiring user judgment on approach
- Breaking changes
- Multi-step complex changes
6. Automated Rebase for Codespell PRs
For codespell PRs (tool == "codespell") that need rebasing, perform the following automated workflow to maintain clean history:
Goal: End with a clean codespell state, no conflicts, and tight commit history.
6.1. Identify Codespell Commits
Before rebasing, identify commits in the PR branch:
cd $REPOS_DIR/<repo-name>
git log --oneline origin/<base-branch>..HEAD
Look for:
- Config commit: Adds
.codespellrc or similar config
- Workflow commit: Adds/modifies
.github/workflows/ files
- Automated typo fix commit: Usually contains "DATALAD RUNCMD" or "codespell -w" or similar automated fix message
- Manual/ambiguous fix commit: Fixes to ambiguous typos or manual corrections
6.2. Save Current State
Create a backup tag before any operations:
git tag backup-before-rebase-$(date +%Y%m%d-%H%M%S)
This allows recovery via git reflog and git reset --hard backup-before-rebase-<timestamp> if needed.
6.3. Rebase Strategy: Clean Rebase Path
Attempt 1: Direct rebase
git fetch origin
git rebase origin/<base-branch>
If rebase succeeds cleanly:
- Proceed to 6.4 (Clean up workflow file)
If rebase has conflicts:
Follow this conflict resolution strategy prioritizing clean history:
-
Abort current rebase
git rebase --abort
-
Drop automated typo fix commit first
git rebase -i origin/<base-branch>
-
Retry rebase
git rebase origin/<base-branch>
-
If still conflicts:
- Abort again:
git rebase --abort
- Also drop manual/ambiguous fix commit if present
- Retry rebase with only config + workflow commits
- Last resort: Start fresh by cherry-picking only config + workflow commits onto latest main
-
If rebase succeeds after dropping commits:
- Proceed to 6.4 to clean up workflow file
6.4. Clean Up Workflow File
After successful rebase, check if the workflow file includes the redundant codespell-problem-matcher@v1 step and remove it if present.
Background: The actions-codespell@v2 action internally includes the problem matcher functionality, so the explicit codespell-project/codespell-problem-matcher@v1 step is redundant.
Process:
-
Check if workflow file has the problem-matcher step:
cd $REPOS_DIR/<repo-name>
workflow_file=$(find .github/workflows -name "*codespell*" -o -name "*spell*" | head -1)
if [ -n "$workflow_file" ]; then
if grep -q "codespell-project/codespell-problem-matcher" "$workflow_file"; then
echo "Found redundant problem-matcher step in $workflow_file"
else
echo "No problem-matcher step found, skipping cleanup"
fi
fi
-
Remove the problem-matcher step if found:
Use Edit tool to remove the entire step block:
BEFORE:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Annotate locations with typos
uses: codespell-project/codespell-problem-matcher@v1
- name: Codespell
uses: codespell-project/actions-codespell@v2
AFTER:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Codespell
uses: codespell-project/actions-codespell@v2
-
Amend the workflow commit:
Find the commit that added the workflow file and amend it:
workflow_commit=$(git log --oneline --diff-filter=A -- "$workflow_file" | head -1 | awk '{print $1}')
if git log --oneline origin/<base-branch>..HEAD | grep -q "$workflow_commit"; then
git add "$workflow_file"
git rebase -i origin/<base-branch>
git commit --amend --no-edit
git rebase --continue
else
git add "$workflow_file"
git commit -m "Remove redundant codespell-problem-matcher step
The actions-codespell@v2 action internally includes the problem matcher,
so the explicit codespell-project/codespell-problem-matcher@v1 step is redundant.
Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com"
fi
4. **Alternative: If workflow commit is first commit in PR:**
Simpler approach when workflow was added in this PR:
```bash
# Stage the cleaned workflow file
git add .github/workflows/codespell.yml
# Amend the first commit (assuming it's the workflow commit)
# Use git rebase -i to identify which commit added the workflow
git log --oneline --reverse origin/<base-branch>..HEAD
# If it's the first commit after base:
git rebase -i origin/<base-branch>
# Mark the workflow commit as 'edit', then:
git commit --amend --no-edit
git rebase --continue
- Proceed to 6.5 (Re-run codespell)
6.5. Re-run Codespell After Clean Rebase
After successful rebase, check for typos and apply fixes BEFORE reporting to user:
Step 1: Check what ambiguous typos were already fixed in original branch
Before rebase, the original branch may have already fixed ambiguous typos. Check the original typo fix commit:
cd $REPOS_DIR/<repo-name>
git log backup-before-rebase-<timestamp> --oneline --grep="codespell" --grep="DATALAD RUNCMD" | head -5
git show <original-typo-fix-commit-hash> | grep -E "^[-+]" | grep -v "^[-+][-+][-+]" | head -100
Identify ambiguous typo fixes from original commit:
- Lines with multiple similar words changed (e.g.,
trough → through)
- Context-dependent fixes that codespell -w wouldn't auto-fix
- Save these for reference when fixing ambiguous typos after rebase
Step 2: Run codespell to identify all typos:
cd $REPOS_DIR/<repo-name>
uvx codespell . 2>&1 | tee codespell-output.txt
Analyze output:
- Non-ambiguous typos: Lines with
==> and single suggestion (codespell -w will fix these)
- Ambiguous typos: Lines with
==> and multiple suggestions (need manual/AI review)
- Count:
grep -c "^.*:" codespell-output.txt
Step 3: Extract ambiguous typos for AI review:
grep "," codespell-output.txt > ambiguous-typos.txt
grep -v "," codespell-output.txt | grep "==>" > simple-typos.txt
6.5b. Fix Ambiguous Typos First (AI-Assisted)
CRITICAL: Fix ambiguous typos BEFORE running codespell -w for non-ambiguous ones.
For each ambiguous typo from ambiguous-typos.txt:
-
Read the file and context around the typo (5-10 lines):
-
Analyze context to determine correct fix:
Common ambiguous patterns and how to resolve:
-
trough ==> through, trough
- "through" = passing from one side to another, via, by means of
- "trough" = container, low point in a wave
- Read context: is it about passing through something or a physical container?
-
manger ==> manager, manger
- "manager" = person who manages
- "manger" = feeding trough for animals
- Usually "manager" in code/business contexts
-
loner ==> longer, loner
- "longer" = comparative of long
- "loner" = person who prefers to be alone
- Check if comparing lengths or describing behavior
-
ot ==> to, of, or, not, it
- Usually ANSI escape codes or abbreviations in comments
- Check: is it a flag like
-ot, a comment like ot her, or code?
-
te ==> the, be, we, to
- Often template parameter names (
TE, template<typename TE>)
- Check if it's code identifier vs. misspelled article
-
fo ==> of, for, to, do, go
- Often flags like
-fo or variable names
- Check context: is it reversed typing or intentional abbreviation?
-
Decision logic:
Fix if:
- Context clearly indicates correct spelling (e.g., "passing trough the data" → "through")
- It's in a comment or documentation (not code identifiers)
- The fix doesn't change meaning or break code
- Previous commit in original branch fixed the same typo the same way
Skip (add to ignore-words-list) if:
- It's a code identifier (variable, function, class name)
- It's a template parameter (TE, TT, etc.)
- It's a domain-specific term intentionally spelled that way
- It's in a third-party library or vendored code
- Multiple occurrences with different intended meanings
- Changing it would break external API compatibility
-
Apply fixes using Edit tool:
-
Track decisions:
Create a list of:
- Fixed: "file:line: old → new (reason)"
- Skipped: "file:line: word (reason - add to ignore-words-list)"
-
Update .codespellrc with skipped words:
If multiple ambiguous typos are legitimate (not errors), add to config:
-
Commit ambiguous fixes separately (if substantial):
git add -u
git commit -m "Fix ambiguous typos requiring context review
Fixed based on context analysis:
- file1:line: trough → through (passing through data)
- file2:line: manger → manager (person managing resources)
Skipped (added to ignore-words-list):
6.6. Regenerate Non-Ambiguous Typo Fixes Using datalad run
Apply non-ambiguous typo fixes using datalad run for reproducibility, then REVIEW BEFORE reporting to user:
IMPORTANT: Use datalad run to wrap codespell -w for auditable, reproducible commits.
Note: datalad run works on plain git repositories - no need to initialize as datalad dataset.
CRITICAL POST-FIX REVIEW: After codespell -w runs, review fixes in context to catch false positives.
-
Check if datalad is available:
datalad --version 2>/dev/null || echo "Need to use uvx"
-
Apply automated fixes using datalad run:
Option A: If datalad is installed:
cd $REPOS_DIR/<repo-name>
datalad run -m "Fix typos found by codespell
Automated fixes applied by codespell -w after rebase onto main.
Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com" 'codespell -w'
**Option B: If datalad not installed (use uvx):**
```bash
cd $REPOS_DIR/<repo-name>
uvx --from datalad datalad run -m "Fix typos found by codespell
Automated fixes applied by codespell -w after rebase onto main.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>" 'uvx codespell -w'
Option C: Interactive mode (if ambiguous typos remain):
datalad run -m "Fix typos interactively with codespell" 'codespell -w -i 3 -C 4'
uvx --from datalad datalad run -m "Fix typos interactively with codespell" 'uvx codespell -w -i 3 -C 4'
The -i 3 flag enables interactive mode, -C 4 shows 4 context lines.
Option D: If using extracted patch (when codespell unavailable):
git add -u
git commit -m "Fix typos found by codespell
Typo fixes extracted from original commit and re-applied after rebase.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>"
-
Why use datalad run?
- Reproducibility: Command is recorded in git commit metadata
- Re-runnable: Can re-execute with
datalad rerun
- Auditable: Clear record of what tool made changes
- Standard practice: Follows introduce-codespell skill workflow
-
Review changes after commit:
git show HEAD --stat
git log --oneline -1
-
Handle ambiguous typos if needed (manual review before datalad run)
- If
codespell -w skipped ambiguous typos, fix them manually first
- Review ambiguous cases using Read tool to understand context
- Use Edit tool to apply correct fixes
- Commit manually, then run datalad run for remaining typos
- Or use interactive mode:
codespell -w -i 3
6.7. CRITICAL: Review Fixes Made by codespell -w
After running datalad run with codespell -w, ALWAYS review the changes in context.
Codespell can make incorrect "fixes" that break code or change meaning:
Common False Positive Patterns:
-
API/Function naming patterns - suffix letters that look like typos:
allocatedp → allocated (WRONG: "p" suffix for pointer variant)
deallocatedp → deallocated (WRONG: same pattern)
widthIn → within (WRONG: parameter name)
readByte → readable (WRONG: method name)
-
Variable naming conventions:
errorOccured → errorOccurred (might be OK, but check usage)
hasHappend → hasHappened (might be OK, but check consistency)
-
Test data or intentional misspellings:
- Test cases that verify error handling
- Sample data with intentional typos
Review Process:
-
Check the diff of the datalad run commit:
git show HEAD --stat
git show HEAD -- path/to/changed/file.c
-
For each changed file, verify:
- Is this in vendored/third-party code? → Should skip entire directory
- Is this a naming pattern (suffix/prefix)? → Add to ignore-words-list
- Does changing it break the code? → Revert and add to ignore-words-list
- Is it used consistently throughout codebase? → Search for other uses
-
Search for related patterns:
git grep -i "allocatedp\|deallocatedp\|somethingp"
git diff HEAD -- . | grep "^-.*allocatedp"
-
Revert incorrect fixes and update config:
Option A: Revert specific lines and add to ignore-words-list
git reset --soft HEAD~1
git checkout HEAD -- path/to/file/with/bad/fix.c
datalad run -m "Fix typos with codespell" 'codespell -w'
Option B: Use inline pragma for specific lines
When a word is only wrong in specific contexts (correct elsewhere), use inline pragma:
{NAME("allocatedp"), CTL(thread_allocatedp)},
{NAME("allocatedp"), CTL(thread_allocatedp)},
IMPORTANT: Use // codespell:ignore without specifying the word.
- ✅ Correct:
// codespell:ignore
- ❌ Wrong:
// codespell:ignore allocatedp (codespell 2.4.1+ doesn't parse word-specific pragmas)
This tells codespell to ignore all words on that line.
-
Common scenarios requiring revert + config update:
- Naming patterns in APIs:
allocatedp, pread, pwrite
- Protocol/spec keywords: Intentional spellings from external specs
- Legacy compatibility: Old API names that can't change
- Foreign language words: Especially in test data or i18n
-
Update .codespellrc after finding false positives:
ignore-words-list = ans,inout,allocatedp,deallocatedp
skip = .git*,./extension/vendored_lib/*
-
Recommit after fixing:
git add .codespellrc
git add -u
datalad run -m "Fix typos with codespell (excluding false positives)" 'codespell -w'
Signs of False Positives to Watch For:
- Changes in vendored/third-party code (jemalloc, tpch, tpcds, etc.)
- Changes to identifiers that match across multiple files consistently
- Changes that affect struct field names, function names, enum values
- Changes in test data or fixture files
- Changes that add/remove characters from what looks like abbreviations
When in Doubt:
- Search codebase for the term before/after the change
- Check if it's used in multiple places with same spelling
- Look at surrounding code patterns (e.g.,
allocated and allocatedp both exist)
- If pattern is intentional, add to ignore-words-list rather than fixing
6.7b. Analyze Identifier Changes (Don't Blindly Revert)
IMPORTANT: Not all identifier changes are false positives. Some identifiers DO contain typos that should be fixed.
Codespell can change identifiers (function names, variables, struct fields). These require analysis to determine:
- Is this fixing an actual typo in the identifier? → Keep the fix
- Is this changing a correct identifier that looks like a typo? → Revert
- Is this part of a public API/interface? → Extra caution
- Would fixing it conflict with existing code? → Check for name collisions
Detection: Find identifier changes in the diff
cd $REPOS_DIR/<repo-name>
git show HEAD | grep -E "^[-+].*\b[a-zA-Z_][a-zA-Z0-9_]*\s*\(" | head -30
git show HEAD | grep -E "^[-+].*(\.|->)[a-z][a-zA-Z0-9_]*" | head -30
git show HEAD | grep -E "^[-+].*\b(auto|const|static|int|bool|string)\s+(&|\*)?\s*[a-z][a-zA-Z0-9_]*\s*(=|;)" | head -30
Analysis Process for Each Identifier Change:
-
Read the context (at least 10 lines before/after):
git show HEAD -- path/to/file.cpp | grep -B10 -A10 "changed_identifier"
-
Ask: Is the original spelling actually wrong?
-
✅ YES, it's a typo → Keep the fix:
IsAvailble → IsAvailable (missing 'a')
varaible → variable (transposed letters)
funciton → function (typo in name)
-
❌ NO, it's intentional → Revert:
HasTable → hashtable (valid method name, not a typo)
larg → large (convention: larg/rarg = left/right argument)
pres → press (abbreviation for "present" or "result")
allocatedp → allocated (API naming: 'p' suffix for pointer variant)
-
Check if it's part of an interface/API:
git grep -n "class.*HasTable\|DUCKDB_API.*HasTable"
git show HEAD -- "*.h" "*.hpp" | grep "HasTable"
-
Check for consistent usage across codebase:
git grep -c "HasTable" | grep -v ":0$"
-
Check for paired patterns (strong signal of intentionality):
git show HEAD | grep -E "larg|rarg"
-
Check for name collisions after fix:
git grep -n "hashtable" | head -20
-
SPECIAL CASE: Intentional typos in tests:
git show HEAD --stat | grep "test/"
git show HEAD -- test/api/test_pending_query.cpp | grep -B5 -A5 "changed_word"
Tests may have intentional typos to verify error handling:
- Testing error messages that include the typo
- Testing that system detects/reports the typo
- Testing compatibility with legacy misspelled identifiers
If typo is intentional in test:
test_error_message("errorOccured");
test_error_message("errorOccurred");
test_error_message("errorOccured");
Use inline pragma // codespell:ignore for intentional typos in tests.
Decision Matrix:
| Original | Changed To | Used >5× | Paired Pattern | Part of API | In Test | Decision |
|---|
HasTable | hashtable | Yes | No | Yes (method) | No | REVERT - Valid method name |
larg | large | Yes | Yes (with rarg) | Yes (struct field) | No | REVERT - Intentional pairing |
pres | press | Yes | No | No (local var) | No | REVERT - Valid abbreviation |
errorOccured | errorOccurred | No | No | No | Yes (test string) | REVERT + PRAGMA - Intentional test typo |
IsAvailble | IsAvailable | No | No | Yes (method) | No | KEEP - Actual typo in method |
varaible | variable | No | No | No | No | KEEP - Actual typo in variable |
Action on False Positives (Intentional Identifiers):
git reset --soft HEAD~1
echo "ignore-words-list = ans,inout,larg,rarg,pres" >> .codespellrc
test_error("errorOccured"); // codespell:ignore
git add .codespellrc test/
datalad run -m "Fix typos with codespell (reverted false positives)" 'codespell -w'
Action on Actual Identifier Typos:
git grep -n "IsAvailable" | head -50
git grep -n "IsAvailable" -- "test/*" "tests/*"
Key Principle:
Analyze first, then decide. Don't blindly revert all identifier changes or blindly accept them all.
The goal is correctness: fix actual typos (even in identifiers), but preserve intentional naming.
6.7b-ii. Special Case: Paired Function Parameters
Function parameters often use single-letter prefixes for parallel data structures. This is especially common in:
- Merge functions:
a[]/b[] arrays with acount/bcount, aidx/bidx
- Comparison functions: parallel indices, pointers, values
- Parallel processing:
aptr/bptr, aval/bval, asize/bsize
Common Paired Patterns:
[a-z]count / [a-z]count - array counts (a/b/c prefix)
[a-z]idx / [a-z]idx - array indices
[a-z]ptr / [a-z]ptr - pointers
[a-z]val / [a-z]val - values
[a-z]size / [a-z]size - sizes
[a-z]arg / [a-z]arg - arguments (e.g., larg/rarg)
Why This Matters:
Codespell may "fix" one side of a pair but not the other, creating asymmetric naming that breaks the intentional pattern:
void MergeLoop(row_t a[], row_t b[], idx_t acount, idx_t bcount) {
idx_t aidx = 0, bidx = 0;
while (aidx < acount && bidx < bcount) {
}
}
void MergeLoop(row_t a[], row_t b[], idx_t account, idx_t bcount) {
idx_t aidx = 0, bidx = 0;
while (aidx < account && bidx < bcount) {
}
}
The asymmetry (account vs bcount) is the key signal of a false positive.
Detection Strategy:
cd $REPOS_DIR/<repo-name>
git show HEAD | grep -E "^[-+].*\b[a-z](count|idx|ptr|val|size|arg)\b" | head -30
file_path=$(git show HEAD --name-only | grep "\.cpp\|\.hpp\|\.c\|\.h" | head -1)
git show HEAD -- "$file_path" | grep -E "\b[a-z](count|idx|ptr|val|size|arg)\b" | head -30
Detection: Asymmetric Changes (One Side Changed, Other Unchanged)
This is the most reliable signal of a false positive in paired variables:
git show HEAD | grep -E "^\+.*\b(account|aindex|apointer)" | while read -r line; do
changed=$(echo "$line" | grep -oE "\b(account|aindex|apointer|avalue|asize)\b" | head -1)
if git show HEAD | grep -qE "\bbcount\b|\bbidx\b|\bbptr\b|\bbval\b|\bbsize\b"; then
echo "⚠️ ASYMMETRIC CHANGE DETECTED: $changed exists with paired b* variable"
echo " This is likely a false positive - check the context"
fi
done
Warning Signs:
- Function with parameters
a[] and b[] (parallel arrays)
- Variables like
acount, aidx alongside bcount, bidx
- Merge/comparison logic (while loops comparing indices)
- Only ONE side changed (asymmetric change)
Decision Logic:
| Changed | Paired With | Pattern | Decision |
|---|
acount → account | bcount exists | Parallel arrays | REVERT - Intentional pairing |
aidx → index | bidx exists | Parallel indices | REVERT - Intentional pairing |
aptr → after | bptr exists | Parallel pointers | REVERT - Intentional pairing |
larg → large | rarg exists | Struct fields | REVERT - Intentional pairing (see 6.7b) |
errcount → errorcount | No pair | Single variable | KEEP - Actual typo fix (if appropriate) |
acount → account | No bcount found | Single variable | ANALYZE - May be legitimate fix |
Action on Paired Variable False Positives:
echo "ignore-words-list = ...,acount" >> .codespellrc
git add .codespellrc
datalad run -m "Fix typos with codespell (excluded paired patterns)" 'codespell -w'
Example False Positive Analysis:
cd $REPOS_DIR/duckdb
git show HEAD -- src/storage/table/update_segment.cpp | grep -B10 -A10 "account"
Validation After Fix:
After reverting paired variable false positives and adding to ignore list:
git diff HEAD -- src/storage/table/update_segment.cpp | grep -E "acount|bcount"
codespell
Key Insight:
Asymmetric changes in paired variables are almost always false positives.
If codespell changes acount → account but leaves bcount unchanged,
this breaks an intentional naming pattern and should be reverted.
The heuristic: Look for lone changes in paired contexts.
6.7c. Detect Test Data False Positives (Duplicate String Literals)
CRITICAL: Codespell can create duplicate test data by "fixing" intentional variations in test strings.
Test files often use intentionally similar strings to test comparison, sorting, or prefix handling:
"hello" vs "hellow" - testing suffix differences
"torororororo" vs "torororororp" - testing character-by-character comparison
When codespell "fixes" these, it creates duplicate test data that breaks the test.
Detection: Find duplicate string literals created by codespell
cd $REPOS_DIR/<repo-name>
git show HEAD --stat | grep "test.*\.\(cpp\|py\|jl\)$" > /tmp/test-files-changed.txt
while read -r line; do
file=$(echo "$line" | awk '{print $1}')
if [ -f "$file" ]; then
echo "=== Checking $file for duplicate strings ==="
git show HEAD -- "$file" | grep -E '^\+.*"[^"]{3,}"' | \
sed 's/.*"\([^"]*\)".*/\1/' | sort | uniq -c | \
awk '$1 > 1 {print " DUPLICATE: \"" $2 "\" appears " $1 " times"}'
fi
done < /tmp/test-files-changed.txt
Specific Check for test_art_keys.cpp Pattern:
git show HEAD -- test/sql/index/test_art_keys.cpp | \
grep -A 20 "keys.push_back.*CreateARTKey" | \
grep '^\+.*".*"' | sed 's/.*"\([^"]*\)".*/\1/' | sort | uniq -c | \
awk '$1 > 1'
Analysis Process for Test Data:
-
Check if string appears in both old and new versions:
git show HEAD^:test/sql/index/test_art_keys.cpp | grep -o '"hello\w*"' | sort | uniq
-
Look for patterns indicating intentional variation:
- Strings differing by one character:
"hello" vs "hellow"
- Strings with repeated patterns:
"torororororo" vs "torororororp"
- Sequences with incremental changes:
"abc", "abcd", "abcde"
-
Check test purpose:
git show HEAD:test/sql/index/test_art_keys.cpp | grep -B5 "hellow" | head -20
Action on Test Data False Positives:
git show HEAD^:test/sql/index/test_art_keys.cpp > /tmp/original.cpp
cp /tmp/original.cpp test/sql/index/test_art_keys.cpp
keys.push_back(ARTKey::CreateARTKey<const char *>(arena_allocator, "hellow")); // codespell:ignore
git add test/sql/index/test_art_keys.cpp
echo "# hellow: intentional test data variation" >> .codespellrc
echo "ignore-words-list = ...,hellow" >> .codespellrc
Decision Matrix for Test Strings:
| Context | Pattern | Duplicate After Fix? | Decision |
|---|
| Test array with "hello", "hellow" | Suffix variation | Yes - both "hello" now | REVERT + PRAGMA |
| Test array with "torororororo", "torororororp" | Char difference | No - left as is | KEEP |
| Error message string with typo | Prose/message | No duplicates | KEEP (if testing error text) or FIX (if not) |
| Test expecting "SELCT" to fail | SQL syntax error | N/A - has pragma | REVERT + PRAGMA |
Warning Signs of Test Data False Positives:
- ✋ Duplicate strings in test arrays after codespell
- ✋ Test file changes near
push_back, append, add with string literals
- ✋ Strings that differ by 1-2 characters in original (prefix/suffix testing)
- ✋ Test names containing "comparison", "sort", "prefix", "key"
Key Principle:
Test data variations are often intentional. If codespell creates duplicates in test arrays, it's likely wrong.
Always check if the "typo" was actually testing something specific (error handling, comparison, etc.).
6.8. Verify Clean State
Before reporting to user, verify:
-
No codespell errors
codespell .
echo "Exit code: $?"
-
No merge conflicts
git status
-
Clean history
git log --oneline origin/<base-branch>..HEAD
Should show: Config → Workflow → Typo fixes (regenerated, if any)
6.9. Report Status - DO NOT PUSH
CRITICAL: NEVER push automatically without explicit user confirmation.
After completing rebase and typo fixes:
-
Report current state:
echo "=== Branch Status ==="
git log --oneline origin/<base-branch>..HEAD
git status
-
Verify codespell clean state:
codespell . || echo "Codespell check complete"
-
Provide push command for user to execute:
echo "Ready to push. User should run:"
echo "cd $REPOS_DIR/<repo-name>"
echo "git push --force-with-lease <remote-name> <branch-name>"
For user's fork:
- Remote is typically
$FORK_REMOTE or origin (check git remote -v)
- Branch name from PR metadata (e.g.,
enh-codespell)
- User must review and approve before pushing
7. Generate Actionable Proposals
For PRs meeting confidence threshold (≥90%), generate detailed action plans with this structure:
High-Confidence Updates (≥90%)
For each PR:
. <repo-owner/repo-name> # ( days waiting) [⚠️ CONFLICTS] [⚠️ CI FAILING]
Title:
Confidence: %
Repo Location: $REPOS_DIR/ [or NEEDS SETUP if missing]
Branch:
Maintainer Feedback
Required Actions
-
<Action 1> ()
-
<Action 2>
- Details and guidance
- File locations if relevant
Pre-flight Checks
8. Repository Setup Instructions
For PRs where repos don't exist locally, provide a dedicated section:
Repository Setup Needed
Before working on these PRs, clone and configure the following repos:
<repo-owner/repo-name>
cd $REPOS_DIR
git clone https://github.com/$GITHUB_USER/<repo-name>
cd <repo-name>
git remote add upstream https://github.com/<owner>/<repo-name>
git fetch --all
gh pr view <PR-number> --repo <owner/repo-name> --json headRefName
git checkout <branch-name>
9. Manual Review Required
For PRs below confidence threshold, provide:
Needs Manual Review (<90% confidence or complex)
<repo-owner/repo-name> # ( days waiting) [flags]
Title:
Confidence: % ()
Issue:
Maintainer Feedback
Why Manual Review
Recommended Action
-
-
10. Summary Report
Generate executive summary at the top of output:
Summary
Total PRs Awaiting Your Response:
Analyzed: (top priority by wait time or as filtered)
High-Confidence Updates: (≥90%)
Manual Review Required: (<90%)
Repository Setup Needed:
Priority Actions (by impact)
- ( PRs) -
- ( PRs) -
Next Steps
- Review high-confidence proposals above
- Set up missing repositories (section 7)
- Work through PRs in priority order
- For manual review items, assess individually
PR Status Table
CRITICAL: Always generate a status table at the end of the report.
After preparing PRs, generate a comprehensive status table showing:
- Repository name and PR number (with URL)
- Local path to the repository
- Push status (checking if local is ahead of remote)
- Notes about the PR state
Table Format:
## 🆕 Newly Prepared PRs (This Batch)
| Repository | PR | Local Path | Push Status | Notes |
|------------|----|-----------| ------------|-------|
| <owner/repo> | [#<num>](<url>) | `<path>` | 🔄 **READY TO PUSH** | <details> |
## 📦 Previously Prepared PRs (If Any)
| Repository | PR | Local Path | Push Status | Notes |
|------------|----|-----------| ------------|-------|
| <owner/repo> | [#<num>](<url>) | `<path>` | ✅ **PUSHED** / 🔄 **READY TO PUSH** | <details> |
## 🚀 Push Commands
```bash
# NEW: <repo-name>
cd <path>
git push --force-with-lease <remote> <branch>
**Push Status Detection:**
For each prepared PR, check push status by comparing local and remote hashes:
```bash
cd $REPOS_DIR/<repo-name>
git fetch <remote> <branch> 2>/dev/null
local_hash=$(git rev-parse <branch> 2>/dev/null)
remote_hash=$(git rev-parse <remote>/<branch> 2>/dev/null)
if [ "$local_hash" = "$remote_hash" ]; then
echo "✅ **PUSHED** - Already synced"
else
echo "🔄 **READY TO PUSH** - Local ahead of remote"
fi
Status Icons:
- ✅ PUSHED - Local and remote are in sync (already pushed)
- 🔄 READY TO PUSH - Local is ahead of remote (needs push)
- ❌ NOT FOUND - Repository doesn't exist locally
Remote Name:
- Default remote for user's fork:
$FORK_REMOTE
- Fallback:
origin
- Check with:
git remote -v
Example Output:
## 🆕 Newly Prepared PRs (This Batch)
| Repository | PR | Local Path | Push Status | Notes |
|------------|----|-----------| ------------|-------|
| duckdb/duckdb | [#19817](https://github.com/duckdb/duckdb/pull/19817) | `$REPOS_DIR/duckdb` | 🔄 **READY TO PUSH** | Rebased, fixed typos |
| foo/bar | [#123](https://github.com/foo/bar/pull/123) | `$REPOS_DIR/bar` | 🔄 **READY TO PUSH** | Removed problem-matcher |
## 📦 Previously Prepared PRs (Awaiting Push)
| Repository | PR | Local Path | Push Status | Notes |
|------------|----|-----------| ------------|-------|
| old/repo | [#456](https://github.com/old/repo/pull/456) | `$REPOS_DIR/repo` | ✅ **PUSHED** | Already synced |
## 🚀 Push Commands
```bash
# NEW: duckdb
cd $REPOS_DIR/duckdb
git push --force-with-lease $FORK_REMOTE enh-codespell
# NEW: bar
cd $REPOS_DIR/bar
git push --force-with-lease $FORK_REMOTE enh-codespell
**Benefits of Status Table:**
1. **At-a-glance status** - User immediately sees what's ready vs already pushed
2. **Prevents duplicate pushes** - Clear indication of what's already synced
3. **Copy-paste commands** - Ready-to-use push commands for unpushed PRs
4. **Tracking across sessions** - Shows PRs from previous sessions still awaiting push
5. **Full context** - URLs, paths, and notes in one place
## Operating Principles
### Data-Driven
- **Trust dashboard data**: Use existing `repositories.json` as source of truth
- **Leverage metadata**: CI status, conflicts, waiting days already calculated
- **No redundant API calls**: Only fetch additional data if explicitly needed
- **Respect rate limits**: Minimize GitHub API usage
### Focus on "Needs Your Response"
- **Primary target**: PRs with `response_status == "awaiting_submitter"`
- **Prioritize by wait time**: Address longest-waiting PRs first
- **CI failures first**: Broken CI blocks merge, fix it
- **Conflicts block merge**: Rebase PRs with conflicts
### Conservative Confidence
- **Default ≥90%**: Only propose changes you're highly confident about
- **Transparent scoring**: Explain why confidence is high or low
- **User override**: Allow `--min-confidence` to adjust threshold
- **Manual review escape**: Always provide option for user judgment
### Actionable Output
- **Concrete commands**: Every proposal includes exact bash commands
- **Pre-flight checks**: Verify repo exists, branch is correct, etc.
- **Copy-paste ready**: Commands should work without modification
- **Grouped by action type**: Conflicts, CI, questions, etc.
### Efficiency
- **Top N by default**: Don't overwhelm with all PRs at once (default: 10)
- **Progressive disclosure**: Summary → high-confidence → manual review → setup
- **Batch similar actions**: Group all rebases, all CI fixes, etc.
- **Repo reuse**: If repo is already set up, skip setup steps
## Review Body Formatting (when composing a PR review/comment body)
When this skill is used to write a review body to be posted via
`gh pr review --body-file` or `gh pr comment --body-file` (and not just
internal action notes), apply the **collapsible-details pattern** so the
review doesn't visually overwhelm the PR page:
- Keep a short **TL;DR** section visible by default (~3–6 bullets at the
top — what's broken, what's missing, severity).
- Wrap each subsequent section (design-doc compliance tables, per-issue
detail, suggested tests, line-by-line minor items, recommendations) in
HTML `<details>` blocks. GitHub renders these collapsed by default.
Template:
```markdown
# PR #NNNN — <topic> review
<one-sentence framing of what was reviewed and against what>
## TL;DR
- <key finding 1>
- <key finding 2>
- <verdict / requested actions>
<details>
<summary>1. Design doc requirements vs. implementation</summary>
<the table or detailed body>
</details>
<details>
<summary>2. Specific issues</summary>
### 2.1 <issue title>
<full detail>
### 2.2 ...
</details>
<details>
<summary>3. Recommendations (priority order)</summary>
1. ...
2. ...
</details>
Why: GitHub PR review bodies render full markdown but lack any built-in
collapsing. Long reviews push the conversation timeline down by screens and
discourage maintainers from reading. Collapsible <details> keeps the
summary scannable and signals which sections to drill into.
Reference example: a review applying this pattern is at
https://github.com/dandi/dandi-archive/pull/2799#pullrequestreview-4197495045.
When NOT to use: short reviews (<~30 lines), single-issue comments, or
inline review comments on specific lines — collapsing them adds clicks for
no benefit.
Error Handling
- Missing dashboard data: If
repositories.json not found, exit with clear error
- No awaiting PRs: If none found, report success and suggest checking other statuses
- Repo not found: Generate setup instructions, don't fail
- Ambiguous feedback: Mark as manual review rather than guessing
- GitHub CLI not auth: Provide
gh auth login instruction if needed for extra data