specsmith 0.13.0.dev503__tar.gz → 0.13.0.dev506__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 (295) hide show
  1. {specsmith-0.13.0.dev503/src/specsmith.egg-info → specsmith-0.13.0.dev506}/PKG-INFO +1 -1
  2. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/pyproject.toml +5 -1
  3. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/broker.py +61 -4
  4. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/auditor.py +28 -0
  5. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/cli.py +8 -0
  6. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/config.py +12 -0
  7. specsmith-0.13.0.dev506/src/specsmith/esdb/__init__.py +110 -0
  8. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/governance_logic.py +8 -1
  9. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/requirements.py +20 -6
  10. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/sync.py +12 -2
  11. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506/src/specsmith.egg-info}/PKG-INFO +1 -1
  12. specsmith-0.13.0.dev503/src/specsmith/esdb/__init__.py +0 -62
  13. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/LICENSE +0 -0
  14. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/README.md +0 -0
  15. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/setup.cfg +0 -0
  16. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/epistemic/__init__.py +0 -0
  17. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/epistemic/belief.py +0 -0
  18. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/epistemic/certainty.py +0 -0
  19. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/epistemic/failure_graph.py +0 -0
  20. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/epistemic/py.typed +0 -0
  21. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/epistemic/recovery.py +0 -0
  22. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/epistemic/session.py +0 -0
  23. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/epistemic/stress_tester.py +0 -0
  24. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/epistemic/trace.py +0 -0
  25. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/__init__.py +0 -0
  26. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/__main__.py +0 -0
  27. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/__init__.py +0 -0
  28. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/chat_runner.py +0 -0
  29. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/cleanup.py +0 -0
  30. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/context_seed.py +0 -0
  31. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/core.py +0 -0
  32. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/dispatch/__init__.py +0 -0
  33. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/dispatch/_status.py +0 -0
  34. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/dispatch/dag.py +0 -0
  35. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/dispatch/dispatcher.py +0 -0
  36. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/dispatch/events.py +0 -0
  37. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/dispatch/result.py +0 -0
  38. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/endpoints.py +0 -0
  39. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/events.py +0 -0
  40. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/execution_profiles.py +0 -0
  41. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/fallback.py +0 -0
  42. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/hf_leaderboard.py +0 -0
  43. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/hf_sync.py +0 -0
  44. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/indexer.py +0 -0
  45. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/llm_client.py +0 -0
  46. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/mcp.py +0 -0
  47. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/memory.py +0 -0
  48. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/model_intelligence.py +0 -0
  49. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/model_profiles.py +0 -0
  50. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/orchestrator.py +0 -0
  51. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/permissions.py +0 -0
  52. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/profiles.py +0 -0
  53. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/provider_registry.py +0 -0
  54. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/repl.py +0 -0
  55. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/router.py +0 -0
  56. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/rules.py +0 -0
  57. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/runner.py +0 -0
  58. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/safety.py +0 -0
  59. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/spawner.py +0 -0
  60. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/suggester.py +0 -0
  61. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/teams.py +0 -0
  62. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/tools.py +0 -0
  63. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/verifier.py +0 -0
  64. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/agent/voice.py +0 -0
  65. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/architect.py +0 -0
  66. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/auth.py +0 -0
  67. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/block_export.py +0 -0
  68. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/channel.py +0 -0
  69. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/ci_manager.py +0 -0
  70. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/commands/__init__.py +0 -0
  71. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/commands/intelligence.py +0 -0
  72. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/compliance/__init__.py +0 -0
  73. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/compliance/_compat.py +0 -0
  74. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/compliance/checker.py +0 -0
  75. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/compliance/evidence.py +0 -0
  76. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/compliance/regulations.py +0 -0
  77. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/compliance/reporter.py +0 -0
  78. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/compressor.py +0 -0
  79. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/console_utils.py +0 -0
  80. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/context_orchestrator.py +0 -0
  81. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/context_window.py +0 -0
  82. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/credit_analyzer.py +0 -0
  83. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/credits.py +0 -0
  84. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/datasources/__init__.py +0 -0
  85. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/datasources/base.py +0 -0
  86. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/datasources/citations.py +0 -0
  87. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/datasources/fpd.py +0 -0
  88. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/datasources/odp.py +0 -0
  89. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/datasources/patentsview.py +0 -0
  90. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/datasources/pfw.py +0 -0
  91. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/datasources/ppubs.py +0 -0
  92. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/datasources/ptab.py +0 -0
  93. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/differ.py +0 -0
  94. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/doctor.py +0 -0
  95. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/drive.py +0 -0
  96. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/editor.py +0 -0
  97. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/epistemic/__init__.py +0 -0
  98. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/epistemic/belief.py +0 -0
  99. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/epistemic/certainty.py +0 -0
  100. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/epistemic/failure_graph.py +0 -0
  101. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/epistemic/recovery.py +0 -0
  102. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/epistemic/stress_tester.py +0 -0
  103. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/esdb/bridge.py +0 -0
  104. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/eval/__init__.py +0 -0
  105. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/eval/builtins.py +0 -0
  106. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/eval/runner.py +0 -0
  107. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/executor.py +0 -0
  108. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/exporter.py +0 -0
  109. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/governance_store.py +0 -0
  110. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/governance_yaml.py +0 -0
  111. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/__init__.py +0 -0
  112. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/app.py +0 -0
  113. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/main_window.py +0 -0
  114. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/session_tab.py +0 -0
  115. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/theme.py +0 -0
  116. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/widgets/__init__.py +0 -0
  117. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/widgets/chat_view.py +0 -0
  118. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/widgets/input_bar.py +0 -0
  119. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/widgets/provider_bar.py +0 -0
  120. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/widgets/token_meter.py +0 -0
  121. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/widgets/tool_panel.py +0 -0
  122. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/widgets/update_checker.py +0 -0
  123. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/gui/worker.py +0 -0
  124. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/history_search.py +0 -0
  125. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/importer.py +0 -0
  126. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/instinct.py +0 -0
  127. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/integrations/__init__.py +0 -0
  128. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/integrations/agent_skill.py +0 -0
  129. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/integrations/aider.py +0 -0
  130. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/integrations/base.py +0 -0
  131. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/integrations/claude_code.py +0 -0
  132. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/integrations/codity.py +0 -0
  133. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/integrations/copilot.py +0 -0
  134. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/integrations/cursor.py +0 -0
  135. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/integrations/gemini.py +0 -0
  136. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/integrations/windsurf.py +0 -0
  137. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/issue_reporter.py +0 -0
  138. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/languages.py +0 -0
  139. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/ledger.py +0 -0
  140. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/mcp_generator.py +0 -0
  141. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/mcp_server.py +0 -0
  142. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/migrations/__init__.py +0 -0
  143. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/migrations/m001_governance_yaml.py +0 -0
  144. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/migrations/m002_agents_slim.py +0 -0
  145. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/migrations/m003_compliance_init.py +0 -0
  146. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/migrations/m004_ledger_esdb.py +0 -0
  147. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/migrations/m005_agent_run_tool.py +0 -0
  148. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/migrations/m006_session_governance.py +0 -0
  149. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/migrations/runner.py +0 -0
  150. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/ollama_cmds.py +0 -0
  151. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/patent.py +0 -0
  152. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/paths.py +0 -0
  153. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/phase.py +0 -0
  154. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/plugins.py +0 -0
  155. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/profiles.py +0 -0
  156. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/rate_limits.py +0 -0
  157. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/releaser.py +0 -0
  158. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/requirements_parser.py +0 -0
  159. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/retrieval.py +0 -0
  160. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/safe_write.py +0 -0
  161. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/scaffolder.py +0 -0
  162. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/serve.py +0 -0
  163. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/session.py +0 -0
  164. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/session_init.py +0 -0
  165. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/session_store.py +0 -0
  166. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/__init__.py +0 -0
  167. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/ai_agents.py +0 -0
  168. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/cloud.py +0 -0
  169. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/corporate.py +0 -0
  170. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/cross_platform.py +0 -0
  171. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/data_engineering.py +0 -0
  172. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/devops.py +0 -0
  173. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/docs.py +0 -0
  174. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/embedded.py +0 -0
  175. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/governance.py +0 -0
  176. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/hardware.py +0 -0
  177. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/mobile.py +0 -0
  178. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/platform_engineering.py +0 -0
  179. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/productivity.py +0 -0
  180. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/software_engineering.py +0 -0
  181. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/specsmith_skills.py +0 -0
  182. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/ssh.py +0 -0
  183. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills/web_backend.py +0 -0
  184. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/skills_builder.py +0 -0
  185. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/agents.md.j2 +0 -0
  186. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
  187. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
  188. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/community/contributing.md.j2 +0 -0
  189. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
  190. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
  191. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/community/license-MIT.j2 +0 -0
  192. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
  193. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/community/security.md.j2 +0 -0
  194. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
  195. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
  196. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
  197. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
  198. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
  199. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/editorconfig.j2 +0 -0
  200. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/gitattributes.j2 +0 -0
  201. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/gitignore.j2 +0 -0
  202. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/go/go.mod.j2 +0 -0
  203. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/go/main.go.j2 +0 -0
  204. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
  205. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
  206. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
  207. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
  208. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
  209. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
  210. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/roles.md.j2 +0 -0
  211. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/rules.md.j2 +0 -0
  212. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
  213. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
  214. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/governance/verification.md.j2 +0 -0
  215. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/js/package.json.j2 +0 -0
  216. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/ledger.md.j2 +0 -0
  217. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/python/cli.py.j2 +0 -0
  218. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/python/init.py.j2 +0 -0
  219. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
  220. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/readme.md.j2 +0 -0
  221. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
  222. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/rust/main.rs.j2 +0 -0
  223. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
  224. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
  225. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
  226. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
  227. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
  228. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
  229. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
  230. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/tool_installer.py +0 -0
  231. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/toolrules.py +0 -0
  232. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/tools.py +0 -0
  233. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/trace.py +0 -0
  234. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/updater.py +0 -0
  235. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/upgrader.py +0 -0
  236. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/validator.py +0 -0
  237. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/vcs/__init__.py +0 -0
  238. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/vcs/base.py +0 -0
  239. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/vcs/bitbucket.py +0 -0
  240. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/vcs/github.py +0 -0
  241. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/vcs/gitlab.py +0 -0
  242. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/vcs_commands.py +0 -0
  243. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/wireframes.py +0 -0
  244. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith/workspace.py +0 -0
  245. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith.egg-info/SOURCES.txt +0 -0
  246. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith.egg-info/dependency_links.txt +0 -0
  247. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith.egg-info/entry_points.txt +0 -0
  248. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith.egg-info/requires.txt +0 -0
  249. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/src/specsmith.egg-info/top_level.txt +0 -0
  250. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_CMD_001.py +0 -0
  251. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_agent_profiles.py +0 -0
  252. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_agent_run_feedback.py +0 -0
  253. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_agent_runner_ready.py +0 -0
  254. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_ai_client.py +0 -0
  255. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_ai_intelligence.py +0 -0
  256. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_auditor.py +0 -0
  257. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_channel.py +0 -0
  258. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_chat_diff_decision.py +0 -0
  259. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_chat_runner_openai_compat.py +0 -0
  260. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_chat_stdin_protocol.py +0 -0
  261. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_cli.py +0 -0
  262. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_cli_workflows_history_drive.py +0 -0
  263. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_compliance.py +0 -0
  264. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_compressor.py +0 -0
  265. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_dispatch.py +0 -0
  266. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_e2e_nexus.py +0 -0
  267. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_endpoints_cli.py +0 -0
  268. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_endpoints_store.py +0 -0
  269. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_epistemic.py +0 -0
  270. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_fallback_chain.py +0 -0
  271. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_importer.py +0 -0
  272. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_integrations.py +0 -0
  273. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_integrations_codity.py +0 -0
  274. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_intelligence.py +0 -0
  275. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_issue_reporter.py +0 -0
  276. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_mcp_client.py +0 -0
  277. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_mcp_server.py +0 -0
  278. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_new_modules.py +0 -0
  279. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_nexus.py +0 -0
  280. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_permissions.py +0 -0
  281. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_phase1_4_new.py +0 -0
  282. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_phase34_completion.py +0 -0
  283. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_rate_limits.py +0 -0
  284. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_req_248_262.py +0 -0
  285. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_req_358_359.py +0 -0
  286. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_scaffolder.py +0 -0
  287. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_skill_marketplace.py +0 -0
  288. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_skills_mcp.py +0 -0
  289. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_smoke.py +0 -0
  290. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_suggester.py +0 -0
  291. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_tools.py +0 -0
  292. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_validator.py +0 -0
  293. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_vcs.py +0 -0
  294. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_warp_parity.py +0 -0
  295. {specsmith-0.13.0.dev503 → specsmith-0.13.0.dev506}/tests/test_warp_parity_followup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.13.0.dev503
