specfact-cli 0.47.3__tar.gz → 0.47.6__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 (279) hide show
  1. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/.gitignore +2 -0
  2. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/PKG-INFO +25 -17
  3. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/README.md +22 -14
  4. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/pyproject.toml +8 -4
  5. specfact_cli-0.47.6/src/__init__.py +6 -0
  6. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/__init__.py +3 -2
  7. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/cli.py +87 -39
  8. specfact_cli-0.47.3/src/__init__.py +0 -6
  9. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/LICENSE +0 -0
  10. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/bundled-module-registry/index.json +0 -0
  11. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/keys/README.md +0 -0
  12. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/keys/module-signing-public.pem +0 -0
  13. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/mappings/node-async.yaml +0 -0
  14. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/mappings/python-async.yaml +0 -0
  15. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/mappings/speckit-default.yaml +0 -0
  16. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/schemas/deviation.schema.json +0 -0
  17. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/schemas/plan.schema.json +0 -0
  18. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/schemas/protocol.schema.json +0 -0
  19. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/github-action.yml.j2 +0 -0
  20. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/persona/architect.md.j2 +0 -0
  21. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/persona/developer.md.j2 +0 -0
  22. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/persona/product-owner.md.j2 +0 -0
  23. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/plan.bundle.yaml.j2 +0 -0
  24. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/policies/kanban.yaml +0 -0
  25. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/policies/mixed.yaml +0 -0
  26. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/policies/safe.yaml +0 -0
  27. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/policies/scrum.yaml +0 -0
  28. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/pr-template.md.j2 +0 -0
  29. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/protocol.yaml.j2 +0 -0
  30. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/resources/templates/telemetry.yaml.example +0 -0
  31. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/__main__.py +0 -0
  32. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/__init__.py +0 -0
  33. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/ado.py +0 -0
  34. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/backlog_base.py +0 -0
  35. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/base.py +0 -0
  36. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/github.py +0 -0
  37. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/openspec.py +0 -0
  38. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/openspec_parser.py +0 -0
  39. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/registry.py +0 -0
  40. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/adapters/speckit.py +0 -0
  41. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/__init__.py +0 -0
  42. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/analyze_agent.py +0 -0
  43. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/base.py +0 -0
  44. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/plan_agent.py +0 -0
  45. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/registry.py +0 -0
  46. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/agents/sync_agent.py +0 -0
  47. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/__init__.py +0 -0
  48. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/ambiguity_scanner.py +0 -0
  49. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/code_analyzer.py +0 -0
  50. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/constitution_evidence_extractor.py +0 -0
  51. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/contract_extractor.py +0 -0
  52. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/control_flow_analyzer.py +0 -0
  53. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/graph_analyzer.py +0 -0
  54. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/relationship_mapper.py +0 -0
  55. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/requirement_extractor.py +0 -0
  56. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/analyzers/test_pattern_extractor.py +0 -0
  57. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/__init__.py +0 -0
  58. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/adapters/__init__.py +0 -0
  59. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/adapters/base.py +0 -0
  60. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/converter.py +0 -0
  61. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/filters.py +0 -0
  62. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/__init__.py +0 -0
  63. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/ado_mapper.py +0 -0
  64. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/base.py +0 -0
  65. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/github_mapper.py +0 -0
  66. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/backlog/mappers/template_config.py +0 -0
  67. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/__init__.py +0 -0
  68. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/_bundle_shim.py +0 -0
  69. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/analyze.py +0 -0
  70. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/contract_cmd.py +0 -0
  71. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/drift.py +0 -0
  72. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/enforce.py +0 -0
  73. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/generate.py +0 -0
  74. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/import_cmd.py +0 -0
  75. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/init.py +0 -0
  76. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/migrate.py +0 -0
  77. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/plan.py +0 -0
  78. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/project_cmd.py +0 -0
  79. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/repro.py +0 -0
  80. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/sdd.py +0 -0
  81. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/spec.py +0 -0
  82. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/sync.py +0 -0
  83. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/update.py +0 -0
  84. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/commands/validate.py +0 -0
  85. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/__init__.py +0 -0
  86. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/bundle_factory.py +0 -0
  87. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/logger_setup.py +0 -0
  88. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/logging_utils.py +0 -0
  89. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/text_utils.py +0 -0
  90. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/common/utils.py +0 -0
  91. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/comparators/__init__.py +0 -0
  92. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/comparators/plan_comparator.py +0 -0
  93. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/contracts/__init__.py +0 -0
  94. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/contracts/crosshair_props.py +0 -0
  95. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/contracts/module_interface.py +0 -0
  96. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/enrichers/constitution_enricher.py +0 -0
  97. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/enrichers/plan_enricher.py +0 -0
  98. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/__init__.py +0 -0
  99. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/contract_generator.py +0 -0
  100. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/openapi_extractor.py +0 -0
  101. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/persona_exporter.py +0 -0
  102. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/plan_generator.py +0 -0
  103. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/protocol_generator.py +0 -0
  104. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/report_generator.py +0 -0
  105. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/task_generator.py +0 -0
  106. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/test_to_openapi.py +0 -0
  107. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/generators/workflow_generator.py +0 -0
  108. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/__init__.py +0 -0
  109. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/codebase_group.py +0 -0
  110. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/govern_group.py +0 -0
  111. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/member_group.py +0 -0
  112. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/project_group.py +0 -0
  113. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/groups/spec_group.py +0 -0
  114. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/importers/__init__.py +0 -0
  115. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/importers/speckit_converter.py +0 -0
  116. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/importers/speckit_scanner.py +0 -0
  117. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/integrations/__init__.py +0 -0
  118. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/integrations/specmatic.py +0 -0
  119. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/merge/__init__.py +0 -0
  120. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/merge/resolver.py +0 -0
  121. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/migrations/__init__.py +0 -0
  122. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/migrations/plan_migrator.py +0 -0
  123. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/__init__.py +0 -0
  124. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/backlog_item.py +0 -0
  125. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/bridge.py +0 -0
  126. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/capabilities.py +0 -0
  127. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/change.py +0 -0
  128. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/contract.py +0 -0
  129. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/deviation.py +0 -0
  130. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/dor_config.py +0 -0
  131. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/enforcement.py +0 -0
  132. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/module_package.py +0 -0
  133. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/persona_template.py +0 -0
  134. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/plan.py +0 -0
  135. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/project.py +0 -0
  136. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/protocol.py +0 -0
  137. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/quality.py +0 -0
  138. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/sdd.py +0 -0
  139. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/source_tracking.py +0 -0
  140. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/task.py +0 -0
  141. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/models/validation.py +0 -0
  142. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modes/__init__.py +0 -0
  143. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modes/detector.py +0 -0
  144. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modes/router.py +0 -0
  145. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/__init__.py +0 -0
  146. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/_bundle_import.py +0 -0
  147. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/init/module-package.yaml +0 -0
  148. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/init/src/__init__.py +0 -0
  149. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/init/src/app.py +0 -0
  150. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/init/src/commands.py +0 -0
  151. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/init/src/first_run_selection.py +0 -0
  152. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/module_io_shim.py +0 -0
  153. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/module_registry/module-package.yaml +0 -0
  154. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/module_registry/src/__init__.py +0 -0
  155. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/module_registry/src/app.py +0 -0
  156. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/module_registry/src/commands.py +0 -0
  157. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/upgrade/module-package.yaml +0 -0
  158. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/upgrade/src/__init__.py +0 -0
  159. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/upgrade/src/app.py +0 -0
  160. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/modules/upgrade/src/commands.py +0 -0
  161. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/parsers/__init__.py +0 -0
  162. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/parsers/persona_importer.py +0 -0
  163. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/__init__.py +0 -0
  164. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/alias_manager.py +0 -0
  165. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/bootstrap.py +0 -0
  166. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/bridge_registry.py +0 -0
  167. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/crypto_validator.py +0 -0
  168. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/custom_registries.py +0 -0
  169. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/dependency_resolver.py +0 -0
  170. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/extension_registry.py +0 -0
  171. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/help_cache.py +0 -0
  172. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/marketplace_client.py +0 -0
  173. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/metadata.py +0 -0
  174. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_availability.py +0 -0
  175. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_discovery.py +0 -0
  176. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_grouping.py +0 -0
  177. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_installer.py +0 -0
  178. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_lifecycle.py +0 -0
  179. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_packages.py +0 -0
  180. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_security.py +0 -0
  181. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/module_state.py +0 -0
  182. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/registry/registry.py +0 -0
  183. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/resources/semgrep/async.yml +0 -0
  184. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/resources/semgrep/code-quality.yml +0 -0
  185. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/resources/semgrep/feature-detection.yml +0 -0
  186. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/runtime.py +0 -0
  187. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/__init__.py +0 -0
  188. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_probe.py +0 -0
  189. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync.py +0 -0
  190. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_openspec_md_parse.py +0 -0
  191. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_requirement_from_proposal.py +0 -0
  192. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_requirement_helpers.py +0 -0
  193. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_tasks_from_proposal.py +0 -0
  194. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_what_changes_format.py +0 -0
  195. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_sync_write_openspec_from_proposal.py +0 -0
  196. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/bridge_watch.py +0 -0
  197. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/change_detector.py +0 -0
  198. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/code_to_spec.py +0 -0
  199. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/drift_detector.py +0 -0
  200. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/repository_sync.py +0 -0
  201. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/spec_to_code.py +0 -0
  202. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/spec_to_tests.py +0 -0
  203. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/watcher.py +0 -0
  204. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/sync/watcher_enhanced.py +0 -0
  205. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/telemetry.py +0 -0
  206. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/__init__.py +0 -0
  207. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/defaults/defect_v1.yaml +0 -0
  208. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/defaults/enabler_v1.yaml +0 -0
  209. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/defaults/spike_v1.yaml +0 -0
  210. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/defaults/user_story_v1.yaml +0 -0
  211. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/frameworks/scrum/user_story_v1.yaml +0 -0
  212. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/personas/product-owner/user_story_v1.yaml +0 -0
  213. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/providers/ado/work_item_v1.yaml +0 -0
  214. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/registry.py +0 -0
  215. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/templates/specification_templates.py +0 -0
  216. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/__init__.py +0 -0
  217. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/acceptance_criteria.py +0 -0
  218. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/auth_tokens.py +0 -0
  219. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/bundle_converters.py +0 -0
  220. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/bundle_loader.py +0 -0
  221. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/code_change_detector.py +0 -0
  222. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/console.py +0 -0
  223. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/content_sanitizer.py +0 -0
  224. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/context_detection.py +0 -0
  225. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/contract_predicates.py +0 -0
  226. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/enrichment_context.py +0 -0
  227. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/enrichment_parser.py +0 -0
  228. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/env_manager.py +0 -0
  229. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/feature_keys.py +0 -0
  230. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/git.py +0 -0
  231. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/github_annotations.py +0 -0
  232. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/icontract_helpers.py +0 -0
  233. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/ide_setup.py +0 -0
  234. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/incremental_check.py +0 -0
  235. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/metadata.py +0 -0
  236. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/optional_deps.py +0 -0
  237. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/performance.py +0 -0
  238. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/persona_ownership.py +0 -0
  239. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/progress.py +0 -0
  240. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/progressive_disclosure.py +0 -0
  241. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/project_artifact_write.py +0 -0
  242. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/prompts.py +0 -0
  243. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/sdd_discovery.py +0 -0
  244. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/source_scanner.py +0 -0
  245. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/startup_checks.py +0 -0
  246. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/structure.py +0 -0
  247. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/structured_io.py +0 -0
  248. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/suggestions.py +0 -0
  249. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/terminal.py +0 -0
  250. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/utils/yaml_utils.py +0 -0
  251. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validation/__init__.py +0 -0
  252. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validation/command_audit.py +0 -0
  253. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/__init__.py +0 -0
  254. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/agile_validation.py +0 -0
  255. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/change_proposal_integration.py +0 -0
  256. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/cli_first_validator.py +0 -0
  257. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/contract_validator.py +0 -0
  258. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/fsm.py +0 -0
  259. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/repro_checker.py +0 -0
  260. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/schema.py +0 -0
  261. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/__init__.py +0 -0
  262. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/contract_populator.py +0 -0
  263. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/crosshair_runner.py +0 -0
  264. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/crosshair_summary.py +0 -0
  265. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/dependency_installer.py +0 -0
  266. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/framework_detector.py +0 -0
  267. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/__init__.py +0 -0
  268. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/base.py +0 -0
  269. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/django.py +0 -0
  270. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/drf.py +0 -0
  271. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/fastapi.py +0 -0
  272. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/frameworks/flask.py +0 -0
  273. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/harness_generator.py +0 -0
  274. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/models.py +0 -0
  275. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/orchestrator.py +0 -0
  276. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/specmatic_runner.py +0 -0
  277. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/validators/sidecar/unannotated_detector.py +0 -0
  278. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/versioning/__init__.py +0 -0
  279. {specfact_cli-0.47.3 → specfact_cli-0.47.6}/src/specfact_cli/versioning/analyzer.py +0 -0
