specfact-cli 0.15.0__tar.gz → 0.15.2__tar.gz
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-0.15.0 → specfact_cli-0.15.2}/PKG-INFO +1 -1
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/pyproject.toml +1 -1
- specfact_cli-0.15.2/resources/prompts/specfact.03-review.md +603 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/__init__.py +1 -1
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/analyzers/ambiguity_scanner.py +13 -3
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/plan.py +199 -17
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/acceptance_criteria.py +40 -0
- specfact_cli-0.15.0/resources/prompts/specfact.03-review.md +0 -281
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/.gitignore +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/LICENSE.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/README.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/mappings/node-async.yaml +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/mappings/python-async.yaml +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/mappings/speckit-default.yaml +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/prompts/shared/cli-enforcement.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/prompts/specfact.01-import.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/prompts/specfact.02-plan.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/prompts/specfact.04-sdd.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/prompts/specfact.05-enforce.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/prompts/specfact.06-sync.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/prompts/specfact.07-contracts.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/prompts/specfact.compare.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/prompts/specfact.validate.md +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/schemas/deviation.schema.json +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/schemas/plan.schema.json +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/schemas/protocol.schema.json +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/templates/github-action.yml.j2 +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/templates/plan.bundle.yaml.j2 +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/templates/pr-template.md.j2 +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/templates/protocol.yaml.j2 +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/resources/templates/telemetry.yaml.example +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/agents/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/agents/analyze_agent.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/agents/base.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/agents/plan_agent.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/agents/registry.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/agents/sync_agent.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/analyzers/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/cli.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/analyze.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/bridge.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/drift.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/enforce.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/generate.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/implement.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/import_cmd.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/init.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/migrate.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/repro.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/run.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/sdd.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/spec.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/commands/sync.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/common/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/common/logger_setup.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/common/logging_utils.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/common/text_utils.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/common/utils.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/comparators/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/comparators/plan_comparator.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/generators/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/generators/contract_generator.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/generators/openapi_extractor.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/generators/plan_generator.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/generators/protocol_generator.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/generators/report_generator.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/generators/task_generator.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/generators/test_to_openapi.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/generators/workflow_generator.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/importers/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/importers/speckit_converter.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/importers/speckit_scanner.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/integrations/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/integrations/specmatic.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/migrations/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/migrations/plan_migrator.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/bridge.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/deviation.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/enforcement.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/plan.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/project.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/protocol.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/quality.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/sdd.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/source_tracking.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/models/task.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/modes/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/modes/detector.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/modes/router.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/resources/semgrep/async.yml +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/runtime.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/bridge_probe.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/bridge_sync.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/bridge_watch.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/change_detector.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/code_to_spec.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/drift_detector.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/repository_sync.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/spec_to_code.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/spec_to_tests.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/speckit_sync.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/watcher.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/telemetry.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/templates/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/templates/bridge_templates.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/templates/specification_templates.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/bundle_loader.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/console.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/context_detection.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/enrichment_context.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/enrichment_parser.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/feature_keys.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/git.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/github_annotations.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/ide_setup.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/incremental_check.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/optional_deps.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/performance.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/progress.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/prompts.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/sdd_discovery.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/source_scanner.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/structure.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/structured_io.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/suggestions.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/utils/yaml_utils.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/validators/__init__.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/validators/cli_first_validator.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/validators/contract_validator.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/validators/fsm.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/validators/repro_checker.py +0 -0
- {specfact_cli-0.15.0 → specfact_cli-0.15.2}/src/specfact_cli/validators/schema.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: specfact-cli
|
|
3
|
-
Version: 0.15.
|
|
3
|
+
Version: 0.15.2
|
|
4
4
|
Summary: Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions.
|
|
5
5
|
Project-URL: Homepage, https://github.com/nold-ai/specfact-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/nold-ai/specfact-cli.git
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "specfact-cli"
|
|
7
|
-
version = "0.15.
|
|
7
|
+
version = "0.15.2"
|
|
8
8
|
description = "Brownfield-first CLI: Reverse engineer legacy Python → specs → enforced contracts. Automate legacy code documentation and prevent modernization regressions."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -0,0 +1,603 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Review project bundle to identify ambiguities, resolve gaps, and prepare for promotion.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# SpecFact Review 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
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
Review project bundle to identify/resolve ambiguities and missing information. Asks targeted questions for promotion readiness.
|
|
18
|
+
|
|
19
|
+
**When to use:** After import/creation, before promotion, when clarification needed.
|
|
20
|
+
|
|
21
|
+
**Quick:** `/specfact.03-review` (uses active plan) or `/specfact.03-review legacy-api`
|
|
22
|
+
|
|
23
|
+
## Interactive Question Presentation
|
|
24
|
+
|
|
25
|
+
**CRITICAL**: When presenting questions interactively, **ALWAYS** generate and display multiple answer options in a table format. This makes it easier for users to select appropriate answers.
|
|
26
|
+
|
|
27
|
+
### Answer Options Format
|
|
28
|
+
|
|
29
|
+
For each question, generate 3-5 reasonable answer options based on:
|
|
30
|
+
|
|
31
|
+
- **Code analysis**: Review existing patterns, similar features, error handling approaches
|
|
32
|
+
- **Domain knowledge**: Best practices, common scenarios, industry standards
|
|
33
|
+
- **Business context**: Product requirements, user needs, feature relationships
|
|
34
|
+
|
|
35
|
+
**Present options in a numbered table with recommended answer:**
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
Question 1/5
|
|
39
|
+
Category: Interaction & UX Flow
|
|
40
|
+
Q: What error/empty states should be handled for story STORY-XXX?
|
|
41
|
+
|
|
42
|
+
Current Plan Settings:
|
|
43
|
+
Story STORY-XXX Acceptance: [current acceptance criteria]
|
|
44
|
+
|
|
45
|
+
Answer Options:
|
|
46
|
+
┌─────┬─────────────────────────────────────────────────────────────────┐
|
|
47
|
+
│ No. │ Option │
|
|
48
|
+
├─────┼─────────────────────────────────────────────────────────────────┤
|
|
49
|
+
│ 1 │ Error handling: Invalid input produces clear error messages │
|
|
50
|
+
│ │ Empty states: Missing data shows "No data available" message │
|
|
51
|
+
│ │ Validation: Required fields validated before processing │
|
|
52
|
+
│ │ ⭐ Recommended (based on code analysis) │
|
|
53
|
+
├─────┼─────────────────────────────────────────────────────────────────┤
|
|
54
|
+
│ 2 │ Error handling: Network failures retry with exponential backoff │
|
|
55
|
+
│ │ Empty states: Show empty state UI with helpful guidance │
|
|
56
|
+
│ │ Validation: Schema-based validation with clear error messages │
|
|
57
|
+
├─────┼─────────────────────────────────────────────────────────────────┤
|
|
58
|
+
│ 3 │ Error handling: Errors logged to stderr with exit codes (CLI) │
|
|
59
|
+
│ │ Empty states: Sensible defaults when data is missing │
|
|
60
|
+
│ │ Validation: Covered in OpenAPI contract files │
|
|
61
|
+
├─────┼─────────────────────────────────────────────────────────────────┤
|
|
62
|
+
│ 4 │ Not applicable - error handling covered in contract files │
|
|
63
|
+
├─────┼─────────────────────────────────────────────────────────────────┤
|
|
64
|
+
│ 5 │ [Custom answer - type your own] │
|
|
65
|
+
└─────┴─────────────────────────────────────────────────────────────────┘
|
|
66
|
+
|
|
67
|
+
Your answer (1-5, or type custom answer): [1] ⭐ Recommended
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**CRITICAL**: Always provide a **recommended answer** (marked with ⭐) based on:
|
|
71
|
+
|
|
72
|
+
- Code analysis (what the actual implementation does)
|
|
73
|
+
- Best practices (industry standards, common patterns)
|
|
74
|
+
- Domain knowledge (what makes sense for this feature)
|
|
75
|
+
|
|
76
|
+
The recommendation helps less-experienced users make informed decisions.
|
|
77
|
+
|
|
78
|
+
### Guidelines for Answer Options
|
|
79
|
+
|
|
80
|
+
- **Option 1-3**: Specific, actionable options based on code analysis and domain knowledge
|
|
81
|
+
- **Option 4**: "Not applicable" or "Covered elsewhere" when appropriate
|
|
82
|
+
- **Option 5**: Always include "[Custom answer - type your own]" as the last option
|
|
83
|
+
- **Base options on research**: Review codebase, similar features, existing patterns
|
|
84
|
+
- **Make options specific**: Avoid generic responses - be concrete and actionable
|
|
85
|
+
- **Use numbered selection**: Allow users to select by number (1-5) or letter (A-E)
|
|
86
|
+
- **⭐ Always provide a recommended answer**: Mark one option as recommended (⭐) based on:
|
|
87
|
+
- Code analysis (what the actual implementation does or should do)
|
|
88
|
+
- Best practices (industry standards, common patterns)
|
|
89
|
+
- Domain knowledge (what makes sense for this specific feature)
|
|
90
|
+
- The recommendation helps less-experienced users make informed decisions
|
|
91
|
+
|
|
92
|
+
## Parameters
|
|
93
|
+
|
|
94
|
+
### Target/Input
|
|
95
|
+
|
|
96
|
+
- `bundle NAME` (optional argument) - Project bundle name (e.g., legacy-api, auth-module). Default: active plan (set via `plan select`)
|
|
97
|
+
- `--category CATEGORY` - Focus on specific taxonomy category. Default: None (all categories)
|
|
98
|
+
|
|
99
|
+
### Output/Results
|
|
100
|
+
|
|
101
|
+
- `--list-questions` - Output questions in JSON format. Default: False
|
|
102
|
+
- `--output-questions PATH` - Save questions directly to file (JSON format). Use with `--list-questions` to save instead of stdout. Default: None
|
|
103
|
+
- `--list-findings` - Output all findings in structured format. Default: False
|
|
104
|
+
- `--findings-format FORMAT` - Output format: json, yaml, or table. Default: json for non-interactive, table for interactive
|
|
105
|
+
|
|
106
|
+
### Behavior/Options
|
|
107
|
+
|
|
108
|
+
- `--no-interactive` - Non-interactive mode (for CI/CD). Default: False (interactive mode)
|
|
109
|
+
- `--answers JSON` - JSON object with question_id -> answer mappings. Default: None
|
|
110
|
+
- `--auto-enrich` - Automatically enrich vague acceptance criteria using PlanEnricher (same enrichment logic as `import from-code`). Default: False (opt-in for review, but import has auto-enrichment enabled by default)
|
|
111
|
+
|
|
112
|
+
**Important**: `--auto-enrich` will **NOT** resolve partial findings such as:
|
|
113
|
+
|
|
114
|
+
- Missing error handling specifications ("Interaction & UX Flow" category)
|
|
115
|
+
- Vague acceptance criteria requiring domain knowledge ("Completion Signals" category)
|
|
116
|
+
- Business context questions requiring human judgment
|
|
117
|
+
|
|
118
|
+
For these cases, use the **export-to-file → LLM reasoning → import-from-file** workflow (see Step 4).
|
|
119
|
+
|
|
120
|
+
### Advanced/Configuration
|
|
121
|
+
|
|
122
|
+
- `--max-questions INT` - Maximum questions per session. Default: 5 (range: 1-10)
|
|
123
|
+
|
|
124
|
+
**Important**: This limits the number of questions asked per review session, not the total number of available questions. If there are more questions than the limit, you may need to run the review multiple times to answer all questions. Each session will ask different questions (avoiding duplicates from previous sessions).
|
|
125
|
+
|
|
126
|
+
## Workflow
|
|
127
|
+
|
|
128
|
+
### Step 1: Parse Arguments
|
|
129
|
+
|
|
130
|
+
- Extract bundle name (defaults to active plan if not specified)
|
|
131
|
+
- Extract optional parameters (max-questions, category, etc.)
|
|
132
|
+
|
|
133
|
+
### Step 2: Execute CLI to Export Questions
|
|
134
|
+
|
|
135
|
+
**CRITICAL**: Always use `/tmp/` for temporary artifacts to avoid polluting the codebase. Never create temporary files in the project root.
|
|
136
|
+
|
|
137
|
+
**Note**: The `--max-questions` parameter (default: 5) limits the number of questions per session, not the total number of available questions. If there are more questions available, you may need to run the review multiple times to answer all questions. Each session will ask different questions (avoiding duplicates from previous sessions).
|
|
138
|
+
|
|
139
|
+
**Export questions to file for LLM reasoning:**
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Export questions to file (REQUIRED for LLM enrichment workflow)
|
|
143
|
+
# Use /tmp/ to avoid polluting the codebase
|
|
144
|
+
specfact plan review [<bundle-name>] --list-questions --output-questions /tmp/questions.json --no-interactive
|
|
145
|
+
# Uses active plan if bundle not specified
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Optional: Get findings for comprehensive analysis:**
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Get findings (saves to stdout - can redirect to /tmp/)
|
|
152
|
+
# Use /tmp/ to avoid polluting the codebase
|
|
153
|
+
specfact plan review [<bundle-name>] --list-findings --findings-format json --no-interactive > /tmp/findings.json
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Note**: The `--output-questions` option saves questions directly to a file, avoiding the need for complex JSON parsing. The ambiguity scanner now recognizes the simplified format (e.g., "Must verify X works correctly (see contract examples)") as valid and will not flag it as vague.
|
|
157
|
+
|
|
158
|
+
**Important**: Always use `/tmp/` for temporary files (`questions.json`, `findings.json`, etc.) to keep the project root clean and avoid accidental commits of temporary artifacts.
|
|
159
|
+
|
|
160
|
+
### Step 3: LLM Reasoning and Answer Generation
|
|
161
|
+
|
|
162
|
+
**CRITICAL**: For partial findings (missing error handling, vague acceptance criteria, business context), `--auto-enrich` will **NOT** resolve them. You must use LLM reasoning.
|
|
163
|
+
|
|
164
|
+
**CRITICAL WORKFLOW**: Present questions with answer options **IN THE CHAT**, wait for user selection, then add selected answers to file.
|
|
165
|
+
|
|
166
|
+
**Workflow:**
|
|
167
|
+
|
|
168
|
+
1. **Read the exported questions file** (`/tmp/questions.json`):
|
|
169
|
+
|
|
170
|
+
- Review all questions in the file
|
|
171
|
+
- Identify which questions require code/feature analysis
|
|
172
|
+
- Determine which questions need domain knowledge or business context
|
|
173
|
+
|
|
174
|
+
2. **Research codebase and features** (as needed):
|
|
175
|
+
|
|
176
|
+
- For error handling questions: Check existing error handling patterns in the codebase
|
|
177
|
+
- For acceptance criteria questions: Review related features and stories
|
|
178
|
+
- For business context questions: Review `idea.yaml`, `product.yaml`, and related documentation
|
|
179
|
+
|
|
180
|
+
3. **Present questions with answer options IN THE CHAT** (REQUIRED):
|
|
181
|
+
|
|
182
|
+
**DO NOT add answers to the file yet!** Present each question with answer options in the chat conversation and wait for user selection.
|
|
183
|
+
|
|
184
|
+
For each question:
|
|
185
|
+
|
|
186
|
+
- **Generate 3-5 reasonable answer options** based on:
|
|
187
|
+
- Code analysis (existing patterns, similar features)
|
|
188
|
+
- Domain knowledge (best practices, common scenarios)
|
|
189
|
+
- Business context (product requirements, user needs)
|
|
190
|
+
- **Present options in a table format** in the chat with numbered choices:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
Question 1/5
|
|
194
|
+
Category: Interaction & UX Flow
|
|
195
|
+
Q: What error/empty states should be handled for story STORY-XXX?
|
|
196
|
+
|
|
197
|
+
Current Plan Settings:
|
|
198
|
+
Story STORY-XXX Acceptance: [current acceptance criteria]
|
|
199
|
+
|
|
200
|
+
Answer Options:
|
|
201
|
+
┌─────┬─────────────────────────────────────────────────────────────────┐
|
|
202
|
+
│ No. │ Option │
|
|
203
|
+
├─────┼─────────────────────────────────────────────────────────────────┤
|
|
204
|
+
│ 1 │ Error handling: Invalid input produces clear error messages │
|
|
205
|
+
│ │ Empty states: Missing data shows "No data available" message │
|
|
206
|
+
│ │ Validation: Required fields validated before processing │
|
|
207
|
+
│ │ ⭐ Recommended (based on code analysis) │
|
|
208
|
+
├─────┼─────────────────────────────────────────────────────────────────┤
|
|
209
|
+
│ 2 │ Error handling: Network failures retry with exponential backoff │
|
|
210
|
+
│ │ Empty states: Show empty state UI with helpful guidance │
|
|
211
|
+
│ │ Validation: Schema-based validation with clear error messages │
|
|
212
|
+
├─────┼─────────────────────────────────────────────────────────────────┤
|
|
213
|
+
│ 3 │ Error handling: Errors logged to stderr with exit codes (CLI) │
|
|
214
|
+
│ │ Empty states: Sensible defaults when data is missing │
|
|
215
|
+
│ │ Validation: Covered in OpenAPI contract files │
|
|
216
|
+
├─────┼─────────────────────────────────────────────────────────────────┤
|
|
217
|
+
│ 4 │ Not applicable - error handling covered in contract files │
|
|
218
|
+
├─────┼─────────────────────────────────────────────────────────────────┤
|
|
219
|
+
│ 5 │ [Custom answer - type your own] │
|
|
220
|
+
└─────┴─────────────────────────────────────────────────────────────────┘
|
|
221
|
+
|
|
222
|
+
Your answer (1-5, or type custom answer): [1] ⭐ Recommended
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
- **Wait for user to select an answer** (number 1-5, letter A-E, or custom text)
|
|
226
|
+
- **Option 5 (or last option)** should always be "[Custom answer - type your own]" to allow free-form input
|
|
227
|
+
- **Base options on code analysis** - review similar features, existing error handling patterns, and domain knowledge
|
|
228
|
+
- **Make options specific and actionable** - not generic responses
|
|
229
|
+
- **⭐ Always provide a recommended answer** - mark one option as recommended (⭐) based on code analysis, best practices, and domain knowledge. This helps less-experienced users make informed decisions.
|
|
230
|
+
- **Present one question at a time** and wait for user selection before moving to the next
|
|
231
|
+
|
|
232
|
+
4. **After user has selected all answers**:
|
|
233
|
+
|
|
234
|
+
- **THEN** export the selected answers to a separate file `/tmp/answers.json`
|
|
235
|
+
- Map user selections to the actual answer text (if user selected option 1, use the text from option 1)
|
|
236
|
+
- If user selected a custom answer, use that text directly
|
|
237
|
+
- **Export format**: Create a JSON object with `question_id -> answer` mappings
|
|
238
|
+
- **DO NOT** add answers to the file until user has selected all answers
|
|
239
|
+
- **CRITICAL**: Export answers to `/tmp/answers.json` (not `/tmp/questions.json`) for CLI import
|
|
240
|
+
|
|
241
|
+
**Example `/tmp/questions.json` structure:**
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
{
|
|
245
|
+
"questions": [
|
|
246
|
+
{
|
|
247
|
+
"id": "Q001",
|
|
248
|
+
"category": "Interaction & UX Flow",
|
|
249
|
+
"question": "What error/empty states should be handled for story STORY-XXX?",
|
|
250
|
+
"related_sections": ["features.FEATURE-XXX.stories.STORY-XXX.acceptance"]
|
|
251
|
+
}
|
|
252
|
+
],
|
|
253
|
+
"total": 5
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Example `/tmp/answers.json` structure (exported after user selections):**
|
|
258
|
+
|
|
259
|
+
```json
|
|
260
|
+
{
|
|
261
|
+
"Q001": "Error handling should include: network failures (retry with exponential backoff), invalid input (clear validation messages), empty results (show 'No data available' message), timeout errors (show progress indicator and allow cancellation). Based on analysis of similar features in the codebase.",
|
|
262
|
+
"Q002": "Answer for question 2 based on code review..."
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**CRITICAL**: Export answers to `/tmp/answers.json` (separate file), not to `/tmp/questions.json`. The CLI expects a file path for `--answers`, not a JSON string extracted from the questions file.
|
|
267
|
+
|
|
268
|
+
### Step 4: Apply Enrichment via CLI
|
|
269
|
+
|
|
270
|
+
**REQUIRED workflow for partial findings:**
|
|
271
|
+
|
|
272
|
+
1. **Export questions to file** (already done in Step 2):
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
# Use /tmp/ to avoid polluting the codebase
|
|
276
|
+
specfact plan review [<bundle-name>] --list-questions --output-questions /tmp/questions.json --no-interactive
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
2. **LLM reasoning and user selection** (Step 3):
|
|
280
|
+
|
|
281
|
+
- LLM presents questions with answer options **IN THE CHAT**
|
|
282
|
+
- User selects answers (1-5, A-E, or custom text)
|
|
283
|
+
- **After user has selected all answers**, LLM adds selected answers to `/tmp/questions.json`
|
|
284
|
+
|
|
285
|
+
3. **Import answers via CLI** (after user selections are complete):
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Import answers from exported file
|
|
289
|
+
# Use /tmp/ to avoid polluting the codebase
|
|
290
|
+
specfact plan review [<bundle-name>] --answers /tmp/answers.json --no-interactive
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**CRITICAL**:
|
|
294
|
+
|
|
295
|
+
- Do NOT add answers to the file until the user has selected all answers
|
|
296
|
+
- Present questions in chat, wait for selections
|
|
297
|
+
- Export answers to `/tmp/answers.json` (separate file, not `/tmp/questions.json`)
|
|
298
|
+
- Import via CLI using the file path: `--answers /tmp/answers.json`
|
|
299
|
+
|
|
300
|
+
**Alternative approaches** (for non-partial findings only):
|
|
301
|
+
|
|
302
|
+
#### Option B: Update idea fields directly via CLI
|
|
303
|
+
|
|
304
|
+
Use `plan update-idea` to update idea fields from enrichment recommendations:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
specfact plan update-idea --bundle [<bundle-name>] --value-hypothesis "..." --narrative "..." --target-users "..."
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
#### Option C: Apply enrichment via import (only if bundle needs regeneration)
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
specfact import from-code [<bundle-name>] --repo . --enrichment enrichment-report.md
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Note:**
|
|
317
|
+
|
|
318
|
+
- **For partial findings**: Always use Option A (export → LLM reasoning → import)
|
|
319
|
+
- **For business context only**: Option B (update-idea) may be sufficient
|
|
320
|
+
- **For bundle regeneration**: Only use Option C if you need to regenerate the bundle
|
|
321
|
+
- **CRITICAL**: Never manually edit `.specfact/` files directly - always use CLI commands
|
|
322
|
+
- This includes `idea.yaml`, `product.yaml`, feature files, story files, etc.
|
|
323
|
+
- Even if a file doesn't exist yet, use CLI commands to create it (e.g., `plan update-idea` will create `idea.yaml` if needed)
|
|
324
|
+
- Direct file modification bypasses validation and can cause inconsistencies
|
|
325
|
+
|
|
326
|
+
- **Preferred**: Use Option A (answers) or Option B (update-idea) for most cases
|
|
327
|
+
- Only use Option C if you need to regenerate the bundle
|
|
328
|
+
- **CRITICAL**: Never manually edit `.specfact/` files directly - always use CLI commands
|
|
329
|
+
- This includes `idea.yaml`, `product.yaml`, feature files, story files, etc.
|
|
330
|
+
- Even if a file doesn't exist yet, use CLI commands to create it (e.g., `plan update-idea` will create `idea.yaml` if needed)
|
|
331
|
+
- Direct file modification bypasses validation and can cause inconsistencies
|
|
332
|
+
|
|
333
|
+
### Step 5: Present Results
|
|
334
|
+
|
|
335
|
+
- Display Q&A, sections touched, coverage summary (initial/updated)
|
|
336
|
+
- Note: Clarifications don't affect hash (stable across review sessions)
|
|
337
|
+
- If enrichment report was created, summarize what was addressed
|
|
338
|
+
|
|
339
|
+
## CLI Enforcement
|
|
340
|
+
|
|
341
|
+
**CRITICAL**: Always use SpecFact CLI commands. See [CLI Enforcement Rules](./shared/cli-enforcement.md) for details.
|
|
342
|
+
|
|
343
|
+
**Rules:**
|
|
344
|
+
|
|
345
|
+
- Execute CLI first - never create artifacts directly
|
|
346
|
+
- Use `--no-interactive` flag in CI/CD environments
|
|
347
|
+
- **NEVER modify `.specfact/` files directly** - always use CLI commands
|
|
348
|
+
- ❌ **DO NOT** edit `idea.yaml`, `product.yaml`, feature files, or any other artifacts directly
|
|
349
|
+
- ❌ **DO NOT** create new artifact files manually (even if they don't exist yet)
|
|
350
|
+
- ✅ **DO** use CLI commands: `plan update-idea`, `plan update-feature`, `plan update-story`, etc.
|
|
351
|
+
- ✅ **DO** use CLI commands to create new artifacts: `plan init`, `plan add-feature`, etc.
|
|
352
|
+
- Use CLI output as grounding for validation
|
|
353
|
+
- Code generation requires LLM (only via AI IDE slash prompts, not CLI-only)
|
|
354
|
+
|
|
355
|
+
**Important**: If an artifact file doesn't exist yet, use the appropriate CLI command to create it. Never create or modify `.specfact/` files manually, as this bypasses validation and can cause inconsistencies.
|
|
356
|
+
|
|
357
|
+
## Dual-Stack Workflow (Copilot Mode)
|
|
358
|
+
|
|
359
|
+
When in copilot mode, follow this three-phase workflow:
|
|
360
|
+
|
|
361
|
+
### Phase 1: CLI Grounding (REQUIRED)
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
# Option 1: Get findings (redirect to /tmp/ to avoid polluting codebase)
|
|
365
|
+
specfact plan review [<bundle-name>] --list-findings --findings-format json --no-interactive > /tmp/findings.json
|
|
366
|
+
|
|
367
|
+
# Option 2: Get questions and save directly to /tmp/ (recommended - avoids JSON parsing)
|
|
368
|
+
specfact plan review [<bundle-name>] --list-questions --output-questions /tmp/questions.json --no-interactive
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Capture**:
|
|
372
|
+
|
|
373
|
+
- CLI-generated findings (ambiguities, missing information)
|
|
374
|
+
- Questions saved directly to file (no complex parsing needed)
|
|
375
|
+
- Structured JSON/YAML output for bulk processing
|
|
376
|
+
- Metadata (timestamps, confidence scores)
|
|
377
|
+
|
|
378
|
+
**Note**: Use `--output-questions` to save questions directly to a file. This avoids the need for complex on-the-fly Python code to extract JSON from CLI output.
|
|
379
|
+
|
|
380
|
+
**CRITICAL**: Always use `/tmp/` for temporary artifacts (`questions.json`, `findings.json`, etc.) to avoid polluting the codebase and prevent accidental commits of temporary files.
|
|
381
|
+
|
|
382
|
+
### Phase 2: LLM Enrichment (REQUIRED for Partial Findings)
|
|
383
|
+
|
|
384
|
+
**Purpose**: Add semantic understanding and domain knowledge to CLI findings
|
|
385
|
+
|
|
386
|
+
**CRITICAL**: `--auto-enrich` will **NOT** resolve partial findings. LLM reasoning is **REQUIRED** for:
|
|
387
|
+
|
|
388
|
+
- Missing error handling specifications ("Interaction & UX Flow" category)
|
|
389
|
+
- Vague acceptance criteria requiring domain knowledge ("Completion Signals" category)
|
|
390
|
+
- Business context questions requiring human judgment
|
|
391
|
+
|
|
392
|
+
**What to do**:
|
|
393
|
+
|
|
394
|
+
1. **Read exported questions file** (`/tmp/questions.json`):
|
|
395
|
+
- Review all questions and their categories
|
|
396
|
+
- Identify questions requiring code/feature analysis
|
|
397
|
+
- Determine questions needing domain knowledge
|
|
398
|
+
|
|
399
|
+
2. **Research codebase**:
|
|
400
|
+
- For error handling: Analyze existing error handling patterns
|
|
401
|
+
- For acceptance criteria: Review related features and stories
|
|
402
|
+
- For business context: Review `idea.yaml`, `product.yaml`, documentation
|
|
403
|
+
|
|
404
|
+
3. **Present questions with answer options IN THE CHAT** (REQUIRED):
|
|
405
|
+
|
|
406
|
+
**DO NOT add answers to the file yet!** Present each question with answer options in the chat conversation.
|
|
407
|
+
|
|
408
|
+
**For each question:**
|
|
409
|
+
|
|
410
|
+
- Generate 3-5 reasonable options based on code analysis and domain knowledge
|
|
411
|
+
- Present in a numbered table (1-5) or lettered table (A-E) **IN THE CHAT**
|
|
412
|
+
- Include a "[Custom answer]" option as the last choice
|
|
413
|
+
- Make options specific and actionable, not generic
|
|
414
|
+
- **Wait for user to select an answer** before moving to the next question
|
|
415
|
+
|
|
416
|
+
**Example format (present in chat):**
|
|
417
|
+
|
|
418
|
+
```text
|
|
419
|
+
Question 1/5
|
|
420
|
+
Category: Interaction & UX Flow
|
|
421
|
+
Q: What error/empty states should be handled for story STORY-XXX?
|
|
422
|
+
|
|
423
|
+
Answer Options:
|
|
424
|
+
┌─────┬─────────────────────────────────────────────────────────────┐
|
|
425
|
+
│ No. │ Option │
|
|
426
|
+
├─────┼─────────────────────────────────────────────────────────────┤
|
|
427
|
+
│ 1 │ [Option based on code analysis - specific and actionable] │
|
|
428
|
+
│ │ ⭐ Recommended (based on code analysis) │
|
|
429
|
+
│ 2 │ [Option based on best practices - domain knowledge] │
|
|
430
|
+
│ 3 │ [Option based on similar features - pattern matching] │
|
|
431
|
+
│ 4 │ [Not applicable / covered elsewhere] │
|
|
432
|
+
│ 5 │ [Custom answer - type your own] │
|
|
433
|
+
└─────┴─────────────────────────────────────────────────────────────┘
|
|
434
|
+
|
|
435
|
+
Your answer (1-5, or type custom answer): [1] ⭐ Recommended
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
4. **After user has selected all answers**:
|
|
439
|
+
|
|
440
|
+
- **THEN** add the selected answers to `/tmp/questions.json` in the `answers` object
|
|
441
|
+
- Map user selections (1-5) to the actual answer text from the options
|
|
442
|
+
- If user selected a custom answer, use that text directly
|
|
443
|
+
- **DO NOT** add answers to the file until user has selected all answers
|
|
444
|
+
|
|
445
|
+
**What NOT to do**:
|
|
446
|
+
|
|
447
|
+
- ❌ Use `--auto-enrich` expecting it to resolve partial findings
|
|
448
|
+
- ❌ Create YAML/JSON artifacts directly (even if they don't exist yet)
|
|
449
|
+
- ❌ Modify CLI artifacts directly (use CLI commands to update)
|
|
450
|
+
- ❌ Edit `idea.yaml`, `product.yaml`, feature files, or story files manually
|
|
451
|
+
- ❌ Create new artifact files manually - use CLI commands instead
|
|
452
|
+
- ❌ Bypass CLI validation
|
|
453
|
+
- ❌ Write to `.specfact/` folder directly (always use CLI)
|
|
454
|
+
- ❌ Create temporary files in project root (always use `/tmp/`)
|
|
455
|
+
|
|
456
|
+
**Output**: Updated `/tmp/questions.json` file with `answers` object populated
|
|
457
|
+
|
|
458
|
+
### Phase 3: CLI Artifact Creation (REQUIRED)
|
|
459
|
+
|
|
460
|
+
**For partial findings (REQUIRED workflow):**
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
# Import answers from /tmp/questions.json file
|
|
464
|
+
# Use /tmp/ to avoid polluting the codebase
|
|
465
|
+
specfact plan review [<bundle-name>] --answers "$(jq -c '.answers' /tmp/questions.json)" --no-interactive
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
**For non-partial findings only:**
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
# Use auto-enrich for simple vague criteria (not partial findings)
|
|
472
|
+
specfact plan review [<bundle-name>] --auto-enrich --no-interactive
|
|
473
|
+
|
|
474
|
+
# Or use batch updates for feature updates
|
|
475
|
+
specfact plan update-feature [--bundle <name>] --batch-updates <updates.json> --no-interactive
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
**Result**: Final artifacts are CLI-generated with validated enrichments
|
|
479
|
+
|
|
480
|
+
**Note**: If code generation is needed, use the validation loop pattern (see [CLI Enforcement Rules](./shared/cli-enforcement.md#standard-validation-loop-pattern-for-llm-generated-code))
|
|
481
|
+
|
|
482
|
+
## Expected Output
|
|
483
|
+
|
|
484
|
+
### Success
|
|
485
|
+
|
|
486
|
+
```text
|
|
487
|
+
✓ Review complete: 5 question(s) answered
|
|
488
|
+
|
|
489
|
+
Project Bundle: legacy-api
|
|
490
|
+
Questions Asked: 5
|
|
491
|
+
|
|
492
|
+
Sections Touched:
|
|
493
|
+
• idea.narrative
|
|
494
|
+
• features[FEATURE-001].acceptance
|
|
495
|
+
• features[FEATURE-002].outcomes
|
|
496
|
+
|
|
497
|
+
Coverage Summary:
|
|
498
|
+
✅ Functional Scope: clear
|
|
499
|
+
✅ Technical Constraints: clear
|
|
500
|
+
⚠️ Business Context: partial
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### Error (Missing Bundle)
|
|
504
|
+
|
|
505
|
+
```text
|
|
506
|
+
✗ Project bundle 'legacy-api' not found
|
|
507
|
+
Create one with: specfact plan init legacy-api
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
## Common Patterns
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
# Get findings first
|
|
514
|
+
/specfact.03-review --list-findings # List all findings
|
|
515
|
+
/specfact.03-review --list-findings --findings-format json # JSON format for enrichment
|
|
516
|
+
|
|
517
|
+
# Interactive review
|
|
518
|
+
/specfact.03-review # Uses active plan (default: 5 questions per session)
|
|
519
|
+
/specfact.03-review legacy-api # Specific bundle
|
|
520
|
+
/specfact.03-review --max-questions 3 # Limit questions per session (may need multiple runs)
|
|
521
|
+
/specfact.03-review --category "Functional Scope" # Focus category
|
|
522
|
+
/specfact.03-review --max-questions 10 # Ask more questions per session (up to 10)
|
|
523
|
+
|
|
524
|
+
# Non-interactive with answers
|
|
525
|
+
/specfact.03-review --answers '{"Q001": "answer"}' # Provide answers directly
|
|
526
|
+
/specfact.03-review --list-questions # Output questions as JSON to stdout
|
|
527
|
+
/specfact.03-review --list-questions --output-questions /tmp/questions.json # Save questions to /tmp/
|
|
528
|
+
|
|
529
|
+
# Auto-enrichment (NOTE: Will NOT resolve partial findings - use export/LLM/import workflow instead)
|
|
530
|
+
/specfact.03-review --auto-enrich # Auto-enrich simple vague criteria only
|
|
531
|
+
|
|
532
|
+
# Recommended workflow for partial findings (use /tmp/ to avoid polluting codebase)
|
|
533
|
+
/specfact.03-review --list-questions --output-questions /tmp/questions.json # Export questions (default: 5 per session)
|
|
534
|
+
# [LLM reasoning: present questions in chat, wait for user selections, then export answers]
|
|
535
|
+
/specfact.03-review --answers /tmp/answers.json # Import answers from file
|
|
536
|
+
# [Repeat if more questions available - each session asks different questions]
|
|
537
|
+
/specfact.03-review --list-questions --output-questions /tmp/questions.json # Export next batch
|
|
538
|
+
/specfact.03-review --answers /tmp/answers.json # Import next batch
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
## Enrichment Workflow
|
|
542
|
+
|
|
543
|
+
**CRITICAL**: `--auto-enrich` will **NOT** resolve partial findings such as:
|
|
544
|
+
|
|
545
|
+
- Missing error handling specifications ("Interaction & UX Flow" category)
|
|
546
|
+
- Vague acceptance criteria requiring domain knowledge ("Completion Signals" category)
|
|
547
|
+
- Business context questions requiring human judgment
|
|
548
|
+
|
|
549
|
+
**For partial findings, use this REQUIRED workflow:**
|
|
550
|
+
|
|
551
|
+
1. **Export questions to file** (use `/tmp/` to avoid polluting codebase):
|
|
552
|
+
|
|
553
|
+
```bash
|
|
554
|
+
specfact plan review [<bundle-name>] --list-questions --output-questions /tmp/questions.json --no-interactive
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
2. **Get findings** (optional, for comprehensive analysis - use `/tmp/`):
|
|
558
|
+
|
|
559
|
+
```bash
|
|
560
|
+
specfact plan review [<bundle-name>] --list-findings --findings-format json --no-interactive > /tmp/findings.json
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
3. **LLM reasoning and user selection** (REQUIRED for partial findings):
|
|
564
|
+
|
|
565
|
+
**CRITICAL**: Present questions with answer options **IN THE CHAT**, wait for user selections, then add selected answers to file.
|
|
566
|
+
|
|
567
|
+
- Read `/tmp/questions.json` file
|
|
568
|
+
- Research codebase for error handling patterns, feature relationships, domain knowledge
|
|
569
|
+
- **Present each question with answer options IN THE CHAT** (see Step 3 for format)
|
|
570
|
+
- **Wait for user to select answers** (1-5, A-E, or custom text)
|
|
571
|
+
- **After user has selected all answers**, export selected answers to `/tmp/answers.json` (separate file)
|
|
572
|
+
- Map user selections to actual answer text (if user selected option 1, use the text from option 1)
|
|
573
|
+
- **Export format**: Create a JSON object with `question_id -> answer` mappings
|
|
574
|
+
- **DO NOT** export answers to file until user has selected all answers
|
|
575
|
+
- **CRITICAL**: Export to `/tmp/answers.json` (not `/tmp/questions.json`) for CLI import
|
|
576
|
+
|
|
577
|
+
4. **Import answers via CLI** (after user selections are complete):
|
|
578
|
+
|
|
579
|
+
```bash
|
|
580
|
+
# Import answers from exported file
|
|
581
|
+
specfact plan review [<bundle-name>] --answers /tmp/answers.json --no-interactive
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
**CRITICAL**: Use the file path `/tmp/answers.json` (not a JSON string extracted from `/tmp/questions.json`)
|
|
585
|
+
|
|
586
|
+
5. **Verify**: Run `plan review` again to confirm improvements
|
|
587
|
+
|
|
588
|
+
**Important**: The `--max-questions` parameter (default: 5) limits questions per session, not the total available. If there are more questions, repeat the workflow (Steps 2-4) until all are answered. Each session asks different questions, avoiding duplicates from previous sessions.
|
|
589
|
+
|
|
590
|
+
**For non-partial findings only:**
|
|
591
|
+
|
|
592
|
+
- **During import**: Auto-enrichment happens automatically (enabled by default)
|
|
593
|
+
- **After import**: Use `specfact plan review --auto-enrich` for simple vague criteria
|
|
594
|
+
- **Note**: The scanner now recognizes simplified format (e.g., "Must verify X works correctly (see contract examples)") as valid
|
|
595
|
+
|
|
596
|
+
**Alternative approaches** (for business context only):
|
|
597
|
+
|
|
598
|
+
- Use `plan update-idea` to update idea fields directly
|
|
599
|
+
- If bundle needs regeneration, use `import from-code --enrichment`
|
|
600
|
+
|
|
601
|
+
## Context
|
|
602
|
+
|
|
603
|
+
{ARGS}
|
|
@@ -521,7 +521,11 @@ class AmbiguityScanner:
|
|
|
521
521
|
else:
|
|
522
522
|
# Check for vague acceptance criteria patterns
|
|
523
523
|
# BUT: Skip if criteria are already code-specific (preserve code-specific criteria from code2spec)
|
|
524
|
-
|
|
524
|
+
# AND: Skip if criteria use the new simplified format (post-GWT refactoring)
|
|
525
|
+
from specfact_cli.utils.acceptance_criteria import (
|
|
526
|
+
is_code_specific_criteria,
|
|
527
|
+
is_simplified_format_criteria,
|
|
528
|
+
)
|
|
525
529
|
|
|
526
530
|
vague_patterns = [
|
|
527
531
|
"is implemented",
|
|
@@ -532,10 +536,16 @@ class AmbiguityScanner:
|
|
|
532
536
|
"is ready",
|
|
533
537
|
]
|
|
534
538
|
|
|
535
|
-
# Only check criteria that are NOT code-specific
|
|
539
|
+
# Only check criteria that are NOT code-specific AND NOT using simplified format
|
|
536
540
|
# Note: Acceptance criteria are simple text descriptions (not OpenAPI format)
|
|
537
541
|
# Detailed testable examples are stored in OpenAPI contract files (.openapi.yaml)
|
|
538
|
-
|
|
542
|
+
# The new simplified format (e.g., "Must verify X works correctly (see contract examples)")
|
|
543
|
+
# is VALID and should not be flagged as vague
|
|
544
|
+
non_code_specific_criteria = [
|
|
545
|
+
acc
|
|
546
|
+
for acc in story.acceptance
|
|
547
|
+
if not is_code_specific_criteria(acc) and not is_simplified_format_criteria(acc)
|
|
548
|
+
]
|
|
539
549
|
|
|
540
550
|
vague_criteria = [
|
|
541
551
|
acc
|