specfact-cli 0.4.2__py3-none-any.whl → 0.6.8__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 (66) hide show
  1. specfact_cli/__init__.py +1 -1
  2. specfact_cli/agents/analyze_agent.py +2 -3
  3. specfact_cli/analyzers/__init__.py +2 -1
  4. specfact_cli/analyzers/ambiguity_scanner.py +601 -0
  5. specfact_cli/analyzers/code_analyzer.py +462 -30
  6. specfact_cli/analyzers/constitution_evidence_extractor.py +491 -0
  7. specfact_cli/analyzers/contract_extractor.py +419 -0
  8. specfact_cli/analyzers/control_flow_analyzer.py +281 -0
  9. specfact_cli/analyzers/requirement_extractor.py +337 -0
  10. specfact_cli/analyzers/test_pattern_extractor.py +330 -0
  11. specfact_cli/cli.py +151 -206
  12. specfact_cli/commands/constitution.py +281 -0
  13. specfact_cli/commands/enforce.py +42 -34
  14. specfact_cli/commands/import_cmd.py +481 -152
  15. specfact_cli/commands/init.py +224 -55
  16. specfact_cli/commands/plan.py +2133 -547
  17. specfact_cli/commands/repro.py +100 -78
  18. specfact_cli/commands/sync.py +701 -186
  19. specfact_cli/enrichers/constitution_enricher.py +765 -0
  20. specfact_cli/enrichers/plan_enricher.py +294 -0
  21. specfact_cli/importers/speckit_converter.py +364 -48
  22. specfact_cli/importers/speckit_scanner.py +65 -0
  23. specfact_cli/models/plan.py +42 -0
  24. specfact_cli/resources/mappings/node-async.yaml +49 -0
  25. specfact_cli/resources/mappings/python-async.yaml +47 -0
  26. specfact_cli/resources/mappings/speckit-default.yaml +82 -0
  27. specfact_cli/resources/prompts/specfact-enforce.md +185 -0
  28. specfact_cli/resources/prompts/specfact-import-from-code.md +626 -0
  29. specfact_cli/resources/prompts/specfact-plan-add-feature.md +188 -0
  30. specfact_cli/resources/prompts/specfact-plan-add-story.md +212 -0
  31. specfact_cli/resources/prompts/specfact-plan-compare.md +571 -0
  32. specfact_cli/resources/prompts/specfact-plan-init.md +531 -0
  33. specfact_cli/resources/prompts/specfact-plan-promote.md +352 -0
  34. specfact_cli/resources/prompts/specfact-plan-review.md +1276 -0
  35. specfact_cli/resources/prompts/specfact-plan-select.md +401 -0
  36. specfact_cli/resources/prompts/specfact-plan-update-feature.md +242 -0
  37. specfact_cli/resources/prompts/specfact-plan-update-idea.md +211 -0
  38. specfact_cli/resources/prompts/specfact-repro.md +268 -0
  39. specfact_cli/resources/prompts/specfact-sync.md +497 -0
  40. specfact_cli/resources/schemas/deviation.schema.json +61 -0
  41. specfact_cli/resources/schemas/plan.schema.json +204 -0
  42. specfact_cli/resources/schemas/protocol.schema.json +53 -0
  43. specfact_cli/resources/templates/github-action.yml.j2 +140 -0
  44. specfact_cli/resources/templates/plan.bundle.yaml.j2 +141 -0
  45. specfact_cli/resources/templates/pr-template.md.j2 +58 -0
  46. specfact_cli/resources/templates/protocol.yaml.j2 +24 -0
  47. specfact_cli/resources/templates/telemetry.yaml.example +35 -0
  48. specfact_cli/sync/__init__.py +10 -1
  49. specfact_cli/sync/watcher.py +268 -0
  50. specfact_cli/telemetry.py +440 -0
  51. specfact_cli/utils/acceptance_criteria.py +127 -0
  52. specfact_cli/utils/enrichment_parser.py +445 -0
  53. specfact_cli/utils/feature_keys.py +12 -3
  54. specfact_cli/utils/ide_setup.py +170 -0
  55. specfact_cli/utils/structure.py +179 -2
  56. specfact_cli/utils/yaml_utils.py +33 -0
  57. specfact_cli/validators/repro_checker.py +22 -1
  58. specfact_cli/validators/schema.py +15 -4
  59. specfact_cli-0.6.8.dist-info/METADATA +456 -0
  60. specfact_cli-0.6.8.dist-info/RECORD +99 -0
  61. {specfact_cli-0.4.2.dist-info → specfact_cli-0.6.8.dist-info}/entry_points.txt +1 -0
  62. specfact_cli-0.6.8.dist-info/licenses/LICENSE.md +202 -0
  63. specfact_cli-0.4.2.dist-info/METADATA +0 -370
  64. specfact_cli-0.4.2.dist-info/RECORD +0 -62
  65. specfact_cli-0.4.2.dist-info/licenses/LICENSE.md +0 -61
  66. {specfact_cli-0.4.2.dist-info → specfact_cli-0.6.8.dist-info}/WHEEL +0 -0