@@ -117,6 +117,8 @@ docs/internal/
117
117
 
118
118
  .codex/skills/openspec-*/
119
119
  !.codex/skills/openspec-workflows/
120
+ .agents/skills/
121
+ skills-lock.json
120
122
 
121
123
  .vibe/skills/openspec-*/
122
124
  !.vibe/skills/openspec-workflows/
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specfact-cli
3
- Version: 0.47.3
4
- Summary: The swiss knife CLI for agile DevOps teams. Keep backlog, specs, tests, and code in sync with validation and contract enforcement for new projects and long-lived codebases.
3
+ Version: 0.47.6
4
+ Summary: AI-bloat defense CLI for Python teams. Run deterministic code review, cleanup forecasts, and spec/contract evidence for AI-assisted and brownfield delivery.
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
7
7
  Project-URL: Documentation, https://github.com/nold-ai/specfact-cli#readme
@@ -210,7 +210,7 @@ License: Apache License
210
210
  See the License for the specific language governing permissions and
211
211
  limitations under the License.
212
212
  License-File: LICENSE
213
- Keywords: agile,backlog,beartype,ceremonies,cli,contract-driven-development,contracts,crosshair,devops,existing-code,icontract,kanban,legacy,modernization,policy-as-code,property-based-testing,safe,scrum,specfact,specs,tdd,validation
213
+ Keywords: agile,ai-bloat,backlog,beartype,ceremonies,clean-code,cli,code-review,contract-driven-development,contracts,crosshair,devops,existing-code,icontract,kanban,legacy,modernization,policy-as-code,property-based-testing,safe,scrum,specfact,specs,tdd,technical-debt,validation
214
214
  Classifier: Development Status :: 4 - Beta
