specpulse 1.0.3__py3-none-any.whl → 1.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. specpulse/__init__.py +1 -1
  2. specpulse/resources/commands/claude/plan.md +180 -50
  3. specpulse/resources/commands/claude/pulse.md +79 -24
  4. specpulse/resources/commands/claude/spec.md +156 -43
  5. specpulse/resources/commands/claude/task.md +229 -48
  6. specpulse/resources/commands/gemini/plan.toml +59 -48
  7. specpulse/resources/commands/gemini/pulse.toml +21 -39
  8. specpulse/resources/commands/gemini/spec.toml +40 -28
  9. specpulse/resources/commands/gemini/task.toml +69 -51
  10. specpulse/resources/memory/constitution.md +2 -2
  11. specpulse/resources/scripts/pulse-init.ps1 +186 -0
  12. specpulse/resources/scripts/pulse-init.py +171 -0
  13. specpulse/resources/scripts/pulse-init.sh +80 -21
  14. specpulse/resources/scripts/pulse-plan.ps1 +251 -0
  15. specpulse/resources/scripts/pulse-plan.py +191 -0
  16. specpulse/resources/scripts/pulse-plan.sh +113 -12
  17. specpulse/resources/scripts/pulse-spec.ps1 +185 -0
  18. specpulse/resources/scripts/pulse-spec.py +167 -0
  19. specpulse/resources/scripts/pulse-spec.sh +86 -11
  20. specpulse/resources/scripts/pulse-task.ps1 +263 -0
  21. specpulse/resources/scripts/pulse-task.py +237 -0
  22. specpulse/resources/scripts/pulse-task.sh +123 -9
  23. specpulse/resources/templates/plan.md +142 -287
  24. specpulse/resources/templates/spec.md +80 -246
  25. specpulse/resources/templates/task.md +114 -93
  26. {specpulse-1.0.3.dist-info → specpulse-1.0.5.dist-info}/METADATA +67 -34
  27. specpulse-1.0.5.dist-info/RECORD +41 -0
  28. specpulse-1.0.3.dist-info/RECORD +0 -33
  29. {specpulse-1.0.3.dist-info → specpulse-1.0.5.dist-info}/WHEEL +0 -0
  30. {specpulse-1.0.3.dist-info → specpulse-1.0.5.dist-info}/entry_points.txt +0 -0
  31. {specpulse-1.0.3.dist-info → specpulse-1.0.5.dist-info}/licenses/LICENSE +0 -0
  32. {specpulse-1.0.3.dist-info → specpulse-1.0.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,251 @@
1
+ # SpecPulse Plan Generation Script
2
+ # Cross-platform PowerShell equivalent of pulse-plan.sh
3
+
4
+ param(
5
+ [Parameter(Mandatory=$true)]
6
+ [string]$FeatureDir,
7
+
8
+ [string]$PlanContent = ""
9
+ )
10
+
11
+ $ErrorActionPreference = "Stop"
12
+ $ProgressPreference = "SilentlyContinue"
13
+
14
+ # Configuration
15
+ $ScriptName = $MyInvocation.MyCommand.Name
16
+ $ProjectRoot = $PSScriptRoot | Split-Path -Parent | Split-Path -Parent
17
+ $MemoryDir = Join-Path $ProjectRoot "memory"
18
+ $ContextFile = Join-Path $MemoryDir "context.md"
19
+ $TemplatesDir = Join-Path $ProjectRoot "resources" "templates"
20
+
21
+ function Write-Log {
22
+ param([string]$Message)
23
+ $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
24
+ Write-Host "[$Timestamp] $ScriptName : $Message" -ForegroundColor Yellow
25
+ }
26
+
27
+ function Exit-WithError {
28
+ param([string]$Message)
29
+ Write-Log "ERROR: $Message"
30
+ exit 1
31
+ }
32
+
33
+ function Sanitize-FeatureDir {
34
+ param([string]$Dir)
35
+
36
+ if ([string]::IsNullOrWhiteSpace($Dir)) {
37
+ Exit-WithError "Feature directory cannot be empty"
38
+ }
39
+
40
+ # Remove non-alphanumeric characters except hyphens and underscores
41
+ $Sanitized = $Dir -replace '[^a-zA-Z0-9_-]', ''
42
+
43
+ if ([string]::IsNullOrWhiteSpace($Sanitized)) {
44
+ Exit-WithError "Invalid feature directory: '$Dir'"
45
+ }
46
+
47
+ return $Sanitized
48
+ }
49
+
50
+ function Find-FeatureDirectory {
51
+ if (-not (Test-Path $ContextFile)) {
52
+ Exit-WithError "No context file found and no feature directory provided"
53
+ }
54
+
55
+ try {
56
+ $Content = Get-Content $ContextFile -Raw -Encoding UTF8
57
+ # Look for "Active Feature" section
58
+ if ($Content -match 'Active Feature:\s*(.+)') {
59
+ $FeatureDir = $matches[1].Trim()
60
+ Write-Log "Using active feature from context: $FeatureDir"
61
+ return $FeatureDir
62
+ } else {
63
+ Exit-WithError "No active feature found in context file"
64
+ }
65
+ } catch {
66
+ Exit-WithError "Failed to read context file: $_"
67
+ }
68
+ }
69
+
70
+ function Get-CurrentFeatureDir {
71
+ param([string]$ProvidedDir)
72
+
73
+ if ($ProvidedDir) {
74
+ return Sanitize-FeatureDir -Dir $ProvidedDir
75
+ } else {
76
+ return Find-FeatureDirectory
77
+ }
78
+ }
79
+
80
+ function Validate-PlanStructure {
81
+ param([string]$PlanFile)
82
+
83
+ if (-not (Test-Path $PlanFile)) {
84
+ Exit-WithError "Plan file does not exist: $PlanFile"
85
+ }
86
+
87
+ # Required sections
88
+ $RequiredSections = @(
89
+ "# Implementation Plan:",
90
+ "## Technology Stack",
91
+ "## Architecture Overview",
92
+ "## Implementation Phases"
93
+ )
94
+
95
+ $Content = Get-Content $PlanFile -Raw -Encoding UTF8
96
+ $MissingSections = @()
97
+
98
+ foreach ($Section in $RequiredSections) {
99
+ if ($Content -notmatch [regex]::Escape($Section)) {
100
+ $MissingSections += $Section
101
+ }
102
+ }
103
+
104
+ if ($MissingSections.Count -gt 0) {
105
+ Write-Log "WARNING: Missing required sections: $($MissingSections -join ', ')"
106
+ }
107
+
108
+ return $MissingSections.Count
109
+ }
110
+
111
+ function Check-ConstitutionalGates {
112
+ param([string]$PlanFile)
113
+
114
+ if (-not (Test-Path $PlanFile)) {
115
+ Exit-WithError "Plan file does not exist: $PlanFile"
116
+ }
117
+
118
+ $Content = Get-Content $PlanFile -Raw -Encoding UTF8
119
+ $GatesStatus = @{}
120
+
121
+ # Check for constitutional gates compliance
122
+ $Gates = @{
123
+ "Simplicity Gate" = "Article VII: Simplicity Gate"
124
+ "Anti-Abstraction Gate" = "Article VII: Anti-Abstraction Gate"
125
+ "Test-First Gate" = "Article III: Test-First Gate"
126
+ "Integration-First Gate" = "Article VIII: Integration-First Gate"
127
+ "Research Gate" = "Article VI: Research Gate"
128
+ }
129
+
130
+ foreach ($Gate in $Gates.GetEnumerator()) {
131
+ if ($Content -match $Gate.Value) {
132
+ $GatesStatus[$Gate.Key] = "COMPLETED"
133
+ } else {
134
+ $GatesStatus[$Gate.Key] = "PENDING"
135
+ }
136
+ }
137
+
138
+ return $GatesStatus
139
+ }
140
+
141
+ function Analyze-Complexity {
142
+ param([string]$PlanFile)
143
+
144
+ if (-not (Test-Path $PlanFile)) {
145
+ Exit-WithError "Plan file does not exist: $PlanFile"
146
+ }
147
+
148
+ $Content = Get-Content $PlanFile -Raw -Encoding UTF8
149
+
150
+ # Count complexity exceptions
151
+ $ExceptionMatches = [regex]::Matches($Content, "Complexity Exception")
152
+ $ExceptionCount = $ExceptionMatches.Count
153
+
154
+ # Check for complexity tracking
155
+ $HasComplexityTracking = $Content -match "Complexity Tracking"
156
+
157
+ # Count modules/projects mentioned
158
+ $ModuleMatches = [regex]::Matches($Content, "(?i)(module|project)s?\s*[:\-]?\s*\d+")
159
+ $ModuleCount = 0
160
+ if ($ModuleMatches.Count -gt 0) {
161
+ foreach ($Match in $ModuleMatches) {
162
+ if ($Match.Value -match "\d+") {
163
+ $ModuleCount = [int]$matches[0]
164
+ break
165
+ }
166
+ }
167
+ }
168
+
169
+ return @{
170
+ ExceptionCount = $ExceptionCount
171
+ HasComplexityTracking = $HasComplexityTracking
172
+ ModuleCount = $ModuleCount
173
+ }
174
+ }
175
+
176
+ # Main execution
177
+ Write-Log "Processing plan..."
178
+
179
+ # Get and sanitize feature directory
180
+ $SanitizedDir = Get-CurrentFeatureDir -ProvidedDir $FeatureDir
181
+
182
+ # Set file paths
183
+ $PlanFile = Join-Path $ProjectRoot "plans" $SanitizedDir "plan.md"
184
+ $SpecFile = Join-Path $ProjectRoot "specs" $SanitizedDir "spec.md"
185
+ $TemplateFile = Join-Path $TemplatesDir "plan.md"
186
+
187
+ # Ensure plans directory exists
188
+ $PlanDir = Split-Path $PlanFile -Parent
189
+ New-Item -ItemType Directory -Path $PlanDir -Force | Out-Null
190
+
191
+ # Handle plan content
192
+ if ($PlanContent) {
193
+ Write-Log "Updating plan file: $PlanFile"
194
+ try {
195
+ Set-Content -Path $PlanFile -Value $PlanContent -Encoding UTF8
196
+ } catch {
197
+ Exit-WithError "Failed to write plan content: $_"
198
+ }
199
+ } else {
200
+ # Ensure plan file exists from template
201
+ if (-not (Test-Path $PlanFile)) {
202
+ if (-not (Test-Path $TemplateFile)) {
203
+ Exit-WithError "Template not found: $TemplateFile"
204
+ }
205
+
206
+ Write-Log "Creating plan file from template: $PlanFile"
207
+ try {
208
+ Copy-Item $TemplateFile $PlanFile -Force
209
+ } catch {
210
+ Exit-WithError "Failed to copy plan template: $_"
211
+ }
212
+ } else {
213
+ Write-Log "Plan file already exists: $PlanFile"
214
+ }
215
+ }
216
+
217
+ # Validate plan structure
218
+ Write-Log "Validating plan structure..."
219
+ $MissingSections = Validate-PlanStructure -PlanFile $PlanFile
220
+
221
+ # Check constitutional gates
222
+ Write-Log "Checking constitutional gates..."
223
+ $GatesStatus = Check-ConstitutionalGates -PlanFile $PlanFile
224
+
225
+ # Analyze complexity
226
+ Write-Log "Analyzing complexity..."
227
+ $ComplexityAnalysis = Analyze-Complexity -PlanFile $PlanFile
228
+
229
+ # Count completed constitutional gates
230
+ $CompletedGates = 0
231
+ foreach ($Status in $GatesStatus.Values) {
232
+ if ($Status -eq "COMPLETED") {
233
+ $CompletedGates++
234
+ }
235
+ }
236
+
237
+ # Check if specification exists
238
+ $SpecExists = Test-Path $SpecFile
239
+
240
+ Write-Log "Plan processing completed successfully"
241
+
242
+ # Output results
243
+ Write-Host "PLAN_FILE=$PlanFile"
244
+ Write-Host "SPEC_EXISTS=$SpecExists"
245
+ Write-Host "MISSING_SECTIONS=$MissingSections"
246
+ Write-Host "COMPLETED_GATES=$CompletedGates"
247
+ Write-Host "TOTAL_GATES=$($GatesStatus.Count)"
248
+ Write-Host "COMPLEXITY_EXCEPTIONS=$($ComplexityAnalysis.ExceptionCount)"
249
+ Write-Host "HAS_COMPLEXITY_TRACKING=$($ComplexityAnalysis.HasComplexityTracking)"
250
+ Write-Host "MODULE_COUNT=$($ComplexityAnalysis.ModuleCount)"
251
+ Write-Host "STATUS=processed"
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ SpecPulse Plan Generation Script
4
+ Cross-platform Python equivalent of pulse-plan.sh
5
+ """
6
+
7
+ import os
8
+ import sys
9
+ import re
10
+ from pathlib import Path
11
+ import datetime
12
+
13
+ class SpecPulsePlan:
14
+ def __init__(self):
15
+ self.script_name = Path(__file__).name
16
+ self.project_root = Path(__file__).parent.parent.parent
17
+ self.memory_dir = self.project_root / "memory"
18
+ self.context_file = self.memory_dir / "context.md"
19
+ self.templates_dir = self.project_root / "resources" / "templates"
20
+
21
+ def log(self, message):
22
+ """Log messages with timestamp"""
23
+ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
24
+ try:
25
+ print(f"[{timestamp}] {self.script_name}: {message}", file=sys.stderr)
26
+ except UnicodeEncodeError:
27
+ # Fallback for Windows console encoding issues
28
+ message = message.encode('cp1252', errors='replace').decode('cp1252')
29
+ print(f"[{timestamp}] {self.script_name}: {message}", file=sys.stderr)
30
+
31
+ def error_exit(self, message):
32
+ """Exit with error message"""
33
+ self.log(f"ERROR: {message}")
34
+ sys.exit(1)
35
+
36
+ def sanitize_feature_dir(self, feature_dir):
37
+ """Sanitize feature directory name"""
38
+ if not feature_dir:
39
+ self.error_exit("Feature directory cannot be empty")
40
+
41
+ sanitized = re.sub(r'[^a-zA-Z0-9_-]', '', feature_dir)
42
+
43
+ if not sanitized:
44
+ self.error_exit(f"Invalid feature directory: '{feature_dir}'")
45
+
46
+ return sanitized
47
+
48
+ def find_feature_directory(self):
49
+ """Find feature directory from context file"""
50
+ if not self.context_file.exists():
51
+ self.error_exit("No context file found and no feature directory provided")
52
+
53
+ try:
54
+ content = self.context_file.read_text(encoding='utf-8')
55
+ match = re.search(r'Active Feature:\s*(.+)', content)
56
+ if match:
57
+ feature_dir = match.group(1).strip()
58
+ self.log(f"Using active feature from context: {feature_dir}")
59
+ return feature_dir
60
+ else:
61
+ self.error_exit("No active feature found in context file")
62
+ except Exception as e:
63
+ self.error_exit(f"Failed to read context file: {e}")
64
+
65
+ def get_current_feature_dir(self, provided_dir):
66
+ """Get current feature directory"""
67
+ if provided_dir:
68
+ return self.sanitize_feature_dir(provided_dir)
69
+ else:
70
+ return self.find_feature_directory()
71
+
72
+ def validate_plan_structure(self, plan_file):
73
+ """Validate plan structure"""
74
+ required_sections = [
75
+ "## Implementation Plan:",
76
+ "## Specification Reference",
77
+ "## Phase -1: Pre-Implementation Gates",
78
+ "## Implementation Phases"
79
+ ]
80
+
81
+ missing_sections = []
82
+ content = plan_file.read_text(encoding='utf-8')
83
+
84
+ for section in required_sections:
85
+ if section not in content:
86
+ missing_sections.append(section)
87
+
88
+ if missing_sections:
89
+ self.log(f"WARNING: Missing required sections: {', '.join(missing_sections)}")
90
+
91
+ return len(missing_sections)
92
+
93
+ def check_constitutional_gates(self, plan_file):
94
+ """Check constitutional gates"""
95
+ constitutional_gates = [
96
+ "Simplicity Gate",
97
+ "Anti-Abstraction Gate",
98
+ "Test-First Gate",
99
+ "Integration-First Gate",
100
+ "Research Gate"
101
+ ]
102
+
103
+ missing_gates = []
104
+ content = plan_file.read_text(encoding='utf-8')
105
+
106
+ for gate in constitutional_gates:
107
+ if gate not in content:
108
+ missing_gates.append(gate)
109
+
110
+ if missing_gates:
111
+ self.log(f"WARNING: Missing constitutional gates: {', '.join(missing_gates)}")
112
+
113
+ # Check gate status
114
+ gate_status_match = re.search(r'Gate Status:\s*\[([^\]]+)\]', content)
115
+ if gate_status_match:
116
+ gate_status = gate_status_match.group(1)
117
+ if gate_status.upper() != "COMPLETED":
118
+ self.log(f"WARNING: Constitutional gates not completed. Status: {gate_status}")
119
+ return gate_status
120
+ else:
121
+ self.log("WARNING: Constitutional gates status not found")
122
+ return "UNKNOWN"
123
+
124
+ return "COMPLETED"
125
+
126
+ def main(self, args):
127
+ """Main execution function"""
128
+ if len(args) < 1:
129
+ self.error_exit("Usage: python pulse-plan.py <feature-dir>")
130
+
131
+ feature_dir = args[0]
132
+
133
+ self.log("Processing implementation plan...")
134
+
135
+ # Get and sanitize feature directory
136
+ sanitized_dir = self.get_current_feature_dir(feature_dir)
137
+
138
+ # Set file paths
139
+ plan_file = self.project_root / "plans" / sanitized_dir / "plan.md"
140
+ template_file = self.templates_dir / "plan.md"
141
+ spec_file = self.project_root / "specs" / sanitized_dir / "spec.md"
142
+
143
+ # Ensure plans directory exists
144
+ plan_file.parent.mkdir(parents=True, exist_ok=True)
145
+
146
+ # Check if specification exists first
147
+ if not spec_file.exists():
148
+ self.error_exit(f"Specification file not found: {spec_file}. Please create specification first.")
149
+
150
+ # Ensure plan template exists
151
+ if not template_file.exists():
152
+ self.error_exit(f"Template not found: {template_file}")
153
+
154
+ # Create plan if it doesn't exist
155
+ if not plan_file.exists():
156
+ self.log(f"Creating implementation plan from template: {plan_file}")
157
+ try:
158
+ plan_file.write_text(template_file.read_text(encoding='utf-8'))
159
+ except Exception as e:
160
+ self.error_exit(f"Failed to copy plan template: {e}")
161
+ else:
162
+ self.log(f"Implementation plan already exists: {plan_file}")
163
+
164
+ # Validate plan structure
165
+ self.log("Validating implementation plan...")
166
+ missing_sections = self.validate_plan_structure(plan_file)
167
+
168
+ # Check Constitutional Gates
169
+ self.log("Checking Constitutional Gates...")
170
+ gate_status = self.check_constitutional_gates(plan_file)
171
+
172
+ # Check if specification has clarifications needed
173
+ if spec_file.exists():
174
+ spec_content = spec_file.read_text(encoding='utf-8')
175
+ clarification_matches = re.findall(r'NEEDS CLARIFICATION', spec_content)
176
+ if clarification_matches:
177
+ clarification_count = len(clarification_matches)
178
+ self.log(f"WARNING: Specification has {clarification_count} clarifications needed - resolve before proceeding")
179
+
180
+ self.log("Implementation plan processing completed successfully")
181
+
182
+ # Output results
183
+ print(f"PLAN_FILE={plan_file}")
184
+ print(f"SPEC_FILE={spec_file}")
185
+ print(f"MISSING_SECTIONS={missing_sections}")
186
+ print(f"CONSTITUTIONAL_GATES_STATUS={gate_status}")
187
+ print("STATUS=ready")
188
+
189
+ if __name__ == "__main__":
190
+ plan = SpecPulsePlan()
191
+ plan.main(sys.argv[1:])
@@ -1,26 +1,127 @@
1
1
  #!/bin/bash
2
2
  # Generate implementation plan
3
3
 
4
- FEATURE_DIR="${1}"
4
+ set -euo pipefail # Exit on error, unset vars, pipe failures
5
5
 
6
+ # Configuration
7
+ SCRIPT_NAME="$(basename "$0")"
8
+ PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
9
+
10
+ # Function to log messages
11
+ log() {
12
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $SCRIPT_NAME: $1" >&2
13
+ }
14
+
15
+ # Function to handle errors
16
+ error_exit() {
17
+ log "ERROR: $1"
18
+ exit 1
19
+ }
20
+
21
+ # Validate arguments
22
+ if [ $# -eq 0 ]; then
23
+ error_exit "Usage: $SCRIPT_NAME <feature-dir>"
24
+ fi
25
+
26
+ FEATURE_DIR="$1"
27
+
28
+ # Sanitize feature directory
29
+ SANITIZED_DIR=$(echo "$FEATURE_DIR" | sed 's/[^a-zA-Z0-9_-]//g')
30
+
31
+ if [ -z "$SANITIZED_DIR" ]; then
32
+ error_exit "Invalid feature directory: '$FEATURE_DIR'"
33
+ fi
34
+
35
+ # Find feature directory if not provided
6
36
  if [ -z "$FEATURE_DIR" ]; then
7
- # Find current feature from context
8
- FEATURE_DIR=$(grep -A1 "Active Feature" memory/context.md | tail -1 | cut -d: -f2 | xargs)
37
+ CONTEXT_FILE="$PROJECT_ROOT/memory/context.md"
38
+ if [ -f "$CONTEXT_FILE" ]; then
39
+ FEATURE_DIR=$(grep -A1 "Active Feature" "$CONTEXT_FILE" | tail -1 | cut -d: -f2 | xargs)
40
+ if [ -z "$FEATURE_DIR" ]; then
41
+ error_exit "No active feature found in context file"
42
+ fi
43
+ log "Using active feature from context: $FEATURE_DIR"
44
+ else
45
+ error_exit "No feature directory provided and no context file found"
46
+ fi
9
47
  fi
10
48
 
11
- PLAN_FILE="plans/${FEATURE_DIR}/plan.md"
49
+ PLAN_FILE="$PROJECT_ROOT/plans/${FEATURE_DIR}/plan.md"
50
+ TEMPLATE_FILE="$PROJECT_ROOT/templates/plan.md"
51
+ SPEC_FILE="$PROJECT_ROOT/specs/${FEATURE_DIR}/spec.md"
52
+
53
+ # Ensure plans directory exists
54
+ mkdir -p "$(dirname "$PLAN_FILE")"
55
+
56
+ # Check if specification exists first
57
+ if [ ! -f "$SPEC_FILE" ]; then
58
+ error_exit "Specification file not found: $SPEC_FILE. Please create specification first."
59
+ fi
60
+
61
+ # Ensure plan template exists
62
+ if [ ! -f "$TEMPLATE_FILE" ]; then
63
+ error_exit "Template not found: $TEMPLATE_FILE"
64
+ fi
12
65
 
13
- # Ensure template exists
66
+ # Create plan if it doesn't exist
14
67
  if [ ! -f "$PLAN_FILE" ]; then
15
- cp templates/plan.md "$PLAN_FILE"
68
+ log "Creating implementation plan from template: $PLAN_FILE"
69
+ cp "$TEMPLATE_FILE" "$PLAN_FILE" || error_exit "Failed to copy plan template"
70
+ else
71
+ log "Implementation plan already exists: $PLAN_FILE"
72
+ fi
73
+
74
+ # Validate plan structure
75
+ log "Validating implementation plan..."
76
+
77
+ # Check for required sections
78
+ REQUIRED_SECTIONS=("## Implementation Plan:" "## Specification Reference" "## Phase -1: Pre-Implementation Gates" "## Implementation Phases")
79
+ MISSING_SECTIONS=()
80
+
81
+ for section in "${REQUIRED_SECTIONS[@]}"; do
82
+ if ! grep -q "$section" "$PLAN_FILE"; then
83
+ MISSING_SECTIONS+=("$section")
84
+ fi
85
+ done
86
+
87
+ if [ ${#MISSING_SECTIONS[@]} -gt 0 ]; then
88
+ log "WARNING: Missing required sections: ${MISSING_SECTIONS[*]}"
89
+ fi
90
+
91
+ # Check Constitutional Gates
92
+ log "Checking Constitutional Gates..."
93
+
94
+ CONSTITUTIONAL_GATES=(
95
+ "Simplicity Gate"
96
+ "Anti-Abstraction Gate"
97
+ "Test-First Gate"
98
+ "Integration-First Gate"
99
+ "Research Gate"
100
+ )
101
+
102
+ for gate in "${CONSTITUTIONAL_GATES[@]}"; do
103
+ if ! grep -q "$gate" "$PLAN_FILE"; then
104
+ log "WARNING: Missing constitutional gate: $gate"
105
+ fi
106
+ done
107
+
108
+ # Check if specification has clarifications needed
109
+ if grep -q "NEEDS CLARIFICATION" "$SPEC_FILE"; then
110
+ CLARIFICATION_COUNT=$(grep -c "NEEDS CLARIFICATION" "$SPEC_FILE")
111
+ log "WARNING: Specification has $CLARIFICATION_COUNT clarifications needed - resolve before proceeding"
112
+ fi
113
+
114
+ # Validate gate compliance
115
+ GATE_STATUS=$(grep -A5 "Gate Status:" "$PLAN_FILE" | tail -1 | sed 's/.*\[\(.*\)\].*/\1/' || echo "PENDING")
116
+
117
+ if [ "$GATE_STATUS" != "COMPLETED" ]; then
118
+ log "WARNING: Constitutional gates not completed. Status: $GATE_STATUS"
16
119
  fi
17
120
 
18
- # Check Phase Gates
19
- echo "Checking Phase Gates..."
20
- echo "- Constitutional compliance"
21
- echo "- Simplicity check (≤3 modules)"
22
- echo "- Test-first strategy"
23
- echo "- Framework selection"
121
+ log "Implementation plan processing completed successfully"
24
122
 
25
123
  echo "PLAN_FILE=$PLAN_FILE"
124
+ echo "SPEC_FILE=$SPEC_FILE"
125
+ echo "MISSING_SECTIONS=${#MISSING_SECTIONS[@]}"
126
+ echo "CONSTITUTIONAL_GATES_STATUS=$GATE_STATUS"
26
127
  echo "STATUS=ready"