exploration · diff
git:20260719.b8f3ce1 to git:20260719.03668ce
1 added, 1 removed. Audit A to A.
---
name: exploration
description: |
Two-mode exploration skill: (1) design dialogue — turn rough ideas into validated
designs through collaborative interview before planning; (2) spike — throwaway
code answering ONE design question, deleted or absorbed, never shipped.
Router invokes mode via dispatch context.
allowed-tools: Read Grep Glob AskUserQuestion Write Edit Bash
user-invocable: false
---
# Exploration (Design + Spike)
Two modes, selected by router dispatch context: `design` (brainstorm a design) or `spike` (throwaway prototype). DESIGN includes an optional inline sub-procedure, the Doubt Pass, for high-stakes decisions — it is not a third mode.
## Mode: DESIGN
Turn rough ideas into validated designs through collaborative dialogue. Understand what to build BEFORE designing how to build it. Use the user's domain language — don't invent new terminology when the repo or prompt already has a stable name.
### Scope Triage (Front of Flow)
Before opening the interview, decide whether this is ONE design or MANY. A request spanning multiple independent subsystems produces a sprawling, unfocused design.
**Multi-subsystem trigger:** 2+ pieces that could be built, tested, and shipped independently — different surfaces, data stores, deploy targets, or pieces joined only by "and."
If multi-subsystem: emit a decomposition recommendation (independent pieces, relationships, build order), then brainstorm ONLY the first sub-project. The router carries the rest forward.
### Synthesize-Now Fast Path
If goal + constraints + acceptance are ALL already evident from the prompt or context: skip the interview, draft the design directly, present for confirmation in ONE pass. Still record rejected alternatives (ADR notes). On correction, fix the named gap — don't restart the full interview.
**Gate:** take the fast path ONLY when all three are stated, not inferred. When in doubt, interview.
### Interview (when fast path gate fails)
Cover these 5 dimensions, but only ask about dimensions that are still unresolved. Skip a question when the answer is already explicit — write the inferred answer, mention the assumption, continue.
1. **Purpose** — what problem does this solve?
2. **Users** — who will use this?
3. **Success** — how will we know it works?
4. **Constraints** — limitations, requirements, out-of-scope
5. **Scope** — single module, single file, full feature, cross-cutting
Always ask: "What is explicitly NOT part of this?" (out-of-scope discovery).
- One question at a time. Multiple choice preferred. Present 2-3 approaches with trade-offs before asking which to pursue. YAGNI ruthlessly — defer what is not essential.
+ One question at a time — asking several questions at once is bewildering. Multiple choice preferred. If a fact can be found by exploring the environment (filesystem, tools), look it up rather than asking; the decisions are the user's. Present 2-3 approaches with trade-offs before asking which to pursue. YAGNI ruthlessly — defer what is not essential.
**Intent Completeness Gate** (before proceeding to design): (1) small enough to fit in one paragraph, (2) contradiction-free, (3) sufficiently specific that a builder could act without clarifying questions. If any fails, ask one more targeted question.
### Domain Glossary + ADR Notes
Accrete domain vocabulary as the interview names terms. Record load-bearing rejected alternatives as ADR notes. Both are emitted in the handoff so the planner inherits the project's language and the rationale for rejected directions.
**Challenge domain terms — don't just accrete, challenge.**
- **Contradiction with CONTEXT.md:** when a term the user uses conflicts with the existing glossary, surface it immediately ("your glossary defines cancellation as X, but you seem to mean Y — which is it?"). Domain-shaping contradictions (contracts/persistence/user-language) stop for human input; low-blast-radius ones proceed with a recorded assumption.
- **Contradiction with code:** when the user states how something works, check whether the code agrees. If not, surface it: "your code cancels entire Orders, but you just said partial cancellation is possible — which is right?"
- **Vague/overloaded terms:** propose a precise canonical term ("you're saying account — do you mean the Customer or the User? those are different things").
- **Update CONTEXT.md inline** as terms resolve (append-only glossary entries). Use the format in `cc10x:domain-modeling/CONTEXT-FORMAT.md`. Create the file lazily if it doesn't exist.
- **Offer an ADR** only when all three are true: hard to reverse, surprising without context, and the result of a real trade-off. Use `cc10x:domain-modeling/ADR-FORMAT.md`; write to `docs/adr/`.
Exploration in DESIGN mode is a designated CONTEXT.md writer (alongside planner and doc-syncer).
### Design Output
Save to `docs/plans/YYYY-MM-DD-<feature>-design.md` (use `-design.md` suffix, not `-plan.md`, to prevent collision with planner output).
Template: Purpose, Users, Success Criteria, Constraints, Out of Scope, Approach Chosen, Domain Glossary (if any), Decisions/ADR notes (if any), Architecture, Components, Data Flow, Error Handling, Testing Strategy, Observability (if applicable), UI Mockup (if UI feature), Questions Resolved.
### Design Self-Review Gate (MANDATORY — before handoff)
Scan the design for the 4 failures that corrupt downstream plans. Fix inline — no second review pass.
1. **No placeholders/TBD** — every section holds a real decision, not a stub. If N/A, say so explicitly.
2. **Internally consistent** — components in Architecture all appear in Data Flow; Error Handling covers the chosen Approach's failure modes; Success Criteria don't conflict with Constraints/Out-of-Scope.
3. **Single-plan scope** — one coherent thing a single plan can sequence. If it grew to span multiple subsystems, narrow to the first and record the rest in Out of Scope.
4. **No two-way-ambiguous requirements** — pick ONE interpretation, state it explicitly.
### Design Handoff (MACHINE-READABLE — do NOT edit .cc10x/*.md)
```yaml
### Brainstorming Handoff (MACHINE-READABLE)
DESIGN_FILE: "{PROJECT_DIR}/docs/plans/YYYY-MM-DD-<feature>-design.md"
DESIGN_SUMMARY: "[one-sentence summary]"
MEMORY_NOTES:
glossary:
- term: "[Term]"
meaning: "[precise meaning]"
decisions:
- decision: "[what was chosen]"
rejected: "[alternative not taken]"
why: "[the constraint or trade-off that decided it]"
```
Router carries design forward and persists memory. Do NOT write memory yourself.
### Doubt Pass (DESIGN sub-procedure — inline self-check)
For non-trivial decisions where correctness matters more than speed: subject the decision to an adversarial re-read BEFORE it stands. This is IN-FLIGHT course correction, not post-hoc review.
#### When to Use
- Working in unfamiliar code
- Stakes are high (production, security-sensitive, irreversible operations)
- A confident output would be cheaper to verify now than to debug later
- The decision involves >2 non-trivial trade-offs
#### The 5-Step Cycle
1. **CLAIM** — state the decision as a testable claim in one paragraph: "We will use X because Y"
2. **EXTRACT** — extract the artifacts the claim depends on: the key assumptions, plus concrete evidence (code samples, API signatures, data flows) that support them
3. **DOUBT** — adversarially re-read the extracted artifacts while deliberately setting the CLAIM aside: work from the ARTIFACT + CONTRACT only, and hunt for the weakest assumption, the scenario where the decision backfires.
4. **RECONCILE** — compare the doubt pass's assessment against the original claim. Where they agree → high confidence. Fix the decision, strengthen the assumption, or reject the finding with evidence.
5. **STOP** — escalate to the user when EITHER: (a) a cycle produces substantive findings but zero are classified as actionable (doubt theater, not doubting), or (b) 3 cycles complete without convergence (the 3-cycle cap — don't loop forever).
*Note: DOUBT is an inline self-check, not fresh-context isolation — sub-agent fan-out is router-owned; if genuinely independent review is required, request router-mediated dispatch in the handoff.*
**Rationalization guard:** "This is too simple to doubt" → simple decisions have simple artifacts, so the doubt pass is fast. No excuse to skip.
---
## Mode: SPIKE
A prototype is **throwaway code that answers exactly ONE design question**. It exists to de-risk an unknown cheaply before paying for the full BUILD chain.
### Hard Wall (read before writing any prototype)
A prototype's rules NEVER leak into a BUILD. "No tests, no abstractions, move fast" lives and dies inside the spike. If the answer is "build it for real," that is a **fresh BUILD through the router** with full TDD/reviewer/verifier gates. The spike's code does not become production by surviving.
<!-- scar: 2026-06-17 — spike's "move fast, no tests" code promoted to production by inertia, skipping TDD/verifier gates. The prototype proving a question is NOT the same as the answer being shipped. -->
### Step 1: State the ONE Question
Write it down — one sentence at the top. The prototype exists only to answer it. If you can't name the question in one sentence, you need design mode or a plan, not a spike.
### Step 2: Pick the Branch
**Branch A — LOGIC question** ("does this logic/state model feel right?"):
- Build a tiny interactive harness/TUI that drives the model by hand
- Isolate the salvageable core behind a pure interface (reducer, state machine, pure functions) — no I/O, no terminal code inside it. This is the part that can be lifted later
- No persistence unless persistence IS the question
**Branch B — UI question** ("what should this look like?"):
- Generate 3-5 structurally DIFFERENT variants on an existing route, switchable via `?variant=` URL param
- Variants must differ structurally (layout, hierarchy, primary affordance) — not just color or copy
- Switcher is dev-only: gate on `process.env.NODE_ENV !== 'production'`
- Read-only: point mutations at a stub
### Step 3: Hand It Over
Give the user the one run command (Branch A) or the URL + `?variant=` keys (Branch B). They drive it. The valuable moments are "wait, that shouldn't be possible" (logic bug) and "I want header from B with sidebar from C" (the real design).
### Step 4: Close-Out (MANDATORY)
**4a. Capture the answer** (router-owned — do NOT write memory directly):
```yaml
### Prototype Handoff (MACHINE-READABLE)
PROTOTYPE_QUESTION: "[the one question]"
PROTOTYPE_ANSWER: "[the verdict]"
PROTOTYPE_DISPOSITION: "delete" | "absorb"
ABSORB_TARGET: "[module/route to build for real, or N/A]"
MEMORY_NOTES: "[one-line durable lesson, or N/A]"
```
**4b. DELETE or ABSORB** (no third option):
- **DELETE** — spike answered the question, nothing salvageable. Remove spike code, throwaway route, switcher. Answer survives in memory; code does not.
- **ABSORB** — spike's pure core or winning variant is worth keeping. ABSORB triggers a fresh BUILD (see Hard Wall). Delete the throwaway harness. Set `PROTOTYPE_DISPOSITION: absorb` and name `ABSORB_TARGET` so the router opens the absorbing BUILD.
Emit the verdict and hand back to the router.