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.
- specfact_cli/__init__.py +1 -1
- specfact_cli/agents/analyze_agent.py +2 -3
- specfact_cli/analyzers/__init__.py +2 -1
- specfact_cli/analyzers/ambiguity_scanner.py +601 -0
- specfact_cli/analyzers/code_analyzer.py +462 -30
- specfact_cli/analyzers/constitution_evidence_extractor.py +491 -0
- specfact_cli/analyzers/contract_extractor.py +419 -0
- specfact_cli/analyzers/control_flow_analyzer.py +281 -0
- specfact_cli/analyzers/requirement_extractor.py +337 -0
- specfact_cli/analyzers/test_pattern_extractor.py +330 -0
- specfact_cli/cli.py +151 -206
- specfact_cli/commands/constitution.py +281 -0
- specfact_cli/commands/enforce.py +42 -34
- specfact_cli/commands/import_cmd.py +481 -152
- specfact_cli/commands/init.py +224 -55
- specfact_cli/commands/plan.py +2133 -547
- specfact_cli/commands/repro.py +100 -78
- specfact_cli/commands/sync.py +701 -186
- specfact_cli/enrichers/constitution_enricher.py +765 -0
- specfact_cli/enrichers/plan_enricher.py +294 -0
- specfact_cli/importers/speckit_converter.py +364 -48
- specfact_cli/importers/speckit_scanner.py +65 -0
- specfact_cli/models/plan.py +42 -0
- specfact_cli/resources/mappings/node-async.yaml +49 -0
- specfact_cli/resources/mappings/python-async.yaml +47 -0
- specfact_cli/resources/mappings/speckit-default.yaml +82 -0
- specfact_cli/resources/prompts/specfact-enforce.md +185 -0
- specfact_cli/resources/prompts/specfact-import-from-code.md +626 -0
- specfact_cli/resources/prompts/specfact-plan-add-feature.md +188 -0
- specfact_cli/resources/prompts/specfact-plan-add-story.md +212 -0
- specfact_cli/resources/prompts/specfact-plan-compare.md +571 -0
- specfact_cli/resources/prompts/specfact-plan-init.md +531 -0
- specfact_cli/resources/prompts/specfact-plan-promote.md +352 -0
- specfact_cli/resources/prompts/specfact-plan-review.md +1276 -0
- specfact_cli/resources/prompts/specfact-plan-select.md +401 -0
- specfact_cli/resources/prompts/specfact-plan-update-feature.md +242 -0
- specfact_cli/resources/prompts/specfact-plan-update-idea.md +211 -0
- specfact_cli/resources/prompts/specfact-repro.md +268 -0
- specfact_cli/resources/prompts/specfact-sync.md +497 -0
- specfact_cli/resources/schemas/deviation.schema.json +61 -0
- specfact_cli/resources/schemas/plan.schema.json +204 -0
- specfact_cli/resources/schemas/protocol.schema.json +53 -0
- specfact_cli/resources/templates/github-action.yml.j2 +140 -0
- specfact_cli/resources/templates/plan.bundle.yaml.j2 +141 -0
- specfact_cli/resources/templates/pr-template.md.j2 +58 -0
- specfact_cli/resources/templates/protocol.yaml.j2 +24 -0
- specfact_cli/resources/templates/telemetry.yaml.example +35 -0
- specfact_cli/sync/__init__.py +10 -1
- specfact_cli/sync/watcher.py +268 -0
- specfact_cli/telemetry.py +440 -0
- specfact_cli/utils/acceptance_criteria.py +127 -0
- specfact_cli/utils/enrichment_parser.py +445 -0
- specfact_cli/utils/feature_keys.py +12 -3
- specfact_cli/utils/ide_setup.py +170 -0
- specfact_cli/utils/structure.py +179 -2
- specfact_cli/utils/yaml_utils.py +33 -0
- specfact_cli/validators/repro_checker.py +22 -1
- specfact_cli/validators/schema.py +15 -4
- specfact_cli-0.6.8.dist-info/METADATA +456 -0
- specfact_cli-0.6.8.dist-info/RECORD +99 -0
- {specfact_cli-0.4.2.dist-info → specfact_cli-0.6.8.dist-info}/entry_points.txt +1 -0
- specfact_cli-0.6.8.dist-info/licenses/LICENSE.md +202 -0
- specfact_cli-0.4.2.dist-info/METADATA +0 -370
- specfact_cli-0.4.2.dist-info/RECORD +0 -62
- specfact_cli-0.4.2.dist-info/licenses/LICENSE.md +0 -61
- {specfact_cli-0.4.2.dist-info → specfact_cli-0.6.8.dist-info}/WHEEL +0 -0
specfact_cli/models/plan.py
CHANGED
|
@@ -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 ---
|