$npx -y skills add Borda/AI-Rig --skill retroPost-run retrospective: reads .experiments/ JSONL, computes Wilcoxon significance, detects dead iterations, flags suspicious jumps, generates next-hypothesis queue for --hypothesis flag.
| 1 | <objective> |
| 2 | |
| 3 | Post-run retrospective analysis. After `/research:run` completes, reads `.experiments/state/<run-id>/experiments.jsonl`, computes statistical significance, detects dead iterations, flags suspicious metric jumps, generates learning summary with next-hypothesis queue. |
| 4 | |
| 5 | NOT for: running experiments (use `/research:run`); designing experiments (use `/research:plan`); validating methodology (use `/research:judge`); verifying paper implementation (use `/research:verify`); comparing runs from different programs/goals — `--compare` valid only for same-program, same-metric runs. Read-only — never modifies code, commits, or experiment state. |
| 6 | |
| 7 | </objective> |
| 8 | |
| 9 | <workflow> |
| 10 | |
| 11 | ## Agent Resolution |
| 12 | |
| 13 | **Agent resolution**: load and follow the protocol below. Contains: foundry check + fallback table. `research:scientist` in same plugin — no fallback needed if research plugin installed. |
| 14 | ```bash |
| 15 | _RESEARCH_SHARED=$(python "${CLAUDE_PLUGIN_ROOT:-plugins/cc_research}/bin/resolve_shared.py" 2>/dev/null) # timeout: 5000 |
| 16 | [ -z "$_RESEARCH_SHARED" ] && { echo "! Plugin path resolution failed — ensure research plugin installed and CLAUDE_PLUGIN_ROOT set, or invoke /research:retro from project root."; exit 1; } |
| 17 | cat "$_RESEARCH_SHARED/agent-resolution.md" |
| 18 | ``` |
| 19 | |
| 20 | ## Retro Mode (Steps T1–T7) |
| 21 | |
| 22 | Triggered by `retro`, `retro <run-id>`, or `retro <run-id> --compare <run-id-2>`. |
| 23 | |
| 24 | **Defaults**: `--threshold 0.001`, `--alpha 0.05`. |
| 25 | |
| 26 | **Unsupported flag check**: load and follow the protocol below. Supported flags for this skill: `--compare`, `--threshold`, `--alpha`. |
| 27 | ```bash |
| 28 | # loads: unsupported-flag-protocol.md |
| 29 | _RESEARCH_SHARED=$(python "${CLAUDE_PLUGIN_ROOT:-plugins/cc_research}/bin/resolve_shared.py" 2>/dev/null) # timeout: 5000 |
| 30 | cat "$_RESEARCH_SHARED/unsupported-flag-protocol.md" |
| 31 | ``` |
| 32 | |
| 33 | **Task tracking**: create tasks for T1–T7 at start — before any tool calls. |
| 34 | |
| 35 | ### Step T1: Locate and load run data |
| 36 | |
| 37 | **Input resolution** (priority order): |
| 38 | |
| 39 | 1. Explicit `<run-id>` arg → read `.experiments/state/<run-id>/` |
| 40 | 2. No arg → scan `.experiments/state/`, pick latest dir where `state.json` has `status: completed` or `status: goal-achieved` |
| 41 | 3. None found → stop with error: |
| 42 | ```text |
| 43 | No completed run found. Run /research:run first, or provide: /research:retro <run-id> |
| 44 | ``` |
| 45 | |
| 46 | **Newer-in-progress check** (only when path 2 used — no explicit run-id given): after selecting completed run, scan `.experiments/state/` for any dir with `status: running` and mtime newer than selected dir. If found, surface warning but don't stop — user may intentionally retro prior completed run: |
| 47 | |
| 48 | ```text |
| 49 | ⚠ Newer in-progress run found: <newer-run-id> (status: running, started <ISO timestamp>). Retro will analyse <selected-run-id> instead. Use /research:retro <run-id> to override. |
| 50 | ``` |
| 51 | |
| 52 | **Load files** from `.experiments/state/<run-id>/`: |
| 53 | |
| 54 | - `state.json`: extract `goal`, `best_metric`, `config` (incl. `metric.direction`), `iteration` count, `best_commit`. Compute `baseline_metric` from iteration 0 in `experiments.jsonl`. |
| 55 | - `experiments.jsonl`: full iteration history — validate each line parses as JSON. If last line truncated, warn and **rewrite sanitized copy to `$RUN_DIR/experiments-clean.jsonl`** (skip truncated last line). All downstream steps (T2 retro_analyze.py, T3 dead-iter scan, T5 scientist) must read sanitized copy — never raw file — so every step sees same iteration set. Persist sanitized path: `echo "$RUN_DIR/experiments-clean.jsonl" > "${TMPDIR:-/tmp}/retro-jsonl-path-${CSID}"` (consumers re-hydrate from this file). If JSONL untruncated, sanitized copy byte-identical to raw file. |
| 56 | - `diary.md`: if present, read for qualitative context in T5. |
| 57 | |
| 58 | If `--compare <run-id-2>` present: load second run identically from `.experiments/state/<run-id-2>/`. If not found, stop: `"Compare target not found: .experiments/state/<run-id-2>/. Check run ID and retry."` |
| 59 | |
| 60 | **Assign `RUN_ID_ARG`** from `$ARGUMENTS` — first positional non-flag token, empty if absent (ADV-H17): |
| 61 | |
| 62 | ```bash |
| 63 | export CSID="${CLAUDE_CODE_SESSION_ID:-$PPID}" |
| 64 | _REMAINDER=$(echo "$ARGUMENTS" | sed -E 's/--compare[= ]+[^ ]+//g; s/--threshold[= ]+[^ ]+//g; s/--alpha[= ]+[^ ]+//g') |
| 65 | RUN_ID_ARG=$(echo "$_REMAINDER" | awk '{for (i=1; i<=NF; i++) if ($i !~ /^--/) { print $i; exit }}') |
| 66 | RUN_ID_ARG="${RUN_ID_ARG:-}" |
| 67 | echo "$RUN_ID_ARG" > "${TMPDIR:-/tmp}/retro-run-id-${CSID}" # persist for T3 (vars lost between Bash calls) |
| 68 | ``` |
| 69 | |
| 70 | **Pre-compute run directory** — also fix `$RUN_ID` (resolved from input resolution above), persist `$RUN_DIR` for T3 (ADV-H18 + ADV-L16): |
| 71 | |
| 72 | ```bash |
| 73 | export CSID |