From 4c2bf31525e9c7e4821f48a37631c52615f7ddfd Mon Sep 17 00:00:00 2001 From: catlog22 Date: Wed, 25 Feb 2026 19:42:45 +0800 Subject: [PATCH] feat(spec-generator): add Phase 1.5 requirement expansion & clarification Insert interactive requirement discussion stage between Discovery and Product Brief to address missing requirement depth analysis. Phase 1.5 uses Gemini CLI for gap analysis, supports multi-round interactive discussion (max 5 rounds), and outputs refined-requirements.json as high-quality input for downstream phases. Compatible with -y auto mode. --- .claude/skills/spec-generator/SKILL.md | 54 ++- .../phases/01-5-requirement-clarification.md | 404 ++++++++++++++++++ .../spec-generator/phases/02-product-brief.md | 29 +- .../specs/document-standards.md | 56 +++ .../spec-generator/specs/quality-gates.md | 12 + 5 files changed, 536 insertions(+), 19 deletions(-) create mode 100644 .claude/skills/spec-generator/phases/01-5-requirement-clarification.md diff --git a/.claude/skills/spec-generator/SKILL.md b/.claude/skills/spec-generator/SKILL.md index 188b3e55..8b2282cd 100644 --- a/.claude/skills/spec-generator/SKILL.md +++ b/.claude/skills/spec-generator/SKILL.md @@ -11,21 +11,23 @@ Structured specification document generator producing a complete specification p ## Architecture Overview ``` -Phase 0: Specification Study (Read specs/ + templates/ - mandatory prerequisite) - | -Phase 1: Discovery -> spec-config.json + discovery-context.json - | -Phase 2: Product Brief -> product-brief.md (multi-CLI parallel analysis) - | -Phase 3: Requirements (PRD) -> requirements/ (_index.md + REQ-*.md + NFR-*.md) - | -Phase 4: Architecture -> architecture/ (_index.md + ADR-*.md, multi-CLI review) - | -Phase 5: Epics & Stories -> epics/ (_index.md + EPIC-*.md) - | -Phase 6: Readiness Check -> readiness-report.md + spec-summary.md - | - Handoff to execution workflows +Phase 0: Specification Study (Read specs/ + templates/ - mandatory prerequisite) + | +Phase 1: Discovery -> spec-config.json + discovery-context.json + | +Phase 1.5: Req Expansion -> refined-requirements.json (interactive discussion + CLI gap analysis) + | (-y auto mode: auto-expansion, skip interaction) +Phase 2: Product Brief -> product-brief.md (multi-CLI parallel analysis) + | +Phase 3: Requirements (PRD) -> requirements/ (_index.md + REQ-*.md + NFR-*.md) + | +Phase 4: Architecture -> architecture/ (_index.md + ADR-*.md, multi-CLI review) + | +Phase 5: Epics & Stories -> epics/ (_index.md + EPIC-*.md) + | +Phase 6: Readiness Check -> readiness-report.md + spec-summary.md + | + Handoff to execution workflows ``` ## Key Design Principles @@ -79,6 +81,16 @@ Phase 1: Discovery & Seed Analysis |- User confirmation (interactive, -y skips) |- Output: spec-config.json, discovery-context.json (optional) +Phase 1.5: Requirement Expansion & Clarification + |- Ref: phases/01-5-requirement-clarification.md + |- CLI gap analysis: completeness scoring, missing dimensions detection + |- Multi-round interactive discussion (max 5 rounds) + | |- Round 1: present gap analysis + expansion suggestions + | |- Round N: follow-up refinement based on user responses + |- User final confirmation of requirements + |- Auto mode (-y): CLI auto-expansion without interaction + |- Output: refined-requirements.json + Phase 2: Product Brief |- Ref: phases/02-product-brief.md |- 3 parallel CLI analyses: Product (Gemini) + Technical (Codex) + User (Claude) @@ -148,6 +160,7 @@ Bash(`mkdir -p "${workDir}"`); .workflow/.spec/SPEC-{slug}-{YYYY-MM-DD}/ ├── spec-config.json # Session configuration + phase state ├── discovery-context.json # Codebase exploration results (optional) +├── refined-requirements.json # Phase 1.5: Confirmed requirements after discussion ├── product-brief.md # Phase 2: Product brief ├── requirements/ # Phase 3: Detailed PRD (directory) │ ├── _index.md # Summary, MoSCoW table, traceability, links @@ -184,8 +197,10 @@ Bash(`mkdir -p "${workDir}"`); "dimensions": [] }, "has_codebase": false, + "refined_requirements_file": "refined-requirements.json", "phasesCompleted": [ { "phase": 1, "name": "discovery", "output_file": "spec-config.json", "completed_at": "ISO8601" }, + { "phase": 1.5, "name": "requirement-clarification", "output_file": "refined-requirements.json", "discussion_rounds": 2, "completed_at": "ISO8601" }, { "phase": 3, "name": "requirements", "output_dir": "requirements/", "output_index": "requirements/_index.md", "file_count": 8, "completed_at": "ISO8601" } ] } @@ -211,6 +226,12 @@ Bash(`mkdir -p "${workDir}"`); | [phases/01-discovery.md](phases/01-discovery.md) | Seed analysis and session setup | Phase start | | [specs/document-standards.md](specs/document-standards.md) | Frontmatter format for spec-config.json | Config generation | +### Phase 1.5: Requirement Expansion & Clarification +| Document | Purpose | When to Use | +|----------|---------|-------------| +| [phases/01-5-requirement-clarification.md](phases/01-5-requirement-clarification.md) | Interactive requirement discussion workflow | Phase start | +| [specs/quality-gates.md](specs/quality-gates.md) | Quality criteria for refined requirements | Validation | + ### Phase 2: Product Brief | Document | Purpose | When to Use | |----------|---------|-------------| @@ -254,6 +275,9 @@ Bash(`mkdir -p "${workDir}"`); |-------|-------|-----------|--------| | Phase 1 | Empty input | Yes | Error and exit | | Phase 1 | CLI seed analysis fails | No | Use basic parsing fallback | +| Phase 1.5 | Gap analysis CLI fails | No | Skip to user questions with basic prompts | +| Phase 1.5 | User skips discussion | No | Proceed with seed_analysis as-is | +| Phase 1.5 | Max rounds reached (5) | No | Force confirmation with current state | | Phase 2 | Single CLI perspective fails | No | Continue with available perspectives | | Phase 2 | All CLI calls fail | No | Generate basic brief from seed analysis | | Phase 3 | Gemini CLI fails | No | Use codex fallback | diff --git a/.claude/skills/spec-generator/phases/01-5-requirement-clarification.md b/.claude/skills/spec-generator/phases/01-5-requirement-clarification.md new file mode 100644 index 00000000..d185febc --- /dev/null +++ b/.claude/skills/spec-generator/phases/01-5-requirement-clarification.md @@ -0,0 +1,404 @@ +# Phase 1.5: Requirement Expansion & Clarification + +在进入正式文档生成前,通过多轮交互讨论对原始需求进行深度挖掘、扩展和确认。 + +## Objective + +- 识别原始需求中的模糊点、遗漏和潜在风险 +- 通过 CLI 辅助分析需求完整性,生成深度探测问题 +- 支持多轮交互讨论,逐步细化需求 +- 生成经用户确认的 `refined-requirements.json` 作为后续阶段的高质量输入 + +## Input + +- Dependency: `{workDir}/spec-config.json` (Phase 1 output) +- Optional: `{workDir}/discovery-context.json` (codebase context) + +## Execution Steps + +### Step 1: Load Phase 1 Context + +```javascript +const specConfig = JSON.parse(Read(`${workDir}/spec-config.json`)); +const { seed_analysis, seed_input, focus_areas, has_codebase, depth } = specConfig; + +let discoveryContext = null; +if (has_codebase) { + try { + discoveryContext = JSON.parse(Read(`${workDir}/discovery-context.json`)); + } catch (e) { /* proceed without */ } +} +``` + +### Step 2: CLI Gap Analysis & Question Generation + +调用 Gemini CLI 分析原始需求的完整性,识别模糊点并生成探测问题。 + +```javascript +Bash({ + command: `ccw cli -p "PURPOSE: 深度分析用户的初始需求,识别模糊点、遗漏和需要澄清的领域。 +Success: 生成 3-5 个高质量的探测问题,覆盖功能范围、边界条件、非功能性需求、用户场景等维度。 + +ORIGINAL SEED INPUT: +${seed_input} + +SEED ANALYSIS: +${JSON.stringify(seed_analysis, null, 2)} + +FOCUS AREAS: ${focus_areas.join(', ')} +${discoveryContext ? ` +CODEBASE CONTEXT: +- Existing patterns: ${discoveryContext.existing_patterns?.slice(0,5).join(', ') || 'none'} +- Tech stack: ${JSON.stringify(discoveryContext.tech_stack || {})} +` : ''} + +TASK: +1. 评估当前需求描述的完整性(1-10 分,列出缺失维度) +2. 识别 3-5 个关键模糊区域,每个区域包含: + - 模糊点描述(为什么不清楚) + - 1-2 个开放式探测问题 + - 1-2 个扩展建议(基于领域最佳实践) +3. 检查以下维度是否有遗漏: + - 功能范围边界(什么在范围内/外?) + - 核心用户场景和流程 + - 非功能性需求(性能、安全、可用性、可扩展性) + - 集成点和外部依赖 + - 数据模型和存储需求 + - 错误处理和异常场景 +4. 基于领域经验提供需求扩展建议 + +MODE: analysis +EXPECTED: JSON output: +{ + \"completeness_score\": 7, + \"missing_dimensions\": [\"Performance requirements\", \"Error handling\"], + \"clarification_areas\": [ + { + \"area\": \"Scope boundary\", + \"rationale\": \"Input does not clarify...\", + \"questions\": [\"Question 1?\", \"Question 2?\"], + \"suggestions\": [\"Suggestion 1\", \"Suggestion 2\"] + } + ], + \"expansion_recommendations\": [ + { + \"category\": \"Non-functional\", + \"recommendation\": \"Consider adding...\", + \"priority\": \"high|medium|low\" + } + ] +} +CONSTRAINTS: 问题必须是开放式的,建议必须具体可执行,使用用户输入的语言 +" --tool gemini --mode analysis`, + run_in_background: true +}); +// Wait for CLI result before continuing +``` + +解析 CLI 输出为结构化数据: +```javascript +const gapAnalysis = { + completeness_score: 0, + missing_dimensions: [], + clarification_areas: [], + expansion_recommendations: [] +}; +// Parse from CLI output +``` + +### Step 3: Interactive Discussion Loop + +核心多轮交互循环。每轮:展示分析结果 → 用户回应 → 更新需求状态 → 判断是否继续。 + +```javascript +// Initialize requirement state +let requirementState = { + problem_statement: seed_analysis.problem_statement, + target_users: seed_analysis.target_users, + domain: seed_analysis.domain, + constraints: seed_analysis.constraints, + confirmed_features: [], + non_functional_requirements: [], + boundary_conditions: [], + integration_points: [], + key_assumptions: [], + discussion_rounds: 0 +}; + +let discussionLog = []; +let userSatisfied = false; + +// === Round 1: Present gap analysis results === +// Display completeness_score, clarification_areas, expansion_recommendations +// Then ask user to respond + +while (!userSatisfied && requirementState.discussion_rounds < 5) { + requirementState.discussion_rounds++; + + if (requirementState.discussion_rounds === 1) { + // --- First round: present initial gap analysis --- + // Format questions and suggestions from gapAnalysis for display + // Present as a structured summary to the user + + AskUserQuestion({ + questions: [ + { + question: buildDiscussionPrompt(gapAnalysis, requirementState), + header: "Req Expand", + multiSelect: false, + options: [ + { label: "I'll answer", description: "I have answers/feedback to provide (type in 'Other')" }, + { label: "Accept all suggestions", description: "Accept all expansion recommendations as-is" }, + { label: "Skip to generation", description: "Requirements are clear enough, proceed directly" } + ] + } + ] + }); + } else { + // --- Subsequent rounds: refine based on user feedback --- + // Call CLI with accumulated context for follow-up analysis + Bash({ + command: `ccw cli -p "PURPOSE: 基于用户最新回应,更新需求理解,识别剩余模糊点。 + +CURRENT REQUIREMENT STATE: +${JSON.stringify(requirementState, null, 2)} + +DISCUSSION HISTORY: +${JSON.stringify(discussionLog, null, 2)} + +USER'S LATEST RESPONSE: +${lastUserResponse} + +TASK: +1. 将用户回应整合到需求状态中 +2. 识别 1-3 个仍需澄清或可扩展的领域 +3. 生成后续问题(如有必要) +4. 如果需求已充分,输出最终需求摘要 + +MODE: analysis +EXPECTED: JSON output: +{ + \"updated_fields\": { /* fields to merge into requirementState */ }, + \"status\": \"need_more_discussion\" | \"ready_for_confirmation\", + \"follow_up\": { + \"remaining_areas\": [{\"area\": \"...\", \"questions\": [\"...\"]}], + \"summary\": \"...\" + } +} +CONSTRAINTS: 避免重复已回答的问题,聚焦未覆盖的领域 +" --tool gemini --mode analysis`, + run_in_background: true + }); + // Wait for CLI result, parse and continue + + // If status === "ready_for_confirmation", break to confirmation step + // If status === "need_more_discussion", present follow-up questions + + AskUserQuestion({ + questions: [ + { + question: buildFollowUpPrompt(followUpAnalysis, requirementState), + header: "Follow-up", + multiSelect: false, + options: [ + { label: "I'll answer", description: "I have more feedback (type in 'Other')" }, + { label: "Looks good", description: "Requirements are sufficiently clear now" }, + { label: "Accept suggestions", description: "Accept remaining suggestions" } + ] + } + ] + }); + } + + // Process user response + // - "Skip to generation" / "Looks good" → userSatisfied = true + // - "Accept all suggestions" → merge suggestions into requirementState, userSatisfied = true + // - "I'll answer" (with Other text) → record in discussionLog, continue loop + // - User selects Other with custom text → parse and record + + discussionLog.push({ + round: requirementState.discussion_rounds, + agent_prompt: currentPrompt, + user_response: userResponse, + timestamp: new Date().toISOString() + }); +} +``` + +#### Helper: Build Discussion Prompt + +```javascript +function buildDiscussionPrompt(gapAnalysis, state) { + let prompt = `## Requirement Analysis Results\n\n`; + prompt += `**Completeness Score**: ${gapAnalysis.completeness_score}/10\n`; + + if (gapAnalysis.missing_dimensions.length > 0) { + prompt += `**Missing Dimensions**: ${gapAnalysis.missing_dimensions.join(', ')}\n\n`; + } + + prompt += `### Key Questions\n\n`; + gapAnalysis.clarification_areas.forEach((area, i) => { + prompt += `**${i+1}. ${area.area}**\n`; + prompt += ` ${area.rationale}\n`; + area.questions.forEach(q => { prompt += ` - ${q}\n`; }); + if (area.suggestions.length > 0) { + prompt += ` Suggestions: ${area.suggestions.join('; ')}\n`; + } + prompt += `\n`; + }); + + if (gapAnalysis.expansion_recommendations.length > 0) { + prompt += `### Expansion Recommendations\n\n`; + gapAnalysis.expansion_recommendations.forEach(rec => { + prompt += `- [${rec.priority}] **${rec.category}**: ${rec.recommendation}\n`; + }); + } + + prompt += `\nPlease answer the questions above, or choose an option below.`; + return prompt; +} +``` + +### Step 4: Auto Mode Handling + +```javascript +if (autoMode) { + // Skip interactive discussion + // CLI generates default requirement expansion based on seed_analysis + Bash({ + command: `ccw cli -p "PURPOSE: 基于种子分析自动生成需求扩展,无需用户交互。 + +SEED ANALYSIS: +${JSON.stringify(seed_analysis, null, 2)} + +SEED INPUT: ${seed_input} +DEPTH: ${depth} +${discoveryContext ? `CODEBASE: ${JSON.stringify(discoveryContext.tech_stack || {})}` : ''} + +TASK: +1. 基于领域最佳实践,自动扩展功能需求清单 +2. 推断合理的非功能性需求 +3. 识别明显的边界条件 +4. 列出关键假设 + +MODE: analysis +EXPECTED: JSON output matching refined-requirements.json schema +CONSTRAINTS: 保守推断,只添加高置信度的扩展 +" --tool gemini --mode analysis`, + run_in_background: true + }); + // Parse output directly into refined-requirements.json +} +``` + +### Step 5: Generate Requirement Confirmation Summary + +在写入文件前,向用户展示最终的需求确认摘要(非 auto mode)。 + +```javascript +if (!autoMode) { + // Build confirmation summary from requirementState + const summary = buildConfirmationSummary(requirementState); + + AskUserQuestion({ + questions: [ + { + question: `## Requirement Confirmation\n\n${summary}\n\nConfirm and proceed to specification generation?`, + header: "Confirm", + multiSelect: false, + options: [ + { label: "Confirm & proceed", description: "Requirements confirmed, start spec generation" }, + { label: "Need adjustments", description: "Go back and refine further" } + ] + } + ] + }); + + // If "Need adjustments" → loop back to Step 3 + // If "Confirm & proceed" → continue to Step 6 +} +``` + +### Step 6: Write refined-requirements.json + +```javascript +const refinedRequirements = { + session_id: specConfig.session_id, + phase: "1.5", + generated_at: new Date().toISOString(), + source: autoMode ? "auto-expansion" : "interactive-discussion", + discussion_rounds: requirementState.discussion_rounds, + + // Core requirement content + clarified_problem_statement: requirementState.problem_statement, + confirmed_target_users: requirementState.target_users.map(u => + typeof u === 'string' ? { name: u, needs: [], pain_points: [] } : u + ), + confirmed_domain: requirementState.domain, + + confirmed_features: requirementState.confirmed_features.map(f => ({ + name: f.name, + description: f.description, + acceptance_criteria: f.acceptance_criteria || [], + edge_cases: f.edge_cases || [], + priority: f.priority || "unset" + })), + + non_functional_requirements: requirementState.non_functional_requirements.map(nfr => ({ + type: nfr.type, // Performance, Security, Usability, Scalability, etc. + details: nfr.details, + measurable_criteria: nfr.measurable_criteria || "" + })), + + boundary_conditions: { + in_scope: requirementState.boundary_conditions.filter(b => b.scope === 'in'), + out_of_scope: requirementState.boundary_conditions.filter(b => b.scope === 'out'), + constraints: requirementState.constraints + }, + + integration_points: requirementState.integration_points, + key_assumptions: requirementState.key_assumptions, + + // Traceability + discussion_log: autoMode ? [] : discussionLog +}; + +Write(`${workDir}/refined-requirements.json`, JSON.stringify(refinedRequirements, null, 2)); +``` + +### Step 7: Update spec-config.json + +```javascript +specConfig.refined_requirements_file = "refined-requirements.json"; +specConfig.phasesCompleted.push({ + phase: 1.5, + name: "requirement-clarification", + output_file: "refined-requirements.json", + discussion_rounds: requirementState.discussion_rounds, + completed_at: new Date().toISOString() +}); + +Write(`${workDir}/spec-config.json`, JSON.stringify(specConfig, null, 2)); +``` + +## Output + +- **File**: `refined-requirements.json` +- **Format**: JSON +- **Updated**: `spec-config.json` (added `refined_requirements_file` field and phase 1.5 to `phasesCompleted`) + +## Quality Checklist + +- [ ] Problem statement refined (>= 30 characters, more specific than seed) +- [ ] At least 2 confirmed features with descriptions +- [ ] At least 1 non-functional requirement identified +- [ ] Boundary conditions defined (in-scope + out-of-scope) +- [ ] Key assumptions listed (>= 1) +- [ ] Discussion rounds recorded (>= 1 in interactive mode) +- [ ] User explicitly confirmed requirements (non-auto mode) +- [ ] `refined-requirements.json` written with valid JSON +- [ ] `spec-config.json` updated with phase 1.5 completion + +## Next Phase + +Proceed to [Phase 2: Product Brief](02-product-brief.md). Phase 2 should load `refined-requirements.json` as primary input instead of relying solely on `spec-config.json.seed_analysis`. diff --git a/.claude/skills/spec-generator/phases/02-product-brief.md b/.claude/skills/spec-generator/phases/02-product-brief.md index d5c637a2..ab876465 100644 --- a/.claude/skills/spec-generator/phases/02-product-brief.md +++ b/.claude/skills/spec-generator/phases/02-product-brief.md @@ -13,6 +13,7 @@ Generate a product brief through multi-perspective CLI analysis, establishing "w ## Input - Dependency: `{workDir}/spec-config.json` +- Primary: `{workDir}/refined-requirements.json` (Phase 1.5 output, preferred over raw seed_analysis) - Optional: `{workDir}/discovery-context.json` - Config: `{workDir}/spec-config.json` - Template: `templates/product-brief.md` @@ -25,6 +26,14 @@ Generate a product brief through multi-perspective CLI analysis, establishing "w const specConfig = JSON.parse(Read(`${workDir}/spec-config.json`)); const { seed_analysis, seed_input, has_codebase, depth, focus_areas } = specConfig; +// Load refined requirements (Phase 1.5 output) - preferred over raw seed_analysis +let refinedReqs = null; +try { + refinedReqs = JSON.parse(Read(`${workDir}/refined-requirements.json`)); +} catch (e) { + // No refined requirements, fall back to seed_analysis +} + let discoveryContext = null; if (has_codebase) { try { @@ -35,13 +44,25 @@ if (has_codebase) { } // Build shared context string for CLI prompts +// Prefer refined requirements over raw seed_analysis +const problem = refinedReqs?.clarified_problem_statement || seed_analysis.problem_statement; +const users = refinedReqs?.confirmed_target_users?.map(u => u.name || u).join(', ') + || seed_analysis.target_users.join(', '); +const domain = refinedReqs?.confirmed_domain || seed_analysis.domain; +const constraints = refinedReqs?.boundary_conditions?.constraints?.join(', ') + || seed_analysis.constraints.join(', '); +const features = refinedReqs?.confirmed_features?.map(f => f.name).join(', ') || ''; +const nfrs = refinedReqs?.non_functional_requirements?.map(n => `${n.type}: ${n.details}`).join('; ') || ''; + const sharedContext = ` SEED: ${seed_input} -PROBLEM: ${seed_analysis.problem_statement} -TARGET USERS: ${seed_analysis.target_users.join(', ')} -DOMAIN: ${seed_analysis.domain} -CONSTRAINTS: ${seed_analysis.constraints.join(', ')} +PROBLEM: ${problem} +TARGET USERS: ${users} +DOMAIN: ${domain} +CONSTRAINTS: ${constraints} FOCUS AREAS: ${focus_areas.join(', ')} +${features ? `CONFIRMED FEATURES: ${features}` : ''} +${nfrs ? `NON-FUNCTIONAL REQUIREMENTS: ${nfrs}` : ''} ${discoveryContext ? ` CODEBASE CONTEXT: - Existing patterns: ${discoveryContext.existing_patterns?.slice(0,5).join(', ') || 'none'} diff --git a/.claude/skills/spec-generator/specs/document-standards.md b/.claude/skills/spec-generator/specs/document-standards.md index 2820cd98..d5efb808 100644 --- a/.claude/skills/spec-generator/specs/document-standards.md +++ b/.claude/skills/spec-generator/specs/document-standards.md @@ -81,6 +81,7 @@ Examples: |------|-------|-------------| | `spec-config.json` | 1 | Session configuration and state | | `discovery-context.json` | 1 | Codebase exploration results (optional) | +| `refined-requirements.json` | 1.5 | Confirmed requirements after discussion | | `product-brief.md` | 2 | Product brief document | | `requirements.md` | 3 | PRD document | | `architecture.md` | 4 | Architecture decisions document | @@ -168,6 +169,7 @@ Derived from [REQ-001](requirements.md#req-001). "dimensions": ["string array - 3-5 exploration dimensions"] }, "has_codebase": "boolean", + "refined_requirements_file": "string (optional) - path to refined-requirements.json", "phasesCompleted": [ { "phase": "number (1-6)", @@ -181,6 +183,60 @@ Derived from [REQ-001](requirements.md#req-001). --- +## refined-requirements.json Schema + +```json +{ + "session_id": "string (required) - matches spec-config.json", + "phase": "1.5", + "generated_at": "ISO8601 (required)", + "source": "interactive-discussion|auto-expansion (required)", + "discussion_rounds": "number (required) - 0 for auto mode", + "clarified_problem_statement": "string (required) - refined problem statement", + "confirmed_target_users": [ + { + "name": "string", + "needs": ["string array"], + "pain_points": ["string array"] + } + ], + "confirmed_domain": "string", + "confirmed_features": [ + { + "name": "string", + "description": "string", + "acceptance_criteria": ["string array"], + "edge_cases": ["string array"], + "priority": "must|should|could|unset" + } + ], + "non_functional_requirements": [ + { + "type": "Performance|Security|Usability|Scalability|Reliability|...", + "details": "string", + "measurable_criteria": "string (optional)" + } + ], + "boundary_conditions": { + "in_scope": ["string array"], + "out_of_scope": ["string array"], + "constraints": ["string array"] + }, + "integration_points": ["string array"], + "key_assumptions": ["string array"], + "discussion_log": [ + { + "round": "number", + "agent_prompt": "string", + "user_response": "string", + "timestamp": "ISO8601" + } + ] +} +``` + +--- + ## Validation Checklist - [ ] Every document starts with valid YAML frontmatter diff --git a/.claude/skills/spec-generator/specs/quality-gates.md b/.claude/skills/spec-generator/specs/quality-gates.md index ae968436..34411fc5 100644 --- a/.claude/skills/spec-generator/specs/quality-gates.md +++ b/.claude/skills/spec-generator/specs/quality-gates.md @@ -88,6 +88,18 @@ Content provides sufficient detail for execution teams. | Dimensions generated | 3-5 exploration dimensions | Warning | | Constraints listed | >= 0 (can be empty with justification) | Info | +### Phase 1.5: Requirement Expansion & Clarification + +| Check | Criteria | Severity | +|-------|----------|----------| +| Problem statement refined | More specific than seed, >= 30 characters | Error | +| Confirmed features | >= 2 features with descriptions | Error | +| Non-functional requirements | >= 1 identified (performance, security, etc.) | Warning | +| Boundary conditions | In-scope and out-of-scope defined | Warning | +| Key assumptions | >= 1 assumption listed | Warning | +| User confirmation | Explicit user confirmation recorded (non-auto mode) | Info | +| Discussion rounds | >= 1 round of interaction (non-auto mode) | Info | + ### Phase 2: Product Brief | Check | Criteria | Severity |