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,210 @@
|
|
|
1
|
+
"""Comprehensive unit tests for validation.py module.
|
|
2
|
+
|
|
3
|
+
Tests all validation functions for complete coverage.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
from devforgeai_cli.feedback.validation import (
|
|
8
|
+
validate_response_length,
|
|
9
|
+
detect_spam,
|
|
10
|
+
is_coherent_text,
|
|
11
|
+
check_sensitive_content,
|
|
12
|
+
validate_story_id,
|
|
13
|
+
validate_workflow_type,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TestValidateResponseLength:
|
|
18
|
+
"""Test validate_response_length function."""
|
|
19
|
+
|
|
20
|
+
def test_valid_length_no_warning(self):
|
|
21
|
+
"""Test response within valid range with no warning."""
|
|
22
|
+
response = "This is a normal response"
|
|
23
|
+
is_valid, warning = validate_response_length(response)
|
|
24
|
+
assert is_valid is True
|
|
25
|
+
assert warning is None
|
|
26
|
+
|
|
27
|
+
def test_too_short_response(self):
|
|
28
|
+
"""Test response below minimum length."""
|
|
29
|
+
response = "Hi"
|
|
30
|
+
is_valid, warning = validate_response_length(response, min_length=5)
|
|
31
|
+
assert is_valid is False
|
|
32
|
+
assert "too short" in warning
|
|
33
|
+
|
|
34
|
+
def test_too_long_response(self):
|
|
35
|
+
"""Test response exceeding maximum length."""
|
|
36
|
+
response = "x" * 11000
|
|
37
|
+
is_valid, warning = validate_response_length(response, max_length=10000)
|
|
38
|
+
assert is_valid is False
|
|
39
|
+
assert "too long" in warning
|
|
40
|
+
|
|
41
|
+
def test_warning_threshold_triggered(self):
|
|
42
|
+
"""Test response triggering warning threshold."""
|
|
43
|
+
response = "x" * 2500
|
|
44
|
+
is_valid, warning = validate_response_length(response, warn_threshold=2000)
|
|
45
|
+
assert is_valid is True
|
|
46
|
+
assert warning is not None
|
|
47
|
+
assert "long" in warning
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class TestDetectSpam:
|
|
51
|
+
"""Test detect_spam function."""
|
|
52
|
+
|
|
53
|
+
def test_empty_text_is_spam(self):
|
|
54
|
+
"""Test that empty text is detected as spam (line 47)."""
|
|
55
|
+
assert detect_spam("") is True
|
|
56
|
+
|
|
57
|
+
def test_character_repetition_detected(self):
|
|
58
|
+
"""Test detection of character repetition."""
|
|
59
|
+
# Need more than 10 chars with 3 or fewer unique chars
|
|
60
|
+
assert detect_spam("aaaaaaaaaaa") is True # 11 a's (only 1 unique char)
|
|
61
|
+
assert detect_spam("abababababab") is True # 12 chars (only 2 unique chars)
|
|
62
|
+
assert detect_spam("111111111111") is True # 12 1's (only 1 unique char)
|
|
63
|
+
|
|
64
|
+
def test_pattern_repetition_detected(self):
|
|
65
|
+
"""Test detection of pattern repetition (lines 61-70)."""
|
|
66
|
+
# Pattern "123" repeated
|
|
67
|
+
assert detect_spam("123123123123123123") is True
|
|
68
|
+
# Pattern "abc" repeated
|
|
69
|
+
assert detect_spam("abcabcabcabcabcabcabcabc") is True
|
|
70
|
+
|
|
71
|
+
def test_low_word_count_spam(self):
|
|
72
|
+
"""Test detection of low word count with long text."""
|
|
73
|
+
# More than 50 chars but less than 5 words
|
|
74
|
+
# Need to have 4 or fewer words with more than 50 chars
|
|
75
|
+
assert detect_spam("aaa bbb ccc ddd" + "x" * 40) is True # 4 words, 55 chars total
|
|
76
|
+
|
|
77
|
+
def test_high_non_alphanumeric_ratio(self):
|
|
78
|
+
"""Test detection of high non-alphanumeric ratio."""
|
|
79
|
+
# Mostly special characters
|
|
80
|
+
assert detect_spam("!@#$%^&*()_+{}|:<>?[]\\;',./~`") is True
|
|
81
|
+
|
|
82
|
+
def test_valid_text_not_spam(self):
|
|
83
|
+
"""Test that valid text is not flagged as spam."""
|
|
84
|
+
assert detect_spam("This is a coherent piece of feedback text") is False
|
|
85
|
+
assert detect_spam("I found the documentation unclear and would like more examples") is False
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class TestIsCoherentText:
|
|
89
|
+
"""Test is_coherent_text function."""
|
|
90
|
+
|
|
91
|
+
def test_short_text_always_coherent(self):
|
|
92
|
+
"""Test that short text (<5 chars) is always considered coherent (line 84)."""
|
|
93
|
+
assert is_coherent_text("hi") is True
|
|
94
|
+
assert is_coherent_text("ok") is True
|
|
95
|
+
assert is_coherent_text("yes") is True
|
|
96
|
+
|
|
97
|
+
def test_single_character_repetition(self):
|
|
98
|
+
"""Test detection of single character repetition."""
|
|
99
|
+
assert is_coherent_text("aaaaaaaaaa") is False
|
|
100
|
+
assert is_coherent_text("1111111111") is False
|
|
101
|
+
|
|
102
|
+
def test_pattern_repetition_incoherent(self):
|
|
103
|
+
"""Test detection of repeated patterns."""
|
|
104
|
+
# Pattern "123" repeated 3+ times
|
|
105
|
+
assert is_coherent_text("123123123") is False
|
|
106
|
+
# Pattern "ab" repeated 3+ times
|
|
107
|
+
assert is_coherent_text("ababababab") is False
|
|
108
|
+
|
|
109
|
+
def test_partial_pattern_match_at_end(self):
|
|
110
|
+
"""Test detection of pattern with partial match at end."""
|
|
111
|
+
# Pattern "abc" repeated 3 times plus partial "ab"
|
|
112
|
+
assert is_coherent_text("abcabcabcab") is False
|
|
113
|
+
|
|
114
|
+
def test_coherent_text_accepted(self):
|
|
115
|
+
"""Test that truly coherent text is accepted."""
|
|
116
|
+
assert is_coherent_text("This is coherent text") is True
|
|
117
|
+
assert is_coherent_text("I would like to provide feedback on the TDD workflow") is True
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class TestCheckSensitiveContent:
|
|
121
|
+
"""Test check_sensitive_content function."""
|
|
122
|
+
|
|
123
|
+
def test_api_key_pattern_detected(self):
|
|
124
|
+
"""Test detection of API key pattern (secret)."""
|
|
125
|
+
feedback = "The command exposed my key: sk-proj1234567890abcdefghij1234567890"
|
|
126
|
+
is_sensitive, types = check_sensitive_content(feedback)
|
|
127
|
+
assert is_sensitive is True
|
|
128
|
+
assert 'secret' in types
|
|
129
|
+
|
|
130
|
+
def test_api_key_word_detected(self):
|
|
131
|
+
"""Test detection of 'api key' mention."""
|
|
132
|
+
feedback = "My API_KEY was visible in the output"
|
|
133
|
+
is_sensitive, types = check_sensitive_content(feedback)
|
|
134
|
+
assert is_sensitive is True
|
|
135
|
+
assert 'api_key' in types
|
|
136
|
+
|
|
137
|
+
def test_data_loss_concern_detected(self):
|
|
138
|
+
"""Test detection of data loss concerns."""
|
|
139
|
+
feedback = "I experienced data loss during the migration"
|
|
140
|
+
is_sensitive, types = check_sensitive_content(feedback)
|
|
141
|
+
assert is_sensitive is True
|
|
142
|
+
assert 'data_loss' in types
|
|
143
|
+
|
|
144
|
+
def test_security_breach_detected(self):
|
|
145
|
+
"""Test detection of security breach (lines 129-130)."""
|
|
146
|
+
feedback = "There was a security breach in the system"
|
|
147
|
+
is_sensitive, types = check_sensitive_content(feedback)
|
|
148
|
+
assert is_sensitive is True
|
|
149
|
+
assert 'critical_issue' in types
|
|
150
|
+
|
|
151
|
+
def test_vulnerability_without_api_key(self):
|
|
152
|
+
"""Test vulnerability detection when no API key mentioned."""
|
|
153
|
+
feedback = "I found a vulnerability in the input validation"
|
|
154
|
+
is_sensitive, types = check_sensitive_content(feedback)
|
|
155
|
+
assert is_sensitive is True
|
|
156
|
+
assert 'critical_issue' in types
|
|
157
|
+
|
|
158
|
+
def test_non_sensitive_feedback(self):
|
|
159
|
+
"""Test that normal feedback is not flagged as sensitive."""
|
|
160
|
+
feedback = "The documentation could be clearer"
|
|
161
|
+
is_sensitive, types = check_sensitive_content(feedback)
|
|
162
|
+
assert is_sensitive is False
|
|
163
|
+
assert len(types) == 0
|
|
164
|
+
|
|
165
|
+
def test_multiple_sensitive_types(self):
|
|
166
|
+
"""Test detection of multiple sensitive types."""
|
|
167
|
+
feedback = "API key exposed and data loss occurred in production database"
|
|
168
|
+
is_sensitive, types = check_sensitive_content(feedback)
|
|
169
|
+
assert is_sensitive is True
|
|
170
|
+
assert 'api_key' in types
|
|
171
|
+
assert 'data_loss' in types
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class TestValidateStoryId:
|
|
175
|
+
"""Test validate_story_id function."""
|
|
176
|
+
|
|
177
|
+
def test_valid_story_ids(self):
|
|
178
|
+
"""Test that valid story IDs are accepted."""
|
|
179
|
+
assert validate_story_id("STORY-001") is True
|
|
180
|
+
assert validate_story_id("STORY-123") is True
|
|
181
|
+
assert validate_story_id("STORY-999") is True
|
|
182
|
+
assert validate_story_id("STORY-1") is True
|
|
183
|
+
|
|
184
|
+
def test_invalid_story_ids(self):
|
|
185
|
+
"""Test that invalid story IDs are rejected."""
|
|
186
|
+
assert validate_story_id("story-001") is False # lowercase
|
|
187
|
+
assert validate_story_id("STORY-abc") is False # non-numeric
|
|
188
|
+
assert validate_story_id("TASK-001") is False # wrong prefix
|
|
189
|
+
assert validate_story_id("STORY001") is False # missing hyphen
|
|
190
|
+
assert validate_story_id("STORY-") is False # missing number
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class TestValidateWorkflowType:
|
|
194
|
+
"""Test validate_workflow_type function."""
|
|
195
|
+
|
|
196
|
+
def test_valid_workflow_types(self):
|
|
197
|
+
"""Test that all valid workflow types are accepted."""
|
|
198
|
+
valid_types = [
|
|
199
|
+
'dev', 'qa', 'orchestrate', 'release', 'ideate',
|
|
200
|
+
'create-story', 'create-epic', 'create-sprint'
|
|
201
|
+
]
|
|
202
|
+
for workflow_type in valid_types:
|
|
203
|
+
assert validate_workflow_type(workflow_type) is True
|
|
204
|
+
|
|
205
|
+
def test_invalid_workflow_types(self):
|
|
206
|
+
"""Test that invalid workflow types are rejected."""
|
|
207
|
+
assert validate_workflow_type('invalid') is False
|
|
208
|
+
assert validate_workflow_type('deploy') is False
|
|
209
|
+
assert validate_workflow_type('build') is False
|
|
210
|
+
assert validate_workflow_type('') is False
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: STORY-TEST-002
|
|
3
|
+
title: Test Story - Autonomous Deferral (VIOLATION)
|
|
4
|
+
epic: EPIC-001
|
|
5
|
+
status: Dev Complete
|
|
6
|
+
priority: HIGH
|
|
7
|
+
points: 8
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Test Story - Autonomous Deferral
|
|
11
|
+
|
|
12
|
+
This story demonstrates the autonomous deferral violation.
|
|
13
|
+
DoD marked [x] but Implementation Notes shows [ ] WITHOUT user approval.
|
|
14
|
+
|
|
15
|
+
## Definition of Done
|
|
16
|
+
|
|
17
|
+
- [x] Unit tests written and passing
|
|
18
|
+
- [x] Integration tests created
|
|
19
|
+
- [x] Deadlock retry with exponential backoff
|
|
20
|
+
- [x] Code follows coding-standards.md
|
|
21
|
+
|
|
22
|
+
## Acceptance Criteria
|
|
23
|
+
|
|
24
|
+
- Given a test scenario
|
|
25
|
+
- When executed
|
|
26
|
+
- Then should pass
|
|
27
|
+
|
|
28
|
+
## Implementation Notes
|
|
29
|
+
|
|
30
|
+
**Developer:** DevForgeAI AI Agent
|
|
31
|
+
**Implemented:** 2025-11-04
|
|
32
|
+
|
|
33
|
+
- [x] Unit tests written and passing - Completed: Created tests
|
|
34
|
+
- [x] Integration tests created - Completed: Created integration tests
|
|
35
|
+
- [ ] Deadlock retry with exponential backoff - Deferred to STORY-XXX: Complex retry logic
|
|
36
|
+
- [x] Code follows coding-standards.md - Completed: Applied standards
|
|
37
|
+
|
|
38
|
+
**VIOLATION:** "Deadlock retry" is marked [x] in DoD but [ ] in Implementation Notes
|
|
39
|
+
WITHOUT "User approved:" marker or valid reference.
|
|
40
|
+
|
|
41
|
+
This is AUTONOMOUS DEFERRAL - should FAIL validation.
|
|
42
|
+
|
|
43
|
+
## Workflow History
|
|
44
|
+
|
|
45
|
+
### 2025-11-04 - Status: Dev Complete
|
|
46
|
+
- Implementation complete (partial)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: STORY-TEST-004
|
|
3
|
+
title: Test Story - Missing Implementation Notes (VIOLATION)
|
|
4
|
+
epic: EPIC-001
|
|
5
|
+
status: Dev Complete
|
|
6
|
+
priority: HIGH
|
|
7
|
+
points: 3
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Test Story - Missing Implementation Notes
|
|
11
|
+
|
|
12
|
+
This story demonstrates missing Implementation Notes section.
|
|
13
|
+
Should FAIL validation.
|
|
14
|
+
|
|
15
|
+
## Definition of Done
|
|
16
|
+
|
|
17
|
+
- [x] Unit tests written and passing
|
|
18
|
+
- [x] Code follows coding-standards.md
|
|
19
|
+
|
|
20
|
+
## Acceptance Criteria
|
|
21
|
+
|
|
22
|
+
- Given a test scenario
|
|
23
|
+
- When executed
|
|
24
|
+
- Then should pass
|
|
25
|
+
|
|
26
|
+
## Workflow History
|
|
27
|
+
|
|
28
|
+
### 2025-11-04 - Status: Dev Complete
|
|
29
|
+
- Implementation complete
|
|
30
|
+
|
|
31
|
+
**VIOLATION:** No Implementation Notes section - should FAIL validation.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: STORY-TEST-003
|
|
3
|
+
title: Test Story - Valid Deferral with User Approval
|
|
4
|
+
epic: EPIC-001
|
|
5
|
+
status: Dev Complete
|
|
6
|
+
priority: HIGH
|
|
7
|
+
points: 8
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Test Story - Valid Deferral
|
|
11
|
+
|
|
12
|
+
This story demonstrates a VALID deferral with proper user approval marker.
|
|
13
|
+
|
|
14
|
+
## Definition of Done
|
|
15
|
+
|
|
16
|
+
- [x] Unit tests written and passing
|
|
17
|
+
- [x] Integration tests created
|
|
18
|
+
- [x] Performance benchmarks created
|
|
19
|
+
- [x] Code follows coding-standards.md
|
|
20
|
+
|
|
21
|
+
## Acceptance Criteria
|
|
22
|
+
|
|
23
|
+
- Given a test scenario
|
|
24
|
+
- When executed
|
|
25
|
+
- Then should pass
|
|
26
|
+
|
|
27
|
+
## Implementation Notes
|
|
28
|
+
|
|
29
|
+
**Developer:** DevForgeAI AI Agent
|
|
30
|
+
**Implemented:** 2025-11-04
|
|
31
|
+
|
|
32
|
+
- [x] Unit tests written and passing - Completed: Created 10 unit tests
|
|
33
|
+
- [x] Integration tests created - Completed: Created integration suite
|
|
34
|
+
- [ ] Performance benchmarks created - Deferred to STORY-042
|
|
35
|
+
**User Approved:** YES (via AskUserQuestion on 2025-11-04)
|
|
36
|
+
**Approval Method:** AskUserQuestion presented 4 options
|
|
37
|
+
**Selected Option:** "Defer to follow-up story"
|
|
38
|
+
**Rationale:** Performance testing requires load testing environment (STORY-041 prerequisite)
|
|
39
|
+
- [x] Code follows coding-standards.md - Completed: Applied standards
|
|
40
|
+
|
|
41
|
+
**VALID:** Deferral has "User Approved: YES" marker - should PASS validation.
|
|
42
|
+
|
|
43
|
+
## Workflow History
|
|
44
|
+
|
|
45
|
+
### 2025-11-04 - Status: Dev Complete
|
|
46
|
+
- Implementation complete with justified deferral
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: STORY-TEST-001
|
|
3
|
+
title: Test Story - All DoD Complete
|
|
4
|
+
epic: EPIC-001
|
|
5
|
+
status: Dev Complete
|
|
6
|
+
priority: HIGH
|
|
7
|
+
points: 5
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Test Story - All DoD Complete
|
|
11
|
+
|
|
12
|
+
This is a test story with all DoD items completed.
|
|
13
|
+
|
|
14
|
+
## Definition of Done
|
|
15
|
+
|
|
16
|
+
- [x] Unit tests written and passing
|
|
17
|
+
- [x] Integration tests created
|
|
18
|
+
- [x] Code follows coding-standards.md
|
|
19
|
+
- [x] Documentation updated
|
|
20
|
+
- [x] All acceptance criteria met
|
|
21
|
+
|
|
22
|
+
## Acceptance Criteria
|
|
23
|
+
|
|
24
|
+
- Given a user
|
|
25
|
+
- When action performed
|
|
26
|
+
- Then expected result
|
|
27
|
+
|
|
28
|
+
## Implementation Notes
|
|
29
|
+
|
|
30
|
+
**Developer:** DevForgeAI AI Agent
|
|
31
|
+
**Implemented:** 2025-11-04
|
|
32
|
+
|
|
33
|
+
- [x] Unit tests written and passing - Completed: Created 10 unit tests, all passing
|
|
34
|
+
- [x] Integration tests created - Completed: Created 3 integration tests with fixtures
|
|
35
|
+
- [x] Code follows coding-standards.md - Completed: Applied naming conventions, error handling
|
|
36
|
+
- [x] Documentation updated - Completed: Updated API docs and README
|
|
37
|
+
- [x] All acceptance criteria met - Completed: Verified via test suite
|
|
38
|
+
|
|
39
|
+
### Files Created
|
|
40
|
+
- src/module.py
|
|
41
|
+
- tests/test_module.py
|
|
42
|
+
|
|
43
|
+
## Workflow History
|
|
44
|
+
|
|
45
|
+
### 2025-11-04 - Status: Dev Complete
|
|
46
|
+
- All DoD items completed
|
|
47
|
+
- Tests passing
|
|
48
|
+
- Ready for QA
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Manual Test Script for STORY-022: invoke-hooks CLI command
|
|
3
|
+
# This script tests the invoke-hooks command manually to verify DoD items
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
echo "=========================================="
|
|
8
|
+
echo "Manual Test Suite for invoke-hooks Command"
|
|
9
|
+
echo "=========================================="
|
|
10
|
+
echo ""
|
|
11
|
+
|
|
12
|
+
# Colors for output
|
|
13
|
+
GREEN='\033[0;32m'
|
|
14
|
+
RED='\033[0;31m'
|
|
15
|
+
YELLOW='\033[1;33m'
|
|
16
|
+
NC='\033[0m' # No Color
|
|
17
|
+
|
|
18
|
+
# Test counter
|
|
19
|
+
PASS=0
|
|
20
|
+
FAIL=0
|
|
21
|
+
|
|
22
|
+
# Helper function to run test
|
|
23
|
+
run_test() {
|
|
24
|
+
local test_name="$1"
|
|
25
|
+
local command="$2"
|
|
26
|
+
local expected_result="$3"
|
|
27
|
+
|
|
28
|
+
echo -e "${YELLOW}[TEST]${NC} $test_name"
|
|
29
|
+
echo "Command: $command"
|
|
30
|
+
|
|
31
|
+
if eval "$command"; then
|
|
32
|
+
if [ "$expected_result" = "success" ]; then
|
|
33
|
+
echo -e "${GREEN}✓ PASSED${NC}"
|
|
34
|
+
((PASS++))
|
|
35
|
+
else
|
|
36
|
+
echo -e "${RED}✗ FAILED${NC} (Expected failure but got success)"
|
|
37
|
+
((FAIL++))
|
|
38
|
+
fi
|
|
39
|
+
else
|
|
40
|
+
if [ "$expected_result" = "failure" ]; then
|
|
41
|
+
echo -e "${GREEN}✓ PASSED${NC}"
|
|
42
|
+
((PASS++))
|
|
43
|
+
else
|
|
44
|
+
echo -e "${RED}✗ FAILED${NC} (Expected success but got failure)"
|
|
45
|
+
((FAIL++))
|
|
46
|
+
fi
|
|
47
|
+
fi
|
|
48
|
+
echo ""
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# Test 1: Manual test - invoke-hooks triggers feedback conversation
|
|
52
|
+
echo "=========================================="
|
|
53
|
+
echo "Test 1: invoke-hooks triggers feedback conversation"
|
|
54
|
+
echo "=========================================="
|
|
55
|
+
echo ""
|
|
56
|
+
echo "This test verifies that running invoke-hooks attempts to invoke the feedback skill."
|
|
57
|
+
echo "Note: This is a mock test since devforgeai-feedback skill integration is not yet complete."
|
|
58
|
+
echo ""
|
|
59
|
+
|
|
60
|
+
# Create a mock test that verifies the command runs
|
|
61
|
+
run_test \
|
|
62
|
+
"Invoke hooks with operation=dev and story=STORY-001" \
|
|
63
|
+
"python3 -c \"
|
|
64
|
+
import sys
|
|
65
|
+
sys.path.insert(0, '.claude/scripts')
|
|
66
|
+
from devforgeai_cli.hooks import invoke_hooks
|
|
67
|
+
|
|
68
|
+
# Mock invocation (will fail gracefully since feedback skill isn't integrated)
|
|
69
|
+
result = invoke_hooks('dev', 'STORY-001')
|
|
70
|
+
print(f'invoke_hooks returned: {result}')
|
|
71
|
+
# We expect False since feedback skill isn't actually callable yet
|
|
72
|
+
sys.exit(0 if result == False else 1)
|
|
73
|
+
\"" \
|
|
74
|
+
"success"
|
|
75
|
+
|
|
76
|
+
echo "Manual verification needed: The invoke_hooks() function was called."
|
|
77
|
+
echo "Actual feedback skill integration will be completed in STORY-023."
|
|
78
|
+
echo ""
|
|
79
|
+
|
|
80
|
+
# Test 2: Manual test - Context includes todos, errors, timing
|
|
81
|
+
echo "=========================================="
|
|
82
|
+
echo "Test 2: Context includes todos, errors, timing"
|
|
83
|
+
echo "=========================================="
|
|
84
|
+
echo ""
|
|
85
|
+
|
|
86
|
+
run_test \
|
|
87
|
+
"Extract context and verify it contains todos, errors, timing" \
|
|
88
|
+
"python3 -c \"
|
|
89
|
+
import sys
|
|
90
|
+
sys.path.insert(0, '.claude/scripts')
|
|
91
|
+
from devforgeai_cli.context_extraction import extract_context
|
|
92
|
+
|
|
93
|
+
# Extract context with test operation
|
|
94
|
+
context = extract_context('dev', 'STORY-001')
|
|
95
|
+
|
|
96
|
+
# Verify structure
|
|
97
|
+
assert 'operation_id' in context, 'Missing operation_id'
|
|
98
|
+
assert 'operation' in context, 'Missing operation'
|
|
99
|
+
assert 'story_id' in context, 'Missing story_id'
|
|
100
|
+
assert 'start_time' in context, 'Missing start_time'
|
|
101
|
+
assert 'end_time' in context, 'Missing end_time'
|
|
102
|
+
assert 'duration' in context, 'Missing duration'
|
|
103
|
+
assert 'status' in context, 'Missing status'
|
|
104
|
+
assert 'todos' in context, 'Missing todos'
|
|
105
|
+
assert 'errors' in context, 'Missing errors'
|
|
106
|
+
assert 'context_size_bytes' in context, 'Missing context_size_bytes'
|
|
107
|
+
|
|
108
|
+
print('✓ Context structure validated')
|
|
109
|
+
print(f' - operation_id: {context[\"operation_id\"]}')
|
|
110
|
+
print(f' - operation: {context[\"operation\"]}')
|
|
111
|
+
print(f' - story_id: {context[\"story_id\"]}')
|
|
112
|
+
print(f' - duration: {context[\"duration\"]}s')
|
|
113
|
+
print(f' - todos: {len(context[\"todos\"])} items')
|
|
114
|
+
print(f' - errors: {len(context[\"errors\"])} items')
|
|
115
|
+
print(f' - context_size: {context[\"context_size_bytes\"]} bytes')
|
|
116
|
+
\"" \
|
|
117
|
+
"success"
|
|
118
|
+
|
|
119
|
+
# Test 3: Manual test - Timeout triggers after 30s
|
|
120
|
+
echo "=========================================="
|
|
121
|
+
echo "Test 3: Timeout triggers after 30s (LONG TEST)"
|
|
122
|
+
echo "=========================================="
|
|
123
|
+
echo ""
|
|
124
|
+
echo "WARNING: This test will take 30+ seconds to complete."
|
|
125
|
+
echo "Press Ctrl+C to skip, or wait for timeout verification."
|
|
126
|
+
echo ""
|
|
127
|
+
|
|
128
|
+
# Give user 5 seconds to cancel
|
|
129
|
+
sleep 3
|
|
130
|
+
|
|
131
|
+
run_test \
|
|
132
|
+
"Verify 30-second timeout triggers and aborts" \
|
|
133
|
+
"python3 -c \"
|
|
134
|
+
import sys
|
|
135
|
+
import time
|
|
136
|
+
import threading
|
|
137
|
+
sys.path.insert(0, '.claude/scripts')
|
|
138
|
+
from devforgeai_cli.hooks import HookInvocationService
|
|
139
|
+
|
|
140
|
+
# Create service
|
|
141
|
+
service = HookInvocationService()
|
|
142
|
+
|
|
143
|
+
# Mock a slow skill invocation (35 seconds)
|
|
144
|
+
def slow_skill():
|
|
145
|
+
time.sleep(35)
|
|
146
|
+
return True
|
|
147
|
+
|
|
148
|
+
# Override invoke_feedback_skill to use slow_skill
|
|
149
|
+
original_method = service.invoke_feedback_skill
|
|
150
|
+
service.invoke_feedback_skill = lambda context: slow_skill()
|
|
151
|
+
|
|
152
|
+
# Call invoke (should timeout after 30s)
|
|
153
|
+
start = time.time()
|
|
154
|
+
result = service.invoke('dev', 'STORY-001')
|
|
155
|
+
elapsed = time.time() - start
|
|
156
|
+
|
|
157
|
+
print(f'Elapsed time: {elapsed:.1f}s')
|
|
158
|
+
print(f'Result: {result}')
|
|
159
|
+
|
|
160
|
+
# Verify timeout occurred (~30s, allow ±2s margin)
|
|
161
|
+
if 28 <= elapsed <= 32 and result == False:
|
|
162
|
+
print('✓ Timeout triggered correctly after ~30s')
|
|
163
|
+
sys.exit(0)
|
|
164
|
+
else:
|
|
165
|
+
print(f'✗ Timeout failed: elapsed={elapsed:.1f}s, result={result}')
|
|
166
|
+
sys.exit(1)
|
|
167
|
+
\"" \
|
|
168
|
+
"success"
|
|
169
|
+
|
|
170
|
+
# Test 4: Integration test - Called from /dev command
|
|
171
|
+
echo "=========================================="
|
|
172
|
+
echo "Test 4: Integration test - Called from /dev command"
|
|
173
|
+
echo "=========================================="
|
|
174
|
+
echo ""
|
|
175
|
+
echo "This test verifies the CLI command can be invoked from command line."
|
|
176
|
+
echo ""
|
|
177
|
+
|
|
178
|
+
run_test \
|
|
179
|
+
"Run invoke-hooks CLI command" \
|
|
180
|
+
"cd .claude/scripts && python3 -m devforgeai_cli.cli invoke-hooks --operation dev --story STORY-001 --verbose 2>&1 | head -20" \
|
|
181
|
+
"failure" # Expected to fail since feedback skill isn't integrated
|
|
182
|
+
|
|
183
|
+
echo "Note: Command executed but failed gracefully (expected until STORY-023)."
|
|
184
|
+
echo ""
|
|
185
|
+
|
|
186
|
+
# Summary
|
|
187
|
+
echo "=========================================="
|
|
188
|
+
echo "Test Summary"
|
|
189
|
+
echo "=========================================="
|
|
190
|
+
echo -e "${GREEN}Passed: $PASS${NC}"
|
|
191
|
+
echo -e "${RED}Failed: $FAIL${NC}"
|
|
192
|
+
echo ""
|
|
193
|
+
|
|
194
|
+
if [ $FAIL -eq 0 ]; then
|
|
195
|
+
echo -e "${GREEN}All manual tests PASSED ✓${NC}"
|
|
196
|
+
exit 0
|
|
197
|
+
else
|
|
198
|
+
echo -e "${RED}Some tests FAILED ✗${NC}"
|
|
199
|
+
exit 1
|
|
200
|
+
fi
|