specfact-cli 0.13.2__tar.gz → 0.13.3__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.
Files changed (143) hide show
  1. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/PKG-INFO +1 -1
  2. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/pyproject.toml +1 -1
  3. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/prompts/specfact.01-import.md +1 -0
  4. specfact_cli-0.13.3/resources/prompts/specfact.07-contracts.md +310 -0
  5. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/prompts/specfact.validate.md +5 -0
  6. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/__init__.py +1 -1
  7. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/__init__.py +1 -1
  8. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/analyze.py +108 -0
  9. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/ide_setup.py +1 -0
  10. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/.gitignore +0 -0
  11. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/LICENSE.md +0 -0
  12. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/README.md +0 -0
  13. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/mappings/node-async.yaml +0 -0
  14. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/mappings/python-async.yaml +0 -0
  15. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/mappings/speckit-default.yaml +0 -0
  16. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/prompts/shared/cli-enforcement.md +0 -0
  17. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/prompts/specfact.02-plan.md +0 -0
  18. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/prompts/specfact.03-review.md +0 -0
  19. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/prompts/specfact.04-sdd.md +0 -0
  20. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/prompts/specfact.05-enforce.md +0 -0
  21. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/prompts/specfact.06-sync.md +0 -0
  22. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/prompts/specfact.compare.md +0 -0
  23. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/schemas/deviation.schema.json +0 -0
  24. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/schemas/plan.schema.json +0 -0
  25. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/schemas/protocol.schema.json +0 -0
  26. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/templates/github-action.yml.j2 +0 -0
  27. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/templates/plan.bundle.yaml.j2 +0 -0
  28. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/templates/pr-template.md.j2 +0 -0
  29. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/templates/protocol.yaml.j2 +0 -0
  30. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/resources/templates/telemetry.yaml.example +0 -0
  31. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/agents/__init__.py +0 -0
  32. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/agents/analyze_agent.py +0 -0
  33. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/agents/base.py +0 -0
  34. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/agents/plan_agent.py +0 -0
  35. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/agents/registry.py +0 -0
  36. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/agents/sync_agent.py +0 -0
  37. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/analyzers/__init__.py +0 -0
  38. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
  39. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
  40. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
  41. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
  42. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
  43. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
  44. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
  45. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
  46. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
  47. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/cli.py +0 -0
  48. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/__init__.py +0 -0
  49. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/bridge.py +0 -0
  50. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/drift.py +0 -0
  51. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/enforce.py +0 -0
  52. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/generate.py +0 -0
  53. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/implement.py +0 -0
  54. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/import_cmd.py +0 -0
  55. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/init.py +0 -0
  56. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/migrate.py +0 -0
  57. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/plan.py +0 -0
  58. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/repro.py +0 -0
  59. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/run.py +0 -0
  60. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/sdd.py +0 -0
  61. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/spec.py +0 -0
  62. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/commands/sync.py +0 -0
  63. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/common/__init__.py +0 -0
  64. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/common/logger_setup.py +0 -0
  65. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/common/logging_utils.py +0 -0
  66. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/common/text_utils.py +0 -0
  67. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/common/utils.py +0 -0
  68. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/comparators/__init__.py +0 -0
  69. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/comparators/plan_comparator.py +0 -0
  70. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
  71. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
  72. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/generators/__init__.py +0 -0
  73. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/generators/contract_generator.py +0 -0
  74. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/generators/openapi_extractor.py +0 -0
  75. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/generators/plan_generator.py +0 -0
  76. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/generators/protocol_generator.py +0 -0
  77. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/generators/report_generator.py +0 -0
  78. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/generators/task_generator.py +0 -0
  79. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/generators/test_to_openapi.py +0 -0
  80. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/generators/workflow_generator.py +0 -0
  81. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/importers/__init__.py +0 -0
  82. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/importers/speckit_converter.py +0 -0
  83. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/importers/speckit_scanner.py +0 -0
  84. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/integrations/__init__.py +0 -0
  85. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/integrations/specmatic.py +0 -0
  86. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/migrations/__init__.py +0 -0
  87. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/migrations/plan_migrator.py +0 -0
  88. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/__init__.py +0 -0
  89. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/bridge.py +0 -0
  90. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/deviation.py +0 -0
  91. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/enforcement.py +0 -0
  92. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/plan.py +0 -0
  93. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/project.py +0 -0
  94. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/protocol.py +0 -0
  95. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/quality.py +0 -0
  96. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/sdd.py +0 -0
  97. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/source_tracking.py +0 -0
  98. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/models/task.py +0 -0
  99. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/modes/__init__.py +0 -0
  100. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/modes/detector.py +0 -0
  101. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/modes/router.py +0 -0
  102. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/resources/semgrep/async.yml +0 -0
  103. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
  104. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
  105. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/runtime.py +0 -0
  106. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/__init__.py +0 -0
  107. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/bridge_probe.py +0 -0
  108. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/bridge_sync.py +0 -0
  109. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/bridge_watch.py +0 -0
  110. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/change_detector.py +0 -0
  111. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/code_to_spec.py +0 -0
  112. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/drift_detector.py +0 -0
  113. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/repository_sync.py +0 -0
  114. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/spec_to_code.py +0 -0
  115. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/spec_to_tests.py +0 -0
  116. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/speckit_sync.py +0 -0
  117. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/sync/watcher.py +0 -0
  118. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/telemetry.py +0 -0
  119. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/templates/__init__.py +0 -0
  120. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/templates/bridge_templates.py +0 -0
  121. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/__init__.py +0 -0
  122. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
  123. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/bundle_loader.py +0 -0
  124. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/console.py +0 -0
  125. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/enrichment_context.py +0 -0
  126. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/enrichment_parser.py +0 -0
  127. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/feature_keys.py +0 -0
  128. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/git.py +0 -0
  129. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/github_annotations.py +0 -0
  130. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/incremental_check.py +0 -0
  131. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/optional_deps.py +0 -0
  132. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/progress.py +0 -0
  133. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/prompts.py +0 -0
  134. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/sdd_discovery.py +0 -0
  135. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/source_scanner.py +0 -0
  136. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/structure.py +0 -0
  137. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/structured_io.py +0 -0
  138. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/utils/yaml_utils.py +0 -0
  139. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/validators/__init__.py +0 -0
  140. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/validators/contract_validator.py +0 -0
  141. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/validators/fsm.py +0 -0
  142. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/src/specfact_cli/validators/repro_checker.py +0 -0
  143. {specfact_cli-0.13.2 → specfact_cli-0.13.3}/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.13.2
