Systematically extract learnings from pull request (GitHub) or merge request (GitLab) history. Processes reviews in batches using parallel subagents, capturing patterns from discussion threads, reviewer feedback, and review metadata.
Writer subagents run in the background and cannot prompt for permissions. Add these allow patterns to project-level .claude/settings.local.json:
-
Detect platform (same as init step 1).
-
Sync with remote — git fetch origin main. If the current branch is behind or diverged from origin/main, tell the operator and suggest creating a fresh branch from origin/main. Multi-session workflows accumulate PRs between sessions — stale branches are the expected case.
-
Read the plan file (docs/plans/$PLAN_FILENAME). If it doesn't exist, tell the operator to run /extract-review-learnings init first.
-
Check progress — find the last completed batch in the progress tracker. Calculate NEXT_PAGE.
-
Glob existing learnings files in all output locations to build EXISTING_CATEGORIES for subagent prompts.
-
Fetch metadata (1 bash call) — use the batch fetch command, substituting BATCH_SIZE and NEXT_PAGE. Store result as BATCH_METADATA. Read BATCH_SIZE from the plan file (default: 10).
!cat ~/.claude/platform-commands/batch-fetch-reviews.sh 2>/dev/null || echo "UNCONFIGURED: run setup-claude.sh to set up platform-commands"
-
Triage and spawn extractor subagents in parallel. Read extractor-prompt.md and use it as a verbatim template — fill in placeholders but do not abbreviate, paraphrase, or add ad-hoc instructions. Every review gets the identical template structure. Research only — no file writes.
Triage into three tiers based on metadata:
- Dedicated extractor (1 MR per agent):
user_notes_count > 10, OR description signals a new module/adapter/integration (keywords: "new module", "new adapter", "integration", "implement", "complete implementation"), OR state is closed with user_notes_count >= 5 (rich "why not" signal)
- Small-group extractor (3-5 MRs per agent):
user_notes_count 2-10, OR zero-discussion but description indicates substantial work (refactors, multi-file fixes, feature additions with filled-in descriptions)
- Skip entirely: Dependency version bumps with empty descriptions, SDK releases with no changes, drafts closed immediately with 0 notes and no commits, reference data additions (asset lists, SQL data inserts)
Key principle: Discussion notes are the easiest signal but not the only one. Implementation patterns in the diff are equally valuable — a 30-file, 0-note MR introducing a new adapter has more signal than a 1-file, 5-note MR where all notes are bot approval + SonarQube. Triage on the work, not just the discussion.
-
Spawn 3 writer subagents in parallel with all extractor outputs concatenated to all. Re-read writer-prompt.md immediately before spawning (use offset+limit for the orchestrator section, lines 1-20) — do not rely on an earlier read. Use it as a verbatim template — fill in placeholders per writer:
- Project writer:
WRITER_SCOPE=project, SCOPE_FILTER=project-specific, READ_PATH=docs/learnings/, WRITE_PATH=docs/learnings/, files from step 5
- General writer:
WRITER_SCOPE=general, SCOPE_FILTER=general, READ_PATH=<defaultWriteTarget provider localPath>, WRITE_PATH=docs/learnings/_staging/general/, files from step 5 (read ~/.claude/learnings-providers.json to find the provider with defaultWriteTarget: true)
- Private writer:
WRITER_SCOPE=private, SCOPE_FILTER=private, READ_PATH=<private provider localPath>, WRITE_PATH=docs/learnings/_staging/private/, files from step 5 (read ~/.claude/learnings-providers.json to find the provider with writeScope: "private")
- DEDUP_GUIDANCE: pull from the plan file's progress tracker notes (recurring pattern mentions). Do not improvise — use what's written.
Each writer independently deduplicates against its own file set.
Create staging directories before spawning:
mkdir -p docs/learnings/_staging/general docs/learnings/_staging/private
-
Finalize staged files — run the finalize script to copy staged files to their final locations and clean up:
bash ~/.claude/commands/extract-request-learnings/finalize-staging.sh .
This script reads ~/.claude/learnings-providers.json to discover provider directories, copies general learnings to all writable providers with writeScope: "global", private learnings to providers with writeScope: "private", handles java/ subdirectories, and removes the staging directory. It's pre-allowed via Bash(bash ~/.claude/commands/**) so it runs without permission prompts.
Do NOT use inline cp commands — the sandbox treats ~/.claude/ as sensitive and will prompt for each file regardless of allow patterns.
-
Verify writes — after finalization, run targeted checks (not full file reads):
GitHub:
wc -l docs/learnings/*.md ~/.claude/learnings*/*.md
grep -c '#FIRST_NUMBER\|#LAST_NUMBER' docs/learnings/*.md
grep -A5 'PR #<LAST_NUMBER>' docs/learnings/*.md | head -6
GitLab:
wc -l docs/learnings/*.md ~/.claude/learnings*/*.md
grep -c '!FIRST_IID\|!LAST_IID' docs/learnings/*.md
grep -A5 'MR !<LAST_IID>' docs/learnings/*.md | head -6
Report any discrepancies before updating progress. Do NOT read full files — use grep for targeted checks only.
-
Update progress tracker — edit the plan file's progress table. Include a brief note on key findings.
-
Report batch summary — 2-3 sentences on signal level, recurring patterns, and new categories. Keep it brief to preserve context.