specsmith 0.17.1.dev661__tar.gz → 0.17.1.dev664__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 (341) hide show
  1. {specsmith-0.17.1.dev661/src/specsmith.egg-info → specsmith-0.17.1.dev664}/PKG-INFO +1 -1
  2. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/pyproject.toml +1 -1
  3. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/context_seed.py +131 -33
  4. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/context_orchestrator.py +51 -10
  5. specsmith-0.17.1.dev664/src/specsmith/esdb_writer.py +226 -0
  6. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/governance_logic.py +19 -0
  7. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/__init__.py +2 -0
  8. specsmith-0.17.1.dev664/src/specsmith/migrations/m008_esdb_full_coverage.py +225 -0
  9. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/governance.py +33 -0
  10. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/wi_store.py +16 -0
  11. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664/src/specsmith.egg-info}/PKG-INFO +1 -1
  12. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith.egg-info/SOURCES.txt +5 -0
  13. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_e2e_nexus.py +110 -0
  14. specsmith-0.17.1.dev664/tests/test_esdb_integration.py +413 -0
  15. specsmith-0.17.1.dev664/tests/test_esdb_writer.py +463 -0
  16. specsmith-0.17.1.dev664/tests/test_repl.py +250 -0
  17. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/LICENSE +0 -0
  18. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/README.md +0 -0
  19. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/setup.cfg +0 -0
  20. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/__init__.py +0 -0
  21. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/belief.py +0 -0
  22. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/certainty.py +0 -0
  23. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/failure_graph.py +0 -0
  24. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/py.typed +0 -0
  25. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/recovery.py +0 -0
  26. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/session.py +0 -0
  27. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/stress_tester.py +0 -0
  28. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/epistemic/trace.py +0 -0
  29. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/__init__.py +0 -0
  30. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/__main__.py +0 -0
  31. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/__init__.py +0 -0
  32. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/broker.py +0 -0
  33. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/chat_runner.py +0 -0
  34. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/cleanup.py +0 -0
  35. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/core.py +0 -0
  36. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/__init__.py +0 -0
  37. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/_status.py +0 -0
  38. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/dag.py +0 -0
  39. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/dispatcher.py +0 -0
  40. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/events.py +0 -0
  41. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/dispatch/result.py +0 -0
  42. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/endpoints.py +0 -0
  43. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/events.py +0 -0
  44. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/execution_profiles.py +0 -0
  45. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/fallback.py +0 -0
  46. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/hf_leaderboard.py +0 -0
  47. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/hf_sync.py +0 -0
  48. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/indexer.py +0 -0
  49. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/llm_client.py +0 -0
  50. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/mcp.py +0 -0
  51. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/memory.py +0 -0
  52. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/model_intelligence.py +0 -0
  53. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/model_profiles.py +0 -0
  54. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/model_router.py +0 -0
  55. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/orchestrator.py +0 -0
  56. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/permissions.py +0 -0
  57. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/profiles.py +0 -0
  58. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/provider_registry.py +0 -0
  59. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/repl.py +0 -0
  60. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/router.py +0 -0
  61. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/rules.py +0 -0
  62. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/runner.py +0 -0
  63. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/safety.py +0 -0
  64. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/spawner.py +0 -0
  65. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/suggester.py +0 -0
  66. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/teams.py +0 -0
  67. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/tools.py +0 -0
  68. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/verifier.py +0 -0
  69. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/agent/voice.py +0 -0
  70. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/approvals.py +0 -0
  71. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/architect.py +0 -0
  72. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/auditor.py +0 -0
  73. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/auth.py +0 -0
  74. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/block_export.py +0 -0
  75. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/channel.py +0 -0
  76. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/ci_manager.py +0 -0
  77. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/cli.py +0 -0
  78. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/commands/__init__.py +0 -0
  79. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/commands/intelligence.py +0 -0
  80. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/commands/issues_policy.py +0 -0
  81. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/commands/reporting.py +0 -0
  82. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/__init__.py +0 -0
  83. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/_compat.py +0 -0
  84. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/checker.py +0 -0
  85. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/evidence.py +0 -0
  86. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/regulations.py +0 -0
  87. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compliance/reporter.py +0 -0
  88. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/compressor.py +0 -0
  89. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/config.py +0 -0
  90. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/console_utils.py +0 -0
  91. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/context_window.py +0 -0
  92. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/credit_analyzer.py +0 -0
  93. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/credits.py +0 -0
  94. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/dashboard.py +0 -0
  95. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/__init__.py +0 -0
  96. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/base.py +0 -0
  97. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/citations.py +0 -0
  98. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/fpd.py +0 -0
  99. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/odp.py +0 -0
  100. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/patentsview.py +0 -0
  101. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/pfw.py +0 -0
  102. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/ppubs.py +0 -0
  103. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/datasources/ptab.py +0 -0
  104. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/differ.py +0 -0
  105. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/doctor.py +0 -0
  106. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/drive.py +0 -0
  107. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/editor.py +0 -0
  108. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/__init__.py +0 -0
  109. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/belief.py +0 -0
  110. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/certainty.py +0 -0
  111. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/failure_graph.py +0 -0
  112. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/recovery.py +0 -0
  113. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/epistemic/stress_tester.py +0 -0
  114. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/esdb/__init__.py +0 -0
  115. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/esdb/_license.py +0 -0
  116. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/esdb/bridge.py +0 -0
  117. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/esdb/sqlite_store.py +0 -0
  118. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/eval/__init__.py +0 -0
  119. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/eval/builtins.py +0 -0
  120. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/eval/runner.py +0 -0
  121. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/executor.py +0 -0
  122. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/exporter.py +0 -0
  123. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/governance_store.py +0 -0
  124. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/governance_yaml.py +0 -0
  125. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/governed_pr.py +0 -0
  126. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/__init__.py +0 -0
  127. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/app.py +0 -0
  128. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/main_window.py +0 -0
  129. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/session_tab.py +0 -0
  130. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/theme.py +0 -0
  131. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/__init__.py +0 -0
  132. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/chat_view.py +0 -0
  133. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/input_bar.py +0 -0
  134. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/provider_bar.py +0 -0
  135. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/token_meter.py +0 -0
  136. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/tool_panel.py +0 -0
  137. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/widgets/update_checker.py +0 -0
  138. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/gui/worker.py +0 -0
  139. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/history_search.py +0 -0
  140. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/importer.py +0 -0
  141. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/instinct.py +0 -0
  142. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/__init__.py +0 -0
  143. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/agent_skill.py +0 -0
  144. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/aider.py +0 -0
  145. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/base.py +0 -0
  146. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/claude_code.py +0 -0
  147. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/codity.py +0 -0
  148. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/copilot.py +0 -0
  149. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/cursor.py +0 -0
  150. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/gemini.py +0 -0
  151. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/integrations/windsurf.py +0 -0
  152. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/issue_reporter.py +0 -0
  153. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/languages.py +0 -0
  154. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/ledger.py +0 -0
  155. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/local_model.py +0 -0
  156. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/mcp_generator.py +0 -0
  157. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/mcp_server.py +0 -0
  158. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m001_governance_yaml.py +0 -0
  159. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m002_agents_slim.py +0 -0
  160. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m003_compliance_init.py +0 -0
  161. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m004_ledger_esdb.py +0 -0
  162. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m005_agent_run_tool.py +0 -0
  163. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m006_session_governance.py +0 -0
  164. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/m007_yaml_first.py +0 -0
  165. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/migrations/runner.py +0 -0
  166. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/ollama_cmds.py +0 -0
  167. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/patent.py +0 -0
  168. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/paths.py +0 -0
  169. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/phase.py +0 -0
  170. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/plugins.py +0 -0
  171. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/policy.py +0 -0
  172. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/profiles.py +0 -0
  173. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/project_metrics.py +0 -0
  174. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/quality_report.py +0 -0
  175. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/rate_limits.py +0 -0
  176. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/recover.py +0 -0
  177. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/releaser.py +0 -0
  178. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/requirements.py +0 -0
  179. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/requirements_parser.py +0 -0
  180. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/retrieval.py +0 -0
  181. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/risk.py +0 -0
  182. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/safe_write.py +0 -0
  183. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/scaffolder.py +0 -0
  184. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/serve.py +0 -0
  185. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/session.py +0 -0
  186. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/session_init.py +0 -0
  187. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/session_store.py +0 -0
  188. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/__init__.py +0 -0
  189. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/ai_agents.py +0 -0
  190. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/cloud.py +0 -0
  191. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/corporate.py +0 -0
  192. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/cross_platform.py +0 -0
  193. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/data_engineering.py +0 -0
  194. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/devops.py +0 -0
  195. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/docs.py +0 -0
  196. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/embedded.py +0 -0
  197. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/hardware.py +0 -0
  198. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/mobile.py +0 -0
  199. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/platform_engineering.py +0 -0
  200. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/productivity.py +0 -0
  201. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/software_engineering.py +0 -0
  202. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/specsmith_skills.py +0 -0
  203. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/ssh.py +0 -0
  204. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills/web_backend.py +0 -0
  205. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/skills_builder.py +0 -0
  206. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/sync.py +0 -0
  207. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/agents.md.j2 +0 -0
  208. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
  209. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
  210. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/contributing.md.j2 +0 -0
  211. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
  212. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
  213. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/license-MIT.j2 +0 -0
  214. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
  215. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/community/security.md.j2 +0 -0
  216. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
  217. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
  218. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
  219. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
  220. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
  221. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/editorconfig.j2 +0 -0
  222. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/gitattributes.j2 +0 -0
  223. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/gitignore.j2 +0 -0
  224. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/go/go.mod.j2 +0 -0
  225. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/go/main.go.j2 +0 -0
  226. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
  227. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
  228. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
  229. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
  230. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
  231. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
  232. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/roles.md.j2 +0 -0
  233. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/rules.md.j2 +0 -0
  234. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
  235. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
  236. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/governance/verification.md.j2 +0 -0
  237. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/js/package.json.j2 +0 -0
  238. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/ledger.md.j2 +0 -0
  239. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/python/cli.py.j2 +0 -0
  240. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/python/init.py.j2 +0 -0
  241. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
  242. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/readme.md.j2 +0 -0
  243. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
  244. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/rust/main.rs.j2 +0 -0
  245. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
  246. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
  247. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
  248. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
  249. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
  250. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
  251. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
  252. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/tool_installer.py +0 -0
  253. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/toolrules.py +0 -0
  254. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/tools.py +0 -0
  255. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/trace.py +0 -0
  256. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/transcripts.py +0 -0
  257. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/updater.py +0 -0
  258. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/upgrader.py +0 -0
  259. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/validator.py +0 -0
  260. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs/__init__.py +0 -0
  261. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs/base.py +0 -0
  262. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs/bitbucket.py +0 -0
  263. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs/github.py +0 -0
  264. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs/gitlab.py +0 -0
  265. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/vcs_commands.py +0 -0
  266. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/wireframes.py +0 -0
  267. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith/workspace.py +0 -0
  268. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith.egg-info/dependency_links.txt +0 -0
  269. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith.egg-info/entry_points.txt +0 -0
  270. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith.egg-info/requires.txt +0 -0
  271. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/src/specsmith.egg-info/top_level.txt +0 -0
  272. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_CMD_001.py +0 -0
  273. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_agent_profiles.py +0 -0
  274. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_agent_run_feedback.py +0 -0
  275. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_agent_runner_ready.py +0 -0
  276. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_ai_client.py +0 -0
  277. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_ai_intelligence.py +0 -0
  278. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_architect_interview.py +0 -0
  279. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_architect_v2.py +0 -0
  280. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_architecture.py +0 -0
  281. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_auditor.py +0 -0
  282. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_channel.py +0 -0
  283. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_chat_diff_decision.py +0 -0
  284. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_chat_runner_openai_compat.py +0 -0
  285. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_chat_stdin_protocol.py +0 -0
  286. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_cleanup_cmd.py +0 -0
  287. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_cli.py +0 -0
  288. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_cli_regressions.py +0 -0
  289. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_cli_workflows_history_drive.py +0 -0
  290. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_compliance.py +0 -0
  291. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_compliance_governance.py +0 -0
  292. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_compressor.py +0 -0
  293. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_dispatch.py +0 -0
  294. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_endpoints_cli.py +0 -0
  295. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_endpoints_store.py +0 -0
  296. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_epistemic.py +0 -0
  297. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_esdb_backend_switch.py +0 -0
  298. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_esdb_enforcement.py +0 -0
  299. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_esdb_license.py +0 -0
  300. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_esdb_sqlite.py +0 -0
  301. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_esdb_verify_chain_cli.py +0 -0
  302. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_fallback_chain.py +0 -0
  303. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_golden_path.py +0 -0
  304. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_importer.py +0 -0
  305. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_init_modes.py +0 -0
  306. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_integrations.py +0 -0
  307. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_integrations_codity.py +0 -0
  308. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_intelligence.py +0 -0
  309. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_issue_policy_features.py +0 -0
  310. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_issue_reporter.py +0 -0
  311. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_issues_263_264.py +0 -0
  312. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_local_model.py +0 -0
  313. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_markdown_deprecation.py +0 -0
  314. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_mcp_client.py +0 -0
  315. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_mcp_server.py +0 -0
  316. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_migration_direction.py +0 -0
  317. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_model_router.py +0 -0
  318. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_new_modules.py +0 -0
  319. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_nexus.py +0 -0
  320. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_permissions.py +0 -0
  321. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_phase1_4_new.py +0 -0
  322. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_phase34_completion.py +0 -0
  323. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_project_metrics.py +0 -0
  324. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_quality_report.py +0 -0
  325. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_rate_limits.py +0 -0
  326. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_reporting_commands.py +0 -0
  327. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_req_248_262.py +0 -0
  328. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_req_358_359.py +0 -0
  329. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_scaffolder.py +0 -0
  330. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_schema_migrations.py +0 -0
  331. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_skill_marketplace.py +0 -0
  332. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_skills_mcp.py +0 -0
  333. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_smoke.py +0 -0
  334. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_suggester.py +0 -0
  335. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_tools.py +0 -0
  336. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_typing_guardrails.py +0 -0
  337. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_validator.py +0 -0
  338. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_vcs.py +0 -0
  339. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_warp_parity.py +0 -0
  340. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_warp_parity_followup.py +0 -0
  341. {specsmith-0.17.1.dev661 → specsmith-0.17.1.dev664}/tests/test_wi_lifecycle.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.17.1.dev661
