specsmith 0.11.3.dev428__tar.gz → 0.11.3.dev431__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 (282) hide show
  1. {specsmith-0.11.3.dev428/src/specsmith.egg-info → specsmith-0.11.3.dev431}/PKG-INFO +1 -1
  2. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/pyproject.toml +3 -1
  3. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/cli.py +29 -6
  4. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/devops.py +170 -0
  5. specsmith-0.11.3.dev431/src/specsmith/skills/governance.py +418 -0
  6. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/vcs_commands.py +35 -0
  7. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431/src/specsmith.egg-info}/PKG-INFO +1 -1
  8. specsmith-0.11.3.dev428/src/specsmith/skills/governance.py +0 -168
  9. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/LICENSE +0 -0
  10. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/README.md +0 -0
  11. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/setup.cfg +0 -0
  12. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/epistemic/__init__.py +0 -0
  13. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/epistemic/belief.py +0 -0
  14. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/epistemic/certainty.py +0 -0
  15. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/epistemic/failure_graph.py +0 -0
  16. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/epistemic/py.typed +0 -0
  17. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/epistemic/recovery.py +0 -0
  18. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/epistemic/session.py +0 -0
  19. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/epistemic/stress_tester.py +0 -0
  20. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/epistemic/trace.py +0 -0
  21. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/__init__.py +0 -0
  22. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/__main__.py +0 -0
  23. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/__init__.py +0 -0
  24. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/broker.py +0 -0
  25. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/chat_runner.py +0 -0
  26. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/cleanup.py +0 -0
  27. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/context_seed.py +0 -0
  28. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/core.py +0 -0
  29. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/dispatch/__init__.py +0 -0
  30. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/dispatch/_status.py +0 -0
  31. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/dispatch/dag.py +0 -0
  32. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/dispatch/dispatcher.py +0 -0
  33. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/dispatch/events.py +0 -0
  34. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/dispatch/result.py +0 -0
  35. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/endpoints.py +0 -0
  36. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/events.py +0 -0
  37. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/execution_profiles.py +0 -0
  38. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/fallback.py +0 -0
  39. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/hf_leaderboard.py +0 -0
  40. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/hf_sync.py +0 -0
  41. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/indexer.py +0 -0
  42. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/llm_client.py +0 -0
  43. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/mcp.py +0 -0
  44. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/memory.py +0 -0
  45. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/model_intelligence.py +0 -0
  46. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/model_profiles.py +0 -0
  47. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/orchestrator.py +0 -0
  48. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/permissions.py +0 -0
  49. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/profiles.py +0 -0
  50. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/provider_registry.py +0 -0
  51. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/repl.py +0 -0
  52. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/router.py +0 -0
  53. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/rules.py +0 -0
  54. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/runner.py +0 -0
  55. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/safety.py +0 -0
  56. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/spawner.py +0 -0
  57. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/suggester.py +0 -0
  58. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/teams.py +0 -0
  59. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/tools.py +0 -0
  60. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/verifier.py +0 -0
  61. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/agent/voice.py +0 -0
  62. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/architect.py +0 -0
  63. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/auditor.py +0 -0
  64. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/auth.py +0 -0
  65. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/block_export.py +0 -0
  66. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/channel.py +0 -0
  67. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/ci_manager.py +0 -0
  68. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/commands/__init__.py +0 -0
  69. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/commands/intelligence.py +0 -0
  70. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/compliance/__init__.py +0 -0
  71. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/compliance/_compat.py +0 -0
  72. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/compliance/checker.py +0 -0
  73. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/compliance/evidence.py +0 -0
  74. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/compliance/regulations.py +0 -0
  75. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/compliance/reporter.py +0 -0
  76. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/compressor.py +0 -0
  77. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/config.py +0 -0
  78. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/console_utils.py +0 -0
  79. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/context_orchestrator.py +0 -0
  80. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/context_window.py +0 -0
  81. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/credit_analyzer.py +0 -0
  82. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/credits.py +0 -0
  83. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/datasources/__init__.py +0 -0
  84. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/datasources/base.py +0 -0
  85. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/datasources/citations.py +0 -0
  86. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/datasources/fpd.py +0 -0
  87. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/datasources/odp.py +0 -0
  88. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/datasources/patentsview.py +0 -0
  89. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/datasources/pfw.py +0 -0
  90. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/datasources/ppubs.py +0 -0
  91. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/datasources/ptab.py +0 -0
  92. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/differ.py +0 -0
  93. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/doctor.py +0 -0
  94. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/drive.py +0 -0
  95. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/editor.py +0 -0
  96. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/epistemic/__init__.py +0 -0
  97. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/epistemic/belief.py +0 -0
  98. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/epistemic/certainty.py +0 -0
  99. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/epistemic/failure_graph.py +0 -0
  100. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/epistemic/recovery.py +0 -0
  101. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/epistemic/stress_tester.py +0 -0
  102. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/esdb/__init__.py +0 -0
  103. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/esdb/bridge.py +0 -0
  104. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/eval/__init__.py +0 -0
  105. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/eval/builtins.py +0 -0
  106. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/eval/runner.py +0 -0
  107. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/executor.py +0 -0
  108. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/exporter.py +0 -0
  109. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/governance_logic.py +0 -0
  110. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/governance_store.py +0 -0
  111. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/governance_yaml.py +0 -0
  112. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/__init__.py +0 -0
  113. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/app.py +0 -0
  114. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/main_window.py +0 -0
  115. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/session_tab.py +0 -0
  116. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/theme.py +0 -0
  117. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/widgets/__init__.py +0 -0
  118. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/widgets/chat_view.py +0 -0
  119. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/widgets/input_bar.py +0 -0
  120. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/widgets/provider_bar.py +0 -0
  121. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/widgets/token_meter.py +0 -0
  122. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/widgets/tool_panel.py +0 -0
  123. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/widgets/update_checker.py +0 -0
  124. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/gui/worker.py +0 -0
  125. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/history_search.py +0 -0
  126. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/importer.py +0 -0
  127. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/instinct.py +0 -0
  128. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/integrations/__init__.py +0 -0
  129. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/integrations/agent_skill.py +0 -0
  130. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/integrations/aider.py +0 -0
  131. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/integrations/base.py +0 -0
  132. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/integrations/claude_code.py +0 -0
  133. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/integrations/copilot.py +0 -0
  134. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/integrations/cursor.py +0 -0
  135. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/integrations/gemini.py +0 -0
  136. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/integrations/windsurf.py +0 -0
  137. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/issue_reporter.py +0 -0
  138. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/languages.py +0 -0
  139. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/ledger.py +0 -0
  140. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/mcp_generator.py +0 -0
  141. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/migrations/__init__.py +0 -0
  142. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/migrations/m001_governance_yaml.py +0 -0
  143. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/migrations/m002_agents_slim.py +0 -0
  144. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/migrations/m003_compliance_init.py +0 -0
  145. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/migrations/m004_ledger_esdb.py +0 -0
  146. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/migrations/m005_agent_run_tool.py +0 -0
  147. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/migrations/runner.py +0 -0
  148. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/ollama_cmds.py +0 -0
  149. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/patent.py +0 -0
  150. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/paths.py +0 -0
  151. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/phase.py +0 -0
  152. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/plugins.py +0 -0
  153. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/profiles.py +0 -0
  154. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/rate_limits.py +0 -0
  155. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/releaser.py +0 -0
  156. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/requirements.py +0 -0
  157. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/requirements_parser.py +0 -0
  158. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/retrieval.py +0 -0
  159. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/safe_write.py +0 -0
  160. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/scaffolder.py +0 -0
  161. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/serve.py +0 -0
  162. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/session.py +0 -0
  163. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/session_init.py +0 -0
  164. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/session_store.py +0 -0
  165. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/__init__.py +0 -0
  166. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/cloud.py +0 -0
  167. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/corporate.py +0 -0
  168. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/cross_platform.py +0 -0
  169. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/docs.py +0 -0
  170. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/embedded.py +0 -0
  171. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/hardware.py +0 -0
  172. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/mobile.py +0 -0
  173. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/productivity.py +0 -0
  174. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills/ssh.py +0 -0
  175. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/skills_builder.py +0 -0
  176. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/sync.py +0 -0
  177. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/agents.md.j2 +0 -0
  178. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/community/bug_report.md.j2 +0 -0
  179. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/community/code_of_conduct.md.j2 +0 -0
  180. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/community/contributing.md.j2 +0 -0
  181. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/community/feature_request.md.j2 +0 -0
  182. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/community/license-Apache-2.0.j2 +0 -0
  183. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/community/license-MIT.j2 +0 -0
  184. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/community/pull_request_template.md.j2 +0 -0
  185. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/community/security.md.j2 +0 -0
  186. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/docs/architecture.md.j2 +0 -0
  187. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/docs/mkdocs.yml.j2 +0 -0
  188. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/docs/readthedocs.yaml.j2 +0 -0
  189. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/docs/requirements.md.j2 +0 -0
  190. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/docs/test-spec.md.j2 +0 -0
  191. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/editorconfig.j2 +0 -0
  192. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/gitattributes.j2 +0 -0
  193. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/gitignore.j2 +0 -0
  194. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/go/go.mod.j2 +0 -0
  195. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/go/main.go.j2 +0 -0
  196. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/belief-registry.md.j2 +0 -0
  197. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/context-budget.md.j2 +0 -0
  198. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/drift-metrics.md.j2 +0 -0
  199. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/epistemic-axioms.md.j2 +0 -0
  200. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/failure-modes.md.j2 +0 -0
  201. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/lifecycle.md.j2 +0 -0
  202. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/roles.md.j2 +0 -0
  203. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/rules.md.j2 +0 -0
  204. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/session-protocol.md.j2 +0 -0
  205. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/uncertainty-map.md.j2 +0 -0
  206. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/governance/verification.md.j2 +0 -0
  207. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/js/package.json.j2 +0 -0
  208. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/ledger.md.j2 +0 -0
  209. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/python/cli.py.j2 +0 -0
  210. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/python/init.py.j2 +0 -0
  211. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/python/pyproject.toml.j2 +0 -0
  212. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/readme.md.j2 +0 -0
  213. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/rust/Cargo.toml.j2 +0 -0
  214. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/rust/main.rs.j2 +0 -0
  215. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/scripts/exec.cmd.j2 +0 -0
  216. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/scripts/exec.sh.j2 +0 -0
  217. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/scripts/run.cmd.j2 +0 -0
  218. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/scripts/run.sh.j2 +0 -0
  219. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/scripts/setup.cmd.j2 +0 -0
  220. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/scripts/setup.sh.j2 +0 -0
  221. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/templates/workflows/release.yml.j2 +0 -0
  222. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/tool_installer.py +0 -0
  223. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/toolrules.py +0 -0
  224. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/tools.py +0 -0
  225. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/trace.py +0 -0
  226. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/updater.py +0 -0
  227. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/upgrader.py +0 -0
  228. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/validator.py +0 -0
  229. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/vcs/__init__.py +0 -0
  230. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/vcs/base.py +0 -0
  231. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/vcs/bitbucket.py +0 -0
  232. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/vcs/github.py +0 -0
  233. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/vcs/gitlab.py +0 -0
  234. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/wireframes.py +0 -0
  235. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith/workspace.py +0 -0
  236. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith.egg-info/SOURCES.txt +0 -0
  237. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith.egg-info/dependency_links.txt +0 -0
  238. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith.egg-info/entry_points.txt +0 -0
  239. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith.egg-info/requires.txt +0 -0
  240. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/src/specsmith.egg-info/top_level.txt +0 -0
  241. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_CMD_001.py +0 -0
  242. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_agent_profiles.py +0 -0
  243. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_agent_runner_ready.py +0 -0
  244. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_ai_client.py +0 -0
  245. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_ai_intelligence.py +0 -0
  246. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_auditor.py +0 -0
  247. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_channel.py +0 -0
  248. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_chat_diff_decision.py +0 -0
  249. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_chat_runner_openai_compat.py +0 -0
  250. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_chat_stdin_protocol.py +0 -0
  251. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_cli.py +0 -0
  252. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_cli_workflows_history_drive.py +0 -0
  253. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_compliance.py +0 -0
  254. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_compressor.py +0 -0
  255. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_dispatch.py +0 -0
  256. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_e2e_nexus.py +0 -0
  257. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_endpoints_cli.py +0 -0
  258. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_endpoints_store.py +0 -0
  259. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_epistemic.py +0 -0
  260. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_fallback_chain.py +0 -0
  261. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_importer.py +0 -0
  262. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_integrations.py +0 -0
  263. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_intelligence.py +0 -0
  264. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_issue_reporter.py +0 -0
  265. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_mcp_client.py +0 -0
  266. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_new_modules.py +0 -0
  267. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_nexus.py +0 -0
  268. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_permissions.py +0 -0
  269. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_phase1_4_new.py +0 -0
  270. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_phase34_completion.py +0 -0
  271. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_rate_limits.py +0 -0
  272. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_req_248_262.py +0 -0
  273. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_scaffolder.py +0 -0
  274. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_skill_marketplace.py +0 -0
  275. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_skills_mcp.py +0 -0
  276. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_smoke.py +0 -0
  277. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_suggester.py +0 -0
  278. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_tools.py +0 -0
  279. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_validator.py +0 -0
  280. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_vcs.py +0 -0
  281. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/tests/test_warp_parity.py +0 -0
  282. {specsmith-0.11.3.dev428 → specsmith-0.11.3.dev431}/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.11.3.dev428
