diff --git a/README.md b/README.md index b6d7848e6..a9d1d6801 100644 --- a/README.md +++ b/README.md @@ -235,11 +235,12 @@ Essential commands for the Spec-Driven Development workflow: Additional commands for enhanced quality and validation: -| Command | Description | -|----------------------|-----------------------------------------------------------------------| -| `/speckit.clarify` | Clarify underspecified areas (recommended before `/speckit.plan`; formerly `/quizme`) | -| `/speckit.analyze` | Cross-artifact consistency & coverage analysis (run after `/speckit.tasks`, before `/speckit.implement`) | -| `/speckit.checklist` | Generate custom quality checklists that validate requirements completeness, clarity, and consistency (like "unit tests for English") | +| Command | Description | +|--------------------------|-----------------------------------------------------------------------| +| `/speckit.clarify` | Clarify underspecified areas (recommended before `/speckit.plan`; formerly `/quizme`) | +| `/speckit.cross-feature` | Cross-feature alignment analysis using systems thinking (optional, run after `/speckit.specify`) | +| `/speckit.analyze` | Cross-artifact consistency & coverage analysis (run after `/speckit.tasks`, before `/speckit.implement`) | +| `/speckit.checklist` | Generate custom quality checklists that validate requirements completeness, clarity, and consistency (like "unit tests for English") | ### Environment Variables diff --git a/scripts/bash/cross-feature-check-all-features.sh b/scripts/bash/cross-feature-check-all-features.sh new file mode 100755 index 000000000..b293c529a --- /dev/null +++ b/scripts/bash/cross-feature-check-all-features.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +# Analyze current feature alignment with all existing features using systems thinking +set -e + +# Platform detection is done inline where sed is used for better portability + +JSON_MODE=false +ARGS=() +for arg in "$@"; do + case "$arg" in + --json) JSON_MODE=true ;; + --help|-h) echo "Usage: $0 [--json] [analysis_focus]"; exit 0 ;; + *) ARGS+=("$arg") ;; + esac +done + +ANALYSIS_FOCUS="${ARGS[*]}" +if [ -z "$ANALYSIS_FOCUS" ]; then + ANALYSIS_FOCUS="Comprehensive Analysis" +fi + +# Resolve repository root. Prefer git information when available, but fall back +# to the script location so the workflow still functions in repositories that +# were initialised with --no-git. +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +FALLBACK_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +if git rev-parse --show-toplevel >/dev/null 2>&1; then + REPO_ROOT=$(git rev-parse --show-toplevel) + HAS_GIT=true +else + REPO_ROOT="$FALLBACK_ROOT" + HAS_GIT=false +fi + +cd "$REPO_ROOT" + +# Get current branch name and find current spec +if [ "$HAS_GIT" = true ]; then + CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) +else + # If no git, try to determine current feature from specs directory + # This is a fallback - in practice, alignment analysis should run on active feature branch + CURRENT_BRANCH=$(ls -t specs/ | head -n 1 2>/dev/null || echo "") +fi + +if [ -z "$CURRENT_BRANCH" ] || [ "$CURRENT_BRANCH" = "main" ] || [ "$CURRENT_BRANCH" = "master" ]; then + echo "Error: Alignment analysis must be run from a feature branch (created by /speckit.specify)" >&2 + exit 1 +fi + +CURRENT_SPEC="$REPO_ROOT/specs/$CURRENT_BRANCH/spec.md" +if [ ! -f "$CURRENT_SPEC" ]; then + echo "Error: Current specification not found at $CURRENT_SPEC" >&2 + exit 1 +fi + +# Find all existing specifications +ALL_SPECS=() +SPECS_DIR="$REPO_ROOT/specs" +if [ -d "$SPECS_DIR" ]; then + for dir in "$SPECS_DIR"/*; do + [ -d "$dir" ] || continue + spec_file="$dir/spec.md" + if [ -f "$spec_file" ] && [ "$spec_file" != "$CURRENT_SPEC" ]; then + ALL_SPECS+=("$spec_file") + fi + done +fi + +# Create analysis file in current feature directory +FEATURE_DIR="$(dirname "$CURRENT_SPEC")" +ANALYSIS_FILE="$FEATURE_DIR/cross-feature-analysis.md" + +# Create analysis file from template +TEMPLATE="$REPO_ROOT/templates/cross-feature-analysis-template.md" +if [ -f "$TEMPLATE" ]; then + cp "$TEMPLATE" "$ANALYSIS_FILE" +else + touch "$ANALYSIS_FILE" +fi + +# Extract clarification line from template to avoid duplication +COMMAND_TEMPLATE="$REPO_ROOT/templates/commands/cross-feature.md" +if [ -f "$COMMAND_TEMPLATE" ]; then + # Extract the clarification message from the template (handles both quotes and backticks) + CLARIFICATION_LINE=$(grep -A 1 "Add:" "$COMMAND_TEMPLATE" | grep "NEEDS CLARIFICATION" | sed 's/.*["'\''`]\(.*NEEDS CLARIFICATION.*\)["'\''`].*/\1/') +fi + +# Fallback if extraction fails +# NOTE: This fallback must match the clarification line in templates/commands/cross-feature.md +# The template is the source of truth - update there first if changing this message +if [ -z "$CLARIFICATION_LINE" ]; then + CLARIFICATION_LINE="- [NEEDS CLARIFICATION: Review cross-feature alignment analysis in cross-feature-analysis.md - potential conflicts identified that may require spec adjustments]" +fi + +# Find the Requirements section and add the clarification line +if [ -f "$CURRENT_SPEC" ]; then + # Check if the clarification line already exists to avoid duplicates + if ! grep -q "cross-feature-analysis.md" "$CURRENT_SPEC"; then + # Find the line with "### Functional Requirements" and add our clarification after it + if grep -q "### Functional Requirements" "$CURRENT_SPEC"; then + # Use portable sed in-place editing for macOS and GNU/Linux + if sed --version >/dev/null 2>&1; then + # GNU sed + sed -i "/### Functional Requirements/a\\$CLARIFICATION_LINE" "$CURRENT_SPEC" + else + # BSD/macOS sed + sed -i.bak "/### Functional Requirements/a\\ +$CLARIFICATION_LINE" "$CURRENT_SPEC" && rm -f "$CURRENT_SPEC.bak" + fi + else + # If no Functional Requirements section, add to end of file + echo "" >> "$CURRENT_SPEC" + echo "$CLARIFICATION_LINE" >> "$CURRENT_SPEC" + fi + fi +fi + +# Build JSON output with all specs array +if $JSON_MODE; then + printf '{"CURRENT_SPEC":"%s","ALL_SPECS":[' "$CURRENT_SPEC" + + # Add all specs as JSON array + first=true + for spec in "${ALL_SPECS[@]}"; do + if [ "$first" = true ]; then + first=false + else + printf ',' + fi + printf '"%s"' "$spec" + done + + printf '],"ANALYSIS_FILE":"%s","ANALYSIS_FOCUS":"%s"}\n' "$ANALYSIS_FILE" "$ANALYSIS_FOCUS" +else + echo "CURRENT_SPEC: $CURRENT_SPEC" + echo "ALL_SPECS: ${ALL_SPECS[*]}" + echo "ANALYSIS_FILE: $ANALYSIS_FILE" + echo "ANALYSIS_FOCUS: $ANALYSIS_FOCUS" +fi \ No newline at end of file diff --git a/scripts/powershell/cross-feature-check-all-features.ps1 b/scripts/powershell/cross-feature-check-all-features.ps1 new file mode 100644 index 000000000..a482bc702 --- /dev/null +++ b/scripts/powershell/cross-feature-check-all-features.ps1 @@ -0,0 +1,140 @@ +# Analyze current feature alignment with all existing features using systems thinking +param( + [string]$Json = "", + [string[]]$Args = @() +) + +$JsonMode = $Json -eq "{ARGS}" -or $Args -contains "--json" +$AnalysisFocus = ($Args | Where-Object { $_ -ne "--json" }) -join " " +if ([string]::IsNullOrWhiteSpace($AnalysisFocus)) { + $AnalysisFocus = "Comprehensive Analysis" +} + +# Get repository root +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition +$FallbackRoot = Resolve-Path (Join-Path $ScriptDir "../..") + +try { + $RepoRoot = git rev-parse --show-toplevel 2>$null + $HasGit = $true +} catch { + $RepoRoot = $FallbackRoot + $HasGit = $false +} + +Set-Location $RepoRoot + +# Get current branch name and find current spec +if ($HasGit) { + try { + $CurrentBranch = git rev-parse --abbrev-ref HEAD 2>$null + } catch { + $CurrentBranch = "" + } +} else { + # If no git, try to determine current feature from specs directory + $SpecsDirs = Get-ChildItem -Path "specs" -Directory -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending + $CurrentBranch = if ($SpecsDirs) { $SpecsDirs[0].Name } else { "" } +} + +if ([string]::IsNullOrWhiteSpace($CurrentBranch) -or $CurrentBranch -eq "main" -or $CurrentBranch -eq "master") { + Write-Error "Error: Alignment analysis must be run from a feature branch (created by /speckit.specify)" + exit 1 +} + +$CurrentSpec = Join-Path $RepoRoot "specs" $CurrentBranch "spec.md" +if (-not (Test-Path $CurrentSpec)) { + Write-Error "Error: Current specification not found at $CurrentSpec" + exit 1 +} + +# Find all existing specifications +$AllSpecs = @() +$SpecsDir = Join-Path $RepoRoot "specs" +if (Test-Path $SpecsDir) { + $SpecDirs = Get-ChildItem -Path $SpecsDir -Directory + foreach ($dir in $SpecDirs) { + $SpecFile = Join-Path $dir.FullName "spec.md" + if ((Test-Path $SpecFile) -and ($SpecFile -ne $CurrentSpec)) { + $AllSpecs += $SpecFile + } + } +} + +# Create analysis file in current feature directory +$FeatureDir = Split-Path -Parent $CurrentSpec +$AnalysisFile = Join-Path $FeatureDir "cross-feature-analysis.md" + +# Create analysis file from template +$Template = Join-Path $RepoRoot "templates" "cross-feature-analysis-template.md" +if (Test-Path $Template) { + Copy-Item $Template $AnalysisFile +} else { + New-Item -ItemType File -Path $AnalysisFile -Force | Out-Null +} + +# Extract clarification line from template to avoid duplication +$CommandTemplate = Join-Path $RepoRoot "templates" "commands" "cross-feature.md" +$ClarificationLine = "" + +if (Test-Path $CommandTemplate) { + # Extract the clarification message from the template (handles both quotes and backticks) + $TemplateContent = Get-Content $CommandTemplate -Raw + if ($TemplateContent -match 'Add: ["''`]([^"''`]+)["''`]') { + $ClarificationLine = $matches[1] + } +} + +# Fallback if extraction fails +# NOTE: This fallback must match the clarification line in templates/commands/cross-feature.md +# The template is the source of truth - update there first if changing this message +if ([string]::IsNullOrWhiteSpace($ClarificationLine)) { + $ClarificationLine = "- [NEEDS CLARIFICATION: Review cross-feature alignment analysis in cross-feature-analysis.md - potential conflicts identified that may require spec adjustments]" +} + +# Find the Requirements section and add the clarification line +if (Test-Path $CurrentSpec) { + $SpecContent = Get-Content $CurrentSpec -Raw + + # Check if the clarification line already exists to avoid duplicates + if (-not $SpecContent.Contains("cross-feature-analysis.md")) { + $Lines = Get-Content $CurrentSpec + $NewLines = @() + $Added = $false + + foreach ($Line in $Lines) { + $NewLines += $Line + # Add clarification line after "### Functional Requirements" + if ($Line -match "^### Functional Requirements" -and -not $Added) { + $NewLines += $ClarificationLine + $Added = $true + } + } + + # If no Functional Requirements section found, add to end + if (-not $Added) { + $NewLines += "" + $NewLines += $ClarificationLine + } + + # Write back to file + $NewLines | Set-Content $CurrentSpec + } +} + +# Build output +if ($JsonMode) { + $AllSpecsJson = $AllSpecs | ForEach-Object { "`"$_`"" } | Join-String -Separator "," + $Output = @{ + CURRENT_SPEC = $CurrentSpec + ALL_SPECS = $AllSpecs + ANALYSIS_FILE = $AnalysisFile + ANALYSIS_FOCUS = $AnalysisFocus + } + $Output | ConvertTo-Json -Compress +} else { + Write-Output "CURRENT_SPEC: $CurrentSpec" + Write-Output "ALL_SPECS: $($AllSpecs -join ' ')" + Write-Output "ANALYSIS_FILE: $AnalysisFile" + Write-Output "ANALYSIS_FOCUS: $AnalysisFocus" +} \ No newline at end of file diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index 57af082ce..5ece1dff8 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -1076,6 +1076,7 @@ def init( "Optional commands that you can use for your specs [bright_black](improve quality & confidence)[/bright_black]", "", f"○ [cyan]/speckit.clarify[/] [bright_black](optional)[/bright_black] - Ask structured questions to de-risk ambiguous areas before planning (run before [cyan]/speckit.plan[/] if used)", + f"○ [cyan]/speckit.cross-feature[/] [bright_black](optional)[/bright_black] - Systems thinking alignment analysis to identify cross-feature conflicts (run after [cyan]/speckit.specify[/])", f"○ [cyan]/speckit.analyze[/] [bright_black](optional)[/bright_black] - Cross-artifact consistency & alignment report (after [cyan]/speckit.tasks[/], before [cyan]/speckit.implement[/])", f"○ [cyan]/speckit.checklist[/] [bright_black](optional)[/bright_black] - Generate quality checklists to validate requirements completeness, clarity, and consistency (after [cyan]/speckit.plan[/])" ] diff --git a/templates/commands/analyze.md b/templates/commands/analyze.md index 473339fc2..827d4e4ca 100644 --- a/templates/commands/analyze.md +++ b/templates/commands/analyze.md @@ -15,13 +15,13 @@ You **MUST** consider the user input before proceeding (if not empty). ## Goal -Identify inconsistencies, duplications, ambiguities, and underspecified items across the three core artifacts (`spec.md`, `plan.md`, `tasks.md`) before implementation. This command MUST run only after `/tasks` has successfully produced a complete `tasks.md`. +Identify inconsistencies, duplications, ambiguities, and underspecified items across the three core artifacts (`spec.md`, `plan.md`, `tasks.md`) before implementation. This command MUST run only after `/speckit.tasks` has successfully produced a complete `tasks.md`. ## Operating Constraints **STRICTLY READ-ONLY**: Do **not** modify any files. Output a structured analysis report. Offer an optional remediation plan (user must explicitly approve before any follow-up editing commands would be invoked manually). -**Constitution Authority**: The project constitution (`/memory/constitution.md`) is **non-negotiable** within this analysis scope. Constitution conflicts are automatically CRITICAL and require adjustment of the spec, plan, or tasks—not dilution, reinterpretation, or silent ignoring of the principle. If a principle itself needs to change, that must occur in a separate, explicit constitution update outside `/analyze`. +**Constitution Authority**: The project constitution (`/memory/constitution.md`) is **non-negotiable** within this analysis scope. Constitution conflicts are automatically CRITICAL and require adjustment of the spec, plan, or tasks—not dilution, reinterpretation, or silent ignoring of the principle. If a principle itself needs to change, that must occur in a separate, explicit constitution update outside `/speckit.analyze`. ## Execution Steps @@ -157,9 +157,9 @@ Output a Markdown report (no file writes) with the following structure: At end of report, output a concise Next Actions block: -- If CRITICAL issues exist: Recommend resolving before `/implement` +- If CRITICAL issues exist: Recommend resolving before `/speckit.implement` - If only LOW/MEDIUM: User may proceed, but provide improvement suggestions -- Provide explicit command suggestions: e.g., "Run /specify with refinement", "Run /plan to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'" +- Provide explicit command suggestions: e.g., "Run /speckit.specify with refinement", "Run /speckit.plan to adjust architecture", "Manually edit tasks.md to add coverage for 'performance-metrics'" ### 8. Offer Remediation diff --git a/templates/commands/cross-feature.md b/templates/commands/cross-feature.md new file mode 100644 index 000000000..1594669b5 --- /dev/null +++ b/templates/commands/cross-feature.md @@ -0,0 +1,49 @@ +--- +description: Analyze how the current feature aligns with existing features using systems thinking to identify conflicts, dependencies, and emergent behaviors. +scripts: + sh: scripts/bash/cross-feature-check-all-features.sh --json "{ARGS}" + ps: scripts/powershell/cross-feature-check-all-features.ps1 -Json "{ARGS}" +--- + +The text the user typed after `/speckit.cross-feature` in the triggering message **is** optional analysis focus. If empty, perform comprehensive alignment analysis. Assume you always have it available in this conversation even if `{ARGS}` appears literally below. + +Given the current feature specification and optional analysis focus, do this: + +1. Run the script `{SCRIPT}` from repo root and parse its JSON output for CURRENT_SPEC, ALL_SPECS, and ANALYSIS_FILE. All file paths must be absolute. + **IMPORTANT** You must only ever run this script once. The JSON is provided in the terminal as output - always refer to it to get the actual content you're looking for. + +2. Load `templates/cross-feature-analysis-template.md` to understand the alignment analysis framework structure. + +3. Read the current feature specification from CURRENT_SPEC to understand: + - Feature purpose and user scenarios + - Functional requirements + - Key entities and relationships + +4. Analyze ALL_SPECS (array of paths to existing specifications) to identify ONLY actual issues: + - **Real conflicts**: Does this feature conflict with existing features? (shared resources, timing issues, contradictory behavior) + - **Dependencies**: Does this feature depend on or modify behavior from existing features? + - **Side effects**: Will this feature cause unexpected problems in other features? + - **Questions**: What needs clarification about cross-feature interactions? + +5. Be concise and action-oriented: + - **Skip empty sections**: If there are no issues in a category, remove that section entirely + - **One-line summaries**: Issues, impacts, and fixes should each be one line + - **Questions not essays**: Raise specific questions, don't explain systems theory + - **Actionable only**: Only include information that requires a decision or action + - **Target length**: 50-100 lines total, not 500+ lines + +6. Write the alignment analysis to ANALYSIS_FILE using the template structure, including ONLY: + - Impact summary (interactions, risk level, action needed) + - Specific questions that need answers (if any) + - Actual issues found with other features (if any) + - Concrete recommendations (if any) + - Remove any sections that don't apply + +7. Add a single clarification line to the current spec.md file in the Requirements section: + - Add: `- [NEEDS CLARIFICATION: Review cross-feature alignment analysis in cross-feature-analysis.md - potential conflicts identified that may require spec adjustments]` + - This ensures `/speckit.clarify` will pick up alignment issues naturally + - **Note:** Scripts should extract this clarification text programmatically from this template to avoid duplication + +8. Report completion with analysis file path, key alignment insights discovered, and any clarification needs identified. + +Note: This command should be run after `/speckit.specify` but before `/speckit.plan` to ensure systems thinking informs the technical implementation planning phase. \ No newline at end of file diff --git a/templates/commands/implement.md b/templates/commands/implement.md index 605559753..4ca01d94b 100644 --- a/templates/commands/implement.md +++ b/templates/commands/implement.md @@ -122,4 +122,4 @@ You **MUST** consider the user input before proceeding (if not empty). - Confirm the implementation follows the technical plan - Report final status with summary of completed work -Note: This command assumes a complete task breakdown exists in tasks.md. If tasks are incomplete or missing, suggest running `/tasks` first to regenerate the task list. +Note: This command assumes a complete task breakdown exists in tasks.md. If tasks are incomplete or missing, suggest running `/speckit.tasks` first to regenerate the task list. diff --git a/templates/commands/specify.md b/templates/commands/specify.md index 7f5f17994..7fa4a2d06 100644 --- a/templates/commands/specify.md +++ b/templates/commands/specify.md @@ -143,7 +143,7 @@ Given that feature description, do this: d. **Update Checklist**: After each validation iteration, update the checklist file with current pass/fail status -6. Report completion with branch name, spec file path, checklist results, and readiness for the next phase (`/speckit.clarify` or `/speckit.plan`). +6. Report completion with branch name, spec file path, checklist results, and readiness for the next phase (`/speckit.clarify`, `/speckit.cross-feature` (optional), or `/speckit.plan`). **NOTE:** The script creates and checks out the new branch and initializes the spec file before writing. diff --git a/templates/cross-feature-analysis-template.md b/templates/cross-feature-analysis-template.md new file mode 100644 index 000000000..e7956ebdd --- /dev/null +++ b/templates/cross-feature-analysis-template.md @@ -0,0 +1,87 @@ +# Alignment Check: [FEATURE NAME] + +**Feature**: `[###-feature-name]` +**Date**: [DATE] +**Analyzed Against**: [Number] existing features + +--- + +## Impact Summary + +**Cross-Feature Interactions**: [Yes/No - if Yes, list which features] +**Conflict Risk**: [None/Low/Medium/High] +**Action Required**: [Yes/No] + +--- + +## Questions to Resolve + +*[Only include this section if there are actual questions. Remove if none.]* + +1. [NEEDS CLARIFICATION: Specific question about interaction between this feature and Feature X] +2. [NEEDS CLARIFICATION: Specific question about shared resource or timing] +3. [NEEDS CLARIFICATION: Specific question about boundary or responsibility] + +--- + +## Issues Found + +*[Only include this section if there are actual issues. Remove if none.]* + +### ⚠️ With Feature [###-feature-name] + +**Issue**: [One-line description of the problem] +**Impact**: [What breaks or goes wrong] +**Fix**: [Specific action to take] + +### ⚠️ With Feature [###-feature-name] + +**Issue**: [One-line description] +**Impact**: [What breaks or goes wrong] +**Fix**: [Specific action to take] + +--- + +## Recommendations + +*[Only include this section if there are actual recommendations. Remove if none.]* + +- [ ] **Do**: [Specific action] because [one-line reason] +- [ ] **Consider**: [Specific action] to prevent [specific problem] +- [ ] **Avoid**: [Specific thing] because [one-line reason] + +--- + +## Feature Dependencies + +*[Only include if there are dependencies. Remove if none.]* + +**This feature depends on**: +- [Feature name]: [What it depends on] + +**Features that will depend on this**: +- [Feature name]: [What they'll need] + +--- + +## Potential Side Effects + +*[Only include if there are notable side effects. Remove if none.]* + +- **[Type of side effect]**: [Brief description] → [What to watch for] + +--- + +## Quick Checklist + +- [ ] All clarification questions answered +- [ ] High/Medium risk issues addressed in spec +- [ ] Recommendations reviewed and incorporated as needed +- [ ] Dependencies documented in spec +- [ ] Clarification line removed from spec.md when complete + +--- + +**Status**: ⏳ Awaiting clarification / ✅ Ready for planning + +*Remove sections that don't apply. Keep it short and actionable.* \ No newline at end of file