3
+ Version: 0.17.1.dev664
4
4
  Summary: AEE governance toolkit for AI-assisted development — session preflight gates, multi-agent dispatch, requirements↔test traceability, ESDB persistence, MCP server, and skills for Warp, Cursor, Claude Code, Copilot, Windsurf, and Aider.
5
5
  Author: Layer1Labs Silicon, Inc.
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.17.1.dev661"
7
+ version = "0.17.1.dev664"
8
8
  description = "AEE governance toolkit for AI-assisted development — session preflight gates, multi-agent dispatch, requirements↔test traceability, ESDB persistence, MCP server, and skills for Warp, Cursor, Claude Code, Copilot, Windsurf, and Aider."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -27,14 +27,17 @@ left off (extended to cover full epistemic continuity).
27
27
  from __future__ import annotations
28
28
 
29
29
  import json
30
+ from collections.abc import Sequence
30
31
  from pathlib import Path
31
32
  from typing import Any
32
33
 
33
- # Maximum total characters injected as seed context. Large enough to
34
- # carry meaningful history; small enough not to bloat every prompt.
35
- _SEED_CHAR_BUDGET = 8_000
34
+ # Maximum total characters injected as seed context. Raised from 8 000 to
35
+ # 12 000 to accommodate the richer per-kind ESDB query output (REQ-399).
36
+ _SEED_CHAR_BUDGET = 12_000
36
37
  _MAX_LEDGER_LINES = 30
