Imported from v1-io/v1tamins (
plugins/v1tamins/skills/v1-goldpan/SKILL.md). Install upstream withnpx skills add v1-io/v1tamins --skill v1-goldpan. Copyright stays with the author.
Goldpan
Pan recent merged PRs and agent session logs (Claude Code, Codex, Cursor) for compound-worthy moments. Present the finds for approval. Drive /ce-compound in lightweight mode over the approved set, one at a time. Discovery is automatic; documentation only happens for items the user approves. Never write to docs/solutions/ — /ce-compound owns that path.
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>.mdand present the top candidates inline. - Ask which candidates to queue. For each approved candidate, stage a context bundle and invoke
/ce-compoundin lightweight mode sequentially.
Never write directly into docs/solutions/ — /ce-compound owns that path. Invoke /ce-compound only after explicit per-candidate approval.
When to Use
Look back over recent activity and name what is worth documenting as a durable solution — typically weekly or after a sprint. Compounding needs fresh material: this skill finds it, /ce-compound writes the doc.
Do not use for:
- Documenting a problem solved in the current session — use
/ce-compounddirectly. - 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, 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, run on the universal-signal keyword set. Scoring is 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:
- Calibrate now (recommended, ~3-5 min) — run the calibration workflow in references/calibration.md. It 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.
- Calibrate now (recommended, ~3-5 min) — run the calibration workflow in references/calibration.md. It dispatches 4 parallel research agents over the project's recent PRs to characterize PR style, identify verbatim signals, and write
If the user passed recalibrate as the argument, force-run calibration even if the signals file exists, overwriting it.
Calibration is one-time. Re-run 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 forfind -mtime -N
- Launch the two scouts below in parallel as
general-purposeAgents. Each scout returns a structured text digest (no files written).
The scout prompts must:
- Tell the scout this is for panning
/ce-compoundcandidates out of recent activity. - Pass references/scoring.md inline (universal rubric).
- If
.agents/goldpan-signals.mdexists, 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:
# 1. Pull all merged PRs in window with full bodies + file lists in one call
BASE_BRANCH="main" # override from .agents/goldpan.config.yaml if present
gh pr list --state merged --base "$BASE_BRANCH" \
--search "merged:>=<since_date>" \
--json number,title,mergedAt,author,body,files \
--limit 200
# 2. Drop anti-signals (per scoring.md and project signals file) before any further reads.
# 3. For survivors, pull commits and read the diff:
gh pr view <number> --json body,commits,files
gh pr diff <number> | head -400 # cap diff reads
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. Use compound-engineering's session scripts (discover-sessions.sh, extract-metadata.py, extract-skeleton.py, extract-errors.py) for layout and extraction. Do not parse JSONL yourself.
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:
# Resolve compound-engineering's extract scripts by basename across the layouts
# the plugin has shipped (ce-session-extract legacy, ce-sessions 3.13.x,
# ce-compound/scripts/session-history 3.15.x), newest version first. Honors an
# explicit $CE_SKILLS_DIR (a compound-engineering "skills" dir) override.
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)" # may be absent in some layouts
# Filtered narrative (user/assistant text + collapsed tool calls) — cap to last N lines
cat <session-file> | python3 "$SKELETON" | tail -n 200
# Tool errors only (Claude is_error: true / Codex non-zero exec) — skip if unavailable
[ -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:
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).SOLUTIONS_PATH="docs/solutions" # override from goldpan.config.yaml if present grep -ril "<keyword>" "$SOLUTIONS_PATH"/ | head -5 - 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 # e.g. "Why CacheManager Redis/S3 reads diverge"
source: # one or more
- pr: <number> # OR session: <id> + platform: claude|codex|cursor
- session: <session-id>
platform: claude
date: YYYY-MM-DD
track: bug | knowledge
suggested_category: <category> # from /ce-compound's schema
synopsis: 3-5 sentence summary
why_compound_worthy: one sentence
keywords: [list, for, dedup]
verified: true | false # was the fix actually shipped/verified?
Reference Files
- references/scoring.md — universal compound-worthiness rubric defined against
/ce-compound's schema - references/calibration.md — Phase 0 calibration workflow that generates
.agents/goldpan-signals.md - references/pr-signals-template.md — template the calibration writes to (also a manual-fill option)
- references/sources.md — source catalogue and how scouts use compound-engineering's session scripts
- references/report-template.md — output report template
- scripts/discover-sessions.sh — wraps compound-engineering's session discovery with archived-codex gap fill + pre-baked compound-signal keywords
Upstream Primitives Used
Use these primitives from Every's compound-engineering plugin. Do not re-implement them.
ce-compound— writes the actual solution doc. Ownsdocs/solutions/and the schema.- session discovery + metadata — cross-platform session discovery + metadata + keyword ranking via
discover-sessions.shandextract-metadata.py. Wrapped byscripts/discover-sessions.sh. - session extraction — single-file skeleton (filtered narrative) or errors mode via
extract-skeleton.pyandextract-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 singlece-sessionsskill (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~/.claudeand~/.codexplugin caches, newest version first), so the skill keeps working as upstream moves them. SetCE_SKILLS_DIRto a compound-engineeringskillsdir 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.pyskeleton 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-compoundis 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.