devforgeai 1.0.4 → 1.0.6
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.
- package/CLAUDE.md +120 -0
- package/package.json +9 -1
- package/src/CLAUDE.md +699 -0
- package/src/claude/scripts/README.md +396 -0
- package/src/claude/scripts/audit-command-skill-overlap.sh +67 -0
- package/src/claude/scripts/check-hooks-fast.sh +70 -0
- package/src/claude/scripts/devforgeai-validate +6 -0
- package/src/claude/scripts/devforgeai_cli/README.md +531 -0
- package/src/claude/scripts/devforgeai_cli/__init__.py +12 -0
- package/src/claude/scripts/devforgeai_cli/cli.py +716 -0
- package/src/claude/scripts/devforgeai_cli/commands/__init__.py +1 -0
- package/src/claude/scripts/devforgeai_cli/commands/check_hooks.py +384 -0
- package/src/claude/scripts/devforgeai_cli/commands/invoke_hooks.py +149 -0
- package/src/claude/scripts/devforgeai_cli/commands/phase_commands.py +731 -0
- package/src/claude/scripts/devforgeai_cli/commands/validate_installation.py +412 -0
- package/src/claude/scripts/devforgeai_cli/context_extraction.py +426 -0
- package/src/claude/scripts/devforgeai_cli/feedback/AC_TO_TEST_MAPPING.md +636 -0
- package/src/claude/scripts/devforgeai_cli/feedback/DELIVERY_SUMMARY.txt +329 -0
- package/src/claude/scripts/devforgeai_cli/feedback/README_TEST_SPECS.md +486 -0
- package/src/claude/scripts/devforgeai_cli/feedback/TEST_IMPLEMENTATION_GUIDE.md +529 -0
- package/src/claude/scripts/devforgeai_cli/feedback/TEST_SPECIFICATIONS.md +2652 -0
- package/src/claude/scripts/devforgeai_cli/feedback/TEST_SPECS_INDEX.md +398 -0
- package/src/claude/scripts/devforgeai_cli/feedback/__init__.py +34 -0
- package/src/claude/scripts/devforgeai_cli/feedback/adaptive_questioning_engine.py +581 -0
- package/src/claude/scripts/devforgeai_cli/feedback/aggregation.py +179 -0
- package/src/claude/scripts/devforgeai_cli/feedback/commands.py +535 -0
- package/src/claude/scripts/devforgeai_cli/feedback/config_defaults.py +58 -0
- package/src/claude/scripts/devforgeai_cli/feedback/config_manager.py +423 -0
- package/src/claude/scripts/devforgeai_cli/feedback/config_models.py +192 -0
- package/src/claude/scripts/devforgeai_cli/feedback/config_schema.py +140 -0
- package/src/claude/scripts/devforgeai_cli/feedback/coverage.json +1 -0
- package/src/claude/scripts/devforgeai_cli/feedback/feature_flag.py +152 -0
- package/src/claude/scripts/devforgeai_cli/feedback/feedback_indexer.py +394 -0
- package/src/claude/scripts/devforgeai_cli/feedback/hot_reload.py +226 -0
- package/src/claude/scripts/devforgeai_cli/feedback/longitudinal.py +115 -0
- package/src/claude/scripts/devforgeai_cli/feedback/models.py +67 -0
- package/src/claude/scripts/devforgeai_cli/feedback/question_router.py +236 -0
- package/src/claude/scripts/devforgeai_cli/feedback/retrospective.py +233 -0
- package/src/claude/scripts/devforgeai_cli/feedback/skip_tracker.py +177 -0
- package/src/claude/scripts/devforgeai_cli/feedback/skip_tracking.py +221 -0
- package/src/claude/scripts/devforgeai_cli/feedback/template_engine.py +549 -0
- package/src/claude/scripts/devforgeai_cli/feedback/validation.py +163 -0
- package/src/claude/scripts/devforgeai_cli/headless/__init__.py +30 -0
- package/src/claude/scripts/devforgeai_cli/headless/answer_models.py +206 -0
- package/src/claude/scripts/devforgeai_cli/headless/answer_resolver.py +204 -0
- package/src/claude/scripts/devforgeai_cli/headless/exceptions.py +36 -0
- package/src/claude/scripts/devforgeai_cli/headless/pattern_matcher.py +156 -0
- package/src/claude/scripts/devforgeai_cli/hooks.py +313 -0
- package/src/claude/scripts/devforgeai_cli/metrics/__init__.py +46 -0
- package/src/claude/scripts/devforgeai_cli/metrics/command_metrics.py +142 -0
- package/src/claude/scripts/devforgeai_cli/metrics/failure_modes.py +152 -0
- package/src/claude/scripts/devforgeai_cli/metrics/story_segmentation.py +181 -0
- package/src/claude/scripts/devforgeai_cli/orchestrate_hooks.py +780 -0
- package/src/claude/scripts/devforgeai_cli/phase_state.py +1229 -0
- package/src/claude/scripts/devforgeai_cli/session/__init__.py +30 -0
- package/src/claude/scripts/devforgeai_cli/session/checkpoint.py +268 -0
- package/src/claude/scripts/devforgeai_cli/tests/__init__.py +1 -0
- package/src/claude/scripts/devforgeai_cli/tests/conftest.py +29 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/TEST_EXECUTION_GUIDE.md +298 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/__init__.py +3 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_adaptive_questioning_engine.py +2171 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_aggregation.py +476 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_config_defaults.py +133 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_config_manager.py +592 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_config_models.py +373 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_config_schema.py +130 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_configuration_management.py +1355 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_edge_cases.py +308 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_feature_flag.py +307 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_feedback_indexer.py +384 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_hot_reload.py +580 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_integration.py +402 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_models.py +105 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_question_routing.py +262 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_retrospective.py +333 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_skip_tracker.py +410 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_skip_tracking.py +159 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_skip_tracking_integration.py +1155 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_template_engine.py +1389 -0
- package/src/claude/scripts/devforgeai_cli/tests/feedback/test_validation_comprehensive.py +210 -0
- package/src/claude/scripts/devforgeai_cli/tests/fixtures/autonomous-deferral-story.md +46 -0
- package/src/claude/scripts/devforgeai_cli/tests/fixtures/missing-impl-notes.md +31 -0
- package/src/claude/scripts/devforgeai_cli/tests/fixtures/valid-deferral-story.md +46 -0
- package/src/claude/scripts/devforgeai_cli/tests/fixtures/valid-story-complete.md +48 -0
- package/src/claude/scripts/devforgeai_cli/tests/manual_test_invoke_hooks.sh +200 -0
- package/src/claude/scripts/devforgeai_cli/tests/session/DELIVERABLES.md +518 -0
- package/src/claude/scripts/devforgeai_cli/tests/session/TEST_SUMMARY.md +468 -0
- package/src/claude/scripts/devforgeai_cli/tests/session/__init__.py +6 -0
- package/src/claude/scripts/devforgeai_cli/tests/session/fixtures/corrupted-checkpoint.json +1 -0
- package/src/claude/scripts/devforgeai_cli/tests/session/fixtures/missing-fields-checkpoint.json +4 -0
- package/src/claude/scripts/devforgeai_cli/tests/session/fixtures/valid-checkpoint.json +15 -0
- package/src/claude/scripts/devforgeai_cli/tests/session/test_checkpoint.py +851 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_check_hooks.py +1886 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_depends_on_normalizer.py +171 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_dod_validator.py +97 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_invoke_hooks.py +1902 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_phase_commands.py +320 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_phase_commands_error_handling.py +1021 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_phase_commands_import.py +697 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_phase_state.py +2187 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_skip_tracking.py +2141 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_skip_tracking_coverage_gap.py +195 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_subagent_enforcement.py +539 -0
- package/src/claude/scripts/devforgeai_cli/tests/test_validate_installation.py +361 -0
- package/src/claude/scripts/devforgeai_cli/utils/__init__.py +11 -0
- package/src/claude/scripts/devforgeai_cli/utils/depends_on_normalizer.py +149 -0
- package/src/claude/scripts/devforgeai_cli/utils/markdown_parser.py +219 -0
- package/src/claude/scripts/devforgeai_cli/utils/story_analyzer.py +249 -0
- package/src/claude/scripts/devforgeai_cli/utils/yaml_parser.py +152 -0
- package/src/claude/scripts/devforgeai_cli/validators/__init__.py +27 -0
- package/src/claude/scripts/devforgeai_cli/validators/ast_grep_validator.py +373 -0
- package/src/claude/scripts/devforgeai_cli/validators/context_validator.py +180 -0
- package/src/claude/scripts/devforgeai_cli/validators/dod_validator.py +309 -0
- package/src/claude/scripts/devforgeai_cli/validators/git_validator.py +107 -0
- package/src/claude/scripts/devforgeai_cli/validators/grep_fallback.py +300 -0
- package/src/claude/scripts/install_hooks.sh +186 -0
- package/src/claude/scripts/invoke_feedback_hooks.sh +59 -0
- package/src/claude/scripts/migrate-ac-headers.sh +122 -0
- package/src/claude/scripts/plan_file_kb.sh +704 -0
- package/src/claude/scripts/requirements.txt +8 -0
- package/src/claude/scripts/session_catalog.sh +543 -0
- package/src/claude/scripts/setup.py +55 -0
- package/src/claude/scripts/start-devforgeai.sh +16 -0
- package/src/claude/scripts/statusline.sh +27 -0
- package/src/claude/scripts/validate_deferrals.py +344 -0
- package/src/claude/skills/devforgeai-qa/SKILL.md +1 -1
- package/src/claude/skills/researching-market/SKILL.md +2 -1
- package/src/cli/lib/copier.js +13 -1
- package/src/claude/skills/designing-systems/scripts/__pycache__/detect_anti_patterns.cpython-312.pyc +0 -0
- package/src/claude/skills/designing-systems/scripts/__pycache__/validate_all_context.cpython-312.pyc +0 -0
- package/src/claude/skills/designing-systems/scripts/__pycache__/validate_architecture.cpython-312.pyc +0 -0
- package/src/claude/skills/designing-systems/scripts/__pycache__/validate_dependencies.cpython-312.pyc +0 -0
- package/src/claude/skills/devforgeai-story-creation/scripts/__pycache__/migrate_story_v1_to_v2.cpython-312.pyc +0 -0
- package/src/claude/skills/devforgeai-story-creation/scripts/tests/__pycache__/measure_accuracy.cpython-312.pyc +0 -0
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
# DevForgeAI Validation Scripts
|
|
2
|
+
|
|
3
|
+
Automated validation utilities for the DevForgeAI framework.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Available Scripts
|
|
8
|
+
|
|
9
|
+
### validate_deferrals.py
|
|
10
|
+
|
|
11
|
+
Lightweight format validator for deferred Definition of Done items.
|
|
12
|
+
|
|
13
|
+
**Purpose:** Quick format validation providing fast feedback (<100ms) as part of three-layer defense architecture.
|
|
14
|
+
|
|
15
|
+
**Architecture Context:**
|
|
16
|
+
|
|
17
|
+
This script is **Layer 1** of the hybrid validation approach:
|
|
18
|
+
- **Layer 1 (this script):** Fast format check (~200 tokens, <100ms)
|
|
19
|
+
- **Layer 2 (task file):** Interactive user approval checkpoint
|
|
20
|
+
- **Layer 3 (subagent):** Comprehensive AI analysis (feasibility, circular deps)
|
|
21
|
+
|
|
22
|
+
**Scope:** Format validation ONLY
|
|
23
|
+
- ✅ Checks incomplete items have justification text
|
|
24
|
+
- ✅ Checks justification matches expected patterns
|
|
25
|
+
- ❌ Does NOT check story/ADR references exist (AI handles in Layer 3)
|
|
26
|
+
- ❌ Does NOT detect circular deferrals (AI handles in Layer 3)
|
|
27
|
+
- ❌ Does NOT analyze feasibility (AI handles in Layer 3)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Basic Usage
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Format-only validation (non-blocking warnings)
|
|
37
|
+
python .claude/scripts/validate_deferrals.py \
|
|
38
|
+
--story-file devforgeai/specs/Stories/STORY-006.story.md \
|
|
39
|
+
--format-only
|
|
40
|
+
|
|
41
|
+
# Quiet mode (for automation - suppresses output)
|
|
42
|
+
python .claude/scripts/validate_deferrals.py \
|
|
43
|
+
--story-file devforgeai/specs/Stories/STORY-006.story.md \
|
|
44
|
+
--format-only \
|
|
45
|
+
--quiet
|
|
46
|
+
|
|
47
|
+
# Check exit code
|
|
48
|
+
echo $? # 0 = valid or format-only mode, 1 = invalid (strict mode), 2 = error
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Parameters
|
|
52
|
+
|
|
53
|
+
| Parameter | Required | Description |
|
|
54
|
+
|-----------|----------|-------------|
|
|
55
|
+
| `--story-file PATH` | Yes | Path to story file to validate |
|
|
56
|
+
| `--format-only` | No | Enable format-only mode (non-blocking, warnings only) |
|
|
57
|
+
| `--quiet` | No | Suppress output (return only exit code) |
|
|
58
|
+
|
|
59
|
+
### Exit Codes
|
|
60
|
+
|
|
61
|
+
| Code | Meaning | When Used |
|
|
62
|
+
|------|---------|-----------|
|
|
63
|
+
| **0** | Valid OR warnings only | Format-only mode always returns 0 (non-blocking) |
|
|
64
|
+
| **1** | Invalid | Strict mode (not used in hybrid approach) |
|
|
65
|
+
| **2** | Configuration error | File not found, parse error, system error |
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Valid Deferral Formats
|
|
70
|
+
|
|
71
|
+
The script recognizes three deferral justification patterns:
|
|
72
|
+
|
|
73
|
+
### 1. Story Split Deferral
|
|
74
|
+
|
|
75
|
+
```markdown
|
|
76
|
+
- [ ] Item description here
|
|
77
|
+
Deferred to STORY-XXX: Brief reason explaining why work moved to follow-up story
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Pattern:** `Deferred to STORY-\d+:`
|
|
81
|
+
|
|
82
|
+
### 2. External Blocker
|
|
83
|
+
|
|
84
|
+
```markdown
|
|
85
|
+
- [ ] Item description here
|
|
86
|
+
Blocked by: External dependency description (e.g., "Payment API v2 not available until 2025-12-01")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Pattern:** `Blocked by:`
|
|
90
|
+
|
|
91
|
+
### 3. Scope Change (with ADR)
|
|
92
|
+
|
|
93
|
+
```markdown
|
|
94
|
+
- [ ] Item description here
|
|
95
|
+
Out of scope: ADR-XXX documents decision to remove from current scope
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Pattern:** `Out of scope: ADR-\d+`
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Examples
|
|
103
|
+
|
|
104
|
+
### Example 1: Story with Unjustified Deferrals (STORY-006 Original Failure)
|
|
105
|
+
|
|
106
|
+
**Input:**
|
|
107
|
+
```markdown
|
|
108
|
+
## Definition of Done
|
|
109
|
+
|
|
110
|
+
- [x] Unit tests passing
|
|
111
|
+
- [ ] Performance benchmarks created
|
|
112
|
+
- [ ] Cross-platform testing
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Output:**
|
|
116
|
+
```
|
|
117
|
+
⚠️ Format issues detected (2 items)
|
|
118
|
+
|
|
119
|
+
Line 2: 'Performance benchmarks created'
|
|
120
|
+
Missing justification. Expected one of:
|
|
121
|
+
- Deferred to STORY-XXX: [reason]
|
|
122
|
+
- Blocked by: [external dependency]
|
|
123
|
+
- Out of scope: ADR-XXX
|
|
124
|
+
|
|
125
|
+
Line 3: 'Cross-platform testing'
|
|
126
|
+
Missing justification. Expected one of:
|
|
127
|
+
- Deferred to STORY-XXX: [reason]
|
|
128
|
+
- Blocked by: [external dependency]
|
|
129
|
+
- Out of scope: ADR-XXX
|
|
130
|
+
|
|
131
|
+
Note: Format-only mode - warnings only (non-blocking)
|
|
132
|
+
Interactive checkpoint will guide you through resolution.
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Exit code:** 0 (format-only mode, non-blocking)
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### Example 2: Story with Valid Deferrals
|
|
140
|
+
|
|
141
|
+
**Input:**
|
|
142
|
+
```markdown
|
|
143
|
+
## Definition of Done
|
|
144
|
+
|
|
145
|
+
- [x] Unit tests passing
|
|
146
|
+
- [ ] Performance benchmarks created
|
|
147
|
+
Deferred to STORY-007: Performance optimization story
|
|
148
|
+
- [ ] Cross-platform testing
|
|
149
|
+
Blocked by: CI/CD matrix not configured until STORY-001
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Output:**
|
|
153
|
+
```
|
|
154
|
+
✓ Deferral format validation PASSED
|
|
155
|
+
All incomplete DoD items have basic justification format
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Exit code:** 0
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### Example 3: All DoD Items Complete
|
|
163
|
+
|
|
164
|
+
**Input:**
|
|
165
|
+
```markdown
|
|
166
|
+
## Definition of Done
|
|
167
|
+
|
|
168
|
+
- [x] Unit tests passing
|
|
169
|
+
- [x] Integration tests passing
|
|
170
|
+
- [x] Code reviewed
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Output:**
|
|
174
|
+
```
|
|
175
|
+
✓ Deferral format validation PASSED
|
|
176
|
+
All incomplete DoD items have basic justification format
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Exit code:** 0
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Integration with /dev Command
|
|
184
|
+
|
|
185
|
+
This script is invoked automatically by `/dev` command in Phase 2.5a (Layer 1):
|
|
186
|
+
|
|
187
|
+
```markdown
|
|
188
|
+
### Phase 2.5a: Quick Format Check
|
|
189
|
+
|
|
190
|
+
Bash(command="python .claude/scripts/validate_deferrals.py --story-file ${STORY_FILE} --format-only --quiet")
|
|
191
|
+
|
|
192
|
+
# Non-blocking - always proceeds to Layer 2 (interactive checkpoint)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Token cost:** ~200 tokens
|
|
196
|
+
**Performance:** <100ms
|
|
197
|
+
**Purpose:** Fast feedback before user interaction
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Integration with Git Hooks (Optional)
|
|
202
|
+
|
|
203
|
+
Create `.git/hooks/pre-commit`:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
#!/bin/bash
|
|
207
|
+
# Pre-commit hook: Validate story deferrals
|
|
208
|
+
|
|
209
|
+
STORY_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\devforgeai/specs/Stories/.*\.story\.md$')
|
|
210
|
+
|
|
211
|
+
if [ -n "$STORY_FILES" ]; then
|
|
212
|
+
echo "Validating story deferrals..."
|
|
213
|
+
|
|
214
|
+
for file in $STORY_FILES; do
|
|
215
|
+
python .claude/scripts/validate_deferrals.py --story-file "$file" --format-only
|
|
216
|
+
|
|
217
|
+
if [ $? -ne 0 ]; then
|
|
218
|
+
echo "❌ Validation failed: $file"
|
|
219
|
+
exit 1
|
|
220
|
+
fi
|
|
221
|
+
done
|
|
222
|
+
|
|
223
|
+
echo "✅ Format validation passed"
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
exit 0
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Note:** Git hooks provide standalone capability when committing outside /dev workflow.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Framework Compliance
|
|
234
|
+
|
|
235
|
+
### Native Tools Efficiency
|
|
236
|
+
|
|
237
|
+
Per `devforgeai/specs/Terminal/native-tools-vs-bash-efficiency-analysis.md`:
|
|
238
|
+
|
|
239
|
+
**This script follows efficiency guidelines:**
|
|
240
|
+
- ✅ Uses Python stdlib file I/O (not Bash cat/sed/grep)
|
|
241
|
+
- ✅ Invoked via Bash subprocess (terminal operation, not file operation)
|
|
242
|
+
- ✅ Minimal token cost (~200 tokens for Bash invocation + output)
|
|
243
|
+
- ✅ No Bash file operations (compliant with "Use native tools for files" mandate)
|
|
244
|
+
|
|
245
|
+
**Pattern:** Bash used ONLY for executing Python (analogous to "pytest", "npm test")
|
|
246
|
+
|
|
247
|
+
### Framework Validation Pattern
|
|
248
|
+
|
|
249
|
+
Follows established patterns from:
|
|
250
|
+
- `.claude/skills/designing-systems/scripts/validate_all_context.py` (Color class, exit codes)
|
|
251
|
+
- `.claude/skills/devforgeai-qa/scripts/validate_spec_compliance.py` (dataclass patterns, argparse)
|
|
252
|
+
|
|
253
|
+
**Consistency:** Matches 16 existing framework validation scripts (Python, not Bash)
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Testing
|
|
258
|
+
|
|
259
|
+
### Test Scenarios
|
|
260
|
+
|
|
261
|
+
**Scenario 1: Unjustified Deferrals (STORY-006)**
|
|
262
|
+
```bash
|
|
263
|
+
python validate_deferrals.py --story-file tmp/STORY-006-tree-sitter-ffi-integration.story.md --format-only
|
|
264
|
+
# Expected: ⚠️ 2 violations detected, exit 0
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Scenario 2: Valid Deferrals**
|
|
268
|
+
```bash
|
|
269
|
+
python validate_deferrals.py --story-file tmp/test-story-valid-deferrals.md --format-only
|
|
270
|
+
# Expected: ✓ PASSED, exit 0
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Scenario 3: All Complete**
|
|
274
|
+
```bash
|
|
275
|
+
python validate_deferrals.py --story-file tmp/test-story-complete.md --format-only
|
|
276
|
+
# Expected: ✓ PASSED, exit 0
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**All scenarios tested:** ✅ PASS
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Performance Characteristics
|
|
284
|
+
|
|
285
|
+
**Execution speed:**
|
|
286
|
+
- Story with 5 DoD items: <50ms
|
|
287
|
+
- Story with 15 DoD items: <100ms
|
|
288
|
+
- Story with 50 DoD items: <200ms
|
|
289
|
+
|
|
290
|
+
**Token cost (when invoked via Bash in /dev workflow):**
|
|
291
|
+
- Bash invocation: ~100 tokens
|
|
292
|
+
- Output (success): ~100 tokens
|
|
293
|
+
- Output (warnings): ~300 tokens
|
|
294
|
+
- **Average:** ~200 tokens
|
|
295
|
+
|
|
296
|
+
**Memory usage:** <5MB (lightweight, no external dependencies)
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Troubleshooting
|
|
301
|
+
|
|
302
|
+
### "Story file not found" Error
|
|
303
|
+
|
|
304
|
+
**Problem:**
|
|
305
|
+
```
|
|
306
|
+
ERROR: Story file not found: devforgeai/specs/Stories/STORY-006.story.md
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Solution:**
|
|
310
|
+
- Verify file path is correct
|
|
311
|
+
- Use Glob to find story: `Glob(pattern="devforgeai/specs/Stories/STORY-006*.story.md")`
|
|
312
|
+
- Check file exists: `ls devforgeai/specs/Stories/`
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
### "No DoD section found" (False Negative)
|
|
317
|
+
|
|
318
|
+
**Problem:** Script reports PASSED but story has no DoD section
|
|
319
|
+
|
|
320
|
+
**Explanation:**
|
|
321
|
+
- Script assumes no DoD section = no violations (lenient)
|
|
322
|
+
- Comprehensive validation (Layer 3 subagent) will catch missing DoD
|
|
323
|
+
|
|
324
|
+
**Solution:** This is expected behavior - not a bug
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
### Pattern Not Recognized
|
|
329
|
+
|
|
330
|
+
**Problem:** Valid justification flagged as violation
|
|
331
|
+
|
|
332
|
+
**Example:**
|
|
333
|
+
```markdown
|
|
334
|
+
- [ ] Item here
|
|
335
|
+
deferred to STORY-007: reason
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Cause:** Lowercase "deferred" doesn't match pattern (expects "Deferred")
|
|
339
|
+
|
|
340
|
+
**Solution:**
|
|
341
|
+
- Script uses case-insensitive matching (re.IGNORECASE)
|
|
342
|
+
- If still not recognized, check pattern matches exactly:
|
|
343
|
+
- `Deferred to STORY-XXX:` (note colon)
|
|
344
|
+
- `Blocked by:` (note colon)
|
|
345
|
+
- `Out of scope: ADR-XXX` (note colon after "scope")
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Related Documentation
|
|
350
|
+
|
|
351
|
+
**RCA-006 Implementation:**
|
|
352
|
+
- Recommendation 1: `.claude/skills/implementing-stories/references/dod-validation-checkpoint.md` (Layer 2)
|
|
353
|
+
- Recommendation 2: `.claude/skills/implementing-stories/SKILL.md` (XML enforcement)
|
|
354
|
+
- Recommendation 3: This script (Layer 1) + `.claude/agents/deferral-validator.md` (Layer 3)
|
|
355
|
+
|
|
356
|
+
**Framework Patterns:**
|
|
357
|
+
- `devforgeai/specs/Terminal/native-tools-vs-bash-efficiency-analysis.md` (token efficiency)
|
|
358
|
+
- `.claude/skills/designing-systems/scripts/` (validation script patterns)
|
|
359
|
+
|
|
360
|
+
**Integration:**
|
|
361
|
+
- `.claude/commands/dev.md` (Phase 2.5a invokes this script)
|
|
362
|
+
- `.claude/agents/deferral-validator.md` (Layer 3 comprehensive validation)
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## Maintenance
|
|
367
|
+
|
|
368
|
+
### Adding New Deferral Patterns
|
|
369
|
+
|
|
370
|
+
Edit `VALID_PATTERNS` in `FormatValidator` class:
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
VALID_PATTERNS = [
|
|
374
|
+
r'Deferred to STORY-\d+:',
|
|
375
|
+
r'Blocked by:',
|
|
376
|
+
r'Out of scope: ADR-\d+',
|
|
377
|
+
r'Your new pattern here' # Add new patterns
|
|
378
|
+
]
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Updating Error Messages
|
|
382
|
+
|
|
383
|
+
Edit violation string in `validate()` method:
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
violations.append(
|
|
387
|
+
f"Line {item.line_num}: '{self._truncate(item.text, 60)}'\n"
|
|
388
|
+
f" Your custom message here"
|
|
389
|
+
)
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
**Last Updated:** 2025-11-04
|
|
395
|
+
**Version:** 1.0.0
|
|
396
|
+
**Status:** Production Ready
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Audit commands for potential lean orchestration violations
|
|
3
|
+
# Story: STORY-410 - Create Automated Audit for Command/Skill Hybrid Violations
|
|
4
|
+
# Source: RCA-038 REC-4
|
|
5
|
+
#
|
|
6
|
+
# Usage: COMMANDS_DIR=.claude/commands bash audit-command-skill-overlap.sh
|
|
7
|
+
#
|
|
8
|
+
# Detects commands with excessive code blocks before Skill() invocation,
|
|
9
|
+
# which may indicate hybrid command/skill violations where manual workflow
|
|
10
|
+
# steps are documented in the command instead of delegating to the skill.
|
|
11
|
+
#
|
|
12
|
+
# Threshold: >4 code blocks (>8 triple-backtick lines) before Skill()
|
|
13
|
+
#
|
|
14
|
+
# Exit codes:
|
|
15
|
+
# 0 - All commands clean (no violations)
|
|
16
|
+
# 1 - One or more violations detected
|
|
17
|
+
|
|
18
|
+
# Strict mode (pipefail but not -e since grep returns 1 on no match)
|
|
19
|
+
set -uo pipefail
|
|
20
|
+
|
|
21
|
+
# Default to .claude/commands if COMMANDS_DIR not set
|
|
22
|
+
COMMANDS_DIR="${COMMANDS_DIR:-.claude/commands}"
|
|
23
|
+
|
|
24
|
+
# Validate directory exists
|
|
25
|
+
if [ ! -d "$COMMANDS_DIR" ]; then
|
|
26
|
+
echo "ERROR: Directory not found: $COMMANDS_DIR" >&2
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Threshold: more than 8 backtick lines = more than 4 code blocks = violation
|
|
31
|
+
BACKTICK_THRESHOLD=8
|
|
32
|
+
|
|
33
|
+
# Track violation count for exit code
|
|
34
|
+
violations=0
|
|
35
|
+
|
|
36
|
+
# Handle case where no .md files exist
|
|
37
|
+
shopt -s nullglob
|
|
38
|
+
|
|
39
|
+
for cmd in "$COMMANDS_DIR"/*.md; do
|
|
40
|
+
filename=$(basename "$cmd")
|
|
41
|
+
|
|
42
|
+
# Find first line containing Skill(command= pattern
|
|
43
|
+
first_skill_line=$(grep -n "Skill(command=" "$cmd" 2>/dev/null | head -1 | cut -d: -f1)
|
|
44
|
+
|
|
45
|
+
if [ -z "$first_skill_line" ]; then
|
|
46
|
+
echo "⚠️ $filename: No Skill() invocation found"
|
|
47
|
+
continue
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
# Count triple-backtick lines before the Skill() line
|
|
51
|
+
# Each code block has an opening ``` and closing ```, so count = 2 * num_blocks
|
|
52
|
+
backtick_lines=$(head -n "$((first_skill_line - 1))" "$cmd" 2>/dev/null | grep -c '```')
|
|
53
|
+
|
|
54
|
+
if [ "$backtick_lines" -gt "$BACKTICK_THRESHOLD" ]; then
|
|
55
|
+
echo "❌ $filename: $backtick_lines code blocks before Skill() - potential hybrid violation"
|
|
56
|
+
violations=$((violations + 1))
|
|
57
|
+
else
|
|
58
|
+
echo "✅ $filename: Clean ($backtick_lines code blocks before Skill())"
|
|
59
|
+
fi
|
|
60
|
+
done
|
|
61
|
+
|
|
62
|
+
# Exit non-zero if any violations found
|
|
63
|
+
if [ "$violations" -gt 0 ]; then
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
exit 0
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Fast check-hooks implementation for audit-deferrals
|
|
3
|
+
# Bypasses Python startup overhead for <100ms requirement
|
|
4
|
+
#
|
|
5
|
+
# Usage: check-hooks-fast.sh audit-deferrals success
|
|
6
|
+
# Exit codes: 0 = trigger, 1 = don't trigger, 2 = error
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
OPERATION="${1:-}"
|
|
11
|
+
STATUS="${2:-}"
|
|
12
|
+
CONFIG_FILE="${3:-devforgeai/config/hooks.yaml}"
|
|
13
|
+
|
|
14
|
+
# Validate arguments
|
|
15
|
+
if [ -z "$OPERATION" ] || [ -z "$STATUS" ]; then
|
|
16
|
+
echo "ERROR: Missing required arguments" >&2
|
|
17
|
+
echo "Usage: check-hooks-fast.sh OPERATION STATUS [CONFIG_FILE]" >&2
|
|
18
|
+
exit 2
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Check for circular invocation
|
|
22
|
+
if [ -n "${DEVFORGEAI_HOOK_ACTIVE:-}" ]; then
|
|
23
|
+
echo "Circular hook invocation detected, skipping" >&2
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Check if config exists
|
|
28
|
+
if [ ! -f "$CONFIG_FILE" ]; then
|
|
29
|
+
echo "Hooks config not found, assuming disabled" >&2
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Fast YAML parsing using grep (no Python overhead)
|
|
34
|
+
# Extract enabled status
|
|
35
|
+
enabled=$(grep "^enabled:" "$CONFIG_FILE" | awk '{print $2}' | tr -d ' ')
|
|
36
|
+
if [ "$enabled" != "true" ]; then
|
|
37
|
+
echo "Hooks are disabled in configuration" >&2
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Extract trigger_on rule for operation (with fallback to global)
|
|
42
|
+
op_trigger=$(grep -A 2 "^ $OPERATION:" "$CONFIG_FILE" | grep "trigger_on:" | awk '{print $2}' | tr -d ' ')
|
|
43
|
+
if [ -z "$op_trigger" ]; then
|
|
44
|
+
# Fallback to global rule
|
|
45
|
+
op_trigger=$(grep "^ trigger_on:" "$CONFIG_FILE" | head -1 | awk '{print $2}' | tr -d ' ')
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Apply trigger rules
|
|
49
|
+
case "$op_trigger" in
|
|
50
|
+
"all")
|
|
51
|
+
# Trigger on any status
|
|
52
|
+
exit 0
|
|
53
|
+
;;
|
|
54
|
+
"failures-only")
|
|
55
|
+
# Trigger only on failure or partial
|
|
56
|
+
if [ "$STATUS" = "failure" ] || [ "$STATUS" = "partial" ]; then
|
|
57
|
+
exit 0
|
|
58
|
+
else
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
;;
|
|
62
|
+
"none"|"")
|
|
63
|
+
# Don't trigger
|
|
64
|
+
exit 1
|
|
65
|
+
;;
|
|
66
|
+
*)
|
|
67
|
+
echo "Invalid trigger_on rule: $op_trigger" >&2
|
|
68
|
+
exit 1
|
|
69
|
+
;;
|
|
70
|
+
esac
|