37
- _MAX_ESDB_RECORDS = 5
38
+ _MAX_PREFLIGHT_RECORDS = 10 # preflight_decision records (conf≥0.6)
39
+ _MAX_VERIFY_RECORDS = 5 # verify_result records (conf≥0.6)
40
+ _MAX_WI_RECORDS = 5 # work_item records (active status only)
38
41
 
39
42
 
40
43
  def build_context_seed(
@@ -42,7 +45,9 @@ def build_context_seed(
42
45
  *,
43
46
  char_budget: int = _SEED_CHAR_BUDGET,
44
47
  max_ledger: int = _MAX_LEDGER_LINES,
45
- max_esdb: int = _MAX_ESDB_RECORDS,
48
+ max_preflight: int = _MAX_PREFLIGHT_RECORDS,
49
+ max_verify: int = _MAX_VERIFY_RECORDS,
50
+ max_wi: int = _MAX_WI_RECORDS,
46
51
  ) -> list[dict[str, Any]]:
47
52
  """Return a list of history turns to prepend to a new agent session.
48
53
 
@@ -50,11 +55,20 @@ def build_context_seed(
50
55
  state or missing optional dependency can never prevent the agent from
51
56
  starting.
52
57
 
58
+ The ESDB query is now **relevance-based** (REQ-399): records are fetched by
59
+ kind (preflight_decision, verify_result, work_item) rather than returning
60
+ the last N records by insertion order. Only active records with
61
+ confidence ≥ 0.6 are included. This ensures epistemically low-quality
62
+ records (failed approaches, stale decisions, low-confidence hypotheses) are
63
+ excluded from the context window.
64
+
53
65
  Args:
54
66
  project_dir: Project root containing ``.specsmith/``.
55
67
  char_budget: Maximum total characters across all seed turns.
56
68
  max_ledger: Maximum LEDGER.md lines to include.
57
- max_esdb: Maximum ESDB ChronoRecords to include.
69
+ max_preflight: Max preflight_decision records to include.
70
+ max_verify: Max verify_result records to include.
71
+ max_wi: Max active work_item records to include.
58
72
 
59
73
  Returns:
60
74
  List of ``{role: str, content: str}`` dicts, oldest first.
@@ -72,7 +86,7 @@ def build_context_seed(
72
86
  turns.append({"role": "system", "content": content})
73
87
  used += len(content)
74
88
 
75
- # ── 2. Prior conversation history ────────────────────────────────
89
+ # ── 2. Prior conversation history ────────────────────────────
76
90
  hist_turns = _load_conversation_history(root, budget=char_budget - used)
77
91
  for t in hist_turns:
78
92
  c = json.dumps(t, ensure_ascii=False)
@@ -81,7 +95,7 @@ def build_context_seed(
81
95
  turns.append(t)
82
96
  used += len(c)
83
97
 
84
- # ── 3. Recent LEDGER entries ─────────────────────────────────────
98
+ # ── 3. Recent LEDGER entries ─────────────────────────────────
85
99
  ledger_block = _load_ledger_snippet(root, max_lines=max_ledger)
86
100
  if ledger_block and used + len(ledger_block) <= char_budget:
87
101
  turns.append(
@@ -92,13 +106,21 @@ def build_context_seed(
92
106
  )
93
107
  used += len(ledger_block)
94
108
 
95
- # ── 4. Recent ESDB records ───────────────────────────────────────
96
- esdb_block = _load_esdb_snippet(root, max_records=max_esdb)
109
+ # ── 4. ESDB records — relevance-based by kind (REQ-399) ──────────────
110
+ esdb_block = _load_esdb_by_kind(
111
+ root,
112
+ max_preflight=max_preflight,
113
+ max_verify=max_verify,
114
+ max_wi=max_wi,
115
+ )
97
116
  if esdb_block and used + len(esdb_block) <= char_budget:
98
117
  turns.append(
99
118
  {
100
119
  "role": "system",
101
- "content": f"[Recent ESDB records — last {max_esdb}]\n{esdb_block}",
120
+ "content": (
121
+ "[ESDB governance context — active preflight"
122
+ f" decisions, verify results, work items]\n{esdb_block}"
123
+ ),
102
124
  }
103
125
  )
104
126
 
@@ -185,31 +207,107 @@ def _load_ledger_snippet(root: Path, *, max_lines: int) -> str:
185
207
  return ""
186
208
 
187
209
 
188
- def _load_esdb_snippet(root: Path, *, max_records: int) -> str:
189
- """Return a compact summary of the most recent ESDB ChronoRecords.
190
-
191
- Uses query.what_is_known() (not store.query()) so infrastructure records
192
- (edge, rollback_event, token_metric, skill_run) are excluded from the
193
- LLM context seed — critical rule §23 / ESDB spec rule 3.
210
+ def _load_esdb_by_kind(
211
+ root: Path,
212
+ *,
213
+ max_preflight: int = 10,
214
+ max_verify: int = 5,
215
+ max_wi: int = 5,
216
+ ) -> str:
217
+ """Return a compact, epistemically-filtered ESDB context block (REQ-399).
218
+
219
+ Queries three specific kinds rather than "last N records by insertion
220
+ order" so the context seed is relevant regardless of store size:
221
+
222
+ 1. ``preflight_decision`` (active, conf≥0.6) — recent accepted preflights;
223
+ sorted highest-confidence first so the best-evidenced ones appear.
224
+ 2. ``verify_result`` (active, conf≥0.6) — recent verify outcomes.
225
+ 3. ``work_item`` (active, conf≥0.6) — open/in-progress WIs.
226
+
227
+ Falls back to ``query.what_is_known()`` for ChronoStore when the SqliteStore
228
+ does not have records of the requested kinds (e.g. before the first preflight).
229
+
230
+ Uses ``store.query(kind=..., rag_filter=True)`` which applies the
231
+ confidence≥0.6 filter, honouring H18 (RAG retrieval filtering).
232
+ Infrastructure kinds (edge, rollback_event, token_metric, skill_run) are
233
+ never returned by this function — ESDB spec rule 3 / critical rule §23.
194
234
  """
235
+ lines: list[str] = []
236
+ seen_ids: set[str] = set()
237
+
238
+ def _fmt(rec: object) -> str:
239
+ rid = getattr(rec, "id", "?")
240
+ kind = getattr(rec, "kind", "?")
241
+ label = getattr(rec, "label", "")
242
+ data = getattr(rec, "data", {}) or {}
243
+ conf = getattr(rec, "confidence", 0.0)
244
+ line = f"[{rid}] {kind} (conf={conf:.2f}): {label[:120]}"
245
+ detail = (
246
+ data.get("decision")
247
+ or data.get("equilibrium")
248
+ or data.get("status")
249
+ or data.get("summary")
250
+ )
251
+ if detail:
252
+ line += f" — {str(detail)[:80]}"
253
+ return line
254
+
255
+ def _add_records(records: Sequence[object], max_n: int) -> None:
256
+ added = 0
257
+ for rec in sorted(records, key=lambda r: -getattr(r, "confidence", 0)):
258
+ if added >= max_n:
259
+ break
260
+ rid = getattr(rec, "id", None)
261
+ if rid and rid not in seen_ids:
262
+ lines.append(_fmt(rec))
263
+ seen_ids.add(rid)
264
+ added += 1
265
+
266
+ # --- Try SqliteStore (always available, no external dep) -----------------
195
267
  try:
196
- from chronomemory import ChronoStore
197
- from chronomemory import query as _cm_query
198
-
199
- with ChronoStore(root) as store:
200
- all_records = _cm_query.what_is_known(store) # active, conf>=0.6, no infra
201
- recent = all_records[-max_records:] if len(all_records) > max_records else all_records
202
- if not recent:
203
- return ""
204
- lines = []
205
- for rec in recent:
206
- line = f"[{rec.id}] {rec.kind}: {rec.label}"
207
- if rec.data.get("summary"):
208
- line += f" \u2014 {str(rec.data['summary'])[:120]}"
209
- lines.append(line)
210
- return "\n".join(lines)
268
+ from specsmith.esdb import SqliteStore
269
+
270
+ sqlite_path = root / ".specsmith" / "esdb.sqlite3"
271
+ if sqlite_path.exists():
272
+ with SqliteStore(root) as store:
273
+ _add_records(
274
+ store.query(kind="preflight_decision", rag_filter=True),
275
+ max_preflight,
276
+ )
277
+ _add_records(
278
+ store.query(kind="verify_result", rag_filter=True),
279
+ max_verify,
280
+ )
281
+ _add_records(
282
+ store.query(kind="work_item", status="active", rag_filter=True),
283
+ max_wi,
284
+ )
211
285
  except Exception: # noqa: BLE001
212
- return ""
286
+ pass
287
+
288
+ # --- Supplement / fall back via ChronoStore ------------------------------
289
+ # Only query ChronoStore when we got fewer records than requested so we
290
+ # don't duplicate records that are in both backends.
291
+ chrono_needed = max_preflight + max_verify + max_wi - len(seen_ids)
292
+ if chrono_needed > 0:
293
+ try:
294
+ from chronomemory import ChronoStore
295
+ from chronomemory import query as _cm_query
296
+
297
+ with ChronoStore(root) as store:
298
+ known = _cm_query.what_is_known(store) # active, conf>=0.6, no infra
299
+ # Group by kind and add missing records
300
+ for kind_key, max_n in (
301
+ ("preflight_decision", max_preflight),
302
+ ("verify_result", max_verify),
303
+ ("work_item", max_wi),
304
+ ):
305
+ kind_recs = [r for r in known if getattr(r, "kind", "") == kind_key]
306
+ _add_records(kind_recs, max_n)
307
+ except Exception: # noqa: BLE001
308
+ pass
309
+
310
+ return "\n".join(lines)
213
311
 
214
312
 
215
313
  __all__ = ["build_context_seed"]
@@ -220,28 +220,69 @@ class ContextOrchestrator:
220
220
  min_confidence: float = 0.5,
221
221
  source_type_exclude: list[str] | None = None,
222
222
  ) -> int:
