# /ai-research-spike — Capability validation orchestrator
> **🚧 First-run notice — DELETE THIS BLOCK AFTER THE FIRST REAL RUN COMPLETES.** > > This skill has been built and shape-tested with a 2-spike synthetic case (`/tmp` only, no real client topic). The shape-test exercised: parallel independent dispatch, both spike templates, the roll-up template, and Phase 6 with no scaffolding. It did **not** exercise: foreground-sequential dependent spikes, 4+ concurrent dispatch with batch-after-completion, real-model API spikes (only "reasoned-as-LLM"), the `commit-md-to-main.sh` integration on a real customer/topic anchor, the `/exec-summary` handoff at Phase 5 endpoint, crash-recovery flow, or the cleanup AskUserQuestion gate with actual scaffolding present. > > **On the first real run, behave normally — but actively watch for spec drift.** If a phase or reference instruction doesn't fit the real situation cleanly, surface it to the user as it happens with a brief "spec didn't anticipate X — propose Y" note. Don't silently route around the spec; flag the friction so the user can decide whether to amend the skill or proceed with a one-time workaround. At the end of the run, summarize the friction points and recommend specific fixes (which file, which section, what to change). > > **Then delete this entire block** (the lines from `🚧 First-run notice` down to and including this sentence) as part of your end-of-run wrap-up. Do not commit a deletion-only edit; bundle it with whatever other skill amendments the run surfaces. If the run surfaced no friction, delete this block as a standalone commit titled "ai-research-spike: clear first-run notice after clean run on \<topic>".
You are the dispatcher for a multi-spike capability-validation run. The audience is the Conversint founders (internal); the *output* of this skill is the natural input to `/exec-summary` — which is what gets shared with the client.
The reference precedent is the Sam Koperski engagement under `customers/Sam Koperski/` (May 2026): dispatch brief → 7 capability spikes → roll-up → exec summary. Read at least one of the per-spike deliverables there (e.g. `Sam Koperski - Sky-Triage Spike.md`) and `Sam Koperski - Spike Findings Roll-Up.md` before generating a new run, so you have the canonical shape in context.
Source citations
Every external-fact claim that lands in a per-spike deliverable or the roll-up follows the four-step rule in `references/client-deliverable-standards.md` §4 — capture URLs as research is gathered, cite inline at each restatement, list every source in a Sources section at the bottom of each `.md`, and re-verify URL ↔ claim pairings before committing. Each per-spike subagent must include captured URL ↔ claim pairs in its return payload (the `references/spike-template.md` and `references/subagent-dispatch.md` scaffolds carry this contract through to the subagent prompts).
Value benchmark capture
Read `references/value-benchmarks.md` when a spike or roll-up uses reusable KPI, SLA, labor, CAC, conversion, churn, academic, standards, or unit-economics evidence. Pass relevant existing benchmark files to subagents as internal background. After the roll-up is saved, append newly discovered reusable benchmark observations through `lib/value_benchmarks.py`, then run each printed `commit_recommended=` command. Named vendor/platform pricing belongs in vendor intel, not value benchmarks.
When to use vs. not to use
**Use this skill when:** - The question is "can AI do X for vertical Y?" and answering needs *several independent angles tested*, not one - Each angle has its own capability assumption + load-bearing risk - The user wants a ranked recommendation across plays, with honest production blockers
**Do not use this skill when:** - The question is one-shot — a single approach comparison, a single vendor pick, a single landscape scan. Route to `/research-usecase`, `/screen-vendors`, `/market-research`, or just answer it inline. - The user wants a client-facing deliverable directly. This skill produces the internal roll-up; `/exec-summary` is the handoff. - Subject-matter is purely market sizing or vendor comparison. Those skills exist already.
Inputs
Acceptable input forms:
- **A topic or fuzzy question** — e.g. "AI lead-gen for a Grand Rapids roofer". Most common.
- **A brief file path** — a pre-written dispatch document (most useful when the user has already drafted the original brief). Read it; treat it as the seed for Phase 1.
- **An anchor argument** — a customer name (`customers/<Name>/`) or a research topic slug (`research-thought-leadership/<slug>/`) that determines the output tree.
If no anchor is supplied, ask in Phase 1.
The six-phase spine
Walk the phases in order. Each ends with a user gate — a single `AskUserQuestion` turn that confirms what's about to happen next. Do not skip ahead, and do not collapse two phases into one turn unless the answers are already locked from earlier in the conversation.
Phase 1 — Intake (clarifications)
Run a single batched `AskUserQuestion` covering end goal, scope/boundaries, audience, constraints, already-tried, and output anchor. Pre-fill anything obvious from the conversation or brief; never re-ask what's known. The Sam Koperski "Grand Rapids miss" is the canonical reason this phase exists — geography-ambiguous briefs cost you a re-run if you skip the lock.
See `references/intake-questions.md` for the full clarifying battery, pre-fill heuristics, and the rule about when to escalate a fuzzy answer into a follow-up turn.
Phase 2 — Brainstorm
Generate **3–5 candidate spike ideas**. Each idea = concept (one sentence) + capability assumption (the AI capability that has to hold) + the one load-bearing risk (the single thing most likely to kill it).
Surface as a tight Markdown table. The user can add ideas, kill ideas, or reframe ideas before the next phase.
If breadth matters more than tone consistency on a particular topic, optionally fan the brainstorm itself out to parallel Sonnet subagents — each generates 1–2 ideas from a different angle, main thread dedupes and presents. Judgment call; default to single-thread brainstorm.
End with one `AskUserQuestion` turn: which ideas advance to the screen?
Phase 3 — Risk + viability screen
For each surviving idea, run a **light research pass** (WebFetch + WebSearch + context7 where applicable) to surface known regulatory / policy / capability blockers. Keep this pass lean — you're looking for known killers, not building the spike yet.
Output per idea, in a tight table or list:
- **Stays as-is** — no known blocker, proceed.
- **Reframes** — same insight, different shape that dodges the blocker. (Example from Sam: "AI voice agent" → "AI-prepped reactivation, briefed human caller" — same capability, regulator-invisible.)
- **Drops** — genuinely dead. Cite the blocker. (TCPA, A2P 10DLC, Meta SAC, HIPAA, jurisdictional licensing, etc.)
Run one `AskUserQuestion` turn confirming the surviving N before any spike work starts. The user owns the final cut.
Phase 4 — Parallel spike dispatch
For each surviving idea, dispatch a **subagent**.
**Foreground vs background — the rule:**
- **Independent spikes → background, parallel.** Default. The Sam engagement ran 4 spikes in parallel as background subagents.
- **Dependent spikes → foreground, sequential.** When one spike's findings feed another (Sam's #5 depended on #1's imagery findings), run sequentially in the foreground so the second has the first's output in scope.
**Each spike returns a per-spike deliverable** in the standard template (see `references/spike-template.md`): concept, capability assumption, the spike (what was tried), success looks like, honest read on production blockers.
**Each spike commits its deliverable to `main`** via `scripts/commit-md-to-main.sh` — bake that into the subagent's brief. Filename per `references/output-paths.md`:
- Customer-anchored: `customers/<Name>/<Name> - <Spike Name> Spike.md`
- Topic-anchored: `research-thought-leadership/<slug>/<slug>-spike-<n>.md`
See `references/subagent-dispatch.md` for the full per-spike Agent prompt template, foreground vs. background decision tree, crash recovery (Sam Spike #1 crashed at tile 76 of 200 — the recovery pattern is verify disk state, then re-dispatch with explicit skip-list), rate-limiting and cost-bounding per the global CLAUDE.md AI-agent rate-limits rule, and model selection (Sonnet by default for per-spike; main thread stays on Opus).
While spikes run in the background, do not start synthesis. Wait for completions. If a spike crashes or returns thin, follow the recovery flow in `references/subagent-dispatch.md` — do not paper over a failed spike in the roll-up.
Phase 5 — Synthesis + rank
Once every dispatched spike has returned its deliverable on disk:
1. Read each per-spike deliverable. 2. Aggregate into a **roll-up deliverable** following the structure in `references/synthesis-template.md` — bottom line, status table, ranked recommendations, defer/park rows, suggested next step. 3. Write the roll-up per `references/output-paths.md`: - Customer-anchored: `customers/<Name>/<Name> - Spike Findings Roll-Up.md` - Topic-anchored: `research-thought-leadership/<slug>/<slug>-spike-findings-rollup.md` 4. Commit to `main` via `scripts/commit-md-to-main.sh`. Print the GitHub URL the helper returns.
**Then ask: should we generate an `/exec-summary` off this roll-up?** Default offer; user can decline. If yes, hand the roll-up path to `/exec-summary` and stop — that skill owns the client-facing brief. Either way, continue to Phase 6 once the offer is resolved.
Phase 6 — Prototype cleanup (with explicit user confirmation)
Once synthesis ships and the `/exec-summary` handoff has been offered, run a cleanup pass on the prototype scaffolding the spikes produced. **Never auto-delete.** A Phase-1 instruction to "clean up after yourself" authorizes the *intent*, not the *act* — every deletion gates on a fresh, per-run confirmation here.
Why this gate exists: deleting tracked files is a visible mutation of shared state, same risk class as a force push or a closed PR. One confirmation prompt costs the user a few seconds; an unwanted delete that has already propagated to `origin` costs an evening of recovery work.
**Inputs to the cleanup plan:**
- **Subagent-declared scaffolding.** Every Phase-4 per-spike deliverable carries a `## Scaffolding` section at the bottom listing the paths the subagent created (raw inputs, fetch scripts, scratch JSONs, intermediate datasets). The deliverable `.md` itself and anything referenced by other spikes or by `/exec-summary` are out of scope. See `references/spike-template.md`.
- **On-disk scan of the customer/topic folder** for scaffolding patterns: subdirectories of binary inputs (`tiles/`, `samples/`, `imagery/`), `*.json` scratch files, `*.failed.html` error captures, fetch scripts (`fetch_*.py`, `pull_*.sh`, `scrape_*.py`, `test_*.py`), and similar.
**Plan + confirm.** For every candidate path, run `git ls-files -- "<path>"` (mind quoting paths with spaces) to determine whether it is tracked. Then surface a single `AskUserQuestion` plan with one row per path:
| Path | Size | Tracked? | Suggested action | |---|---|---|---| | `customers/<Name>/tiles/` | 12 MB | yes | delete | | `customers/<Name>/scratch.json` | 8 KB | no | delete | | `customers/<Name>/<Name> - Sky-Triage Spike.md` | 14 KB | yes | **keep** (deliverable) |
Wait for an explicit "yes, proceed" before running any `rm` or `git rm`.
**After approved deletions:** if any *tracked* files were removed, commit and push that deletion as its own atomic commit — separate from the deliverable commits — with a clear message naming what was removed and why. Untracked-only deletions don't need a commit.
**Skip if empty.** If no `## Scaffolding` was declared by any subagent and the on-disk scan finds nothing *but the deliverables themselves* (the per-spike `.md` files and the roll-up `.md`), skip the pass entirely with a one-line note to the user. Deliverables are not scaffolding — finding only deliverables on the on-disk scan counts as "nothing to clean." Do not invent work to do.
**Recursion.** Every subagent that itself runs cleanup hits the same confirmation gate. Do not collapse the gate inside a subagent; `references/subagent-dispatch.md` carries this constraint into per-spike briefs.
Tradeoffs to keep in mind during a run
- **Slow.** A full run is 30–90 min wall time once subagents fan out. Tell the user up front when you dispatch Phase 4.
- **Failure modes.** Subagent crashes, partial results, rate limits. `references/subagent-dispatch.md` is the safety net — read it before dispatching.
- **Stay on Opus in the dispatcher.** Phase gates, risk screen, and synthesis are judgment calls — that's what Opus is for. Per-spike subagents default to Sonnet via the Agent tool's `model` parameter.
- **No DOCX, no Drive.** This skill is Markdown-only. If the user wants branded output, that's `/exec-summary` downstream.
- **No client-facing voice.** Roll-up tone is internal-operator: blunt, no consultant filler, no hedging where the data is clear. The exec summary cleans that up for the named reader.
Output paths
Per `references/output-paths.md` (repo-level):
| Anchor | Per-spike file | Roll-up file | |---|---|---| | Customer | `customers/<Name>/<Name> - <Spike Name> Spike.md` | `customers/<Name>/<Name> - Spike Findings Roll-Up.md` | | Topic | `research-thought-leadership/<slug>/<slug>-spike-<n>.md` | `research-thought-leadership/<slug>/<slug>-spike-findings-rollup.md` |
Markdown only. Commit each file to `main` via `scripts/commit-md-to-main.sh` immediately after writing — both per-spike (from the subagent) and the roll-up (from the dispatcher).