3
+ Version: 0.13.3
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.13.2"
7
+ version = "0.13.3"
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"
@@ -33,6 +33,7 @@ Import codebase → plan bundle. CLI extracts routes/schemas/relationships/contr
33
33
  - Read `.specfact/projects/<bundle>/enrichment_context.md`
34
34
  - Enrich: business context, "why" reasoning, missing acceptance criteria
35
35
  - Validate: contracts vs code, feature/story alignment
36
+ - Save enrichment report to `.specfact/reports/enrichment/` (if created)
36
37
 
37
38
  3. **Present**: Bundle location, report path, summary (features/stories/contracts/relationships)
38
39
 
@@ -0,0 +1,310 @@
1
+ ---
2
+ description: Analyze contract coverage, generate enhancement prompts, and apply contracts sequentially with careful review.
3
+ ---
4
+
5
+ # SpecFact Contract Enhancement Workflow
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
+ Complete contract enhancement workflow: analyze coverage → generate prompts → apply contracts sequentially with careful review.
18
+
19
+ **When to use:** After codebase analysis, when adding contracts to existing code, improving contract coverage.
20
+
21
+ **Quick:** `/specfact.07-contracts` (uses active plan) or `/specfact.07-contracts legacy-api`
22
+
23
+ ## Parameters
24
+
25
+ ### Target/Input
26
+
27
+ - `bundle NAME` (optional argument) - Project bundle name (e.g., legacy-api, auth-module). Default: active plan (set via `plan select`)
28
+ - `--repo PATH` - Repository path. Default: current directory (.)
29
+ - `--apply CONTRACTS` - Contract types to apply: 'all-contracts', 'beartype', 'icontract', 'crosshair', or comma-separated list. Default: 'all-contracts'
30
+ - `--min-priority PRIORITY` - Minimum priority for files to process: 'high', 'medium', 'low'. Default: 'low' (process all files missing contracts)
31
+
32
+ ### Behavior/Options
33
+
34
+ - `--no-interactive` - Non-interactive mode (for CI/CD). Default: False (interactive mode with careful review)
35
+ - `--auto-apply` - Automatically apply contracts after validation (skips confirmation). Default: False (requires confirmation)
36
+ - `--batch-size INT` - Number of files to process before pausing for review. Default: 1 (one file at a time for careful review)
37
+
38
+ ## Workflow
39
+
40
+ ### Step 1: Analyze Contract Coverage
41
+
42
+ **First, identify files missing contracts:**
43
+
44
+ ```bash
45
+ specfact analyze contracts --repo <repo-path> --bundle <bundle-name>
46
+ # Uses active plan if bundle not specified
47
+ ```
48
+
49
+ **Parse the output to identify:**
50
+ - Files missing beartype (marked with ✗)
51
+ - Files missing icontract (marked with ✗)
52
+ - Files missing crosshair (marked with ✗ or dim ✗)
53
+ - Files that need attention (prioritized in the table)
54
+
55
+ **Extract file list:**
56
+ - Focus on files marked with ✗ for beartype or icontract
57
+ - Crosshair is optional (marked with dim ✗), but can be included if user requests
58
+ - Filter out pure data model files (they use Pydantic validation)
59
+
60
+ **Present summary:**
61
+ - Total files analyzed
62
+ - Files missing contracts (by type)
63
+ - Files recommended for enhancement
64
+
65
+ ### Step 2: Generate Enhancement Prompts
66
+
67
+ **For each file missing contracts, generate a prompt:**
68
+
69
+ ```bash
70
+ specfact generate contracts-prompt <file-path> --apply <contract-types> --bundle <bundle-name>
71
+ ```
72
+
73
+ **Important:**
74
+ - Generate prompts for ALL files missing contracts (or based on --min-priority)
75
+ - Prompts are saved to `.specfact/projects/<bundle-name>/prompts/enhance-<filename>-<contracts>.md`
76
+ - If no bundle, prompts saved to `.specfact/prompts/`
77
+ - Each prompt file contains instructions for the AI IDE to enhance the file
78
+
79
+ **Present prompt generation summary:**
80
+ - Number of prompts generated
81
+ - Location of prompt files
82
+ - List of files ready for enhancement
83
+
84
+ ### Step 3: User Review and Selection
85
+
86
+ **Present files for user selection:**
87
+
88
+ ```text
89
+ Files ready for contract enhancement:
90
+ 1. src/auth/login.py (missing: beartype, icontract)
91
+ 2. src/api/users.py (missing: beartype, icontract, crosshair)
92
+ 3. src/utils/helpers.py (missing: beartype)
93
+ ...
94
+
95
+ Select files to enhance (comma-separated numbers, 'all', or 'skip'):
96
+ ```
97
+
98
+ **Wait for user input:**
99
+ - If user selects specific files, process only those
100
+ - If user selects 'all', process all files sequentially
101
+ - If user selects 'skip', move to next step or exit
102
+
103
+ **In non-interactive mode:**
104
+ - Process all files automatically (or based on --min-priority)
105
+ - Still process sequentially (one at a time) for careful validation
106
+
107
+ ### Step 4: Apply Contracts Sequentially
108
+
109
+ **For each selected file, apply contracts one at a time:**
110
+
111
+ **4.1: Read the prompt file**
112
+
113
+ ```bash
114
+ # Prompt file location: .specfact/projects/<bundle-name>/prompts/enhance-<filename>-<contracts>.md
115
+ # Or: .specfact/prompts/enhance-<filename>-<contracts>.md
116
+ ```
117
+
118
+ **4.2: Enhance the code using AI IDE**
119
+
120
+ - Read the original file
121
+ - Apply contracts according to the prompt instructions
122
+ - Write enhanced code to temporary file: `enhanced_<filename>.py`
123
+ - **DO NOT modify the original file directly**
124
+
125
+ **4.3: Validate enhanced code**
126
+
127
+ ```bash
128
+ specfact generate contracts-apply enhanced_<filename>.py --original <original-file-path>
129
+ ```
130
+
131
+ **Validation includes:**
132
+ - File size check
133
+ - Syntax validation
134
+ - AST structure comparison
135
+ - Contract imports verification
136
+ - Code quality checks (ruff, pylint, basedpyright, mypy if available)
137
+ - Test execution (scoped to relevant test files)
138
+
139
+ **4.4: Handle validation results**
140
+
141
+ **If validation fails:**
142
+ - Review error messages
143
+ - Fix issues in enhanced code
144
+ - Re-validate (up to 3 attempts)
145
+ - If still failing after 3 attempts, skip this file and continue to next
146
+
147
+ **If validation succeeds:**
148
+ - Show diff preview (what will change)
149
+ - If `--auto-apply` is False, ask for confirmation:
150
+ ```text
151
+ Validation passed. Apply changes to <original-file>? (y/n):
152
+ ```
153
+ - If confirmed (or `--auto-apply` is True), apply changes automatically
154
+ - If not confirmed, skip this file and continue to next
155
+
156
+ **4.5: Pause for review (if --batch-size > 1)**
157
+
158
+ After processing `--batch-size` files, pause and show summary:
159
+ ```text
160
+ Processed 3/10 files:
161
+ ✓ src/auth/login.py - Contracts applied successfully
162
+ ✓ src/api/users.py - Contracts applied successfully
163
+ ⏭ src/utils/helpers.py - Skipped (user declined)
164
+
165
+ Continue with next batch? (y/n):
166
+ ```
167
+
168
+ ### Step 5: Final Summary
169
+
170
+ **After all files processed, show final summary:**
171
+
172
+ ```text
173
+ Contract Enhancement Complete
174
+
175
+ Summary:
176
+ - Files analyzed: 25
177
+ - Files processed: 18
178
+ - Files enhanced: 15
179
+ - Files skipped: 3
180
+ - Files failed: 0
181
+
182
+ Enhanced files:
183
+ ✓ src/auth/login.py (beartype, icontract)
184
+ ✓ src/api/users.py (beartype, icontract, crosshair)
185
+ ...
186
+
187
+ Next steps:
188
+ 1. Verify contract coverage: specfact analyze contracts --bundle <bundle-name>
189
+ 2. Run full test suite: pytest (or your project's test command)
190
+ 3. Review changes: git diff
191
+ 4. Commit enhanced code
192
+ ```
193
+
194
+ ## CLI Enforcement
195
+
196
+ **CRITICAL**: Always use SpecFact CLI commands. See [CLI Enforcement Rules](./shared/cli-enforcement.md) for details.
197
+
198
+ **Rules:**
199
+ - Execute CLI commands in sequence (analyze → generate → apply)
200
+ - Never modify `.specfact/` directly
201
+ - Always validate before applying changes
202
+ - Process files sequentially for careful review
203
+ - Use `--no-interactive` only in CI/CD environments
204
+ - Use CLI output as grounding for all operations
205
+
206
+ ## Expected Output
207
+
208
+ ### Step 1: Analysis Results
209
+
210
+ ```text
211
+ Contract Coverage Analysis: legacy-api
212
+ Repository: /path/to/repo
213
+
214
+ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┓
215
+ ┃ File ┃ beartype ┃ icontract ┃ crosshair ┃ Coverage ┃
216
+ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━┩
217
+ │ src/auth/login.py │ ✗ │ ✗ │ ✗ │ 0% │
218
+ │ src/api/users.py │ ✗ │ ✗ │ ✗ │ 0% │
219
+ ...
220
+
221
+ Summary:
222
+ Files analyzed: 25
223
+ Files with beartype: 7 (28.0%)
224
+ Files with icontract: 7 (28.0%)
225
+ Files with crosshair: 2 (8.0%)
226
+
227
+ Found 18 files missing contracts.
228
+ ```
229
+
230
+ ### Step 2: Prompt Generation
231
+
232
+ ```text
233
+ Generating enhancement prompts...
234
+
235
+ ✓ Generated prompt for: src/auth/login.py
236
+ Location: .specfact/projects/legacy-api/prompts/enhance-login.py-all-contracts.md
237
+
238
+ ✓ Generated prompt for: src/api/users.py
239
+ Location: .specfact/projects/legacy-api/prompts/enhance-users.py-all-contracts.md
240
+
241
+ ...
242
+
243
+ ✓ Generated 18 prompts successfully
244
+ ```
245
+
246
+ ### Step 3: User Selection
247
+
248
+ ```text
249
+ Files ready for contract enhancement:
250
+ 1. src/auth/login.py (missing: beartype, icontract, crosshair)
251
+ 2. src/api/users.py (missing: beartype, icontract, crosshair)
252
+ 3. src/utils/helpers.py (missing: beartype)
253
+ ...
254
+
255
+ Select files to enhance (comma-separated numbers, 'all', or 'skip'): all
256
+ ```
257
+
258
+ ### Step 4: Sequential Application
259
+
260
+ ```text
261
+ Processing file 1/18: src/auth/login.py
262
+
263
+ [Reading prompt file...]
264
+ [Enhancing code with AI IDE...]
265
+ [Writing enhanced code to: enhanced_login.py]
266
+
267
+ Validating enhanced code...
268
+ ✓ File size check: passed
269
+ ✓ Syntax validation: passed
270
+ ✓ AST structure: passed (15 definitions preserved)
271
+ ✓ Contract imports: verified
272
+ ✓ Code quality checks: passed (ruff, pylint)
273
+ ✓ Tests: 12/12 passed
274
+
275
+ Diff preview:
276
+ + from beartype import beartype
277
+ + from icontract import require, ensure
278
+ ...
279
+
280
+ Apply changes to src/auth/login.py? (y/n): y
281
+ ✓ Contracts applied successfully
282
+
283
+ [Pausing for review... Press Enter to continue to next file]
284
+ ```
285
+
286
+ ## Common Patterns
287
+
288
+ ```bash
289
+ /specfact.07-contracts # Uses active plan, all-contracts, interactive
290
+ /specfact.07-contracts legacy-api # Specific bundle
291
+ /specfact.07-contracts --apply beartype,icontract # Specific contract types
292
+ /specfact.07-contracts --min-priority high # Only high-priority files
293
+ /specfact.07-contracts --batch-size 3 # Process 3 files before pausing
294
+ /specfact.07-contracts --auto-apply # Auto-apply after validation (no confirmation)
295
+ /specfact.07-contracts --no-interactive # CI/CD mode (still sequential for safety)
296
+ ```
297
+
298
+ ## Important Notes
299
+
300
+ 1. **Sequential Processing**: Files are processed one at a time (or in small batches) to allow careful review
301
+ 2. **Validation Required**: All enhanced code must pass validation before applying
302
+ 3. **User Control**: User can skip files, pause between files, or stop the process
303
+ 4. **Data Model Files**: Pure Pydantic/dataclass files are automatically excluded (they use Pydantic validation)
304
+ 5. **Prompt Location**: Prompts are saved to bundle-specific directories when bundle is provided
305
+ 6. **Temporary Files**: Enhanced code is written to temporary files (`enhanced_<filename>.py`) for validation before applying
306
+
307
+ ## Context
308
+
309
+ {ARGS}
310
+
@@ -64,6 +64,11 @@ specfact repro --repo <path> [--verbose] [--fail-fast] [--fix] [--budget <second
64
64
 
65
65
  **CRITICAL**: Always use SpecFact CLI commands. See [CLI Enforcement Rules](./shared/cli-enforcement.md) for details.
66
66
 
67
+ **Rules:**
68
+ - Execute CLI first - never create artifacts directly
69
+ - Never modify `.specfact/` directly
70
+ - Use CLI output as grounding for validation results
71
+
67
72
  ## Expected Output
68
73
 
69
74
  ### Success
@@ -3,4 +3,4 @@ SpecFact CLI - Spec→Contract→Sentinel tool for contract-driven development.
3
3
  """
4
4
 
5
5
  # Define the package version (kept in sync with pyproject.toml and setup.py)
6
- __version__ = "0.13.2"
6
+ __version__ = "0.13.3"
@@ -9,6 +9,6 @@ This package provides command-line tools for:
9
9
  - Validating reproducibility
10
10
  """
11
11
 
12
- __version__ = "0.13.2"
12
+ __version__ = "0.13.3"
13
13
 
14
14
  __all__ = ["__version__"]
@@ -7,6 +7,7 @@ contract coverage, code quality metrics, and enhancement opportunities.
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
+ import ast
10
11
  from pathlib import Path
11
12
 
12
13
  import typer
@@ -207,6 +208,30 @@ def _analyze_file_quality(file_path: Path) -> CodeQuality:
207
208
  with file_path.open(encoding="utf-8") as f:
208
209
  content = f.read()
209
210
 
211
+ # Quick check: if file is in models/ directory, likely a data model file
212
+ # This avoids expensive AST parsing for most data model files
213
+ file_str = str(file_path)
214
+ is_models_dir = "/models/" in file_str or "\\models\\" in file_str
215
+
216
+ # For files in models/ directory, do quick AST check to confirm
217
+ if is_models_dir:
218
+ try:
219
+ import ast
220
+
221
+ tree = ast.parse(content, filename=str(file_path))
222
+ # Quick check: if only BaseModel classes with no business logic, skip contract check
223
+ if _is_pure_data_model_file(tree):
224
+ return CodeQuality(
225
+ beartype=True, # Pydantic provides type validation
226
+ icontract=True, # Pydantic provides validation (Field validators)
227
+ crosshair=False, # CrossHair not typically used for data models
228
+ coverage=0.0,
229
+ )
230
+ except (SyntaxError, ValueError):
231
+ # If AST parsing fails, fall through to normal check
232
+ pass
233
+
234
+ # Check for contract decorators in content
210
235
  has_beartype = "beartype" in content or "@beartype" in content
211
236
  has_icontract = "icontract" in content or "@require" in content or "@ensure" in content
212
237
  has_crosshair = "crosshair" in content.lower()
@@ -223,3 +248,86 @@ def _analyze_file_quality(file_path: Path) -> CodeQuality:
223
248
  except Exception:
224
249
  # Return default quality if analysis fails
225
250
  return CodeQuality()
251
+
252
+
253
+ def _is_pure_data_model_file(tree: ast.AST) -> bool:
254
+ """
255
+ Quick check if file contains only pure data models (Pydantic BaseModel, dataclasses) with no business logic.
256
+
257
+ Returns:
258
+ True if file is pure data models, False otherwise
259
+ """
260
+ has_pydantic_models = False
261
+ has_dataclasses = False
262
+ has_business_logic = False
263
+
264
+ # Standard methods that don't need contracts (including common helper methods)
265
+ standard_methods = {
266
+ "__init__",
267
+ "__str__",
268
+ "__repr__",
269
+ "__eq__",
270
+ "__hash__",
271
+ "model_dump",
272
+ "model_validate",
273
+ "dict",
274
+ "json",
275
+ "copy",
276
+ "update",
277
+ # Common helper methods on data models (convenience methods, not business logic)
278
+ "compute_summary",
279
+ "update_summary",
280
+ "to_dict",
281
+ "from_dict",
282
+ "validate",
283
+ "serialize",
284
+ "deserialize",
285
+ }
286
+
287
+ # Check module-level functions and class methods separately
288
+ # First, collect all classes and check their methods
289
+ for node in ast.walk(tree):
290
+ if isinstance(node, ast.ClassDef):
291
+ # Check methods in this class
292
+ for item in node.body:
293
+ if isinstance(item, (ast.FunctionDef, ast.AsyncFunctionDef)) and item.name not in standard_methods:
294
+ # Non-standard method - likely business logic
295
+ has_business_logic = True
296
+ break
297
+ if has_business_logic:
298
+ break
299
+
300
+ # Then check for module-level functions (functions not inside any class)
301
+ if not has_business_logic and isinstance(tree, ast.Module):
302
+ # Get all top-level nodes (module body)
303
+ for node in tree.body:
304
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)) and not node.name.startswith(
305
+ "_"
306
+ ): # Public functions
307
+ has_business_logic = True
308
+ break
309
+
310
+ # Check for Pydantic models and dataclasses
311
+ for node in ast.walk(tree):
312
+ if isinstance(node, ast.ClassDef):
313
+ for base in node.bases:
314
+ if isinstance(base, ast.Name) and base.id == "BaseModel":
315
+ has_pydantic_models = True
316
+ break
317
+ if isinstance(base, ast.Attribute) and base.attr == "BaseModel":
318
+ has_pydantic_models = True
319
+ break
320
+
321
+ for decorator in node.decorator_list:
322
+ if (isinstance(decorator, ast.Name) and decorator.id == "dataclass") or (
323
+ isinstance(decorator, ast.Attribute) and decorator.attr == "dataclass"
324
+ ):
325
+ has_dataclasses = True
326
+ break
327
+
328
+ # Business logic check is done above (methods and module-level functions)
329
+
330
+ # File is pure data model if:
331
+ # 1. Has Pydantic models or dataclasses
332
+ # 2. No business logic methods or functions
333
+ return (has_pydantic_models or has_dataclasses) and not has_business_logic
@@ -119,6 +119,7 @@ SPECFACT_COMMANDS = [
119
119
  "specfact.04-sdd",
120
120
  "specfact.05-enforce",
121
121
  "specfact.06-sync",
122
+ "specfact.07-contracts",
122
123
  "specfact.compare",
123
124
  "specfact.validate",
124
125
  ]
File without changes
File without changes
File without changes