223
- """Mark low-confidence records as 'evicted-from-context' in memory only.
223
+ """Tombstone low-confidence records in the ESDB store (REQ-400).
224
224
 
225
- NOTE: This does NOT delete from the WAL it only removes from the
226
- in-context representation returned by the current query.
225
+ Writes back to the store (tombstone via store.delete()) so the eviction
226
+ persists across sessions. Data is never physically removed — tombstone
227
+ only. Infrastructure records (edge, rollback_event, token_metric,
228
+ skill_run) and governance records (requirement, testcase) are exempt.
227
229
 
228
- Returns the count of records that would be evicted.
230
+ Returns the count of records actually tombstoned.
229
231
  """
232
+ _EXEMPT_KINDS = frozenset(
233
+ {
234
+ "requirement",
235
+ "testcase",
236
+ "edge",
237
+ "rollback_event",
238
+ "token_metric",
239
+ "skill_run",
240
+ }
241
+ )
230
242
 
243
+ # --- Try ChronoStore first (commercial backend) ----------------------
231
244
  wal = self.root / ".chronomemory" / "events.wal"
232
- if not wal.exists():
233
- return 0
245
+ if wal.exists():
246
+ try:
247
+ from chronomemory import ChronoStore
248
+
249
+ with ChronoStore(self.root) as store:
250
+ records = store.query()
251
+ count = 0
252
+ for rec in records:
253
+ if getattr(rec, "kind", "") in _EXEMPT_KINDS:
254
+ continue
255
+ evict = rec.confidence < min_confidence
256
+ if (
257
+ source_type_exclude
258
+ and getattr(rec, "source_type", "") in source_type_exclude
259
+ ):
260
+ evict = True
261
+ if evict:
262
+ store.delete(rec.id) # tombstone — never physically removed
263
+ count += 1
264
+ return count
265
+ except Exception: # noqa: BLE001
266
+ pass # fall through to SqliteStore
267
+
268
+ # --- Fall back to SqliteStore (free default backend) -----------------
234
269
  try:
235
- from chronomemory import ChronoStore
270
+ from specsmith.esdb import SqliteStore
236
271
 
237
- with ChronoStore(self.root) as store:
238
- records = store.query()
272
+ sqlite_path = self.root / ".specsmith" / "esdb.sqlite3"
273
+ if not sqlite_path.exists():
274
+ return 0
275
+ with SqliteStore(self.root) as store:
276
+ records = store.query(status="active")
239
277
  count = 0
240
278
  for rec in records:
279
+ if rec.kind in _EXEMPT_KINDS:
280
+ continue
241
281
  evict = rec.confidence < min_confidence
242
- if source_type_exclude and rec.source_type in source_type_exclude:
282
+ if source_type_exclude and rec.kind in source_type_exclude:
243
283
  evict = True
244
284
  if evict:
285
+ store.delete(rec.id) # tombstone
245
286
  count += 1
246
287
  return count
247
288
  except Exception: # noqa: BLE001
@@ -0,0 +1,226 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 Layer1Labs Silicon, Inc. All rights reserved.
3
+ """specsmith.esdb_writer — centralised best-effort ESDB write paths (REQ-395..402).
4
+
5
+ This module provides the write paths that were previously missing from ESDB:
6
+ - Preflight decisions (kind="preflight_decision")
7
+ - Verify results (kind="verify_result")
8
+ - Work item records (kind="work_item")
9
+
10
+ All three functions are **best-effort** — they are wrapped in try/except so
11
+ they never block their callers when ESDB is unavailable or the store fails.
12
+
13
+ Backend-agnostic: uses ``open_default_store()`` which dispatches to either
14
+ the free SQLite backend or the commercial ChronoStore backend depending on
15
+ what is installed and licensed.
16
+
17
+ Record confidence mapping:
18
+ preflight_decision → payload["confidence_target"] (0.7–0.9 typical)
19
+ verify_result → 0.85 on equilibrium, 0.4 otherwise
20
+ work_item → wi.confidence_target; tombstone on terminal states
21
+
22
+ REQ-395: ESDBWriter utility module
23
+ REQ-396: Preflight decision ESDB write path
24
+ REQ-397: Verify result ESDB write path
25
+ REQ-398: Work item ESDB synchronisation
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ import hashlib
31
+ from pathlib import Path
32
+ from typing import TYPE_CHECKING, Any
33
+
34
+ if TYPE_CHECKING:
35
+ pass # avoid circular imports at runtime
36
+
37
+
38
+ # ---------------------------------------------------------------------------
39
+ # Internal helpers
40
+ # ---------------------------------------------------------------------------
41
+
42
+
43
+ def _short_hash(text: str, length: int = 8) -> str:
44
+ """Return first *length* hex chars of SHA-256 of *text*."""
45
+ return hashlib.sha256(text.encode("utf-8")).hexdigest()[:length].upper()
46
+
47
+
48
+ # ---------------------------------------------------------------------------
49
+ # Public write functions — all best-effort (wrapped in try/except by callers)
50
+ # ---------------------------------------------------------------------------
51
+
52
+
53
+ def write_preflight_record(
54
+ project_root: str | Path,
55
+ payload: dict[str, Any],
56
+ ) -> bool:
57
+ """Upsert a ``preflight_decision`` ESDB record from a preflight payload.
58
+
59
+ Called by ``run_preflight()`` after the work item is minted.
60
+
61
+ Record shape:
62
+ id = payload["work_item_id"] (e.g. "WI-3A9F1C02")
63
+ kind = "preflight_decision"
64
+ label = utterance extracted from payload
65
+ confidence = payload["confidence_target"]
66
+ source_ids = payload["requirement_ids"]
67
+ status = "active"
68
+ data = {decision, intent, work_item_id, test_case_ids, ...}
69
+
70
+ Returns True on success, False on any error (error is swallowed).
71
+ """
72
+ try:
73
+ work_item_id = payload.get("work_item_id", "")
74
+ if not work_item_id:
75
+ return False # only persist accepted preflights that minted a WI
76
+
77
+ from specsmith.esdb import SqliteRecord, open_default_store
78
+
79
+ root = Path(project_root)
80
+ pf_id = f"PF-{work_item_id}"
81
+ record = SqliteRecord(
82
+ id=pf_id,
83
+ kind="preflight_decision",
84
+ status="active",
85
+ label=str(payload.get("instruction", payload.get("intent", "")))[:200],
86
+ confidence=float(payload.get("confidence_target", 0.7)),
87
+ data={
88
+ "decision": payload.get("decision", ""),
89
+ "intent": payload.get("intent", ""),
90
+ "work_item_id": work_item_id,
91
+ "test_case_ids": payload.get("test_case_ids", []),
92
+ "instruction": payload.get("instruction", ""),
93
+ "ai_disclosure": payload.get("ai_disclosure", {}),
94
+ },
95
+ source_ids=list(payload.get("requirement_ids", [])),
96
+ )
97
+ with open_default_store(root, warn=False) as store:
98
+ store.upsert(record)
99
+ return True
100
+ except Exception: # noqa: BLE001 — best-effort; never blocks preflight
101
+ return False
102
+
103
+
104
+ def write_verify_record(
105
+ project_root: str | Path,
106
+ result: dict[str, Any],
107
+ ) -> bool:
108
+ """Upsert a ``verify_result`` ESDB record from a verify payload.
109
+
110
+ Called by ``run_verify()`` after the work item is marked implemented.
111
+
112
+ Record shape:
113
+ id = "VERIFY-{work_item_id}"
114
+ kind = "verify_result"
115
+ label = brief summary string
116
+ confidence = 0.85 on equilibrium else 0.4
117
+ source_ids = [work_item_id] (links to preflight_decision record)
118
+ status = "active"
119
+ data = {equilibrium, retry_strategy, files_changed_count, ...}
120
+
121
+ When equilibrium is reached the corresponding ``preflight_decision``
122
+ record is tombstoned (status → "tombstone") to signal completion.
123
+
124
+ Returns True on success, False on any error.
125
+ """
126
+ try:
127
+ work_item_id = result.get("work_item_id", "")
128
+ equilibrium = bool(result.get("equilibrium", False))
129
+ confidence = 0.85 if equilibrium else 0.4
130
+
131
+ from specsmith.esdb import SqliteRecord, open_default_store
132
+
133
+ root = Path(project_root)
134
+ verify_id = (
135
+ f"VERIFY-{work_item_id}" if work_item_id else f"VERIFY-{_short_hash(str(result))}"
136
+ )
137
+
138
+ record = SqliteRecord(
139
+ id=verify_id,
140
+ kind="verify_result",
141
+ status="active",
142
+ label=str(result.get("summary", ""))[:200],
143
+ confidence=confidence,
144
+ data={
145
+ "equilibrium": equilibrium,
146
+ "confidence": result.get("confidence", confidence),
147
+ "retry_strategy": result.get("retry_strategy", ""),
148
+ "files_changed_count": len(result.get("files_changed", [])),
149
+ "work_item_id": work_item_id,
150
+ },
151
+ source_ids=[work_item_id] if work_item_id else [],
152
+ )
153
+ with open_default_store(root, warn=False) as store:
154
+ store.upsert(record)
155
+ # When equilibrium reached, tombstone the preflight_decision record
156
+ # so context seed knows this WI is complete.
157
+ if equilibrium and work_item_id:
158
+ pf_id = f"PF-{work_item_id}"
159
+ existing = store.get(pf_id)
160
+ if existing is not None and existing.kind == "preflight_decision":
161
+ store.delete(pf_id)
162
+ return True
163
+ except Exception: # noqa: BLE001 — best-effort
164
+ return False
165
+
166
+
167
+ def write_work_item_record(
168
+ project_root: str | Path,
169
+ wi: Any, # WorkItem — avoid circular import; duck-typed
170
+ ) -> bool:
171
+ """Upsert a ``work_item`` ESDB record mirroring a WorkItem.
172
+
173
+ Called by WorkItemStore after create/set_status/mark_implemented/promote.
174
+
175
+ Record shape:
176
+ id = wi.id (e.g. "WI-3A9F1C02")
177
+ kind = "work_item"
178
+ label = wi.intent[:200]
179
+ confidence = wi.confidence_target
180
+ source_ids = wi.requirement_ids + wi.test_case_ids
181
+ status = "active" for open/implemented
182
+ "tombstone" for promoted/closed/archived/rejected
183
+ data = {status, kind, verified, promoted_to_req, blast_radius, ...}
184
+
185
+ Returns True on success, False on any error.
186
+ """
187
+ try:
188
+ from specsmith.esdb import SqliteRecord, open_default_store
189
+
190
+ _TERMINAL = frozenset({"promoted", "closed", "archived", "rejected"})
191
+ esdb_status = "tombstone" if wi.status in _TERMINAL else "active"
192
+
193
+ source_ids = list(getattr(wi, "requirement_ids", []))
194
+ source_ids += list(getattr(wi, "test_case_ids", []))
195
+
196
+ record = SqliteRecord(
197
+ id=wi.id,
198
+ kind="work_item",
199
+ status=esdb_status,
200
+ label=str(wi.intent or wi.id)[:200],
201
+ confidence=float(getattr(wi, "confidence_target", 0.7)),
202
+ data={
203
+ "status": wi.status,
204
+ "kind": getattr(wi, "kind", "feature"),
205
+ "verified": getattr(wi, "verified", False),
206
+ "promoted_to_req": getattr(wi, "promoted_to_req", ""),
207
+ "blast_radius_estimate": getattr(wi, "blast_radius_estimate", ""),
208
+ "created_at": getattr(wi, "created_at", ""),
209
+ "updated_at": getattr(wi, "updated_at", ""),
210
+ "closed_reason": getattr(wi, "closed_reason", ""),
211
+ },
212
+ source_ids=source_ids,
213
+ )
214
+ root = Path(project_root)
215
+ with open_default_store(root, warn=False) as store:
216
+ store.upsert(record)
217
+ return True
218
+ except Exception: # noqa: BLE001 — best-effort
219
+ return False
220
+
221
+
222
+ __all__ = [
223
+ "write_preflight_record",
224
+ "write_verify_record",
225
+ "write_work_item_record",
226
+ ]
@@ -271,6 +271,16 @@ def run_preflight(
271
271
  except Exception: # noqa: BLE001
272
272
  pass
273
273
 
274
+ # ESDB write — persist preflight decision for session resume and RAG (REQ-396).
275
+ # Best-effort: esdb_writer swallows all errors so ESDB is never on the
276
+ # critical path for preflight.
277
+ try:
278
+ from specsmith.esdb_writer import write_preflight_record
279
+
280
+ write_preflight_record(_root_str, payload)
281
+ except Exception: # noqa: BLE001
282
+ pass
283
+
274
284
  return payload
275
285
 
276
286
 
@@ -370,6 +380,15 @@ def run_verify(
370
380
  except Exception: # noqa: BLE001
371
381
  pass
372
382
 
383
+ # ESDB write — persist verify result for session resume and audit (REQ-397).
384
+ # Also tombstones the preflight_decision record on equilibrium.
385
+ try:
386
+ from specsmith.esdb_writer import write_verify_record
387
+
388
+ write_verify_record(root, out)
389
+ except Exception: # noqa: BLE001
390
+ pass
391
+
373
392
  return out
374
393
 
375
394
 
@@ -115,6 +115,7 @@ class _MigrationRegistry:
115
115
  m005_agent_run_tool,
116
116
  m006_session_governance,
117
117
  m007_yaml_first,
118
+ m008_esdb_full_coverage,
118
119
  )
119
120
 
120
121
  instances: list[Migration] = [
@@ -125,6 +126,7 @@ class _MigrationRegistry:
125
126
  m005_agent_run_tool.AgentRunToolMigration(),
126
127
  m006_session_governance.SessionGovernanceMigration(),
127
128
  m007_yaml_first.YamlFirstMigration(),
129
+ m008_esdb_full_coverage.EsdbFullCoverageMigration(),
128
130
  ]
129
131
  instances.sort(key=lambda m: m.version)
130
132
  self._migrations = instances