215
215
  Classifier: Intended Audience :: Developers
216
216
  Classifier: License :: OSI Approved :: Apache Software License
@@ -283,8 +283,8 @@ Description-Content-Type: text/markdown
283
283
 
284
284
  # SpecFact CLI
285
285
 
286
- > Review AI-assisted code against your own contracts.
287
- > Catch drift before it reaches PR or main.
286
+ > Defend AI-assisted Python code from bloat before it reaches PR.
287
+ > Run deterministic review, cleanup forecasts, and spec/contract evidence locally.
288
288
 
289
289
  [![PyPI version](https://img.shields.io/pypi/v/specfact-cli.svg?color=22c55e)](https://pypi.org/project/specfact-cli/)
290
290
  [![Python versions](https://img.shields.io/pypi/pyversions/specfact-cli.svg)](https://pypi.org/project/specfact-cli/)
@@ -315,7 +315,7 @@ uvx specfact-cli code review run --path . --scope full
315
315
  **Sample output:**
316
316
 
317
317
  ```text
318
- SpecFact CLI - v0.46.4
318
+ SpecFact CLI - v0.47.4
319
319
 
320
320
  Running Ruff checks...
321
321
  Running Radon complexity checks...
@@ -347,23 +347,30 @@ specfact code review run --path . --scope full
347
347
 
348
348
  The sample output comes from a pinned capture against `nold-ai/specfact-demo-repo`. Reproduce it with `docs/_support/readme-first-contact/capture-readme-output.sh`; capture metadata lives alongside the raw logs in `docs/_support/readme-first-contact/sample-output/`.
349
349
 
350
- The Code Review bundle also reports `ai_bloat` advisories for code shapes that AI-assisted coding often amplifies, such as redundant wrappers, passthrough lambdas, identity `try`/`except` blocks, and avoidable intermediate lists. These findings are advisory, score-neutral, and not AI-authorship detection. Use the generated `.specfact/code-review.json` report with the Project bundle's `/specfact.08-simplify` IDE prompt to review each cleanup before accepting it. See the [AI bloat quickstart](https://modules.specfact.io/quickstart-ai-bloat/) on the modules docs site.
350
+ ## AI-bloat defense loop
351
+
352
+ SpecFact is the local AI-bloat defense CLI for Python-first teams using AI IDEs. The Code Review bundle reports `ai_bloat` advisories for code shapes that AI-assisted coding often amplifies: redundant wrappers, passthrough lambdas, identity `try`/`except` blocks, avoidable intermediate lists, and long low-branch functions.
353
+
354
+ For cleanup work, run a JSON review, inspect the cleanup forecast and AI-bloat index, hand remediation packets to your AI IDE, accept only safe changes, then re-run review for proof. The JSON report is the portable handoff artifact for Claude, Codex, Cursor, Copilot, or a headless agent.
355
+
356
+ These findings are bloat-shape detection and cleanup guidance, not AI-authorship detection. Exact simplify flags and report fields live in the [AI bloat quickstart](https://modules.specfact.io/quickstart-ai-bloat/) and [Code Review run guide](https://modules.specfact.io/bundles/code-review/run/) on the modules docs site.
351
357
 
352
358
  ## What SpecFact does
353
359
 
354
- - **Reviews AI-assisted changes deterministically** — compare code against contracts, clean-code rules, and policy gates
360
+ - **Defends against AI bloat deterministically** — forecast cleanup impact and route remediation packets to your AI IDE
361
+ - **Reviews AI-assisted changes against evidence** — compare code against contracts, clean-code rules, and policy gates
355
362
  - **Extracts structure from existing code** — reverse-engineer brownfield repos before you change them
356
363
  - **Blocks drift before merge** — use the same checks locally, in pre-commit, and in CI
357
- - **Links backlog intent to code reality** — connect backlog, specs, validation, and implementation
364
+ - **Consumes upstream planning inputs** — treat Spec Kit, OpenSpec, backlog, specs, tests, and contracts as validation evidence
358
365
  - **Stays local-first** — no cloud account, no vendor lock-in, no built-in model dependency
359
366
 
360
367
  ## What is SpecFact?
361
368
 
362
- SpecFact is a local CLI for catching backlog/spec/code drift before it becomes expensive. It gives solo developers, legacy maintainers, and teams a validation layer around AI-assisted delivery, brownfield reverse engineering, and contract-first reviews.
369
+ SpecFact is a local CLI for AI-bloat defense, deterministic code review, and backlog/spec/code drift control. It gives solo developers, legacy maintainers, and teams a validation layer around AI-assisted delivery, brownfield reverse engineering, and contract-first reviews.
363
370
 
364
371
  It exists because delivery drifts in predictable ways:
365
372
 
366
- - AI-assisted code lands faster than validation catches up
373
+ - AI-assisted code lands faster than cleanup and validation catch up
367
374
  - brownfield systems rarely have trustworthy up-to-date specs
368
375
  - backlog intent gets reinterpreted before it reaches code
369
376
  - teams need the same review rules across IDEs, CI, and pull requests
@@ -384,7 +391,7 @@ For a **single-hook** setup in downstream repos, keep using the stable id and sc
384
391
 
385
392
  ```yaml
386
393
  - repo: https://github.com/nold-ai/specfact-cli
387
- rev: v0.46.4
394
+ rev: v0.47.4
388
395
  hooks:
389
396
  - id: specfact-smart-checks
390
397
  ```
@@ -412,17 +419,18 @@ SpecFact uses the same discipline it asks you to trust:
412
419
 
413
420
  ## For teams and organizations
414
421
 
415
- SpecFact still scales beyond the solo-developer entry path:
422
+ SpecFact still scales beyond the solo-developer entry path, but validation stays
423
+ the center:
416
424
 
417
- - **Backlog + ceremony workflows** for GitHub, Azure DevOps, Jira, and Linear
425
+ - **Upstream context adapters** for GitHub, Azure DevOps, Jira, Linear, OpenSpec, and Spec Kit inputs
418
426
  - **DoR/DoD and policy enforcement** for teams that need repeatable gates
419
427
  - **Evidence-backed PR review** with the same checks used locally
420
428
  - **CI/CD adoption path** that keeps validation deterministic instead of model-driven
421
429
 
422
- Start with:
430
+ Optional module-deep paths include:
423
431
 
424
- - `specfact backlog ceremony standup ...`
425
- - `specfact backlog ceremony refinement ...`
432
+ - `specfact project import ...`
433
+ - `specfact spec validate ...`
426
434
  - `specfact backlog verify-readiness --bundle <bundle-name>`
427
435
  - `specfact govern ...`
428
436
 
@@ -1,7 +1,7 @@
1
1
  # SpecFact CLI
2
2
 
3
- > Review AI-assisted code against your own contracts.
4
- > Catch drift before it reaches PR or main.
3
+ > Defend AI-assisted Python code from bloat before it reaches PR.
4
+ > Run deterministic review, cleanup forecasts, and spec/contract evidence locally.
5
5
 
6
6
  [![PyPI version](https://img.shields.io/pypi/v/specfact-cli.svg?color=22c55e)](https://pypi.org/project/specfact-cli/)
7
7
  [![Python versions](https://img.shields.io/pypi/pyversions/specfact-cli.svg)](https://pypi.org/project/specfact-cli/)
@@ -32,7 +32,7 @@ uvx specfact-cli code review run --path . --scope full
32
32
  **Sample output:**
33
33
 
34
34
  ```text
35
- SpecFact CLI - v0.46.4
35
+ SpecFact CLI - v0.47.4
36
36
 
37
37
  Running Ruff checks...
38
38
  Running Radon complexity checks...
@@ -64,23 +64,30 @@ specfact code review run --path . --scope full
64
64
 
65
65
  The sample output comes from a pinned capture against `nold-ai/specfact-demo-repo`. Reproduce it with `docs/_support/readme-first-contact/capture-readme-output.sh`; capture metadata lives alongside the raw logs in `docs/_support/readme-first-contact/sample-output/`.
66
66
 
67
- The Code Review bundle also reports `ai_bloat` advisories for code shapes that AI-assisted coding often amplifies, such as redundant wrappers, passthrough lambdas, identity `try`/`except` blocks, and avoidable intermediate lists. These findings are advisory, score-neutral, and not AI-authorship detection. Use the generated `.specfact/code-review.json` report with the Project bundle's `/specfact.08-simplify` IDE prompt to review each cleanup before accepting it. See the [AI bloat quickstart](https://modules.specfact.io/quickstart-ai-bloat/) on the modules docs site.
67
+ ## AI-bloat defense loop
68
+
69
+ SpecFact is the local AI-bloat defense CLI for Python-first teams using AI IDEs. The Code Review bundle reports `ai_bloat` advisories for code shapes that AI-assisted coding often amplifies: redundant wrappers, passthrough lambdas, identity `try`/`except` blocks, avoidable intermediate lists, and long low-branch functions.
70
+
71
+ For cleanup work, run a JSON review, inspect the cleanup forecast and AI-bloat index, hand remediation packets to your AI IDE, accept only safe changes, then re-run review for proof. The JSON report is the portable handoff artifact for Claude, Codex, Cursor, Copilot, or a headless agent.
72
+
73
+ These findings are bloat-shape detection and cleanup guidance, not AI-authorship detection. Exact simplify flags and report fields live in the [AI bloat quickstart](https://modules.specfact.io/quickstart-ai-bloat/) and [Code Review run guide](https://modules.specfact.io/bundles/code-review/run/) on the modules docs site.
68
74
 
69
75
  ## What SpecFact does
70
76
 
71
- - **Reviews AI-assisted changes deterministically** — compare code against contracts, clean-code rules, and policy gates
77
+ - **Defends against AI bloat deterministically** — forecast cleanup impact and route remediation packets to your AI IDE
78
+ - **Reviews AI-assisted changes against evidence** — compare code against contracts, clean-code rules, and policy gates
72
79
  - **Extracts structure from existing code** — reverse-engineer brownfield repos before you change them
73
80
  - **Blocks drift before merge** — use the same checks locally, in pre-commit, and in CI
74
- - **Links backlog intent to code reality** — connect backlog, specs, validation, and implementation
81
+ - **Consumes upstream planning inputs** — treat Spec Kit, OpenSpec, backlog, specs, tests, and contracts as validation evidence
75
82
  - **Stays local-first** — no cloud account, no vendor lock-in, no built-in model dependency
76
83
 
77
84
  ## What is SpecFact?
78
85
 
79
- SpecFact is a local CLI for catching backlog/spec/code drift before it becomes expensive. It gives solo developers, legacy maintainers, and teams a validation layer around AI-assisted delivery, brownfield reverse engineering, and contract-first reviews.
86
+ SpecFact is a local CLI for AI-bloat defense, deterministic code review, and backlog/spec/code drift control. It gives solo developers, legacy maintainers, and teams a validation layer around AI-assisted delivery, brownfield reverse engineering, and contract-first reviews.
80
87
 
81
88
  It exists because delivery drifts in predictable ways:
82
89
 
83
- - AI-assisted code lands faster than validation catches up
90
+ - AI-assisted code lands faster than cleanup and validation catch up
84
91
  - brownfield systems rarely have trustworthy up-to-date specs
85
92
  - backlog intent gets reinterpreted before it reaches code
86
93
  - teams need the same review rules across IDEs, CI, and pull requests
@@ -101,7 +108,7 @@ For a **single-hook** setup in downstream repos, keep using the stable id and sc
101
108
 
102
109
  ```yaml
103
110
  - repo: https://github.com/nold-ai/specfact-cli
104
- rev: v0.46.4
111
+ rev: v0.47.4
105
112
  hooks:
106
113
  - id: specfact-smart-checks
107
114
  ```
@@ -129,17 +136,18 @@ SpecFact uses the same discipline it asks you to trust:
129
136
 
130
137
  ## For teams and organizations
131
138
 
132
- SpecFact still scales beyond the solo-developer entry path:
139
+ SpecFact still scales beyond the solo-developer entry path, but validation stays
140
+ the center:
133
141
 
134
- - **Backlog + ceremony workflows** for GitHub, Azure DevOps, Jira, and Linear
142
+ - **Upstream context adapters** for GitHub, Azure DevOps, Jira, Linear, OpenSpec, and Spec Kit inputs
135
143
  - **DoR/DoD and policy enforcement** for teams that need repeatable gates
136
144
  - **Evidence-backed PR review** with the same checks used locally
137
145
  - **CI/CD adoption path** that keeps validation deterministic instead of model-driven
138
146
 
139
- Start with:
147
+ Optional module-deep paths include:
140
148
 
141
- - `specfact backlog ceremony standup ...`
142
- - `specfact backlog ceremony refinement ...`
149
+ - `specfact project import ...`
150
+ - `specfact spec validate ...`
143
151
  - `specfact backlog verify-readiness --bundle <bundle-name>`
144
152
  - `specfact govern ...`
145
153
 
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "specfact-cli"
7
- version = "0.47.3"
8
- description = "The swiss knife CLI for agile DevOps teams. Keep backlog, specs, tests, and code in sync with validation and contract enforcement for new projects and long-lived codebases."
7
+ version = "0.47.6"
8
+ description = "AI-bloat defense CLI for Python teams. Run deterministic code review, cleanup forecasts, and spec/contract evidence for AI-assisted and brownfield delivery."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
11
  license = { file = "LICENSE" } # Apache License 2.0
@@ -14,8 +14,12 @@ authors = [
14
14
  ]
15
15
  keywords = [
16
16
  "agile",
17
+ "ai-bloat",
17
18
  "devops",
18
19
  "backlog",
20
+ "code-review",
21
+ "clean-code",
22
+ "technical-debt",
19
23
  "scrum",
20
24
  "kanban",
21
25
  "safe",
@@ -220,9 +224,9 @@ security-audit = "python scripts/security_audit_gate.py"
220
224
  # Development scripts
221
225
  test = "pytest {args}"
222
226
  test-cov = "pytest --cov=src --cov-report=term-missing {args}"
223
- type-check = "basedpyright --pythonpath $(python -c 'import sys; print(sys.executable)') {args}"
227
+ type-check = "basedpyright --pythonpath \"$(python -c 'import sys; print(sys.executable)')\" {args}"
224
228
  # basedpyright --level error: suppress warning noise in pre-commit (Block 1 runs `hatch run lint`).
225
- lint = "ruff format . --check && basedpyright --level error --pythonpath $(python -c 'import sys; print(sys.executable)') && ruff check . && pylint src tests tools && python scripts/verify_safe_project_writes.py"
229
+ lint = "ruff format . --check && basedpyright --level error --pythonpath \"$(python -c 'import sys; print(sys.executable)')\" && ruff check . && pylint src tests tools && python scripts/verify_safe_project_writes.py"
226
230
  lint-changed = "python scripts/run_changed_lint.py {args}"
227
231
  governance = "pylint src tests tools --reports=y --output-format=parseable"
228
232
  format = "ruff check . --fix && ruff format ."
@@ -0,0 +1,6 @@
1
+ """
2
+ SpecFact CLI - AI-bloat defense CLI for Python teams.
3
+ """
4
+
5
+ # Package version: keep in sync with pyproject.toml, setup.py, src/specfact_cli/__init__.py
6
+ __version__ = "0.47.6"
@@ -1,7 +1,8 @@
1
1
  """
2
- SpecFact CLI - The swiss knife CLI for agile DevOps teams.
2
+ SpecFact CLI - AI-bloat defense CLI for Python teams.
3
3
 
4
4
  This package provides command-line tools for:
5
+ - Defending AI-assisted code against cleanup bloat
5
6
  - Turning code into clear specs and plans
6
7
  - Keeping backlog, specs, tests, and code in sync
7
8
  - Enforcing validation and contract checks before production
@@ -75,6 +76,6 @@ def _install_progressive_disclosure() -> None:
75
76
  # keeps missing-command and missing-parameter UX consistent outside the root CLI too.
76
77
  _install_progressive_disclosure()
77
78
 
78
- __version__ = "0.47.3"
79
+ __version__ = "0.47.6"
79
80
 
80
81
  __all__ = ["__version__"]
@@ -87,19 +87,12 @@ KNOWN_BUNDLE_GROUP_OR_SHIM_NAMES: frozenset[str] = frozenset(
87
87
  "project",
88
88
  "spec",
89
89
  "govern",
90
- "plan",
91
- "validate",
92
90
  "contract",
93
91
  "sdd",
94
92
  "generate",
95
93
  "enforce",
96
94
  "patch",
97
- "migrate",
98
- "repro",
99
- "drift",
100
- "analyze",
101
95
  "policy",
102
- "sync",
103
96
  }
104
97
  )
105
98
 
@@ -109,14 +102,7 @@ _INVOKED_TO_MARKETPLACE_MODULE: dict[str, str] = {
109
102
  "backlog": "nold-ai/specfact-backlog",
110
103
  "policy": "nold-ai/specfact-backlog",
111
104
  "code": "nold-ai/specfact-codebase",
112
- "analyze": "nold-ai/specfact-codebase",
113
- "drift": "nold-ai/specfact-codebase",
114
- "validate": "nold-ai/specfact-codebase",
115
- "repro": "nold-ai/specfact-codebase",
116
105
  "project": "nold-ai/specfact-project",
117
- "plan": "nold-ai/specfact-project",
118
- "sync": "nold-ai/specfact-project",
119
- "migrate": "nold-ai/specfact-project",
120
106
  "spec": "nold-ai/specfact-spec",
121
107
  "contract": "nold-ai/specfact-spec",
122
108
  "sdd": "nold-ai/specfact-spec",
@@ -126,6 +112,18 @@ _INVOKED_TO_MARKETPLACE_MODULE: dict[str, str] = {
126
112
  "patch": "nold-ai/specfact-govern",
127
113
  }
128
114
 
115
+ # Removed flat root aliases -> canonical grouped replacement (see docs/migration/migration-guide.md).
116
+ # These must never route through marketplace module availability diagnostics.
117
+ _REMOVED_FLAT_ALIAS_TO_CANONICAL: dict[str, str] = {
118
+ "plan": "specfact project",
119
+ "validate": "specfact code validate",
120
+ "analyze": "specfact code analyze",
121
+ "drift": "specfact code drift",
122
+ "repro": "specfact code repro",
123
+ "sync": "specfact project sync",
124
+ "migrate": "specfact project migrate",
125
+ }
126
+
129
127
 
130
128
  def _print_missing_bundle_command_help(invoked: str) -> None:
131
129
  """Print install guidance when a bundle group or shim is not registered."""
@@ -168,34 +166,81 @@ def _print_missing_bundle_command_help(invoked: str) -> None:
168
166
  )
169
167
 
170
168
 
169
+ def _print_removed_flat_alias_help(invoked: str) -> None:
170
+ """Print canonical grouped-command guidance for a removed flat root alias."""
171
+ canonical = _REMOVED_FLAT_ALIAS_TO_CANONICAL[invoked]
172
+ console = get_configured_console()
173
+ console.print(
174
+ f"[bold red]No such command '{invoked}'.[/bold red]\n"
175
+ f"The flat [bold]specfact {invoked}[/bold] command was removed. "
176
+ f"Use [bold]{canonical} ...[/bold] instead."
177
+ )
178
+
179
+
180
+ def _print_unresolved_root_token_help(invoked: str) -> bool:
181
+ """Render guidance for an unresolved root token; return True when guidance was printed."""
182
+ if invoked in _REMOVED_FLAT_ALIAS_TO_CANONICAL:
183
+ _print_removed_flat_alias_help(invoked)
184
+ return True
185
+ if invoked in KNOWN_BUNDLE_GROUP_OR_SHIM_NAMES:
186
+ _print_missing_bundle_command_help(invoked)
187
+ return True
188
+ return False
189
+
190
+
191
+ def _resolve_root_command_with_guidance(resolve: Callable[[Any, list[str]], Any], ctx: Any, args: list[str]) -> Any:
192
+ """Resolve a root command, replacing unresolved known tokens with actionable guidance."""
193
+ if not args:
194
+ return resolve(ctx, args)
195
+ invoked = args[0]
196
+ try:
197
+ result = resolve(ctx, args)
198
+ except click.UsageError:
199
+ if _print_unresolved_root_token_help(invoked):
200
+ raise SystemExit(1) from None
201
+ raise
202
+ except ValueError as exc:
203
+ if _print_unresolved_root_token_help(invoked):
204
+ raise SystemExit(1) from exc
205
+ raise
206
+ _name, cmd, remaining = result
207
+ if cmd is not None or not remaining:
208
+ return result
209
+ unresolved = remaining[0]
210
+ if _print_unresolved_root_token_help(unresolved):
211
+ raise SystemExit(1)
212
+ return result
213
+
214
+
171
215
  class _RootCLIGroup(ProgressiveDisclosureGroup):
172
216
  """Root group that shows actionable error when an unknown command is a known bundle group/shim."""
173
217
 
174
218
  @ensure(lambda result: isinstance(result, tuple) and len(result) == 3, "result must be a 3-tuple")
175
219
  def resolve_command(self, ctx: Any, args: list[str]) -> Any:
176
- if not args:
177
- return super().resolve_command(ctx, args)
178
- invoked = args[0]
179
- try:
180
- result = super().resolve_command(ctx, args)
181
- except click.UsageError:
182
- if invoked in KNOWN_BUNDLE_GROUP_OR_SHIM_NAMES:
183
- _print_missing_bundle_command_help(invoked)
184
- raise SystemExit(1) from None
185
- raise
186
- except ValueError as exc:
187
- if invoked in KNOWN_BUNDLE_GROUP_OR_SHIM_NAMES:
188
- _print_missing_bundle_command_help(invoked)
189
- raise SystemExit(1) from exc
190
- raise
191
- _name, cmd, remaining = result
192
- if cmd is not None or not remaining:
193
- return result
194
- invoked = remaining[0]
195
- if invoked not in KNOWN_BUNDLE_GROUP_OR_SHIM_NAMES:
196
- return result
197
- _print_missing_bundle_command_help(invoked)
198
- raise SystemExit(1)
220
+ return _resolve_root_command_with_guidance(super().resolve_command, ctx, args)
221
+
222
+
223
+ def _patch_missing_bundle_resolution(group: click.Group) -> click.Group:
224
+ """Patch a generated Typer root group to preserve missing bundle diagnostics."""
225
+ if getattr(group, "_specfact_missing_bundle_resolution", False):
226
+ return group
227
+
228
+ original_get_command = group.get_command
229
+ original_resolve_command = group.resolve_command
230
+
231
+ def _get_command(ctx: click.Context, cmd_name: str) -> click.Command | None:
232
+ command = original_get_command(ctx, cmd_name)
233
+ if command is None and _print_unresolved_root_token_help(cmd_name):
234
+ raise SystemExit(1)
235
+ return command
236
+
237
+ def _resolve_command(ctx: click.Context, args: list[str]) -> Any:
238
+ return _resolve_root_command_with_guidance(original_resolve_command, ctx, args)
239
+
240
+ group.get_command = _get_command # type: ignore[method-assign]
241
+ group.resolve_command = _resolve_command # type: ignore[method-assign]
242
+ group._specfact_missing_bundle_resolution = True # type: ignore[attr-defined]
243
+ return group
199
244
 
200
245
 
201
246
  # Map shell names for completion support
@@ -581,8 +626,7 @@ def _load_lazy_delegate_typer(cmd_name: str) -> typer.Typer:
581
626
  try:
582
627
  return CommandRegistry.get_typer(resolved_name)
583
628
  except ValueError as exc:
584
- if cmd_name in KNOWN_BUNDLE_GROUP_OR_SHIM_NAMES:
585
- _print_missing_bundle_command_help(cmd_name)
629
+ if _print_unresolved_root_token_help(cmd_name):
586
630
  raise SystemExit(1) from None
587
631
  _raise_lazy_delegate_click_exception(exc)
588
632
  raise AssertionError("unreachable") from None
@@ -866,6 +910,8 @@ def _get_command(typer_instance: typer.Typer) -> click.Command:
866
910
  return _build_lazy_delegate_group(cmd_name, help_str)
867
911
  assert _typer_get_command_original is not None
868
912
  result = _typer_get_command_original(typer_instance)
913
+ if typer_instance is app and isinstance(result, click.Group):
914
+ result = _patch_missing_bundle_resolution(result)
869
915
  flatten_name = getattr(typer_instance, "_specfact_flatten_same_name", None)
870
916
  if isinstance(flatten_name, str) and isinstance(result, click.Group) and flatten_name in result.commands:
871
917
  _flatten_specfact_nested_subgroup(result, flatten_name)
@@ -894,6 +940,8 @@ def _get_group_from_info_wrapper(
894
940
  suggest_commands=suggest_commands,
895
941
  rich_markup_mode=rich_markup_mode,
896
942
  )
943
+ if typer_instance is app:
944
+ result = _patch_missing_bundle_resolution(result)
897
945
  flatten_name = getattr(typer_instance, "_specfact_flatten_same_name", None) if typer_instance else None
898
946
  if isinstance(flatten_name, str) and flatten_name in result.commands:
899
947
  _flatten_specfact_nested_subgroup(result, flatten_name)
@@ -1,6 +0,0 @@
1
- """
2
- SpecFact CLI - Spec→Contract→Sentinel tool for contract-driven development.
3
- """
4
-
5
- # Package version: keep in sync with pyproject.toml, setup.py, src/specfact_cli/__init__.py
6
- __version__ = "0.47.3"
File without changes