3
+ Version: 0.11.3.dev431
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.11.3.dev428"
7
+ version = "0.11.3.dev431"
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"
@@ -127,6 +127,8 @@ select = ["E", "F", "W", "I", "UP", "B", "SIM"]
127
127
  "src/specsmith/ci_manager.py" = ["E501"]
128
128
  # Context orchestrator: tier descriptions are intentionally descriptive
129
129
  "src/specsmith/context_orchestrator.py" = ["E501"]
130
+ # Skills module: skill body strings contain markdown content with long lines
131
+ "src/specsmith/skills/*.py" = ["E501"]
130
132
  # Migration files: rule description strings and template content
131
133
  "src/specsmith/migrations/m001_governance_yaml.py" = ["E501"]
132
134
  "src/specsmith/migrations/m004_ledger_esdb.py" = ["E501"]
@@ -2471,8 +2471,14 @@ def push_cmd(project_dir: str, force: bool) -> None:
2471
2471
  default=False,
2472
2472
  help="Commit only; skip push.",
2473
2473
  )
2474
+ @click.option(
2475
+ "--force",
2476
+ is_flag=True,
2477
+ default=False,
2478
+ help="Override push safety checks (e.g. direct-to-main guard).",
2479
+ )
2474
2480
  @click.option("--json", "as_json", is_flag=True, default=False)