@@ -26,6 +26,14 @@ class Story(BaseModel):
26
26
  tasks: list[str] = Field(default_factory=list, description="Implementation tasks (methods, functions)")
27
27
  confidence: float = Field(default=1.0, ge=0.0, le=1.0, description="Confidence score (0.0-1.0)")
28
28
  draft: bool = Field(default=False, description="Whether this is a draft story")
29
+ scenarios: dict[str, list[str]] | None = Field(
30
+ None,
31
+ description="Scenarios extracted from control flow: primary, alternate, exception, recovery (Given/When/Then format)",
32
+ )
33
+ contracts: dict[str, Any] | None = Field(
34
+ None,
35
+ description="API contracts extracted from function signatures: parameters, return_type, preconditions, postconditions, error_contracts",
36
+ )
29
37
 
30
38
 
31
39
  class Feature(BaseModel):
@@ -84,6 +92,39 @@ class Metadata(BaseModel):
84
92
  stage: str = Field(default="draft", description="Plan stage (draft, review, approved, released)")
85
93
  promoted_at: str | None = Field(None, description="ISO timestamp of last promotion")
86
94
  promoted_by: str | None = Field(None, description="User who performed last promotion")
95
+ analysis_scope: str | None = Field(
96
+ None, description="Analysis scope: 'full' for entire repository, 'partial' for subdirectory analysis"
97
+ )
98
+ entry_point: str | None = Field(None, description="Entry point path for partial analysis (relative to repo root)")
99
+ external_dependencies: list[str] = Field(
100
+ default_factory=list, description="List of external modules/packages imported from outside entry point"
101
+ )
102
+
103
+
104
+ class Clarification(BaseModel):
105
+ """Single clarification Q&A."""
106
+
107
+ id: str = Field(..., description="Unique question ID (e.g., Q001)")
108
+ category: str = Field(..., description="Taxonomy category (Functional Scope, Data Model, etc.)")
109
+ question: str = Field(..., description="Clarification question")
110
+ answer: str = Field(..., description="User-provided answer")
111
+ integrated_into: list[str] = Field(
112
+ default_factory=list, description="Plan sections updated (e.g., 'features.FEATURE-001.acceptance')"
113
+ )
114
+ timestamp: str = Field(..., description="ISO timestamp of answer")
115
+
116
+
117
+ class ClarificationSession(BaseModel):
118
+ """Session of clarifications."""
119
+
120
+ date: str = Field(..., description="Session date (YYYY-MM-DD)")
121
+ questions: list[Clarification] = Field(default_factory=list, description="Questions asked in this session")
122
+
123
+
124
+ class Clarifications(BaseModel):
125
+ """Plan bundle clarifications."""
126
+
127
+ sessions: list[ClarificationSession] = Field(default_factory=list, description="Clarification sessions")
87
128
 
88
129
 
89
130
  class PlanBundle(BaseModel):
@@ -95,3 +136,4 @@ class PlanBundle(BaseModel):
95
136
  product: Product = Field(..., description="Product definition")
96
137
  features: list[Feature] = Field(default_factory=list, description="Product features")
97
138
  metadata: Metadata | None = Field(None, description="Plan bundle metadata")