3
+ Version: 0.13.0.dev506
4
4
  Summary: Applied Epistemic Engineering toolkit — AEE agent sessions, execution profiles, FPGA/HDL governance, tool installer, 50+ CLI commands.
5
5
  Author: BitConcepts
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "specsmith"
7
- version = "0.13.0.dev503"
7
+ version = "0.13.0.dev506"
8
8
  description = "Applied Epistemic Engineering toolkit — AEE agent sessions, execution profiles, FPGA/HDL governance, tool installer, 50+ CLI commands."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -224,6 +224,10 @@ module = [
224
224
  "specsmith.session_store",
225
225
  # MCP server: lazy in-function imports and dynamic Any patterns
226
226
  "specsmith.mcp_server",
227
+ # ESDB package: conditional chronomemory stubs in except ImportError branch
228
+ # produce type[_Stub] vs type[ChronoRecord] assignment errors that are
229
+ # correct at runtime but cannot be expressed statically without TYPE_CHECKING.
230
+ "specsmith.esdb",
227
231
  ]
228
232
  ignore_errors = true
229
233
 
@@ -144,6 +144,11 @@ def classify_intent(utterance: str) -> Intent:
144
144
  # Extended to match project-prefixed IDs e.g. REQ-NN-001, REQ-CLI-042
