Research Spike
A spike is a time-boxed investigation whose deliverable is knowledge,
not shipped code. You answer a specific question, surface the trade-offs,
and recommend a path — so the team can plan implementation with confidence
instead of guessing.
Use a spike when the work is uncertain: feasibility is unknown, there are
multiple viable approaches, an unfamiliar API/library is in play, or scope
can't be estimated until something is prototyped. If the path is already
clear and it's just work to be done, skip the spike and go straight to
implementation planning.
Configuration
Reads .rig/config.json:
sourceScope[0] — the default code scope explorers map first
(default: src).
tracker.provider — linear | github | none (default: none).
When none, skip all tracking-ticket steps and deliver the writeup in
chat only. When set, optionally create a Spike: tracking ticket and
post findings back to it.
tracker.team / tracker.project — where a Linear tracking ticket is
filed, when the provider is linear.
agents.architect — the project's name for the canonical architect
role (default: architect). Explore and Plan are Claude Code
built-ins and are used as-is.
style.guideFile — the writing style for the findings writeup
(default: .claude/STYLE.md).
If the file is absent, use the defaults above (treat the tracker as
none) and note you're running unconfigured.
Core rules of a spike
- Time-box it. Decide the budget up front (default: half a day / ~4h
of effort). The goal is enough signal to decide, not a complete build.
- The output is a writeup, not a PR. Any code is throwaway prototype
used to learn — it does not get merged. Mark prototype branches clearly
and don't open a PR-to-trunk from them.
- End with a recommendation and concrete next steps (usually: tickets to
create, or a "don't do this" with the reason).
- Be honest about what you couldn't verify. Lead with the verdict, back
it with evidence, and mark anything you can't support with
file:line (or a
run/probe result) as unverifiable — never pad a recommendation with
confidence you didn't earn.
- Pin the codebase state. Record the commit SHA you investigated against
(
git rev-parse HEAD) plus the date, so the recommendation is reproducible
and its staleness is obvious once the trunk moves on.
Arguments
The user invoked this with: $ARGUMENTS
What to do
If no question was given (empty $ARGUMENTS)
Ask the user for the spike question and, ideally, what decision it unblocks.
A good spike question is specific and answerable ("Can we stream logs over
SSE without exceeding the gateway idle timeout?"), not open-ended ("look
into logging"). Confirm the time-box before starting.
If the user gave a question (or create <QUESTION>)
Frame the spike. Restate it as:
- Question — the one thing this spike answers.
- Decision it unblocks — what the team does differently based on the
answer.
- Time-box — effort budget (default ~4h; confirm with the user).
- Done-when — the specific signal that ends the spike (e.g. "we know
whether approach A is viable and roughly how many tickets it implies").
Optionally create a tracking ticket so the work is visible — only if
tracker.provider is not none. Skip this step entirely when the tracker
is none.
- For
linear: mcp__claude_ai_Linear__save_issue, using
tracker.team and tracker.project from the profile.
- For
github: open a tracking issue with gh issue create.
- title: prefix with
Spike: ("Spike: SSE streaming feasibility")
- state: "Todo" / backlog
- labels: add a
spike/research label if one exists
- description: the Question / Decision / Time-box / Done-when frame above.
- Do this when the spike is non-trivial or others need visibility; skip
for a quick inline investigation.
Investigate. First pin the codebase: capture
git rev-parse HEAD + today's date for the findings header (all
code-grounded claims are "as of" this SHA). Then run research in parallel —
this is fan-out work:
- Spawn
Explore agents to map how the relevant code works today
(start with the default source scope from .rig/config.json
(sourceScope[0]), then any infra/adjacent packages) and find prior art.
- Spawn the
Plan or architect agent (the latter mapped through
agents.architect) to sketch candidate approaches and their trade-offs.
- Force a structured return from each fan-out agent so findings stay
comparable and evidence-backed — e.g.
{ finding, evidence: [{file:line, quote}], confidence: high|med|low }
from explorers, and { approach, buildable: yes|no|with-caveats, files_to_touch, effort: S|M|L, risks } from the planner.
WebFetch / WebSearch for unfamiliar APIs, library docs, or version
constraints — read the docs before guessing semantics (guessing at
API behavior has cost real PRs).
- If a prototype is needed to learn, build the smallest throwaway one.
Keep it on a clearly-named scratch branch; do not open a PR to the
trunk.
Verify the risky assumptions. Don't stop at "this looks possible."
Decompose the recommendation into the discrete claims it depends on (a
timeout holds, an API supports X, a migration is reversible, the current
code does Y), then prove each one — run the probe, hit the endpoint, read
the code. Give every claim an explicit verdict with evidence:
| Claim |
Verdict |
Evidence |
Confidence |
| … |
confirmed / refuted / partially-true / unverifiable |
file:line or probe result |
high/med/low |
Mark anything you genuinely couldn't check as unverifiable rather than
guessing — an honest gap is more useful than a padded verdict, and it
becomes an open question below.
Write the findings. The writeup is the entire deliverable, so it has to
survive a skim by someone who wasn't here. Write it to style.guideFile
(default .claude/STYLE.md) — verdict in the first sentence, one idea per
sentence, every claim anchored to file:line or a run result, no filler and
no jargon. Use these sections:
Header — the question under test, the time-box, and the pinned
codebase state (SHA + date) the claims were checked against.
Question & answer — lead with the verdict (Yes / No / It depends,
and the one-line why).
What was investigated — what you read, ran, and prototyped.
Findings — the per-claim verdict table from step 4 (evidence +
confidence), making explicit what you verified vs. left unverifiable.
Options & trade-offs — a table when there's more than one path:
Recommendation — the path you'd take and why.
Next steps — concrete follow-up tickets (titles + one-liners), or an
explicit "do not pursue, because …".
Open questions — anything still unknown that a later spike or the
implementation would need to resolve.
Proof it before it goes anywhere: run /rig-proof find on the draft and
apply what comes back. The writeup is the deliverable, and it outlives the
spike.
If a tracking ticket was created in step 2, post the writeup back to it
(mcp__claude_ai_Linear__save_comment for Linear, gh issue comment for
GitHub). Surface it in chat regardless.
Hand off. Based on the recommendation, point the user at the right
next step:
- Clear single path → implement a single new ticket.
- Several independent pieces → plan a sprint of independent tickets.
- Interleaved pieces with a shared runtime contract → plan an epic on a
shared integration branch.
- Not worth doing → say so plainly and close the spike ticket.
Do not auto-create the implementation tickets or start coding — a
spike ends at the recommendation. The user decides whether to proceed.
If the user passed a ticket identifier (e.g. ABC-123)
Only applicable when tracker.provider is not none.
- Fetch it (
mcp__claude_ai_Linear__get_issue for Linear, gh issue view
for GitHub) to read the spike's framing.
- Run steps 3–6 above against that ticket, posting the findings back as a
comment and moving it to the appropriate state when done.
1---2name: rig-spike3description: Run a time-boxed research spike to answer an open technical question or de-risk an approach BEFORE committing to implementation. Produces written findings + a recommendation (and optionally a throwaway prototype), not production code. Use when the team needs to evaluate feasibility, compare options, or reduce uncertainty before a feature is planned. Triggers on: 'spike', 'research spike', 'investigate', 'evaluate feasibility', 'de-risk', 'proof of concept', 'POC', 'compare options', 'can we', 'what would it take'.4---56# Research Spike78A spike is a **time-boxed investigation** whose deliverable is *knowledge*,9not shipped code. You answer a specific question, surface the trade-offs,10and recommend a path — so the team can plan implementation with confidence11instead of guessing.1213Use a spike when the work is *uncertain*: feasibility is unknown, there are14multiple viable approaches, an unfamiliar API/library is in play, or scope15can't be estimated until something is prototyped. If the path is already16clear and it's just work to be done, skip the spike and go straight to17implementation planning.1819## Configuration2021Reads `.rig/config.json`:2223- `sourceScope[0]` — the default code scope explorers map first24 (default: `src`).25- `tracker.provider` — `linear` | `github` | `none` (default: `none`).26 When `none`, skip all tracking-ticket steps and deliver the writeup in27 chat only. When set, optionally create a `Spike:` tracking ticket and28 post findings back to it.29- `tracker.team` / `tracker.project` — where a Linear tracking ticket is30 filed, when the provider is `linear`.31- `agents.architect` — the project's name for the canonical `architect`32 role (default: `architect`). `Explore` and `Plan` are Claude Code33 built-ins and are used as-is.34- `style.guideFile` — the writing style for the findings writeup35 (default: `.claude/STYLE.md`).3637If the file is absent, use the defaults above (treat the tracker as38`none`) and note you're running unconfigured.3940**Core rules of a spike**4142- **Time-box it.** Decide the budget up front (default: half a day / ~4h43 of effort). The goal is *enough* signal to decide, not a complete build.44- **The output is a writeup, not a PR.** Any code is throwaway prototype45 used to learn — it does not get merged. Mark prototype branches clearly46 and don't open a PR-to-trunk from them.47- **End with a recommendation and concrete next steps** (usually: tickets to48 create, or a "don't do this" with the reason).49- **Be honest about what you couldn't verify.** Lead with the verdict, back50 it with evidence, and mark anything you can't support with `file:line` (or a51 run/probe result) as `unverifiable` — never pad a recommendation with52 confidence you didn't earn.53- **Pin the codebase state.** Record the commit SHA you investigated against54 (`git rev-parse HEAD`) plus the date, so the recommendation is reproducible55 and its staleness is obvious once the trunk moves on.5657## Arguments5859The user invoked this with: $ARGUMENTS6061## What to do6263### If no question was given (empty `$ARGUMENTS`)6465Ask the user for the spike question and, ideally, what decision it unblocks.66A good spike question is specific and answerable ("Can we stream logs over67SSE without exceeding the gateway idle timeout?"), not open-ended ("look68into logging"). Confirm the time-box before starting.6970### If the user gave a question (or `create <QUESTION>`)71721. **Frame the spike.** Restate it as:73 - **Question** — the one thing this spike answers.74 - **Decision it unblocks** — what the team does differently based on the75 answer.76 - **Time-box** — effort budget (default ~4h; confirm with the user).77 - **Done-when** — the specific signal that ends the spike (e.g. "we know78 whether approach A is viable and roughly how many tickets it implies").79802. **Optionally create a tracking ticket** so the work is visible — only if81 `tracker.provider` is not `none`. Skip this step entirely when the tracker82 is `none`.83 - For `linear`: `mcp__claude_ai_Linear__save_issue`, using84 `tracker.team` and `tracker.project` from the profile.85 - For `github`: open a tracking issue with `gh issue create`.86 - title: prefix with `Spike:` ("Spike: SSE streaming feasibility")87 - state: "Todo" / backlog88 - labels: add a `spike`/`research` label if one exists89 - description: the Question / Decision / Time-box / Done-when frame above.90 - Do this when the spike is non-trivial or others need visibility; skip91 for a quick inline investigation.92933. **Investigate.** First pin the codebase: capture94 `git rev-parse HEAD` + today's date for the findings header (all95 code-grounded claims are "as of" this SHA). Then run research in parallel —96 this is fan-out work:97 - Spawn `Explore` agents to map how the relevant code works today98 (start with the default source scope from `.rig/config.json`99 (`sourceScope[0]`), then any infra/adjacent packages) and find prior art.100 - Spawn the `Plan` or `architect` agent (the latter mapped through101 `agents.architect`) to sketch candidate approaches and their trade-offs.102 - Force a **structured return** from each fan-out agent so findings stay103 comparable and evidence-backed — e.g.104 `{ finding, evidence: [{file:line, quote}], confidence: high|med|low }`105 from explorers, and `{ approach, buildable: yes|no|with-caveats,106 files_to_touch, effort: S|M|L, risks }` from the planner.107 - `WebFetch` / `WebSearch` for unfamiliar APIs, library docs, or version108 constraints — **read the docs before guessing semantics** (guessing at109 API behavior has cost real PRs).110 - If a prototype is needed to learn, build the *smallest* throwaway one.111 Keep it on a clearly-named scratch branch; do **not** open a PR to the112 trunk.1131144. **Verify the risky assumptions.** Don't stop at "this looks possible."115 Decompose the recommendation into the discrete claims it depends on (a116 timeout holds, an API supports X, a migration is reversible, the current117 code does Y), then prove each one — run the probe, hit the endpoint, read118 the code. Give every claim an explicit verdict with evidence:119120 | Claim | Verdict | Evidence | Confidence |121 |-------|---------|----------|------------|122 | … | confirmed / refuted / partially-true / **unverifiable** | `file:line` or probe result | high/med/low |123124 Mark anything you genuinely couldn't check as `unverifiable` rather than125 guessing — an honest gap is more useful than a padded verdict, and it126 becomes an open question below.1271285. **Write the findings.** The writeup is the entire deliverable, so it has to129 survive a skim by someone who wasn't here. Write it to `style.guideFile`130 (default `.claude/STYLE.md`) — verdict in the first sentence, one idea per131 sentence, every claim anchored to `file:line` or a run result, no filler and132 no jargon. Use these sections:133134 - **Header** — the question under test, the time-box, and the pinned135 codebase state (`SHA` + date) the claims were checked against.136 - **Question & answer** — lead with the verdict (Yes / No / It depends,137 and the one-line why).138 - **What was investigated** — what you read, ran, and prototyped.139 - **Findings** — the per-claim verdict table from step 4 (evidence +140 confidence), making explicit what you verified vs. left `unverifiable`.141 - **Options & trade-offs** — a table when there's more than one path:142143 | Option | Effort | Risk | Notes |144 |--------|--------|------|-------|145146 - **Recommendation** — the path you'd take and why.147 - **Next steps** — concrete follow-up tickets (titles + one-liners), or an148 explicit "do not pursue, because …".149 - **Open questions** — anything still unknown that a later spike or the150 implementation would need to resolve.151152 Proof it before it goes anywhere: run `/rig-proof find` on the draft and153 apply what comes back. The writeup is the deliverable, and it outlives the154 spike.155156 If a tracking ticket was created in step 2, post the writeup back to it157 (`mcp__claude_ai_Linear__save_comment` for Linear, `gh issue comment` for158 GitHub). Surface it in chat regardless.1591606. **Hand off.** Based on the recommendation, point the user at the right161 next step:162 - Clear single path → implement a single new ticket.163 - Several independent pieces → plan a sprint of independent tickets.164 - Interleaved pieces with a shared runtime contract → plan an epic on a165 shared integration branch.166 - Not worth doing → say so plainly and close the spike ticket.167168 Do **not** auto-create the implementation tickets or start coding — a169 spike ends at the recommendation. The user decides whether to proceed.170171### If the user passed a ticket identifier (e.g. ABC-123)172173Only applicable when `tracker.provider` is not `none`.1741751. Fetch it (`mcp__claude_ai_Linear__get_issue` for Linear, `gh issue view`176 for GitHub) to read the spike's framing.1772. Run steps 3–6 above against that ticket, posting the findings back as a178 comment and moving it to the appropriate state when done.