specsmith 0.3.6.dev174__tar.gz → 0.3.6.dev176__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 (166) hide show
  1. {specsmith-0.3.6.dev174/src/specsmith.egg-info → specsmith-0.3.6.dev176}/PKG-INFO +1 -1
  2. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/pyproject.toml +1 -1
  3. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/runner.py +118 -1
  4. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176/src/specsmith.egg-info}/PKG-INFO +1 -1
  5. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/LICENSE +0 -0
  6. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/README.md +0 -0
  7. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/setup.cfg +0 -0
  8. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/epistemic/__init__.py +0 -0
  9. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/epistemic/belief.py +0 -0
  10. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/epistemic/certainty.py +0 -0
  11. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/epistemic/failure_graph.py +0 -0
  12. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/epistemic/py.typed +0 -0
  13. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/epistemic/recovery.py +0 -0
  14. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/epistemic/session.py +0 -0
  15. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/epistemic/stress_tester.py +0 -0
  16. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/epistemic/trace.py +0 -0
  17. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/__init__.py +0 -0
  18. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/__main__.py +0 -0
  19. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/__init__.py +0 -0
  20. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/core.py +0 -0
  21. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/hooks.py +0 -0
  22. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/optimizer.py +0 -0
  23. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/profiles/epistemic-auditor.md +0 -0
  24. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/profiles/planner.md +0 -0
  25. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/profiles/verifier.md +0 -0
  26. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/providers/__init__.py +0 -0
  27. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/providers/anthropic.py +0 -0
  28. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/providers/gemini.py +0 -0
  29. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/providers/mistral.py +0 -0
  30. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/providers/ollama.py +0 -0
  31. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/providers/openai.py +0 -0
  32. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/skills.py +0 -0
  33. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/agent/tools.py +0 -0
  34. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/architect.py +0 -0
  35. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/auditor.py +0 -0
  36. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/auth.py +0 -0
  37. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/cli.py +0 -0
  38. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/commands/__init__.py +0 -0
  39. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/compressor.py +0 -0
  40. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/config.py +0 -0
  41. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/credit_analyzer.py +0 -0
  42. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/credits.py +0 -0
  43. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/differ.py +0 -0
  44. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/doctor.py +0 -0
  45. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/epistemic/__init__.py +0 -0
  46. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/epistemic/belief.py +0 -0
  47. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/epistemic/certainty.py +0 -0
  48. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/epistemic/failure_graph.py +0 -0
  49. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/epistemic/recovery.py +0 -0
  50. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/epistemic/stress_tester.py +0 -0
  51. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/executor.py +0 -0
  52. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/exporter.py +0 -0
  53. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/__init__.py +0 -0
  54. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/app.py +0 -0
  55. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/main_window.py +0 -0
  56. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/session_tab.py +0 -0
  57. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/theme.py +0 -0
  58. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/widgets/__init__.py +0 -0
  59. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/widgets/chat_view.py +0 -0
  60. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/widgets/input_bar.py +0 -0
  61. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/widgets/provider_bar.py +0 -0
  62. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/widgets/token_meter.py +0 -0
  63. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/widgets/tool_panel.py +0 -0
  64. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/widgets/update_checker.py +0 -0
  65. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/gui/worker.py +0 -0
  66. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/importer.py +0 -0
  67. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/integrations/__init__.py +0 -0
  68. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/integrations/aider.py +0 -0
  69. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/integrations/base.py +0 -0
  70. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/integrations/claude_code.py +0 -0
  71. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/integrations/copilot.py +0 -0
  72. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/integrations/cursor.py +0 -0
  73. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/integrations/gemini.py +0 -0
  74. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/integrations/warp.py +0 -0
  75. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/integrations/windsurf.py +0 -0
  76. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/languages.py +0 -0
  77. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/ledger.py +0 -0
  78. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/ollama_cmds.py +0 -0
  79. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/patent.py +0 -0
  80. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/phase.py +0 -0
  81. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/plugins.py +0 -0
  82. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/profiles.py +0 -0
  83. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/rate_limits.py +0 -0
  84. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/releaser.py +0 -0
  85. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/requirements.py +0 -0
  86. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/retrieval.py +0 -0
  87. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/scaffolder.py +0 -0
  88. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/session.py +0 -0
  89. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/agents.md.j2 +0 -0
  90. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
  91. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
  92. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/community/contributing.md.j2 +0 -0
  93. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
  94. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
  95. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/community/license-MIT.j2 +0 -0
  96. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
  97. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/community/security.md.j2 +0 -0
  98. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
  99. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
  100. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
  101. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
  102. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
  103. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/docs/workflow.md.j2 +0 -0
  104. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/editorconfig.j2 +0 -0
  105. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/gitattributes.j2 +0 -0
  106. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/gitignore.j2 +0 -0
  107. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/go/go.mod.j2 +0 -0
  108. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/go/main.go.j2 +0 -0
  109. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
  110. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
  111. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
  112. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
  113. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
  114. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/governance/roles.md.j2 +0 -0
  115. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/governance/rules.md.j2 +0 -0
  116. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
  117. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/governance/verification.md.j2 +0 -0
  118. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/governance/workflow.md.j2 +0 -0
  119. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/js/package.json.j2 +0 -0
  120. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/ledger.md.j2 +0 -0
  121. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/python/cli.py.j2 +0 -0
  122. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/python/init.py.j2 +0 -0
  123. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
  124. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/readme.md.j2 +0 -0
  125. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
  126. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/rust/main.rs.j2 +0 -0
  127. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
  128. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
  129. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
  130. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
  131. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
  132. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
  133. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
  134. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/tool_installer.py +0 -0
  135. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/toolrules.py +0 -0
  136. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/tools.py +0 -0
  137. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/trace.py +0 -0
  138. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/updater.py +0 -0
  139. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/upgrader.py +0 -0
  140. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/validator.py +0 -0
  141. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/vcs/__init__.py +0 -0
  142. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/vcs/base.py +0 -0
  143. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/vcs/bitbucket.py +0 -0
  144. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/vcs/github.py +0 -0
  145. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/vcs/gitlab.py +0 -0
  146. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/vcs_commands.py +0 -0
  147. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/wireframes.py +0 -0
  148. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith/workspace.py +0 -0
  149. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith.egg-info/SOURCES.txt +0 -0
  150. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith.egg-info/dependency_links.txt +0 -0
  151. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith.egg-info/entry_points.txt +0 -0
  152. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith.egg-info/requires.txt +0 -0
  153. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/src/specsmith.egg-info/top_level.txt +0 -0
  154. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_auditor.py +0 -0
  155. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_cli.py +0 -0
  156. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_compressor.py +0 -0
  157. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_epistemic.py +0 -0
  158. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_importer.py +0 -0
  159. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_integrations.py +0 -0
  160. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_optimizer.py +0 -0
  161. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_rate_limits.py +0 -0
  162. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_scaffolder.py +0 -0
  163. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_smoke.py +0 -0
  164. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_tools.py +0 -0
  165. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_validator.py +0 -0
  166. {specsmith-0.3.6.dev174 → specsmith-0.3.6.dev176}/tests/test_vcs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.3.6.dev174
