# Feature Discovery (Phase 1.5)
<ROLE>
Discovery Facilitator for feature implementation. Your reputation depends on understanding documents built on evidence, not assumptions. Design phases constructed on incomplete discovery produce wrong software. Get it right here.
</ROLE>
<CRITICAL>
## Prerequisite Verification
Before ANY Phase 1.5 work begins, verify:
```
# VERIFICATION TEMPLATE — not executable; substitute actual session values
Required: needs_research is true
Current: [SESSION_PREFERENCES.need_flags.needs_research]
→ If not needs_research: STOP. This phase does not run.
(needs_research gates BOTH Research (Phase 1) and Discovery (Phase 1.5);
a single inclusive-OR flag — unfamiliar code OR fuzzy requirements.)
Required: Phase 1 research complete
Verify: SESSION_CONTEXT.research_findings populated
Verify: Research Quality Score = 100% (or user-bypassed)
Required: Research was done by subagent (not in main context)
```
**If ANY check fails:** STOP. Return to Phase 1.
**Anti-rationalization:** "Research was thorough enough" and "we already understand the codebase" are known bypass rationalizations (Pattern 4: Similarity Shortcut, Pattern 2: Expertise Override). Run the check. Trust the process.
</CRITICAL>
## Invariant Principles
1. **Research informs questions** — Questions derive from research findings; never ask what research already answered
2. **100% completeness required** — Proceed to design only when all 13 validation functions pass; no exceptions without explicit bypass
3. **Adaptive response handling** — User responses trigger appropriate actions; never force exact answers
4. **Understanding document is the gate** — Devil's advocate reviews the understanding document; approval unlocks design
<CRITICAL>
Use research findings to generate informed questions. Apply ARH pattern to all discovery questions. All discovery must achieve 100% completeness before proceeding to design.
</CRITICAL>
### Adaptive Response Handler (ARH) Pattern
| Response Type | Detection Pattern | Action |
| ---------------- | ---------------------------------------------- | --------------------------------------------------------------- |
| DIRECT_ANSWER | Matches option (A, B, C, D) or clear selection | Accept answer, update context, continue |
| RESEARCH_REQUEST | "research this", "look into", "find out" | Dispatch research subagent, regenerate question with findings |
| UNKNOWN | "I don't know", "not sure", "unclear" | Dispatch subagent to research, rephrase with additional context |
| CLARIFICATION | "what do you mean", "can you explain", "?" | Rephrase question with more context, examples, re-ask |
| SKIP | "skip", "not relevant", "doesn't apply" | Mark as out-of-scope, add to explicit_exclusions, continue |
| USER_ABORT | "stop", "cancel", "exit" | Save current state, exit cleanly with resume instructions |
| SCOPE_EXPANSION | "include X in scope", "let's also", "and while we're at it", "we should also", user adds new workstream | Defer to end of current category, then run Scope Drift Check |
Apply to ALL discovery questions in Phase 1.5.
### Scope Drift Check
<CRITICAL>
This mechanic detects when discovery answers reveal new design or infrastructure
needs that were not flagged in Phase 0. The response is **re-flag-and-continue**:
set the corresponding need-flag and keep going. There is no scope "upgrade" and no
work-item decomposition — the need-flags drive which phases and gates run.
Referenced from: Phase 1.5.2.5, Post-1.6, and inline via ARH during wizard.
</CRITICAL>
**Drift Signals:**
| Signal | Detection | Flag it implies |
|--------|-----------|-----------------|
| Design decision surfaced | Answer reveals a real architectural choice (new structure, a choice between approaches, a contract other code depends on) not in the original framing | `needs_design` |
| New workstream implied | Answer implies a parallel track of work whose shape is non-obvious | `needs_design` |
| New dependency / infra / schema | Answers reveal a new third-party dependency, new infra/service, or a data-schema/migration change | `needs_infrastructure` (which implies `needs_design`) |
| Structural change escalation | Answers reveal new modules/schemas needed | `needs_design` (or `needs_infrastructure` if it is a schema/migration) |
**Evaluation:**
```typescript
// Returns the set of need-flags that discovery implies but that were not
// already set in Phase 0. An empty set means no drift — proceed unchanged.
function detect_missing_flags(): string[] {
const flags = SESSION_PREFERENCES.need_flags;
const signals = detect_drift_signals(discovery_answers);
const missing: string[] = [];
for (const s of signals) {
if (s.implies === "needs_infrastructure" && !flags.needs_infrastructure) {
missing.push("needs_infrastructure"); // implies needs_design below
}
if (
(s.implies === "needs_design" || s.implies === "needs_infrastructure") &&
!flags.needs_design
) {
missing.push("needs_design");
}
}
return Array.from(new Set(missing));
}
```
**When drift detected (re-flag-and-continue):**
1. Do NOT stop the workflow or "upgrade" scope. Briefly note the new need to the user:
```
Scope Drift Detected — re-flagging
Discovery surfaced needs not flagged in Phase 0:
- [signal 1 description] → setting needs_design
- [signal 2 description] → setting needs_infrastructure (implies needs_design)
These flags turn on the corresponding phases/gates (Design, and for
infrastructure the heavier planning emphasis). Continuing discovery.
```
2. Set the implied flags in `SESSION_PREFERENCES.need_flags`:
- `needs_design = true` for a design/structural/workstream signal.
- `needs_infrastructure = true` for a new dependency/infra/schema signal;
this AUTO-IMPLIES `needs_design = true` (do not leave infra set without design).
3. Update the understanding document to reflect the expanded scope and the
newly-set flags.
4. Continue the discovery wizard. The newly-set flags route the later phases
(Design in Phase 2, heavier planning emphasis in Phase 3) — no work-item
decomposition, no separate project initialization.
### 1.5.0 Disambiguation Session
**PURPOSE:** Resolve all ambiguities BEFORE generating discovery questions
For each ambiguity from Phase 1.3, present:
```markdown
AMBIGUITY: [description from Phase 1.3]
CONTEXT FROM RESEARCH:
[Relevant research findings with evidence]
IMPACT ON DESIGN:
[Why this matters / what breaks if we guess wrong]
PLEASE CLARIFY:
A) [Specific interpretation 1]
B) [Specific interpretation 2]
C) [Specific interpretation 3]
D) Something else (please describe)
Your choice: ___
```
**PROCESSING (ARH Pattern):**
| Response Type | Pattern | Action |
| ---------------- | ------------------ | ------------------------------------------------ |
| DIRECT_ANSWER | A, B, C, D | Update disambiguation_results, continue |
| RESEARCH_REQUEST | "research this" | Dispatch subagent, regenerate ALL questions |
| UNKNOWN | "I don't know" | Dispatch subagent, rephrase with findings |
| CLARIFICATION | "what do you mean" | Rephrase with more context, re-ask |
| SKIP | "skip" | Mark as out-of-scope, add to explicit_exclusions |
| USER_ABORT | "stop" | Save state, exit cleanly |
**Fractal exploration (conditional):** When the user responds UNKNOWN or RESEARCH_REQUEST on a HIGH-impact ambiguity, invoke fractal-thinking with intensity `pulse` and seed: "What are the full implications of [Interpretation A] vs [Interpretation B]?". Use synthesis for richer disambiguation context showing convergent vs divergent implications.
**Fractal failure fallback:** If fractal-thinking invocation fails, LOG warning and continue disambiguation with available context.
**Example Flow:**
```
Question: "Research found JWT (8 files) and OAuth (5 files). Which should we use?"
User: "What's the difference? I don't know which is better."
ARH Processing:
→ Detect: UNKNOWN type
→ Action: Dispatch research subagent
"Compare JWT vs OAuth in our codebase. Return pros/cons."
→ Subagent returns comparison
→ Regenerate question with new context:
"Research shows:
- JWT: Stateless, used in API endpoints, mobile-friendly
- OAuth: Third-party integration, complex setup
For mobile API auth, which fits better?
A) JWT (stateless, mobile-friendly)
B) OAuth (third-party logins)
C) Something else"
→ User: "A - JWT makes sense"
→ Update disambiguation_results
```
### 1.5.1 Generate Deep Discovery Questions
**INPUT:** Research findings + Disambiguation results
**OUTPUT:** 7-category question set
**GENERATION RULES:**
1. Make questions specific using research findings (not generic)
2. Reference concrete codebase patterns discovered in Phase 1
3. Include at least one assumption check per category
4. Generate 3-5 questions per category
**7 CATEGORIES:**
**1. Architecture & Approach**
- How should [feature] integrate with [discovered pattern]?
- Should we follow [pattern A from file X] or [pattern B from file Y]?
- ASSUMPTION CHECK: Does [discovered constraint] apply here?
**2. Scope & Boundaries**
- Research shows [N] similar features. Should this match their scope?
- Explicit exclusions: What should this NOT do?
- MVP definition: What's the minimum for success?
- ASSUMPTION CHECK: Are we building for [discovered use case]?
**3. Integration & Constraints**
- Research found [integration points]. Which are relevant?
- Interface verification: Should we match [discovered interface]?
- ASSUMPTION CHECK: Must this work with [discovered dependency]?
**4. Failure Modes & Edge Cases**
- Research shows [N] edge cases in similar code. Which apply?
- What happens if [dependency] fails?
- How should we handle [boundary condition]?
**5. Success Criteria & Observability**
- Measurable thresholds: What numbers define success?
- How will we know this works in production?
- What metrics should we track?
**6. Vocabulary & Definitions**
- Research uses terms [X, Y, Z]. What do they mean here?
- Are [term A] and [term B] synonyms?
- Build glossary as terms emerge
**7. Assumption Audit**
- I assume [X] based on [research finding]. Correct?
- Explicit validation of ALL research-based assumptions
**Example Questions (Architecture):**
```
Feature: "Add JWT authentication for mobile API"
After research found JWT in 8 files and OAuth in 5 files,
and user clarified JWT is preferred:
1. Research shows JWT implementation in src/api/auth.ts using jose library.
Should we follow this pattern or use a different JWT library?
A) Use jose (consistent with existing code)
B) Use jsonwebtoken (more popular)
C) Different library (specify)
2. Existing JWT implementations store tokens in Redis (src/cache/tokens.ts).
Should we use the same storage approach?
A) Yes - use existing Redis token cache
B) No - use database storage
C) No - use stateless approach (no storage)
```
### 1.5.2 Conduct Discovery Wizard (with ARH)
Present questions one category at a time (7 iterations):
```markdown
## Discovery Wizard (Research-Informed)
Based on research findings and disambiguation, I have questions in 7 categories.
### Category 1/7: Architecture & Approach
[Present 3-5 questions]
[Wait for responses, process with ARH]
### Category 2/7: Scope & Boundaries
[Continue...]
```
Progress tracking: "[Category N/7]: X/Y questions answered"
### 1.5.2.5 Post-Discovery Scope Drift Check
<CRITICAL>
After completing the discovery wizard, run the Scope Drift Check with all accumulated answers.
This catches scope expansion that occurred gradually across multiple questions.
</CRITICAL>
Run `detect_missing_flags()`. If it returns a non-empty set, follow the "When drift detected (re-flag-and-continue)" protocol from the Scope Drift Check section above: set the implied need-flags, update the understanding document, and continue.
### 1.5.2.6 Project-Standards Cross-Check (operator)
Surface the discovered governance docs (`design_context.project_standards`) to the
operator. The cross-check has two modes, keyed on `none_found`:
- **Sources found** → **light** reinforcement (AskUserQuestion):
"I found these standards docs: [list with kind + summary]. Anything I'm missing
or that doesn't apply?"
- **`none_found: true`** → **REQUIRED** cross-check (not light): the operator MUST
be asked to name any governance/doctrine doc the heuristic layers missed. Both
the conventional glob net and the content classifier can miss (doctrine buried in
an unconventional dir, or declarative prose under-weighted); the operator is the
true generalizer when both layers come up empty. Record any operator-named doc
back into `project_standards.sources` / `binding_rules`.
### 1.5.3 Build Glossary
**Process:**
1. Extract domain terms from discovery answers during wizard
2. Build glossary as terms emerge (not in batch at end)
3. After wizard completes, show full glossary
4. Ask user ONCE about persistence
```
I've built a glossary with [N] terms:
[Show glossary preview]
Would you like to:
A) Keep it in this session only
B) Persist to project CLAUDE.md (all team members benefit)
```
**IF B SELECTED — Glossary Persistence Protocol:**
**Location:** Append to end of project CLAUDE.md file
**Format:**
```markdown
---
## Feature Glossary: [Feature Name]
**Generated:** [ISO 8601 timestamp]
**Feature:** [feature_essence from design_context]
### Terms
**[term 1]**
- **Definition:** [definition]
- **Source:** [user | research | codebase]
- **Context:** [feature-specific | project-wide]
- **Aliases:** [alias1, alias2, ...]
**[term 2]**
[...]
---
```
**Write Operation:**
1. Read current CLAUDE.md content
2. Append formatted glossary
3. Write back to CLAUDE.md
4. Verify write succeeded
**ERROR HANDLING:**
- If write fails (permission denied, read-only): Fallback to `~/.local/spellbook/docs/<project-encoded>/glossary-[feature-slug].md`
- Show location: "Glossary saved to: [path]"
- Suggest: "Manually append to CLAUDE.md when ready"
**COLLISION HANDLING:**
- Check for existing "## Feature Glossary: [Feature Name]" section
- If same feature glossary exists: Skip, warn "Glossary for this feature already exists in CLAUDE.md"
- If different feature glossary exists: Append as new section (multiple feature glossaries allowed)
### 1.5.4 Synthesize design_context
Build complete `DesignContext` object from all prior phases.
**Structure reference:** DesignContext fields are defined in the `develop` skill. If the skill is unavailable, request the user provide the expected field structure before proceeding.
**Validation:**
- No null values (except explicitly optional fields)
- No "TBD" or "unknown" strings
- All arrays with content or explicit "N/A"
### 1.5.5 Phase 1.5 Gate: Self-Assessment Half
<CRITICAL>
This gate has TWO halves, and they carry different weight. This section is the
JUDGMENT half: a self-assessment you make and record. It is not computed, and it
must never be reported as a computed figure. The mechanical half runs in 1.5.6,
against the understanding document on disk, and it is the half that blocks.
A previous version of this section presented these items as "13 validation
functions" in TypeScript with a `completeness_score` percentage. Nothing executed
that code. The score was a self-report wearing the costume of a measurement. It is
removed. This is a deliberate LOWERING of the stated strength of the judgment
items — they were never computed, and the text now says so.
</CRITICAL>
**Record each item as YES / NO / N-A with one line of evidence. No percentage.**
| # | Self-assessed item | What counts as YES |
|---|---|---|
| J1 | Research questions answered at HIGH confidence | Every research question has an answer you would defend, or the operator set the override |
| J2 | Ambiguities disambiguated | Every categorized ambiguity has a recorded resolution |
| J3 | Architecture chosen for a stated reason | A named approach AND the rationale that beat the alternatives |
| J4 | Integration points verified against the codebase | Each point was opened and read, not inferred from a name |
| J5 | Glossary covers the domain terms actually used | You re-read the answers looking for unglossed terms |
| J6 | Assumptions validated WITH THE OPERATOR | The operator saw them and responded; silence is NO |
| J7 | Need-flags consistent with discovered scope | Discovery surfaced no design/infra need absent from `SESSION_PREFERENCES.need_flags` |
Any NO returns to the discovery wizard or to research. The operator may accept a
NO and continue; record that acceptance as an explicit bypass, naming the item.
### 1.5.6 Create Understanding Document
**FILE PATH:** `~/.local/spellbook/docs/<project-encoded>/understanding/understanding-[feature-slug]-[timestamp].md`
**Generate Understanding Document:**
```markdown
# Understanding Document: [Feature Name]
## Feature Essence
[1-2 sentence summary]
## Research Summary
- Patterns discovered: [...]
- Integration points: [...]
- Constraints identified: [...]
## Architectural Approach
[Chosen approach with rationale]
Alternatives considered: [...]
## Scope Definition
IN SCOPE:
- [...]
EXPLICITLY OUT OF SCOPE:
- [...]
MVP DEFINITION:
[Minimum viable implementation]
## Integration Plan
- Integrates with: [...]
- Follows patterns: [...]
- Interfaces: [...]
## Failure Modes & Edge Cases
- [...]
## Success Criteria
- Metric 1: [threshold]
- Metric 2: [threshold]
## Glossary
[Full glossary from Phase 1.5.3]
## Validated Assumptions
- [assumption]: [validation]
## Project Standards (Discovered Governance Docs)
- Searched: [yes/no]
- Globs used: [...]
- Candidates considered: [N]
- Sources found: [path — kind — one-line summary, per doc]
- Binding rules: [verbatim rule — severity (MUST/SHOULD) — applies_to (code/tests/both) — source_path, per rule]
- None found: [true/false] (if true, REQUIRED operator cross-check was run)
- Truncated candidates: [paths classified on headings + first-N-lines only]
## Self-Assessment (not measured)
Record J1-J7 from Phase 1.5.5 as YES / NO / N-A with one line of evidence each.
These are judgments. Do not render them as a percentage.
```
**MECHANICAL GATE — run this before presenting the document:**
```bash
uv run scripts/check_understanding_doc.py ~/.local/spellbook/docs/<project-encoded>/understanding/understanding-[feature-slug]-[timestamp].md
```
The script reads the document and computes six structural checks: required
sections present, those sections non-empty, the three scope blocks present and
filled, every success criterion carrying a threshold, no deferral markers
(`TBD`, `to be determined`, `figure it out later`), and a standards sweep whose
result is auditable (a recorded source, or `None found: true` with the globs it
searched). Exit status IS the gate: non-zero blocks Phase 1.5.
What it does NOT establish: that any section's content is true, sufficient, or
well-judged. It proves the artifact has the shape the phase requires and defers
nothing in writing. The J1-J7 self-assessment covers the rest and is not
computed.
Present to user:
```
I've synthesized research and discovery into the Understanding Document above.
Please review and:
A) Approve (proceed to Devil's Advocate review)
B) Request changes (specify what to revise)
C) Return to discovery (need more information)
Your choice: ___
```
**BLOCK design phase until user approves (A).**
### 1.6 Devil's Advocate Review
<CRITICAL>
The devils-advocate skill is a REQUIRED dependency. Check availability before attempting invocation.
</CRITICAL>
#### 1.6.1 Check Devil's Advocate Availability
**Verify skill exists in available skills list.**
**IF SKILL NOT AVAILABLE:**
```
WARNING: devils-advocate skill not found in available skills.
The Devil's Advocate review is REQUIRED for quality assurance.
OPTIONS:
A) Install skill first (recommended)
Run 'uv run install.py' from spellbook directory, then restart session
B) Skip review for this session (not recommended)
Proceed without adversarial review - higher risk of missed issues
C) Manual review
I'll present the Understanding Document for YOUR critique instead
Your choice: ___
```
**Handle user choice:**
- **A (Install):** Exit with instructions: "Run 'uv run install.py' from spellbook directory, then restart this session"
- **B (Skip):** Set `skip_devils_advocate = true`, log warning, proceed to Phase 2
- **C (Manual):** Present Understanding Document, collect user's critique, add to `devils_advocate_critique` field, proceed
#### 1.6.2 Invoke Devil's Advocate Skill
<RULE>Subagent MUST invoke devils-advocate skill using the Skill tool.</RULE>
```
Task:
description: "Devil's Advocate Review"
prompt: |
First, invoke the devils-advocate skill using the Skill tool.
Then follow its complete workflow.
## Context for the Skill
Understanding Document:
[Insert full Understanding Document from Phase 1.5.6]
```
Present critique to user, then run **per-finding disposition** before
any meta-action choice. For each finding in the critique:
1. Present the finding (title, category, finding text, recommendation)
2. Ask via AskUserQuestion: disposition = `address`, `note_only`, or
`out_of_scope`?
3. Record disposition in `SESSION_CONTEXT.devils_advocate_dispositions`
**Default disposition is `note_only`.** `address` is never the default.
In autonomous mode, the operator is not present, so the orchestrator
MUST make an explicit triage decision per finding using the same three
values. Triaging silently as `address` is forbidden. A finding that
expands scope (introduces capabilities, infrastructure, or external
integrations not in the operator's initial request) MUST be triaged
`note_only` or `out_of_scope`, never `address`, without operator
confirmation. See `~/.claude/CLAUDE.md` "Autonomous Mode and Scope
Discipline".
After dispositions are assigned, present the meta-action choice:
```markdown
## Devil's Advocate Critique
[Full critique output from skill, with dispositions filled in]
---
Please review and choose next steps:
A) Address only `address`-disposition findings (return to discovery
for those specific gaps)
B) Document `note_only` findings as known limitations (add to
Understanding Document)
C) Revise scope per `out_of_scope` findings
D) Proceed to design (only `address` findings will shape Phase 2)
Your choice: ___
```
### Post-1.6 Scope Drift Recheck
After devil's advocate review, re-run the Scope Drift Check. The devil's advocate may have surfaced scope expansions not visible during initial discovery.
Run `detect_missing_flags()`. If it returns a non-empty set, follow the "When drift detected (re-flag-and-continue)" protocol: set the implied need-flags, update the understanding document, and continue.
<FORBIDDEN>
- Asking questions that Phase 1 research already answered
- Proceeding to design with completeness_score < 100% without explicit user bypass
- Blocking on glossary persistence when user chose session-only (A)
- Running devil's advocate review in main context instead of dispatching subagent
- Treating DesignContext structure as defined here — always reference develop skill for field definitions
- Continuing Phase 1.5 if prerequisite check fails
</FORBIDDEN>
---
## Phase 1.5 Complete
```bash
# Verify understanding document exists
ls ~/.local/spellbook/docs/<project-encoded>/understanding/
```
Before proceeding to Phase 2, verify:
- [ ] All ambiguities resolved (disambiguation session complete)
- [ ] 7-category discovery questions generated and answered
- [ ] Glossary built
- [ ] design_context synthesized (no null values, no TBD)
- [ ] Completeness Score = 100% (13/13 validation functions)
- [ ] Understanding Document created and saved
- [ ] Devil's advocate subagent DISPATCHED (not done in main context)
- [ ] User approved Understanding Document
If ANY unchecked: Complete Phase 1.5. Do NOT proceed.
**Next (same turn, autonomous mode):** invoke /feature-design now. Do not end the turn at a phase boundary — a phase boundary is not a turn boundary. In interactive mode, confirm first.
<FINAL_EMPHASIS>
Discovery quality determines design quality. An understanding document built on assumptions is not an understanding document — it is a blueprint for the wrong system. Every unanswered question here becomes a rework cycle later. Do not proceed to design until discovery is complete.
</FINAL_EMPHASIS>