145
145
  _REQ_ID = re.compile(r"-\s*\*\*ID:\*\*\s*(REQ-(?:[A-Z][A-Z0-9_]*-)?\d+)")
146
146
  _REQ_DESC = re.compile(r"-\s*\*\*Description:\*\*\s*(.+)")
147
+ # Style A heading: ## REQ-001 or ## REQ-CLI-001: Title
148
+ _STYLE_A_HEADING = re.compile(
149
+ r"^#{1,3}\s+(REQ-(?:[A-Z][A-Z0-9_]*-)?\d+)(?::\s*(.+))?\s*$",
150
+ re.MULTILINE,
151
+ )
147
152
 
148
153
  # A small stopword list to keep keyword matches meaningful.
149
154
  _STOPWORDS = frozenset(
@@ -205,6 +210,19 @@ class RequirementSummary:
205
210
  def parse_requirements(req_md_path: Path) -> list[RequirementSummary]:
206
211
  """Parse REQUIREMENTS.md into ``RequirementSummary`` records.
207
212
 
213
+ Handles two heading styles:
214
+
215
+ Style A (standard specsmith format)::
216
+
217
+ ## REQ-001: Title
218
+ Description text as a plain paragraph.
219
+
220
+ Style B (numbered-heading format)::
221
+
222
+ ## 1. Title
223
+ - **ID:** REQ-001
224
+ - **Description:** description text
225
+
208
226
  Best-effort: missing files yield an empty list.
209
227
  """
210
228
  req_md_path = req_md_path.resolve() # CodeQL py/path-injection: normalise before fs access
@@ -215,14 +233,53 @@ def parse_requirements(req_md_path: Path) -> list[RequirementSummary]:
215
233
  except ValueError:
216
234
  return []
217
235
  out: list[RequirementSummary] = []
236
+
237
+ # ── Style A: ## REQ-NNN: Title (standard specsmith format) ────────────────
238
+ # Split on any Style A heading first; if the file uses this format
239
+ # exclusively, the Style B pass below will be a no-op.
240
+ lines = text.splitlines()
241
+ current_id: str = ""
242
+ current_title: str = ""
243
+ current_desc: str = ""
244
+ seen_ids: set[str] = set()
245
+
246
+ def _flush_style_a() -> None:
247
+ if current_id and current_id not in seen_ids:
248
+ seen_ids.add(current_id)
249
+ out.append(
250
+ RequirementSummary(req_id=current_id, title=current_title, description=current_desc)
251
+ )
252
+
253
+ for line in lines:
254
+ m_a = _STYLE_A_HEADING.match(line)
255
+ if m_a:
256
+ _flush_style_a()
257
+ current_id = m_a.group(1)
258
+ current_title = (m_a.group(2) or "").strip()
259
+ current_desc = ""
260
+ continue
261
+ if current_id:
262
+ stripped = line.strip()
263
+ # Bullet description fields
264
+ m_desc = _REQ_DESC.match(line)
265
+ if m_desc:
266
+ current_desc = current_desc or m_desc.group(1).strip()
267
+ continue
268
+ # Plain paragraph text (not a heading, not a bullet, not empty)
269
+ if stripped and not stripped.startswith("#") and not stripped.startswith("-"):
270
+ current_desc = current_desc or stripped
271
+ _flush_style_a()
272
+
273
+ # ── Style B: ## N. Title with - **ID:** REQ-NNN inline ────────────────────
218
274
  blocks = re.split(r"^##\s+\d+\.\s+", text, flags=re.MULTILINE)[1:]
219
275
  for block in blocks:
220
- lines = block.splitlines()
221
- title = lines[0].strip() if lines else ""
276
+ block_lines = block.splitlines()
277
+ title = block_lines[0].strip() if block_lines else ""
222
278
  m_id = _REQ_ID.search(block)
223
279
  m_desc = _REQ_DESC.search(block)
224
- if not m_id:
225
- continue
280
+ if not m_id or m_id.group(1) in seen_ids:
281
+ continue # skip if no ID or already captured by Style A pass
282
+ seen_ids.add(m_id.group(1))
226
283
  out.append(
227
284
  RequirementSummary(
228
285
  req_id=m_id.group(1),
@@ -779,6 +779,34 @@ def check_type_mismatch(root: Path) -> list[AuditResult]:
779
779
  raw = yaml.safe_load(f)
780
780
  config = ProjectConfig(**raw)
781
781
 
782
+ # Skip when type_override == type (explicit user suppression, #196).
783
+ if config.type_override and config.type_override == config.type:
784
+ results.append(
785
+ AuditResult(
786
+ name="type-mismatch",
787
+ passed=True,
788
+ message=(
789
+ f"Project type {config.type} is explicitly overridden; "
790
+ f"auto-detection skipped"
791
+ ),
792
+ )
793
+ )
794
+ return results
795
+
796
+ # Skip for unrecognised (custom) type strings — there is no known
797
+ # ProjectType to compare against, so detection is meaningless.
798
+ if config.project_type_enum is None:
799
+ results.append(
800
+ AuditResult(
801
+ name="type-mismatch",
802
+ passed=True,
803
+ message=(
804
+ f"Project type {config.type!r} is a custom type; auto-detection skipped"
805
+ ),
806
+ )
807
+ )
808
+ return results
809
+
782
810
  # Skip auto-detection for types that must be specified explicitly.
783
811
  if config.type in _EXPLICIT_ONLY_TYPES:
784
812
  results.append(
@@ -2159,6 +2159,7 @@ def req_add(
2159
2159
  add_req(
2160
2160
  root,
2161
2161
  effective_id,
2162
+ title=title,
2162
2163
  component=component,
2163
2164
  priority=priority,
2164
2165
  description=description,
@@ -2592,6 +2593,13 @@ def save_cmd(project_dir: str, message: str, no_push: bool, force: bool, as_json
2592
2593
  steps.append(
2593
2594
  {"step": "esdb_backup", "ok": True, "note": "JSON fallback (no WAL to backup)"}
2594
2595
  )
2596
+ except ImportError:
2597
+ # chronomemory not installed — non-fatal; commit and push still proceed.
2598
+ # Install with: pipx inject specsmith
2599
+ # "chronomemory @ git+https://github.com/layer1labs/chronomemory.git@v0.1.1"
2600
+ from specsmith.esdb import _INSTALL_HINT # noqa: PLC0415
2601
+
2602
+ steps.append({"step": "esdb_backup", "ok": True, "note": f"skipped — {_INSTALL_HINT}"})
2595
2603
  except Exception as exc: # noqa: BLE001
2596
2604
  steps.append({"step": "esdb_backup", "ok": False, "error": str(exc)})
2597
2605
 
@@ -224,6 +224,18 @@ class ProjectConfig(BaseModel):
224
224
  ),
225
225
  )
226
226
 
227
+ # Explicit type override — suppresses the type-mismatch audit check.
228
+ # Set this when your project uses a custom or research-specific type string
229
+ # that cannot be auto-detected (e.g. 'research-mathematics'). When
230
+ # type_override matches type, check_type_mismatch is suppressed.
231
+ type_override: str = Field(
232
+ default="",
233
+ description=(
234
+ "Explicit type override. When set to the same value as `type`, "
235
+ "the type-mismatch audit check is suppressed regardless of what "
236
+ "auto-detection infers from the project files."
237
+ ),
238
+ )
227
239
  # Fallback type — used when this project type is not yet supported
228
240
  # by the installed specsmith version. specsmith silently falls back to
229
241
  # this type for scaffolding purposes while still recording the intended type.
@@ -0,0 +1,110 @@
1
+ # specsmith.esdb — ESDB integration package
2
+ #
3
+ # Re-exports the full chronomemory v0.1.1 public surface under the
4
+ # specsmith.esdb namespace so internal modules can use a single import
5
+ # path and never import chronomemory directly in more than one place.
6
+ #
7
+ # chronomemory is a git-URL dependency stripped from the PyPI wheel.
8
+ # If it is not installed, all symbols are stubbed with a class that
9
+ # raises a clear ImportError with install instructions rather than
10
+ # crashing silently at module import time.
11
+ #
12
+ # Install the missing dep:
13
+ # pipx inject specsmith "chronomemory @ git+https://github.com/layer1labs/chronomemory.git@v0.1.1"
14
+
15
+ _INSTALL_HINT = (
16
+ "chronomemory is not installed.\n"
17
+ "Run: pipx inject specsmith "
18
+ '"chronomemory @ git+https://github.com/layer1labs/chronomemory.git@v0.1.1"'
19
+ )
20
+
21
+ try:
22
+ # Re-export query and metrics as module references so callers can do:
23
+ # from specsmith.esdb import query, metrics
24
+ from chronomemory import (
25
+ RUST_BACKEND,
26
+ # Core store
27
+ ChronoRecord,
28
+ ChronoStore,
29
+ # Phase 2: context pack compiler
30
+ ContextPack,
31
+ ContextPackCompiler,
32
+ ContextPackEntry,
33
+ DependencyEdge,
34
+ # Phase 2: dependency graph
35
+ DepGraph,
36
+ # Bridge (backward-compat with .specsmith/*.json)
37
+ EsdbBridge,
38
+ EsdbRecord,
39
+ EsdbStatus,
40
+ # Phase 2: epistemic rollback
41
+ RollbackReport,
42
+ # Phase 3: optional Rust acceleration (None / False when not compiled)
43
+ RustChronoStore,
44
+ RustRecord,
45
+ WalEvent,
46
+ invalidate,
47
+ metrics, # noqa: F401 — module re-export
48
+ open_store,
49
+ query, # noqa: F401 — module re-export
50
+ )
51
+
52
+ CHRONO_AVAILABLE: bool = True
53
+
54
+ except ImportError:
55
+ CHRONO_AVAILABLE = False
56
+
57
+ class _Stub: # type: ignore[no-redef]
58
+ """Placeholder that raises a clear error on instantiation or call."""
59
+
60
+ def __init__(self, *_: object, **__: object) -> None:
61
+ raise ImportError(_INSTALL_HINT)
62
+
63
+ def __call__(self, *_: object, **__: object) -> "_Stub":
64
+ raise ImportError(_INSTALL_HINT)
65
+
66
+ def __class_getitem__(cls, _: object) -> "type[_Stub]":
67
+ return cls
68
+
69
+ # Stub every exported name so `from specsmith.esdb import X` doesn't fail.
70
+ ChronoRecord = ChronoStore = EsdbBridge = EsdbRecord = EsdbStatus = _Stub # type: ignore[misc]
71
+ ContextPack = ContextPackCompiler = ContextPackEntry = _Stub # type: ignore[misc]
72
+ DepGraph = DependencyEdge = RollbackReport = _Stub # type: ignore[misc]
73
+ RustChronoStore = RustRecord = WalEvent = invalidate = open_store = _Stub # type: ignore[misc]
74
+ RUST_BACKEND: bool = False # type: ignore[misc]
75
+
76
+ class _StubModule:
77
+ """Stub module reference so 'from specsmith.esdb import query, metrics' works."""
78
+
79
+ def __getattr__(self, name: str) -> "_Stub":
80
+ raise ImportError(_INSTALL_HINT)
81
+
82
+ query = _StubModule() # type: ignore[assignment]
83
+ metrics = _StubModule() # type: ignore[assignment]
84
+
85
+ __all__ = [
86
+ # Core
87
+ "ChronoStore",
88
+ "ChronoRecord",
89
+ "WalEvent",
90
+ "open_store",
91
+ # Bridge
92
+ "EsdbBridge",
93
+ "EsdbRecord",
94
+ "EsdbStatus",
95
+ # Phase 2
96
+ "DepGraph",
97
+ "DependencyEdge",
98
+ "RollbackReport",
99
+ "invalidate",
100
+ "ContextPack",
101
+ "ContextPackCompiler",
102
+ "ContextPackEntry",
103
+ # Phase 3
104
+ "RustChronoStore",
105
+ "RustRecord",
106
+ "RUST_BACKEND",
107
+ # Modules
108
+ "query",
109
+ "metrics",
110
+ ]
@@ -73,9 +73,16 @@ def run_preflight(
73
73
 
74
74
  root = _safe_resolve(project_dir)
75
75
  intent = classify_intent(utterance)
76
+ # Requirements live at docs/REQUIREMENTS.md, not at the project root.
77
+ # Falling back to root/REQUIREMENTS.md would always yield an empty list
78
+ # on standard projects, causing preflight to always return
79
+ # needs_clarification (GitHub issue #197).
80
+ _req_md = root / "docs" / "REQUIREMENTS.md"
81
+ if not _req_md.exists():
82
+ _req_md = root / "REQUIREMENTS.md" # legacy fallback
76
83
  scope = infer_scope(
77
84
  utterance,
78
- root / "REQUIREMENTS.md",
85
+ _req_md,
79
86
  repo_index_path=root / ".repo-index" / "files.json",
80
87
  )
81
88
 
@@ -92,19 +92,33 @@ def add_req(
92
92
  root: Path,
93
93
  req_id: str,
94
94
  *,
95
+ title: str = "",
95
96
  component: str = "",
96
97
  priority: str = "medium",
97
98
  description: str = "",
98
99
  ) -> None:
99
- """Append a new requirement to REQUIREMENTS.md."""
100
+ """Append a new requirement to REQUIREMENTS.md.
101
+
102
+ Emits the standard Style A format::
103
+
104
+ ## REQ-NNN: Title
105
+ Description text as a plain paragraph.
106
+
107
+ This matches the format already used by every other requirement in
108
+ REQUIREMENTS.md and is correctly parsed by ``sync`` and ``preflight``.
109
+ """
100
110
  req_path = root / "docs" / "REQUIREMENTS.md"
101
- entry = f"\n### {req_id}\n"
111
+ # Build heading: ## REQ-NNN or ## REQ-NNN: Title
112
+ heading_title = f": {title}" if title else ""
113
+ entry = f"\n## {req_id}{heading_title}\n"
114
+ if description:
115
+ # Plain paragraph — not a bullet list (matches parser expectations)
116
+ entry += f"{description}\n"
117
+ # Legacy fields kept for backward-compat but written as metadata bullets
102
118
  if component:
103
119
  entry += f"- **Component**: {component}\n"
104
- entry += f"- **Priority**: {priority}\n"
105
- entry += "- **Status**: Draft\n"
106
- if description:
107
- entry += f"- **Description**: {description}\n"
120
+ if priority and priority != "medium":
121
+ entry += f"- **Priority**: {priority}\n"
108
122
 
109
123
  content = req_path.read_text(encoding="utf-8") if req_path.exists() else "# Requirements\n"
110
124
 
@@ -33,11 +33,13 @@ from typing import Any
33
33
  # ---------------------------------------------------------------------------
34
34
 
35
35
  # Matches either:
36
- # Style A: ## REQ-001 or ## REQ-CLI-001 Title
36
+ # Style A: ## REQ-001 or ## REQ-CLI-001: Title
37
+ # The optional ": Title" suffix is captured in group(2).
37
38
  # Style B: ## N. Title (ID comes from inline - **ID:** REQ-NNN field)
38
39
  _FLEX_REQ_ID = r"REQ-(?:[A-Z][A-Z0-9_]*-)?\d+"
39
40
  _NUMBERED_HEADING = re.compile(r"^#{1,3}\s+\d+\.\s+(.+?)\s*$")
40
- _DIRECT_HEADING = re.compile(r"^#{1,3}\s+(" + _FLEX_REQ_ID + r")\b")
41
+ # Group 1: REQ-ID, Group 2 (optional): title text after the colon.
42
+ _DIRECT_HEADING = re.compile(r"^#{1,3}\s+(" + _FLEX_REQ_ID + r")(?::\s*(.+))?\s*$")
41
43
  _ID_FIELD = re.compile(r"^-\s+\*\*ID:\*\*\s+(" + _FLEX_REQ_ID + r")")
42
44
  _FIELD_LINE = re.compile(r"^-\s+\*\*(.+?):\*\*\s+(.+)")
43
45
 
@@ -61,7 +63,11 @@ def parse_requirements_md(text: str) -> list[dict[str, Any]]:
61
63
  m_direct = _DIRECT_HEADING.match(line)
62
64
  if m_direct:
63
65
  _flush()
66
+ # Group 2 carries the title when the heading is '## REQ-NNN: Title'
67
+ inline_title = (m_direct.group(2) or "").strip()
64
68
  current = {"id": m_direct.group(1)}
69
+ if inline_title:
70
+ current["title"] = inline_title
65
71
  pending_title = ""
66
72
  continue
67
73
 
@@ -86,6 +92,10 @@ def parse_requirements_md(text: str) -> list[dict[str, Any]]:
86
92
  val = m_field.group(2).strip()
87
93
  if key not in ("id",):
88
94
  current.setdefault(key, val)
95
+ elif line.strip() and not line.startswith("#"):
96
+ # Plain paragraph text after the heading — capture as description
97
+ # (e.g. '## REQ-001: Title\nThe system SHALL...')
98
+ current.setdefault("description", line.strip())
89
99
 
90
100
  _flush()
91
101
  return [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.13.0.dev503
3
+ Version: 0.13.0.dev506
4
4
  Summary: Applied Epistemic Engineering toolkit — AEE agent sessions, execution profiles, FPGA/HDL governance, tool installer, 50+ CLI commands.
5
5
  Author: BitConcepts
6
6
  License-Expression: MIT
@@ -1,62 +0,0 @@
1
- # specsmith.esdb — ESDB integration package
2
- #
3
- # Re-exports the full chronomemory v0.1.1 public surface under the
4
- # specsmith.esdb namespace so internal modules can use a single import
5
- # path and never import chronomemory directly in more than one place.
6
-
7
- # Re-export query and metrics as module references so callers can do:
8
- # from specsmith.esdb import query, metrics
9
- from chronomemory import (
10
- RUST_BACKEND,
11
- # Core store
12
- ChronoRecord,
13
- ChronoStore,
14
- # Phase 2: context pack compiler
15
- ContextPack,
16
- ContextPackCompiler,
17
- ContextPackEntry,
18
- DependencyEdge,
19
- # Phase 2: dependency graph
20
- DepGraph,
21
- # Bridge (backward-compat with .specsmith/*.json)
22
- EsdbBridge,
23
- EsdbRecord,
24
- EsdbStatus,
25
- # Phase 2: epistemic rollback
26
- RollbackReport,
27
- # Phase 3: optional Rust acceleration (None / False when not compiled)
28
- RustChronoStore,
29
- RustRecord,
30
- WalEvent,
31
- invalidate,
32
- metrics, # noqa: F401 — module re-export
33
- open_store,
34
- query, # noqa: F401 — module re-export
35
- )
36
-
37
- __all__ = [
38
- # Core
39
- "ChronoStore",
40
- "ChronoRecord",
41
- "WalEvent",
42
- "open_store",
43
- # Bridge
44
- "EsdbBridge",
45
- "EsdbRecord",
46
- "EsdbStatus",
47
- # Phase 2
48
- "DepGraph",
49
- "DependencyEdge",
50
- "RollbackReport",
51
- "invalidate",
52
- "ContextPack",
53
- "ContextPackCompiler",
54
- "ContextPackEntry",
55
- # Phase 3
56
- "RustChronoStore",
57
- "RustRecord",
58
- "RUST_BACKEND",
59
- # Modules
60
- "query",
61
- "metrics",
62
- ]