2475
- def save_cmd(project_dir: str, message: str, no_push: bool, as_json: bool) -> None:
2481
+ def save_cmd(project_dir: str, message: str, no_push: bool, force: bool, as_json: bool) -> None:
2476
2482
  """Save governance state: ESDB backup, commit, and push.
2477
2483
 
2478
2484
  Combines ``specsmith esdb backup`` + ``specsmith commit`` + ``specsmith push``
@@ -2511,7 +2517,7 @@ def save_cmd(project_dir: str, message: str, no_push: bool, as_json: bool) -> No
2511
2517
 
2512
2518
  # 3. Push
2513
2519
  if not no_push:
2514
- push_result = run_push(root)
2520
+ push_result = run_push(root, force=force)
2515
2521
  steps.append({"step": "push", "ok": push_result.success, "message": push_result.message})
2516
2522
 
2517
2523
  ok = all(s["ok"] for s in steps)
@@ -2688,11 +2694,28 @@ def pr_cmd(project_dir: str, title: str, draft: bool) -> None:
2688
2694
 
2689
2695
  @main.command(name="pull")
2690
2696
  @click.option("--project-dir", type=click.Path(exists=True), default=".")
2691
- def pull_cmd(project_dir: str) -> None:
2692
- """Pull latest changes and check for governance conflicts."""
2693
- from specsmith.vcs_commands import run_sync
2697
+ @click.option(
2698
+ "--discard",
2699
+ is_flag=True,
2700
+ default=False,
2701
+ help="Hard-reset to remote and pull, discarding all local changes.",
2702
+ )
2703
+ @click.option(
2704
+ "--clean",
2705
+ is_flag=True,
2706
+ default=False,
2707
+ help="Like --discard but also removes untracked files (git clean -fd).",
2708
+ )
2709
+ def pull_cmd(project_dir: str, discard: bool, clean: bool) -> None:
2710
+ """Pull latest changes and check for governance conflicts.
2711
+
2712
+ Use --discard to hard-reset to the remote branch, discarding local
2713
+ changes. Add --clean to also remove untracked files.
2714
+ """
2715
+ from specsmith.vcs_commands import run_discard, run_sync
2694
2716
 
2695
- result = run_sync(Path(project_dir).resolve())
2717
+ root = Path(project_dir).resolve()
2718
+ result = run_discard(root, clean=clean) if discard or clean else run_sync(root)
2696
2719
  if result.success:
2697
2720
  console.print(f"[green]\u2713[/green] {result.message}")
2698
2721
  else:
@@ -4,6 +4,176 @@
4
4
  from specsmith.skills import SkillDomain, SkillEntry
5
5
 
6
6
  SKILLS: list[SkillEntry] = [
7
+ SkillEntry(
8
+ slug="github-actions-ci",
9
+ name="GitHub Actions CI — Layer1Labs pattern (zero-trust, parallel, coverage-gated)",
10
+ description=(
11
+ "Standard Layer1Labs GitHub Actions CI pattern: permissions: {} at workflow level, "
12
+ "per-job contents: read grants, parallel jobs (no needs chain), full Python matrix "
13
+ "3.10–3.13, and --cov-fail-under=85 coverage gate."
14
+ ),
15
+ domain=SkillDomain.DEVOPS,
16
+ tags=[
17
+ "ci",
18
+ "github-actions",
19
+ "permissions",
20
+ "pytest",
21
+ "coverage",
22
+ "ruff",
23
+ "mypy",
24
+ "security",
25
+ "python",
26
+ "matrix",
27
+ "zero-trust",
28
+ ],
29
+ platforms=["linux", "windows", "macos"],
30
+ prerequisites=["gh"],
31
+ body=(
32
+ """\
33
+ # GitHub Actions CI Skill (Layer1Labs pattern)
34
+
35
+ Standard CI pattern used across all Layer1Labs / BitConcepts Python projects.
36
+ Reference implementation: `chronomemory/.github/workflows/ci.yml`
37
+
38
+ ## Core principles
39
+ - `permissions: {}` at workflow level — deny all by default.
40
+ - `permissions: contents: read` on each individual job — grant minimum needed.
41
+ - All jobs run **in parallel** — no `needs:` dependency chain unless truly required.
42
+ - Full Python matrix: **3.10, 3.11, 3.12, 3.13** × ubuntu-latest, windows-latest.
43
+ - Coverage gate: `--cov-fail-under=85`.
44
+ - Named jobs (`name:` field) for readable GitHub UI.
45
+ - `fail-fast: false` on the test matrix so all combinations are reported.
46
+
47
+ ## Canonical template
48
+ ```yaml
49
+ name: CI
50
+
51
+ on:
52
+ push:
53
+ branches: [main, develop]
54
+ pull_request:
55
+ branches: [main, develop]
56
+ workflow_dispatch:
57
+
58
+ # Default: deny all. Each job grants only what it needs.
59
+ permissions: {}
60
+
61
+ jobs:
62
+ lint:
63
+ name: Lint (ruff)
64
+ runs-on: ubuntu-latest
65
+ permissions:
66
+ contents: read
67
+ steps:
68
+ - uses: actions/checkout@v6
69
+ - uses: actions/setup-python@v6
70
+ with:
71
+ python-version: "3.12"
72
+ cache: pip
73
+ - run: pip install ruff
74
+ - name: ruff format --check
75
+ run: ruff format --check src/ tests/
76
+ - name: ruff check
77
+ run: ruff check src/ tests/
78
+
79
+ typecheck:
80
+ name: Type check (mypy)
81
+ runs-on: ubuntu-latest
82
+ permissions:
83
+ contents: read
84
+ steps:
85
+ - uses: actions/checkout@v6
86
+ - uses: actions/setup-python@v6
87
+ with:
88
+ python-version: "3.12"
89
+ cache: pip
90
+ - run: pip install -e ".[dev]"
91
+ - run: mypy src/<package>/
92
+
93
+ test:
94
+ name: Test (Python ${{ matrix.python-version }} / ${{ matrix.os }})
95
+ runs-on: ${{ matrix.os }}
96
+ permissions:
97
+ contents: read
98
+ strategy:
99
+ fail-fast: false
100
+ matrix:
101
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
102
+ os: [ubuntu-latest, windows-latest]
103
+ steps:
104
+ - uses: actions/checkout@v6
105
+ - uses: actions/setup-python@v6
106
+ with:
107
+ python-version: ${{ matrix.python-version }}
108
+ cache: pip
109
+ - run: pip install -e ".[dev]"
110
+ - run: pytest --cov=<package> --cov-report=term-missing --cov-fail-under=85
111
+
112
+ security:
113
+ name: Security audit (pip-audit)
114
+ runs-on: ubuntu-latest
115
+ permissions:
116
+ contents: read
117
+ steps:
118
+ - uses: actions/checkout@v6
119
+ - uses: actions/setup-python@v6
120
+ with:
121
+ python-version: "3.12"
122
+ cache: pip
123
+ - run: pip install pip-audit
124
+ - run: pip install -e .
125
+ - run: pip-audit
126
+ ```
127
+
128
+ ## What NOT to do
129
+ - Do NOT set `permissions: contents: read` at workflow level — use `permissions: {}` + per-job grants.
130
+ - Do NOT use `needs: [lint, typecheck]` to gate the test job — run all in parallel.
131
+ - Do NOT omit Python 3.11 from the matrix.
132
+ - Do NOT skip `--cov-fail-under` — the 85% gate is non-negotiable.
133
+ - Do NOT use `cancel-in-progress: true` (concurrency block) unless there is a
134
+ specific reason — chronomemory pattern omits it.
135
+ - Do NOT use `macos-latest` in the matrix unless macOS-specific behavior must be
136
+ tested — it is ~10× slower and uses more CI minutes.
137
+
138
+ ## Rust projects (additional jobs)
139
+ ```yaml
140
+ rust-lint:
141
+ name: Rust lint (clippy + fmt)
142
+ runs-on: ubuntu-latest
143
+ permissions:
144
+ contents: read
145
+ steps:
146
+ - uses: actions/checkout@v6
147
+ - uses: dtolnay/rust-toolchain@stable
148
+ with:
149
+ components: clippy, rustfmt
150
+ - run: cargo fmt --check --all
151
+ - run: cargo clippy --workspace -- -D warnings
152
+
153
+ rust-test:
154
+ name: Rust tests
155
+ runs-on: ubuntu-latest
156
+ permissions:
157
+ contents: read
158
+ steps:
159
+ - uses: actions/checkout@v6
160
+ - uses: dtolnay/rust-toolchain@stable
161
+ - run: cargo test --workspace
162
+
163
+ security:
164
+ name: Security audit (cargo-audit)
165
+ runs-on: ubuntu-latest
166
+ permissions:
167
+ contents: read
168
+ steps:
169
+ - uses: actions/checkout@v6
170
+ - uses: dtolnay/rust-toolchain@stable
171
+ - run: cargo install cargo-audit --locked
172
+ - run: cargo audit
173
+ ```
174
+ """
175
+ ),
176
+ ),
7
177
  SkillEntry(
8
178
  slug="docker-workflow",
9
179
  name="Docker — multi-stage builds, Compose, registries, security",
@@ -0,0 +1,418 @@
1
+ # SPDX-License-Identifier: MIT
2
+ """Governance skills — project lifecycle, verification, review, and release."""
3
+
4
+ from specsmith.skills import SkillDomain, SkillEntry
5
+
6
+ SKILLS: list[SkillEntry] = [
7
+ SkillEntry(
8
+ slug="verifier",
9
+ name="Verifier — five-gate verification",
10
+ description=(
11
+ "Runs the standard five-gate loop: ruff, mypy, pytest, pip-audit, "
12
+ "and specsmith audit/validate. Halts at the first failing gate."
13
+ ),
14
+ domain=SkillDomain.GOVERNANCE,
15
+ tags=["verification", "ci", "python", "lint", "test", "security"],
16
+ project_types=["cli-python", "library-python", "backend-frontend"],
17
+ platforms=[],
18
+ prerequisites=["ruff", "mypy", "pytest", "pip-audit"],
19
+ body=(
20
+ "# Verifier Skill\n\n"
21
+ "## Purpose\n"
22
+ "Enforce a deterministic, ordered quality gate before any commit.\n\n"
23
+ "## Gates (run in strict order — halt at first failure)\n"
24
+ "1. `ruff check .` — zero lint errors.\n"
25
+ "2. `ruff format --check src tests` — zero format drift.\n"
26
+ "3. `mypy src/` — zero type errors.\n"
27
+ "4. `pytest -q --tb=short` — all tests green.\n"
28
+ "5. `pip-audit` — no known vulnerabilities.\n"
29
+ "6. `specsmith audit && specsmith validate --strict` — governance clean.\n\n"
30
+ "## Rules\n"
31
+ "- Never skip a gate. Never amend a commit to bypass failures.\n"
32
+ "- Surface the first failing gate's output verbatim in your response.\n"
33
+ "- If gate 6 fails with a sync-drift warning, run `specsmith sync` first.\n\n"
34
+ "## After all gates pass\n"
35
+ '```\nspecsmith ledger add "All gates passed — ready to commit"\n'
36
+ 'git add -A && git commit -m "<msg>"\n```\n'
37
+ ),
38
+ ),
39
+ SkillEntry(
40
+ slug="planner",
41
+ name="Planner — propose-then-execute",
42
+ description=(
43
+ "Forces the agent to emit a Plan block with explicit success criteria "
44
+ "before any tool call. Each step is gated on prior-step success."
45
+ ),
46
+ domain=SkillDomain.GOVERNANCE,
47
+ tags=["planning", "governance", "aee"],
48
+ prerequisites=[],
49
+ body=(
50
+ "# Planner Skill\n\n"
51
+ "## Purpose\n"
52
+ "Prevent surprise changes. All work must be planned before execution.\n\n"
53
+ "## Protocol\n"
54
+ "1. Emit a `Plan:` block listing each step with a measurable success criterion.\n"
55
+ "2. Wait for user confirmation (`safe` profile) or proceed (`yolo` profile).\n"
56
+ "3. Execute steps one at a time; update `status: done | failed` after each.\n"
57
+ "4. Never call tools outside the plan. If new work is discovered, amend the plan.\n"
58
+ "5. Log plan completion to LEDGER.md.\n\n"
59
+ "## Plan block format\n"
60
+ "```\nPlan:\n 1. [step] — success: [criterion]\n"
61
+ " 2. [step] — success: [criterion]\n```\n"
62
+ ),
63
+ ),
64
+ SkillEntry(
65
+ slug="diff-reviewer",
66
+ name="Diff Reviewer — surface changes for approval",
67
+ description=(
68
+ "Emits a diff block per changed file and waits for Accept/Reject "
69
+ "before committing. Rejected diffs feed the next retry."
70
+ ),
71
+ domain=SkillDomain.GOVERNANCE,
72
+ tags=["review", "diff", "governance", "approval"],
73
+ prerequisites=[],
74
+ body=(
75
+ "# Diff Reviewer Skill\n\n"
76
+ "## When to use\n"
77
+ "Any task that modifies source files, config, or governance docs.\n\n"
78
+ "## Protocol\n"
79
+ "1. Perform all changes in working tree (do not commit yet).\n"
80
+ "2. Run `git diff HEAD` and emit one fenced diff block per file.\n"
81
+ "3. Pause and wait for `accept` / `reject` / `comment` per diff.\n"
82
+ "4. For rejected diffs: revert that file, apply the comment as context, retry.\n"
83
+ "5. Only commit once every diff has been accepted.\n\n"
84
+ "## Rules\n"
85
+ "- Never auto-accept your own changes.\n"
86
+ "- Surface the full diff, not a summary. Summaries hide bugs.\n"
87
+ ),
88
+ ),
89
+ SkillEntry(
90
+ slug="onboarding-coach",
91
+ name="Onboarding Coach — guided first session",
92
+ description=(
93
+ "Walks a new user through the project: scaffold check, REQUIREMENTS "
94
+ "tour, AGENTS.md rules summary, and a suggested first action."
95
+ ),
96
+ domain=SkillDomain.GOVERNANCE,
97
+ tags=["onboarding", "documentation", "new-user"],
98
+ prerequisites=["specsmith"],
99
+ body=(
100
+ "# Onboarding Coach Skill\n\n"
101
+ "## Sequence\n"
102
+ "1. `specsmith doctor --onboarding` — surface any missing setup step.\n"
103
+ "2. Read `AGENTS.md`; summarise hard rules in ≤ 5 bullets.\n"
104
+ "3. Read `docs/REQUIREMENTS.md`; list top 5 P1 requirements.\n"
105
+ "4. `specsmith phase show` — report current AEE phase and readiness %.\n"
106
+ "5. Suggest one concrete preflight utterance the user can run next.\n\n"
107
+ "## Output format\n"
108
+ "```\n🌱 Phase: <phase> (<pct>% ready)\n"
109
+ "📋 Top requirements: ...\n📌 Rules: ...\n"
110
+ '→ Suggested next: specsmith preflight "..."\n```\n'
111
+ ),
112
+ ),
113
+ SkillEntry(
114
+ slug="release-pilot",
115
+ name="Release Pilot — gitflow release cut",
116
+ description=(
117
+ "Drives a full gitflow release: CI green check, version bump, "
118
+ "CHANGELOG entry, tag, and publish."
119
+ ),
120
+ domain=SkillDomain.GOVERNANCE,
121
+ tags=["release", "vcs", "gitflow", "automation", "pypi", "github"],
122
+ prerequisites=["gh", "git"],
123
+ body=(
124
+ "# Release Pilot Skill\n\n"
125
+ "## Preconditions (abort if any fail)\n"
126
+ "- `gh run list --branch develop --limit 1 --json conclusion` = `SUCCESS`.\n"
127
+ "- `gh pr list --state open --base main` returns 0 open PRs.\n"
128
+ "- `CHANGELOG.md` has the new version section already drafted.\n"
129
+ "- `specsmith audit && specsmith validate --strict` clean on develop.\n\n"
130
+ "## Sequence\n"
131
+ "1. Bump version: `specsmith release <version>`.\n"
132
+ "2. `git add -A && git commit -m 'release: v<version>'`.\n"
133
+ "3. Push develop: `git push origin develop`.\n"
134
+ "4. Wait for CI: `gh run watch`.\n"
135
+ "5. Merge to main: `git checkout main && git merge --ff-only develop`.\n"
136
+ "6. Tag: `git tag -a v<version> -m 'v<version>'`.\n"
137
+ "7. Push: `git push origin main --tags`.\n"
138
+ "8. Release workflow handles PyPI upload + GitHub Release automatically.\n\n"
139
+ "## Rollback\n"
140
+ "If step 7 fails: `git tag -d v<version> && git reset --hard HEAD~1`.\n"
141
+ ),
142
+ ),
143
+ SkillEntry(
144
+ slug="chronomemory-esdb",
145
+ name="ChronoMemory ESDB — epistemic state database (v0.1.1)",
146
+ description=(
147
+ "Full API reference and critical rules for chronomemory v0.1.1: "
148
+ "ChronoStore WAL, query module, ContextPackCompiler, DepGraph, "
149
+ "token metrics, skills system, and Rust acceleration."
150
+ ),
151
+ domain=SkillDomain.GOVERNANCE,
152
+ tags=[
153
+ "esdb",
154
+ "chronomemory",
155
+ "epistemics",
156
+ "wal",
157
+ "persistence",
158
+ "context-pack",
159
+ "query",
160
+ "dep-graph",
161
+ "rollback",
162
+ "token-metrics",
163
+ "aee",
164
+ "anti-hallucination",
165
+ ],
166
+ prerequisites=["chronomemory"],
167
+ body=(
168
+ """\
169
+ # ChronoMemory ESDB Skill (v0.1.1)
170
+
171
+ EpiStemic State Database for Layer1Labs agentic projects.
172
+ WAL at `<root>/.chronomemory/events.wal` — NDJSON, append-only, SHA-256 chained.
173
+
174
+ ## Imports
175
+ ```python
176
+ from chronomemory import (
177
+ ChronoStore, ChronoRecord, WalEvent, open_store, # Core
178
+ EsdbBridge, # Backward-compat bridge
179
+ DepGraph, DependencyEdge, # Phase 2: dep graph
180
+ RollbackReport, invalidate, # Phase 2: rollback
181
+ ContextPack, ContextPackCompiler, ContextPackEntry, # Phase 2: context packs
182
+ RustChronoStore, RustRecord, RUST_BACKEND, # Phase 3: Rust (optional)
183
+ )
184
+ from chronomemory import query # 18 ESDB §23 query functions
185
+ from chronomemory import metrics # token metrics + skill system
186
+
187
+ # Or via specsmith.esdb namespace (preferred within specsmith code):
188
+ from specsmith.esdb import ChronoStore, query, metrics, ContextPackCompiler
189
+ ```
190
+
191
+ ## Critical rules — never break these
192
+ 1. `dependencies = []` in pyproject.toml must stay empty — chronomemory is stdlib-only.
193
+ 2. Never physically delete WAL records — always `store.delete(id)` (tombstone only).
194
+ 3. Use `query.what_is_known(store)` not `store.query(rag_filter=True)` for LLM context
195
+ — the former excludes infra record kinds (edge, rollback_event, token_metric, skill_run).
196
+ 4. Governance status (`defined`/`implemented`) ≠ ESDB status (`active`/`tombstone`)
197
+ — never conflate when migrating from `.specsmith/*.json`.
198
+ 5. WAL is append-only NDJSON — one JSON object per line, SHA-256 chained.
199
+
200
+ ## Core write/read
201
+ ```python
202
+ with ChronoStore(project_root) as store:
203
+ store.upsert(ChronoRecord(
204
+ id="FACT-001", kind="fact",
205
+ label="CPSC projection is the sole validity authority",
206
+ source_type="observed", confidence=0.99,
207
+ evidence=["CPSC-Specification.md §9"],
208
+ ))
209
+ store.delete("OLD-001") # tombstone only — never physically removes
210
+ store.chain_valid() # verify SHA-256 WAL integrity
211
+
212
+ # For LLM context — always use query.what_is_known (rule #3)
213
+ with ChronoStore(project_root) as store:
214
+ beliefs = query.what_is_known(store) # active, conf>=0.6, no infra records
215
+ hypotheses = query.what_requires_reverification(store)
216
+ done = query.has_this_work_been_done(store, "migrate flat JSON")
217
+ ```
218
+
219
+ ## Backward-compat bridge
220
+ ```python
221
+ bridge = EsdbBridge(project_root)
222
+ bridge.status().backend # "ChronoStore WAL" or "json"
223
+ store.migrate_from_json(Path(project_root) / ".specsmith")
224
+ ```
225
+
226
+ ## Dependency graph
227
+ ```python
228
+ g = DepGraph(store=store)
229
+ g.add_edge("HYP-001", "FACT-001", "depends_on")
230
+ # Valid edge types: assumes contradicts depends_on derived_from
231
+ # generated_from invalidates supports supersedes validated_by
232
+ ```
233
+
234
+ ## Epistemic rollback
235
+ ```python
236
+ report = store.invalidate("FACT-001", "reason", dep_graph=g)
237
+ # Cascades depends_on/derived_from → status=hypothesis, confidence halved
238
+ ```
239
+
240
+ ## Context pack for LLM injection
241
+ ```python
242
+ pack = ContextPackCompiler(store).compile(
243
+ task_id="TASK-42", goal="fix ruff errors", token_budget=4096
244
+ )
245
+ context_json = pack.to_dict() # inject into LLM context
246
+ # Excludes: tombstone/invalidated/hypothesis, conf<0.6, infra kinds, over-budget
247
+ ```
248
+
249
+ ## Query API (18 functions — all degrade gracefully without dep_graph)
250
+ ```python
251
+ query.what_is_known(store) # active beliefs, no infra kinds
252
+ query.what_requires_reverification(store) # hypotheses needing confirmation
253
+ query.has_this_work_been_done(store, label) # bool — check prior decisions
254
+ query.why_do_we_believe(store, "FACT-001") # evidence chain for a record
255
+ query.what_skills_apply(store, "run lint") # skills matching task label
256
+ query.what_changed_since(store, seq) # records written after WAL seq N
257
+ query.what_confidence_collapsed(store, 0.6) # hypotheses below threshold
258
+ query.what_can_agent_do_next(store, goal) # unblocked action records
259
+ query.what_should_agent_not_do(store) # stop_condition records
260
+ query.is_this_action_duplicate(store, label) # alias for has_this_work_been_done
261
+ ```
262
+
263
+ ## Token metrics
264
+ ```python
265
+ metrics.record_token_metric(
266
+ store, task_id="TASK-1",
267
+ context_tokens=512, input_tokens=256, output_tokens=128,
268
+ tool_calls=4, elapsed_ms=1800, success=True,
269
+ )
270
+ metrics.token_efficiency_report(store) # {tokens_per_success, avg_tool_calls, ...}
271
+ ```
272
+
273
+ ## Skills system
274
+ ```python
275
+ # Register a skill
276
+ store.upsert(ChronoRecord(
277
+ id="SKILL-ruff", kind="skill", label="ruff linter", confidence=0.9,
278
+ data={"activation": ["lint", "ruff", "python"]},
279
+ ))
280
+ metrics.find_skills(store, "run ruff lint") # returns matching skill records
281
+ metrics.record_skill_run(store, "SKILL-ruff", # writes a skill_run WAL record
282
+ success=True, tokens_used=150, output={"errors": 0})
283
+ ```
284
+
285
+ ## Rust acceleration (Phase 3)
286
+ ```python
287
+ from chronomemory import RUST_BACKEND
288
+ # False by default — requires: pip install maturin
289
+ # maturin develop --manifest-path crates/chronomemory-py/Cargo.toml
290
+ # When True, RustChronoStore and RustRecord are available.
291
+ print("Rust backend:", RUST_BACKEND)
292
+ ```
293
+ """
294
+ ),
295
+ ),
296
+ SkillEntry(
297
+ slug="gh-ci-polling",
298
+ name="GitHub Actions CI polling — smart wait with gh CLI",
299
+ description=(
300
+ "Poll GitHub Actions CI using gh run watch or gh run list with JSON output. "
301
+ "Never use sleep-based waiting. Covers: wait for run, check latest run status, "
302
+ "tail failure logs, and poll a specific job."
303
+ ),
304
+ domain=SkillDomain.GOVERNANCE,
305
+ tags=[
306
+ "ci",
307
+ "github-actions",
308
+ "gh",
309
+ "polling",
310
+ "wait",
311
+ "workflow",
312
+ "devops",
313
+ ],
314
+ prerequisites=["gh"],
315
+ body=(
316
+ """\
317
+ # GitHub Actions CI Polling Skill
318
+
319
+ ## Rule: NEVER sleep-wait for CI
320
+ Do NOT use `Start-Sleep`, `sleep`, `time.sleep`, or any fixed delay to wait
321
+ for CI. Always use `gh run watch` or poll with `gh run list --json`.
322
+
323
+ ## 1. Wait for the most recent run on a branch to complete
324
+ ```bash
325
+ # Blocks until the latest run finishes, then exits 0 (pass) or non-zero (fail)
326
+ gh run watch --repo <owner>/<repo> $(gh run list --repo <owner>/<repo> --branch <branch> --limit 1 --json databaseId --jq '.[0].databaseId')
327
+ ```
328
+ ```pwsh
329
+ # PowerShell equivalent
330
+ $runId = gh run list --repo <owner>/<repo> --branch <branch> --limit 1 --json databaseId | ConvertFrom-Json | Select-Object -ExpandProperty databaseId
331
+ gh run watch --repo <owner>/<repo> $runId
332
+ ```
333
+
334
+ ## 2. Check status of the latest N runs (non-blocking)
335
+ ```bash
336
+ gh run list --repo <owner>/<repo> --limit 3 --branch <branch>
337
+ # STATUS column: ✓ = success X = failure * = in_progress - = queued
338
+ ```
339
+
340
+ ## 3. Check if latest run is complete and passed (scripted)
341
+ ```bash
342
+ status=$(gh run list --repo <owner>/<repo> --branch <branch> --limit 1 --json conclusion --jq '.[0].conclusion')
343
+ echo "Conclusion: $status" # success | failure | cancelled | ""
344
+ # Empty string = still running
345
+ ```
346
+ ```pwsh
347
+ $status = gh run list --repo <owner>/<repo> --branch <branch> --limit 1 --json conclusion | ConvertFrom-Json | Select-Object -ExpandProperty conclusion
348
+ ```
349
+
350
+ ## 4. Poll until complete (manual loop — use only when gh run watch unavailable)
351
+ ```bash
352
+ while true; do
353
+ status=$(gh run list --repo <owner>/<repo> --branch <branch> --limit 1 --json status,conclusion --jq '.[0]')
354
+ running=$(echo $status | jq -r '.status')
355
+ conclusion=$(echo $status | jq -r '.conclusion')
356
+ if [ "$running" != "in_progress" ] && [ "$running" != "queued" ]; then
357
+ echo "Done: $conclusion"; break
358
+ fi
359
+ echo "Still running ($running)..."
360
+ sleep 15 # Only acceptable here — inside an explicit polling loop with state check
361
+ done
362
+ ```
363
+
364
+ ## 5. View failure logs immediately
365
+ ```bash
366
+ # Show only the failed step logs for the latest run
367
+ gh run view --repo <owner>/<repo> --log-failed $(gh run list --repo <owner>/<repo> --branch <branch> --limit 1 --json databaseId --jq '.[0].databaseId')
368
+ ```
369
+
370
+ ## 6. Watch a specific run ID
371
+ ```bash
372
+ gh run watch --repo <owner>/<repo> <run-id> # blocks, streams progress
373
+ gh run view --repo <owner>/<repo> <run-id> # snapshot of current state
374
+ gh run view --repo <owner>/<repo> <run-id> --log-failed # failure logs only
375
+ ```
376
+
377
+ ## Extracting run IDs after a push
378
+ ```bash
379
+ # Get the run triggered by the most recent push
380
+ gh run list --repo <owner>/<repo> --branch <branch> --limit 1 --json databaseId,status,name
381
+ ```
382
+
383
+ ## Key rules
384
+ - `gh run watch` is the correct primitive — it polls internally and exits when done.
385
+ - Never substitute `sleep N; gh run list` for `gh run watch`.
386
+ - If `gh run watch` is unavailable (older gh version), use the polling loop in §4
387
+ with a minimum 15-second interval and an explicit status check, NOT a fixed sleep.
388
+ - Always check `conclusion` (not just `status`) to determine pass/fail.
389
+ `status=completed` with `conclusion=failure` is a failure.
390
+ """
391
+ ),
392
+ ),
393
+ SkillEntry(
394
+ slug="issue-triage",
395
+ name="Issue Triage — classify and prioritise GitHub issues",
396
+ description=(
397
+ "Reads open GitHub issues, deduplicates, labels by type/severity, "
398
+ "and produces a prioritised action list."
399
+ ),
400
+ domain=SkillDomain.GOVERNANCE,
401
+ tags=["github", "issues", "triage", "project-management"],
402
+ prerequisites=["gh", "specsmith"],
403
+ body=(
404
+ "# Issue Triage Skill\n\n"
405
+ "## Sequence\n"
406
+ "1. `gh issue list --state open --limit 100 --json number,title,labels,createdAt`\n"
407
+ "2. Group by type: bug / enhancement / question / docs.\n"
408
+ "3. Detect duplicates: flag issues with >60% title-word overlap.\n"
409
+ "4. Score severity: crash/data-loss = P0; broken feature = P1;"
410
+ " UX = P2; nice-to-have = P3.\n"
411
+ "5. Emit a prioritised table: `| # | Title | Type | Severity | Duplicate of |`\n"
412
+ "6. Ask: 'Which should I implement first this session?'\n\n"
413
+ "## Rules\n"
414
+ "- Never close an issue without fixing it or explicitly marking as won't-fix.\n"
415
+ "- Link PRs: `gh issue develop <number> --checkout` creates a fix branch.\n"
416
+ ),
417
+ ),
418
+ ]