| name | v1-goldpan |
| description | Use when explicitly mining recent PRs and agent sessions for lessons to document. Triggers on "goldpan" or "mine recent sessions". |
| disable-model-invocation | true |
| allowed-tools | ["Bash","Read","Write","Edit","Grep","Glob","Skill","Agent","ToolSearch","AskUserQuestion"] |
Goldpan
Pan recent merged PRs and agent session logs (Claude Code + Codex + Cursor) for compound-worthy moments worth documenting, present the finds for approval, then drive /ce-compound (lightweight mode) sequentially over the approved set. Discovery is automatic; documentation only happens for items the user approves.
This skill composes two existing primitives — ce-compound (writes solution docs) and compound-engineering's session scripts (cross-platform session reading) — and adds the panning workflow around them. It does not write to docs/solutions/ directly; that is /ce-compound's job.
Quick Start
- Confirm the time window (default
7d).
- Calibration check (Phase 0): if no project signals file exists, prompt to calibrate.
- Launch two scout subagents in parallel — Scout A (merged PRs) and Scout B+C (sessions across all platforms).
- De-dup candidates against the project's solutions docs.
- Write
.agents/goldpan/session-notes/compound-candidates-<YYYY-MM-DD>.md and present the top candidates inline.
- Ask the user which candidates to queue. For each approved candidate, stage a context bundle and invoke
/ce-compound in lightweight mode sequentially.
The skill never writes directly into docs/solutions/ — /ce-compound owns that path. The skill only invokes /ce-compound after explicit per-candidate approval.
When to Use
Use when the user wants to look back over recent activity and identify what is worth documenting as a durable solution — typically weekly or after a sprint. Compounding requires fresh material: this skill finds the material, /ce-compound writes the doc.
Do not use for:
- Documenting a problem solved in the current session — use
/ce-compound directly.
- Auditing or refreshing existing solution docs — use
/ce-compound-refresh.
- Reviewing PRs for code quality — use
/v1-deep-review.
Inputs
Pass the window as the skill's argument when invoking, e.g. /v1-goldpan 14d. Accepts Nd (days), an explicit since:YYYY-MM-DD, or the literal recalibrate to force a fresh calibration pass before scouting. Default 7d.
If the user does not specify a window, ask once: "Default 7-day window — adjust?". Do not loop.
Configuration
Read these per-project files when present; fall back to defaults otherwise:
| File | Default | Purpose |
|---|
.agents/goldpan-signals.md | absent | Calibrated, project-specific PR signals (verbatim phrases, anti-signals, subsystem priorities, calibration PR set). Generated by Phase 0 calibration. |
docs/solutions/ | this path | Where solution docs live. Symlinks accepted. Override by reading .agents/goldpan.config.yaml if present (key: solutions_path). |
| Default PR base branch | main | Override via .agents/goldpan.config.yaml (key: pr_base_branch). |
If .agents/goldpan-signals.md is absent the skill still works using only the universal-signal keyword set, but scoring will be weaker until calibration runs.
Workflow
Phase 0: Calibration check
On every invocation:
- Check for
.agents/goldpan-signals.md. If present, skip to Phase 1.
- If absent, present a blocking question to the user:
- Calibrate now (recommended, ~3-5 min) — run the calibration workflow described in references/calibration.md, which dispatches 4 parallel research agents over the project's recent PRs to characterize PR style, identify verbatim signals, and write
.agents/goldpan-signals.md. After calibration completes, proceed to Phase 1.
- Skip — use universal signals only — proceed to Phase 1 with weaker scoring. Note in the final report that the project has no calibrated signals.
- Cancel — abort the goldpan run.
If the user passed recalibrate as the argument, force-run calibration regardless of whether the signals file exists, overwriting it.
The calibration is one-time. Re-run it after major team or codebase changes (new authors, large refactors, framework migrations) by invoking /v1-goldpan recalibrate.
Phase 1: Resolve window and dispatch scouts
- Resolve the window into:
since_date — YYYY-MM-DD (today minus N days)
mtime_days — integer N for find -mtime -N
- Launch the two scouts below in parallel as
general-purpose Agents. Each scout returns a structured text digest (no files written).
The scout prompts must:
- Tell the scout this is for panning
/ce-compound candidates out of recent activity.
- Pass references/scoring.md inline (universal rubric).
- If
.agents/goldpan-signals.md exists, pass it inline too (project-specific evidence).
- Demand the structured candidate format below.
- Cap output (e.g. "up to 12 candidates").
Scout A — Merged PRs
Brief: shortlist compound-worthy merged PRs from the window. Score against references/scoring.md and (if present) the project's .agents/goldpan-signals.md. Do not score on assumed language; only the rubric and the calibrated evidence catalogued in those files.
Tooling:
BASE_BRANCH="main"
gh pr list --state merged --base "$BASE_BRANCH" \
--search "merged:>=<since_date>" \
--json number,title,mergedAt,author,body,files \
--limit 200
gh pr view <number> --json body,commits,files
gh pr diff <number> | head -400
Strongest single tell is in the diff, not the body: any PR that adds an AIDEV-NOTE: (or equivalent project-specific marker noted in the signals file) is almost certainly compound-worthy regardless of body quality.
Calibration: the project signals file's "Calibration PRs" section, if present, lists ~10 known compound-worthy PRs from a prior window. Use them as a sanity check — if your scout's candidate set diverges wildly from that calibration set, your filter is miscalibrated.
Scout B+C — Agent sessions (Claude Code, Codex, Cursor)
Run as one scout, not two. The compound-engineering plugin already owns the cross-platform layout knowledge through its session scripts (discover-sessions.sh, extract-metadata.py, extract-skeleton.py, extract-errors.py); this skill composes them rather than re-implementing JSONL parsing.
Brief: discover agent sessions touched within the window for this project, rank them by compound-signal density via the keyword filter, then deep-dive only the top-ranked sessions. Cross-reference any session whose branch/gitBranch matches a merged-PR head branch from Scout A and treat it as supporting evidence for that PR rather than a separate candidate. Standalone candidates from sessions are rarer; promote only when a session resolves a problem that did NOT result in a PR (e.g. an investigation, a runbook gap, or a convention agreed in chat).
Step 1 — Discover and rank with the bundled wrapper (see scripts/discover-sessions.sh):
bash <skill-path>/scripts/discover-sessions.sh <N>
The wrapper invokes compound-engineering's upstream discover-sessions.sh (Claude + Codex active + Cursor) plus a one-line find over ~/.codex/archived_sessions/ to fill an upstream gap, then pipes everything through the upstream extract-metadata.py with a compound-signal keyword set baked in. It resolves those scripts across compound-engineering's plugin layouts automatically (see Upstream Primitives Used). Output is JSONL — one session per line with match_count and keyword_matches, plus a final _meta line.
The default keyword set is the universal compound signals: AIDEV-NOTE, Root Cause, failure mode, that worked, it's fixed, working now, lgtm, problem solved, ship it, etc. If the project's signals file lists additional verbatim phrases, the scout should append them via the COMPOUND_SIGNAL_KEYWORDS env var.
Step 2 — Triage: drop sessions with match_count: 0; sort by match_count; cap to the top ~20 per platform. For each surviving session, the metadata line gives branch, last_ts, and size — branch matching against Scout A is the cheapest dedup.
Step 3 — Deep-dive only the top sessions, using compound-engineering's extract scripts rather than reading raw JSONL:
find_ce_script() {
local script="$1" rel p
for rel in \
"ce-session-extract/scripts/$script" \
"ce-sessions/scripts/$script" \
"ce-compound/scripts/session-history/$script"; do
[ -n "${CE_SKILLS_DIR:-}" ] && [ -f "$CE_SKILLS_DIR/$rel" ] && { printf '%s\n' "$CE_SKILLS_DIR/$rel"; return 0; }
done
local roots=()
[ -d "$HOME/.codex/plugins/cache" ] && roots+=("$HOME/.codex/plugins/cache")
[ -d "$HOME/.claude/plugins/cache" ] && roots+=("$HOME/.claude/plugins/cache")
[ ${#roots[@]} -eq 0 ] && return 1
p="$(find "${roots[@]}" -type f -name "$script" 2>/dev/null \
| grep -E "/compound-engineering/[^/]+/skills/(ce-session-extract|ce-sessions)/scripts/${script}$|/compound-engineering/[^/]+/skills/ce-compound/scripts/session-history/${script}$" \
| sort -V | tail -n1 || true)"
[ -n "$p" ] && { printf '%s\n' "$p"; return 0; }
return 1
}
SKELETON="$(find_ce_script extract-skeleton.py || true)"
[ -n "$SKELETON" ] || { echo "ERROR: compound-engineering extract-skeleton.py not found (ce-session-extract / ce-sessions / ce-compound layouts)" >&2; exit 1; }
ERRORS="$(find_ce_script extract-errors.py || true)"
cat <session-file> | python3 "$SKELETON" | tail -n 200
[ -n "$ERRORS" ] && cat <session-file> | python3 "$ERRORS"
Skeleton mode strips thinking blocks and tool-result noise and collapses repeat calls — three orders of magnitude smaller than the raw file. Errors mode surfaces the failed approaches that often anchor a "What didn't work" section.
Anti-signals (drop the session candidate):
- Last user turn is a follow-up question or correction (resolution didn't land)
- Session ends mid-tool-use (interrupted)
- Branch already matches a PR Scout A surfaced — fold into that PR's candidate
- Skeleton ends with assistant message containing a
docs/solutions/... path — already documented
Phase 2: Consolidate and de-dup
- Collect each scout's candidate list.
- Merge candidates that describe the same underlying problem (a PR plus the session that produced it count as one candidate — keep both source pointers).
- De-dup against existing solutions: for each candidate, run targeted greps in the project's solutions path:
SOLUTIONS_PATH="docs/solutions"
grep -ril "<keyword>" "$SOLUTIONS_PATH"/ | head -5
If a clear existing match is found, mark the candidate as covered and demote it (keep in the report under a separate "Already documented" section so the user can decide to refresh).
- Score each candidate against the rubric in references/scoring.md — High / Medium / Low.
Phase 3: Write the report
Write to .agents/goldpan/session-notes/compound-candidates-<today>.md using the template in references/report-template.md. Inline in the chat, list only the High candidates with a one-line synopsis and a copy-paste /ce-compound invocation hint, then move directly into Phase 4.
Phase 4: Approval & Queue
After printing the inline summary (High candidates only), get explicit approval before invoking /ce-compound. Then drive the queue sequentially.
4a. Multi-select approval
Use AskUserQuestion with multiSelect: true to present the High candidates plus a "None — stop here" option. Offer Medium candidates only if the user asks. The schema for AskUserQuestion is deferred — call ToolSearch with select:AskUserQuestion first to load it.
If AskUserQuestion is unavailable (non-Claude-Code harness, or call errors), fall back to a numbered chat prompt: "Reply with the comma-separated numbers to queue, or none." Do not silently skip the prompt and do not pre-select any candidates.
4b. Stage one context bundle per approved candidate
For each approved candidate, write .agents/goldpan/session-notes/compound-queue/<YYYY-MM-DD>-<slug>.md containing the synthesized evidence. The bundle is the input that /ce-compound will treat as "the recently solved problem". Format:
# Queued compound candidate: <title>
**Source:** PR #<n> | Claude session `<id>` | Codex session `<id>`
**Track:** bug | knowledge
**Suggested category:** <category>/
**Component:** <service-or-module>
## Problem
<the problem in 2-4 sentences, sourced from PR body / session messages>
## What didn't work
<failed approaches, in bullets — bug track only; omit for knowledge track>
## Solution
<the verified fix, with code snippets pulled directly from the PR diff or session>
## Why this works
<root cause + why this addresses it>
## Evidence
- PR #<n>: <url>
- Claude session: <path>
- Codex session: <path>
- Key commits: <sha-list>
The bundle must be self-contained — /ce-compound should not need to re-derive anything from session logs. Pull diff snippets, error messages, and the verifying-it-worked statement directly from the source.
If the synthesis is thin (the source material lacks a clear problem/solution narrative), abort that candidate, log "skipped: thin evidence" in chat, and continue to the next one. Do not invent details.
4c. Sequential invocation
For each staged bundle, invoke the compound skill via the Skill tool, one at a time:
Skill(skill: "compound-engineering:ce-compound", args: "<title> — see .agents/goldpan/session-notes/compound-queue/<file>")
Before the call, print the bundle contents into chat as plain markdown so /ce-compound's Phase 0/1 sees the problem in recent conversation. When /ce-compound asks Full vs Lightweight, pick Lightweight unless the user explicitly chose Full at approval time. When it asks about session-history search, choose No — this skill already panned the relevant sessions.
Process one candidate fully before starting the next. After each completes, print a one-line status: OK docs/solutions/<category>/<file>.md (or updated). If /ce-compound reports a failure, mark the bundle file with # STATUS: failed — <reason> at the top and continue to the next.
4d. Final summary
After the queue drains, print:
Queue complete. Documented N of M approved candidates.
- OK <path1>
- OK <path2>
- FAIL <path3> (skipped: <reason>)
Bundles retained at .agents/goldpan/session-notes/compound-queue/ — delete after review.
Do not write to docs/solutions/ directly. All documentation goes through /ce-compound.
Candidate Schema (what scouts return)
Every candidate must have:
title: short imperative phrase
source:
- pr: <number>
- session: <session-id>
platform: claude
date: YYYY-MM-DD
track: bug | knowledge
suggested_category: <category>
synopsis: 3-5 sentence summary
why_compound_worthy: one sentence
keywords: [list, for, dedup]
verified: true | false
Reference Files
Upstream Primitives Used
This skill composes (rather than re-implements) primitives from Every's compound-engineering plugin:
ce-compound — writes the actual solution doc. Owns docs/solutions/ and the schema.
- session discovery + metadata — cross-platform session discovery + metadata + keyword ranking via
discover-sessions.sh and extract-metadata.py. Wrapped by scripts/discover-sessions.sh.
- session extraction — single-file skeleton (filtered narrative) or errors mode via
extract-skeleton.py and extract-errors.py. Used directly by Scout B+C deep-dives.
Upstream layout drift: compound-engineering has relocated these scripts across releases — ce-session-inventory / ce-session-extract (legacy) → a single ce-sessions skill (3.13.x) → ce-compound/scripts/session-history/ (3.15.x). The wrapper and the Step-3 snippet resolve each script by basename across all of these layouts (in both the ~/.claude and ~/.codex plugin caches, newest version first), so the skill keeps working as upstream moves them. Set CE_SKILLS_DIR to a compound-engineering skills dir to override resolution.
If those scripts are absent (compound-engineering plugin uninstalled), the wrapper exits with a clear error naming the missing script. Install the compound-engineering plugin rather than re-implementing — see v1tamins README → Recommended companion for install commands.
Anti-Patterns
- Don't read full session transcripts. Use
extract-skeleton.py skeleton mode; never bulk-load JSONL.
- Don't fabricate candidates. If a session has no clear "fix shipped + root cause" signal, skip it.
- Don't write into
docs/solutions/. That's /ce-compound's job — even from Phase 4.
- Don't queue without explicit approval. Phase 4a is gated on a blocking question. No silent auto-approve, no defaulting to "all High".
- Don't queue thin candidates. If the synthesized bundle would be vague or speculative, drop it before invoking
/ce-compound.
- Don't run queued items in parallel.
/ce-compound is sequential by design and the conversation context needs to reset between items.
- Don't include
/ce-compound-style full prose in the candidate report. The synopsis is a pointer; the staged bundle is the evidence.
- Don't skip calibration silently. If signals file is missing, present the choice; don't just degrade quality without telling the user.