139
+ clarifications: Clarifications | None = Field(None, description="Plan clarifications (Q&A sessions)")
@@ -0,0 +1,49 @@
1
+ # Node.js/TypeScript async anti-pattern detection rules
2
+
3
+ # Promise patterns to detect
4
+ promise_patterns:
5
+ # Unhandled promise rejections
6
+ - pattern: "new Promise(.*) without catch"
7
+ severity: HIGH
8
+ message: "Promise created without error handling"
9
+
10
+ # Missing await
11
+ - pattern: "Promise.* without await"
12
+ severity: MEDIUM
13
+ message: "Promise not awaited"
14
+
15
+ # Promise.all without error handling
16
+ - pattern: "Promise.all(.*) without catch"
17
+ severity: HIGH
18
+ message: "Promise.all without error handling"
19
+
20
+ # Async/await patterns
21
+ async_await:
22
+ # Blocking in async function
23
+ - pattern: "fs.readFileSync(.*) in async function"
24
+ severity: HIGH
25
+ message: "Blocking file operation in async function, use fs.readFile instead"
26
+
27
+ # Serial async operations that could be parallel
28
+ - pattern: "sequential await that could be parallel"
29
+ severity: LOW
30
+ message: "Consider using Promise.all for parallel operations"
31
+
32
+ # Event emitter patterns
33
+ events:
34
+ # Missing error event handler
35
+ - pattern: "EventEmitter without error handler"
36
+ severity: MEDIUM
37
+ message: "EventEmitter missing error event handler"
38
+
39
+ # Callback patterns (legacy)
40
+ callbacks:
41
+ # Callback hell
42
+ - pattern: "deeply nested callbacks"
43
+ severity: MEDIUM
44
+ message: "Consider using async/await instead of callbacks"
45
+
46
+ # Missing error-first callback
47
+ - pattern: "callback without error parameter"
48
+ severity: LOW
49
+ message: "Callback should follow error-first pattern"
@@ -0,0 +1,47 @@
1
+ # Python async anti-pattern detection rules
2
+
3
+ # Async function patterns to detect
4
+ async_patterns:
5
+ # Fire-and-forget tasks (missing await)
6
+ - pattern: "asyncio.create_task(.*) without await"
7
+ severity: HIGH
8
+ message: "Task created but never awaited"
9
+
10
+ # Blocking calls in async functions
11
+ - pattern: "time.sleep(.*) in async function"
12
+ severity: HIGH
13
+ message: "Blocking sleep in async function, use asyncio.sleep instead"
14
+
15
+ # Missing error handling
16
+ - pattern: "await .* without try/except"
17
+ severity: MEDIUM
18
+ message: "Async call without error handling"
19
+
20
+ # Long-running tasks without timeout
21
+ - pattern: "await .* without timeout"
22
+ severity: MEDIUM
23
+ message: "Async operation without timeout"
24
+
25
+ # Event loop patterns
26
+ event_loop:
27
+ # Multiple event loops
28
+ - pattern: "asyncio.new_event_loop()"
29
+ severity: MEDIUM
30
+ message: "Creating new event loop, prefer asyncio.get_event_loop()"
31
+
32
+ # Blocking operations on event loop
33
+ - pattern: "loop.run_until_complete(.*) in async context"
34
+ severity: HIGH
35
+ message: "Blocking event loop with run_until_complete"
36
+
37
+ # Protocol violations
38
+ protocols:
39
+ # State transitions without validation
40
+ - pattern: "state change without validation"
41
+ severity: HIGH
42
+ message: "State transition without protocol validation"
43
+
44
+ # Missing guards
45
+ - pattern: "transition without guard check"
46
+ severity: MEDIUM
47
+ message: "State transition missing guard validation"
@@ -0,0 +1,82 @@
1
+ # Default Spec-Kit to SpecFact CLI mapping
2
+ #
3
+ # This mapping defines how Spec-Kit artifacts are converted to SpecFact format
4
+ # and vice versa. Spec-Kit uses markdown artifacts (spec.md, plan.md, tasks.md)
5
+ # while SpecFact uses YAML plan bundles.
6
+ #
7
+ # Spec-Kit Format Compatibility:
8
+ # - spec.md: Frontmatter, INVSEST criteria, Scenarios (Primary/Alternate/Exception/Recovery)
9
+ # - plan.md: Constitution Check, Phases (Phase 0/1/2/-1), Technology Stack, Constraints, Unknowns
10
+ # - tasks.md: Phase organization (Phase 1: Setup, Phase 2: Foundational, Phase 3+: Stories), Parallel markers [P]
11
+
12
+ # Directory structure mapping
13
+ directories:
14
+ spec: contracts/protocols
15
+ schemas: src/schemas
16
+ workflows: .github/workflows
17
+ docs: docs
18
+ # Spec-Kit structure: .specify/specs/[###-feature-name]/spec.md, plan.md, tasks.md
19
+
20
+ # File mapping
21
+ files:
22
+ components.yaml: contracts/protocols/workflow.protocol.yaml
23
+ architecture.md: docs/architecture.md
24
+ # Spec-Kit files: spec.md, plan.md, tasks.md, constitution.md
25
+
26
+ # State mapping (Spec-Kit → SpecFact)
27
+ states:
28
+ # Map common Spec-Kit state names to SpecFact conventions
29
+ initial: INIT
30
+ planning: PLANNING
31
+ implementation: IMPLEMENTATION
32
+ review: REVIEW
33
+ done: DONE
34
+ completed: COMPLETED
35
+ failed: FAILED
36
+
37
+ # Event mapping
38
+ events:
39
+ # Map common event names
40
+ start: start
41
+ approve: approve
42
+ reject: reject
43
+ complete: complete
44
+ fail: fail
45
+
46
+ # Feature extraction rules
47
+ features:
48
+ # Extract features from Spec-Kit structure
49
+ from_directories: true
50
+ from_issues: true
51
+ from_commits: true
52
+ confidence_threshold: 0.5
53
+ # Spec-Kit format: Features are in spec.md with User Stories, INVSEST criteria, Scenarios
54
+ # Each feature directory contains spec.md, plan.md, tasks.md
55
+
56
+ # Story extraction rules
57
+ stories:
58
+ # Extract stories from test files
59
+ from_tests: true
60
+ test_patterns:
61
+ - "test_*.py"
62
+ - "test_*.ts"
63
+ - "test_*.js"
64
+ - "*.spec.ts"
65
+ - "*.spec.js"
66
+ # Extract from commit messages
67
+ from_commits: true
68
+ commit_patterns:
69
+ - "STORY-\\d+"
70
+ - "story/.*"
71
+ # Spec-Kit format: Stories are in spec.md with:
72
+ # - Priority (P1/P2/P3)
73
+ # - INVSEST criteria (Independent, Negotiable, Valuable, Estimable, Small, Testable)
74
+ # - Scenarios (Primary, Alternate, Exception, Recovery)
75
+ # - "Why this priority" text
76
+
77
+ # Schema conversion
78
+ schemas:
79
+ # Convert JSON Schema to Pydantic
80
+ json_schema_to_pydantic: true
81
+ # Convert OpenAPI to Pydantic
82
+ openapi_to_pydantic: true
@@ -0,0 +1,185 @@
1
+ ---
2
+ description: "Configure quality gates and enforcement modes for contract validation"
3
+ ---
4
+
5
+ # SpecFact Enforce Command
6
+
7
+ ## User Input
8
+
9
+ ```text
10
+ $ARGUMENTS
11
+ ```
12
+
13
+ You **MUST** consider the user input before proceeding (if not empty).
14
+
15
+ ## ⚠️ CRITICAL: CLI Usage Enforcement
16
+
17
+ **YOU MUST ALWAYS USE THE SPECFACT CLI**. Never create artifacts directly.
18
+
19
+ ### Rules
20
+
21
+ 1. **ALWAYS execute CLI first**: Run `specfact enforce stage` before any analysis - execute the CLI command before any other operations
22
+ 2. **NEVER write code**: Do not implement enforcement configuration logic - the CLI handles this
23
+ 3. **NEVER create YAML/JSON directly**: All enforcement configuration must be CLI-generated
24
+ 4. **NEVER bypass CLI validation**: CLI ensures schema compliance and metadata - use it, don't bypass its validation
25
+ 5. **Use CLI output as grounding**: Parse CLI output, don't regenerate or recreate it - use the CLI output as the source of truth
26
+ 6. **NEVER manipulate internal code**: Do NOT use Python code to directly modify EnforcementConfig objects or any internal data structures. The CLI is THE interface - use it exclusively.
27
+ 7. **No internal knowledge required**: You should NOT need to know about internal implementation details (EnforcementConfig model, EnforcementPreset enum, etc.). All operations must be performed via CLI commands.
28
+ 8. **NEVER read artifacts directly**: Do NOT read enforcement configuration files directly to extract information unless for display purposes. Use CLI commands to get configuration information.
29
+
30
+ ### What Happens If You Don't Follow This
31
+
32
+ - ❌ Artifacts may not match CLI schema versions
33
+ - ❌ Missing metadata and telemetry
34
+ - ❌ Format inconsistencies
35
+ - ❌ Validation failures
36
+ - ❌ Works only in Copilot mode, fails in CI/CD
37
+ - ❌ Breaks when CLI internals change
38
+ - ❌ Requires knowledge of internal code structure
39
+
40
+ ## ⏸️ Wait States: User Input Required
41
+
42
+ **When user input is required, you MUST wait for the user's response.**
43
+
44
+ ### Wait State Rules
45
+
46
+ 1. **Never assume**: If input is missing, ask and wait
47
+ 2. **Never continue**: Do not proceed until user responds
48
+ 3. **Be explicit**: Clearly state what information you need
49
+ 4. **Provide options**: Give examples or default suggestions
50
+
51
+ ## Goal
52
+
53
+ Configure quality gates and enforcement modes for contract validation. This command sets the enforcement preset that determines how contract violations are handled (minimal, balanced, strict).
54
+
55
+ ## Operating Constraints
56
+
57
+ **STRICTLY READ-WRITE**: This command modifies enforcement configuration. All updates must be performed by the specfact CLI.
58
+
59
+ **Command**: `specfact enforce stage`
60
+
61
+ **Mode Auto-Detection**: The CLI automatically detects operational mode (CI/CD or CoPilot) based on environment. No need to specify `--mode` flag.
62
+
63
+ ## What This Command Does
64
+
65
+ The `specfact enforce stage` command:
66
+
67
+ 1. **Validates** the preset value (minimal, balanced, strict)
68
+ 2. **Creates** enforcement configuration from preset
69
+ 3. **Displays** configuration summary as a table
70
+ 4. **Saves** configuration to `.specfact/config/enforcement.yaml`
71
+ 5. **Reports** configuration path and status
72
+
73
+ ## Execution Steps
74
+
75
+ ### 1. Parse Arguments and Validate Input
76
+
77
+ **Parse user input** to extract:
78
+
79
+ - Preset (optional, default: `balanced`)
80
+ - Valid values: `minimal`, `balanced`, `strict`
81
+
82
+ **WAIT STATE**: If user wants to set enforcement but hasn't specified preset, ask:
83
+
84
+ ```text
85
+ "Which enforcement preset would you like to use?
86
+ - minimal: Log violations, never block
87
+ - balanced: Block HIGH severity, warn MEDIUM (default)
88
+ - strict: Block all MEDIUM+ violations
89
+
90
+ Enter preset (minimal/balanced/strict):
91
+ [WAIT FOR USER RESPONSE - DO NOT CONTINUE]"
92
+ ```
93
+
94
+ ### 2. Execute Enforce Stage Command
95
+
96
+ **Execute CLI command**:
97
+
98
+ ```bash
99
+ # Use default (balanced)
100
+ specfact enforce stage
101
+
102
+ # Specify preset
103
+ specfact enforce stage --preset minimal
104
+ specfact enforce stage --preset balanced
105
+ specfact enforce stage --preset strict
106
+ ```
107
+
108
+ **Capture from CLI**:
109
+
110
+ - Preset validation (must be minimal, balanced, or strict)
111
+ - Configuration created from preset
112
+ - Configuration summary table displayed
113
+ - Configuration saved to `.specfact/config/enforcement.yaml`
114
+
115
+ ### 3. Handle Errors
116
+
117
+ **Common errors**:
118
+
119
+ - **Unknown preset**: CLI will report error and list valid presets
120
+ - **Invalid preset format**: CLI will validate and report error
121
+
122
+ ### 4. Report Completion
123
+
124
+ **After successful execution**:
125
+
126
+ ```markdown
127
+ ✓ Enforcement mode set successfully!
128
+
129
+ **Preset**: balanced
130
+ **Configuration**: `.specfact/config/enforcement.yaml`
131
+
132
+ **Enforcement Summary**:
133
+
134
+ | Severity | Action |
135
+ |----------|--------|
136
+ | HIGH | Block |
137
+ | MEDIUM | Warn |
138
+ | LOW | Log |
139
+
140
+ **Next Steps**:
141
+ - Run validation: `/specfact-cli/specfact-repro`
142
+ - Review configuration: Check `.specfact/config/enforcement.yaml`
143
+ ```
144
+
145
+ ## Guidelines
146
+
147
+ ### Enforcement Presets
148
+
149
+ **minimal**:
150
+
151
+ - Log all violations
152
+ - Never block execution
153
+ - Best for: Development, exploration, learning
154
+
155
+ **balanced** (default):
156
+
157
+ - Block HIGH severity violations
158
+ - Warn on MEDIUM severity violations
159
+ - Log LOW severity violations
160
+ - Best for: Most production use cases
161
+
162
+ **strict**:
163
+
164
+ - Block all MEDIUM+ severity violations
165
+ - Log LOW severity violations
166
+ - Best for: Critical systems, compliance requirements
167
+
168
+ ### Configuration Location
169
+
170
+ - Configuration is saved to: `.specfact/config/enforcement.yaml`
171
+ - This file is automatically created/updated by the CLI
172
+ - Configuration persists across sessions
173
+
174
+ ### Best Practices
175
+
176
+ - Start with `balanced` preset for most use cases
177
+ - Use `minimal` during development to avoid blocking
178
+ - Use `strict` for production deployments or compliance
179
+ - Review configuration file to understand exact behavior
180
+
181
+ ## Context
182
+
183
+ {ARGS}
184
+
185
+ --- End Command ---