3
+ Version: 0.3.6.dev176
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.3.6.dev174"
7
+ version = "0.3.6.dev176"
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"
@@ -173,6 +173,25 @@ This applies to Qwen, DeepSeek, LLaMA, Mistral, and EVERY other model.
173
173
  If the user inputs another language, internally translate it, then reply IN ENGLISH ONLY.
174
174
  VIOLATING THIS RULE IS A CRITICAL ERROR.
175
175
 
176
+ ## TOOL ERROR RULE — HARD STOP (NEVER TROUBLESHOOT ERRORS):
177
+ When ANY tool returns an error, exception, or non-zero exit code:
178
+ 1. STOP immediately. Do not attempt to fix, diagnose, or retry.
179
+ 2. Say in ONE sentence: what you were doing and what failed.
180
+ Example: "The audit tool hit an unexpected error and needs to be reported."
181
+ 3. Then say: "Would you like to report this bug?"
182
+ 4. Wait. Do nothing else. The user will decide.
183
+ This tool is not designed to fix itself. Fail fast, report quickly.
184
+
185
+ ## RESPONSE STYLE RULE — CONVERSATIONAL PLAIN ENGLISH:
186
+ Always respond in natural sentences, like a helpful colleague would.
187
+ - NEVER dump raw tool output, JSON, tables of IDs, or code blocks in your reply.
188
+ - Summarize what you found in 1-3 plain sentences.
189
+ - If a command found issues: say how many and what kind.
190
+ - If everything is fine: say so briefly.
191
+ - Details go in the tool result panel; your words give the meaning.
192
+ Example good: "Audit found 3 issues: LEDGER.md is missing and 2 requirements lack tests."
193
+ Example bad: "The tool returned: [\u2717] LEDGER.md MISSING, [\u2717] REQ-001 uncovered..."
194
+
176
195
  You are an AEE-integrated specsmith agent for this project.
177
196
 
178
197
  ## Project Governance
@@ -281,6 +300,7 @@ class AgentRunner:
281
300
  self._skills: list[Skill] = load_skills(Path(self.project_dir))
282
301
  self._hooks = HookRegistry()
283
302
  self._system_prompt = ""
303
+ self._hard_stop: bool = False # set True when a critical tool crash is detected
284
304
 
285
305
  # Execution profile — loaded from scaffold.yml at session start
286
306
  from specsmith import profiles
@@ -379,6 +399,76 @@ class AgentRunner:
379
399
  hits = len(self._NON_ASCII_BLOCKS.findall(text))
380
400
  return hits > 5 and (hits / max(len(text), 1)) > 0.05
381
401
 
402
+ # ---- Critical error patterns that trigger a hard stop ----
403
+ _CRITICAL_PATTERNS = re.compile(
404
+ r"Traceback \(most recent call last\)"
405
+ r"|\[ERROR\]"
406
+ r"|UnicodeDecodeError"
407
+ r"|UnicodeEncodeError"
408
+ r"|ImportError"
409
+ r"|ModuleNotFoundError"
410
+ r"|AttributeError: '"
411
+ r"|TypeError: unsupported"
412
+ r"|PermissionError"
413
+ r"|OSError: "
414
+ r"|RuntimeError: ",
415
+ re.IGNORECASE,
416
+ )
417
+
418
+ @staticmethod
419
+ def _is_critical_error(output: str) -> bool:
420
+ """Return True if tool output indicates an unexpected crash.
421
+
422
+ Normal governance failures (audit issues, missing files) are NOT
423
+ critical — only Python exceptions and import errors are.
424
+ """
425
+ if not output:
426
+ return False
427
+ # Non-zero exit alone is expected (e.g. audit found issues).
428
+ # Only flag when a Python exception signature is present.
429
+ return AgentRunner._CRITICAL_PATTERNS.search(output) is not None
430
+
431
+ def _collect_diagnostics(self, tool_name: str, output: str) -> dict:
432
+ """Collect diagnostic context for a crash report."""
433
+ import platform as _platform
434
+ import sys as _sys
435
+
436
+ from specsmith import __version__ as _ver
437
+
438
+ project_type = ""
439
+ try:
440
+ import yaml as _yaml
441
+
442
+ sf = Path(self.project_dir) / "scaffold.yml"
443
+ if sf.exists():
444
+ raw = _yaml.safe_load(sf.read_text(encoding="utf-8")) or {}
445
+ project_type = str(raw.get("type", ""))
446
+ except Exception: # noqa: BLE001
447
+ pass
448
+
449
+ # Classify repo: Python exceptions from specsmith module → specsmith CLI
450
+ # Extension/bridge errors would never reach here (they don’t use this runner)
451
+ repo = "specsmith"
452
+
453
+ # Extract first meaningful error line for the summary
454
+ summary = output.strip().splitlines()
455
+ _err_pat = re.compile(r"\w+Error|Exception|RuntimeError")
456
+ summary_line = next(
457
+ (ln.strip() for ln in reversed(summary) if _err_pat.match(ln.strip())),
458
+ summary[0] if summary else "Unknown error",
459
+ )[:200]
460
+
461
+ return {
462
+ "tool": tool_name,
463
+ "summary": summary_line,
464
+ "detail": output[:4000],
465
+ "specsmith_version": _ver,
466
+ "python_version": _sys.version.split()[0],
467
+ "os_info": f"{_platform.system()} {_platform.release()}",
468
+ "project_type": project_type,
469
+ "repo": repo,
470
+ }
471
+
382
472
  def _agent_turn(self, user_input: str, silent: bool = False) -> str:
383
473
  """Execute one user→agent turn with tool loop."""
384
474
  # Inject a lightweight English-only reminder into every user message.
@@ -443,9 +533,15 @@ class AgentRunner:
443
533
  break
444
534
 
445
535
  # Process tool calls
536
+ self._hard_stop = False # reset before each batch
446
537
  tool_results = self._execute_tool_calls(response.tool_calls, silent=silent)
447
538
  self._state.tool_calls_made += len(tool_results)
448
539
 
540
+ # Fail fast: a critical tool crash was detected — break immediately
541
+ # without sending the error back to the LLM (which would try to fix it).
542
+ if self._hard_stop:
543
+ break
544
+
449
545
  # Add assistant message with tool calls
450
546
  self._state.messages.append(
451
547
  Message(
@@ -543,7 +639,12 @@ class AgentRunner:
543
639
  def _execute_tool_calls(
544
640
  self, tool_calls: list[dict[str, Any]], silent: bool = False
545
641
  ) -> list[ToolResult]:
546
- """Execute tool calls and return results."""
642
+ """Execute tool calls and return results.
643
+
644
+ Sets ``self._hard_stop = True`` if any tool produces a critical error
645
+ (Python exception, import error, etc.) so the caller can break the
646
+ agentic loop immediately without sending the error to the LLM.
647
+ """
547
648
  from specsmith import profiles as _profiles
548
649
 
549
650
  results: list[ToolResult] = []
@@ -669,6 +770,22 @@ class AgentRunner:
669
770
 
670
771
  elapsed = time.time() * 1000 - start_ms
671
772
 
773
+ # ---- Fail-fast: detect critical errors -------------------------
774
+ # A critical error is an unexpected crash (Python exception, import
775
+ # failure, etc.) — NOT a normal governance failure (audit issues,
776
+ # missing files) which the LLM should describe conversationally.
777
+ if self._is_critical_error(output):
778
+ self._hard_stop = True
779
+ diagnostics = self._collect_diagnostics(name, output)
780
+ if not silent and self._json_events:
781
+ self._emit_event(type="tool_crash", **diagnostics)
782
+ elif not silent:
783
+ self._print(
784
+ f"\n[CRITICAL ERROR in {name}] "
785
+ f"{diagnostics['summary']}\n"
786
+ "Session stopped. Please report this bug."
787
+ )
788
+
672
789
  if not silent:
673
790
  if self._json_events:
674
791
  self._emit_event(type="tool_finished", name=name, result=output, is_error=error)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: specsmith
3
- Version: 0.3.6.dev174
3
+ Version: 0.3.6.dev176
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