misterdev 0.2.2__tar.gz → 0.3.1__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 (322) hide show
  1. {misterdev-0.2.2/misterdev.egg-info → misterdev-0.3.1}/PKG-INFO +22 -2
  2. {misterdev-0.2.2 → misterdev-0.3.1}/README.md +21 -1
  3. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/__init__.py +1 -1
  4. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/agent.py +186 -39
  5. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/project_analyzer/__init__.py +2 -0
  6. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/project_analyzer/detection.py +104 -0
  7. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/config.py +37 -5
  8. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/__init__.py +14 -0
  9. misterdev-0.3.1/misterdev/core/context/contracts/c_tree_sitter.py +183 -0
  10. misterdev-0.3.1/misterdev/core/context/contracts/cpp_tree_sitter.py +344 -0
  11. misterdev-0.3.1/misterdev/core/context/contracts/csharp_tree_sitter.py +191 -0
  12. misterdev-0.3.1/misterdev/core/context/contracts/extraction.py +68 -0
  13. misterdev-0.3.1/misterdev/core/context/contracts/javascript_tree_sitter.py +198 -0
  14. misterdev-0.3.1/misterdev/core/context/contracts/kotlin_tree_sitter.py +272 -0
  15. misterdev-0.3.1/misterdev/core/context/contracts/swift_tree_sitter.py +256 -0
  16. misterdev-0.3.1/misterdev/core/context/contracts/typescript_tree_sitter.py +377 -0
  17. misterdev-0.3.1/misterdev/core/context/guidance/__init__.py +137 -0
  18. misterdev-0.3.1/misterdev/core/context/guidance/_rules.py +51 -0
  19. misterdev-0.3.1/misterdev/core/context/guidance/cpp.py +78 -0
  20. misterdev-0.3.1/misterdev/core/context/guidance/csharp.py +103 -0
  21. misterdev-0.3.1/misterdev/core/context/guidance/css.py +133 -0
  22. misterdev-0.3.1/misterdev/core/context/guidance/elixir.py +92 -0
  23. misterdev-0.3.1/misterdev/core/context/guidance/html.py +91 -0
  24. misterdev-0.3.1/misterdev/core/context/guidance/kotlin.py +119 -0
  25. misterdev-0.3.1/misterdev/core/context/guidance/python.py +110 -0
  26. misterdev-0.3.1/misterdev/core/context/guidance/react.py +98 -0
  27. misterdev-0.3.1/misterdev/core/context/guidance/rust.py +208 -0
  28. misterdev-0.3.1/misterdev/core/context/guidance/swift.py +104 -0
  29. misterdev-0.3.1/misterdev/core/context/guidance/typescript.py +97 -0
  30. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/lsp.py +49 -0
  31. misterdev-0.3.1/misterdev/core/context/lsp_swift.py +412 -0
  32. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/__init__.py +1 -2
  33. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/cache.py +1 -1
  34. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/graph.py +93 -8
  35. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/nodes.py +12 -4
  36. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/context_budget.py +4 -0
  37. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/model_selector.py +9 -3
  38. misterdev-0.3.1/misterdev/core/evolution/__init__.py +54 -0
  39. misterdev-0.3.1/misterdev/core/evolution/__main__.py +161 -0
  40. misterdev-0.3.1/misterdev/core/evolution/adapters.py +295 -0
  41. misterdev-0.3.1/misterdev/core/evolution/archive.py +158 -0
  42. misterdev-0.3.1/misterdev/core/evolution/attribution.py +92 -0
  43. misterdev-0.3.1/misterdev/core/evolution/driver.py +293 -0
  44. misterdev-0.3.1/misterdev/core/evolution/fitness.py +96 -0
  45. misterdev-0.3.1/misterdev/core/evolution/guardrail.py +81 -0
  46. misterdev-0.3.1/misterdev/core/evolution/holdout.py +103 -0
  47. misterdev-0.3.1/misterdev/core/evolution/loop.py +172 -0
  48. misterdev-0.3.1/misterdev/core/evolution/prior.py +84 -0
  49. misterdev-0.3.1/misterdev/core/evolution/proposer.py +181 -0
  50. misterdev-0.3.1/misterdev/core/evolution/sandbox.py +79 -0
  51. misterdev-0.3.1/misterdev/core/evolution/screen.py +149 -0
  52. misterdev-0.3.1/misterdev/core/evolution/tool_library.py +184 -0
  53. misterdev-0.3.1/misterdev/core/execution/compile_view.py +118 -0
  54. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/error_classifier.py +8 -6
  55. misterdev-0.3.1/misterdev/core/execution/error_log_compressor.py +135 -0
  56. misterdev-0.3.1/misterdev/core/execution/failure_view.py +433 -0
  57. misterdev-0.3.1/misterdev/core/execution/governance.py +403 -0
  58. misterdev-0.3.1/misterdev/core/execution/probe.py +178 -0
  59. misterdev-0.3.1/misterdev/core/learning/__init__.py +31 -0
  60. misterdev-0.3.1/misterdev/core/learning/failure_log.py +289 -0
  61. misterdev-0.3.1/misterdev/core/learning/failure_taxonomy.py +146 -0
  62. misterdev-0.3.1/misterdev/core/learning/reproduction.py +213 -0
  63. misterdev-0.3.1/misterdev/core/learning/targeting.py +103 -0
  64. misterdev-0.3.1/misterdev/core/learning/warm_start.py +204 -0
  65. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/assessment.py +1 -0
  66. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/decomposer.py +16 -2
  67. misterdev-0.3.1/misterdev/core/planning/lesson_store.py +407 -0
  68. misterdev-0.3.1/misterdev/core/planning/metacognition.py +111 -0
  69. misterdev-0.3.1/misterdev/core/planning/verifier_decomposition.py +357 -0
  70. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/reporting/report.py +31 -0
  71. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/gatekeeper/__init__.py +37 -2
  72. misterdev-0.3.1/misterdev/core/verification/reflection.py +105 -0
  73. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/spec_tests.py +10 -2
  74. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/base.py +54 -3
  75. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/commands_mixin.py +20 -7
  76. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/critic_spec_mixin.py +78 -21
  77. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/edits_mixin.py +10 -2
  78. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/execute_mixin.py +141 -8
  79. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/gates_mixin.py +175 -10
  80. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/helpers.py +67 -9
  81. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/__init__.py +3 -1
  82. misterdev-0.3.1/misterdev/tools/dependency.py +68 -0
  83. {misterdev-0.2.2 → misterdev-0.3.1/misterdev.egg-info}/PKG-INFO +22 -2
  84. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev.egg-info/SOURCES.txt +108 -1
  85. {misterdev-0.2.2 → misterdev-0.3.1}/pyproject.toml +4 -0
  86. misterdev-0.3.1/tests/test_audit_gate.py +104 -0
  87. misterdev-0.3.1/tests/test_compile_view.py +57 -0
  88. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_contracts.py +1 -1
  89. misterdev-0.3.1/tests/test_contracts_c.py +71 -0
  90. misterdev-0.3.1/tests/test_contracts_cpp.py +196 -0
  91. misterdev-0.3.1/tests/test_contracts_csharp_ts.py +69 -0
  92. misterdev-0.3.1/tests/test_contracts_javascript.py +82 -0
  93. misterdev-0.3.1/tests/test_contracts_kotlin.py +142 -0
  94. misterdev-0.3.1/tests/test_contracts_swift.py +169 -0
  95. misterdev-0.3.1/tests/test_contracts_typescript.py +200 -0
  96. misterdev-0.3.1/tests/test_dependency_tool.py +61 -0
  97. misterdev-0.3.1/tests/test_detect_lint_deps.py +91 -0
  98. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_error_classifier.py +3 -1
  99. misterdev-0.3.1/tests/test_error_log_compressor.py +90 -0
  100. misterdev-0.3.1/tests/test_evolution_adapters.py +99 -0
  101. misterdev-0.3.1/tests/test_evolution_archive.py +89 -0
  102. misterdev-0.3.1/tests/test_evolution_attribution.py +73 -0
  103. misterdev-0.3.1/tests/test_evolution_driver.py +194 -0
  104. misterdev-0.3.1/tests/test_evolution_fitness.py +68 -0
  105. misterdev-0.3.1/tests/test_evolution_guardrail.py +54 -0
  106. misterdev-0.3.1/tests/test_evolution_holdout.py +95 -0
  107. misterdev-0.3.1/tests/test_evolution_holdout_wiring.py +98 -0
  108. misterdev-0.3.1/tests/test_evolution_loop.py +152 -0
  109. misterdev-0.3.1/tests/test_evolution_prior.py +49 -0
  110. misterdev-0.3.1/tests/test_evolution_proposer.py +124 -0
  111. misterdev-0.3.1/tests/test_evolution_sandbox.py +107 -0
  112. misterdev-0.3.1/tests/test_evolution_screen.py +125 -0
  113. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_executor.py +163 -1
  114. misterdev-0.3.1/tests/test_failure_log.py +155 -0
  115. misterdev-0.3.1/tests/test_failure_targeting.py +66 -0
  116. misterdev-0.3.1/tests/test_failure_taxonomy.py +81 -0
  117. misterdev-0.3.1/tests/test_failure_view.py +235 -0
  118. misterdev-0.3.1/tests/test_gates_error_context.py +66 -0
  119. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_governance.py +56 -0
  120. misterdev-0.3.1/tests/test_grounded_spec.py +82 -0
  121. misterdev-0.3.1/tests/test_guidance.py +47 -0
  122. misterdev-0.3.1/tests/test_guidance_cpp.py +37 -0
  123. misterdev-0.3.1/tests/test_guidance_csharp.py +28 -0
  124. misterdev-0.3.1/tests/test_guidance_css.py +29 -0
  125. misterdev-0.3.1/tests/test_guidance_elixir.py +31 -0
  126. misterdev-0.3.1/tests/test_guidance_html.py +32 -0
  127. misterdev-0.3.1/tests/test_guidance_kotlin.py +33 -0
  128. misterdev-0.3.1/tests/test_guidance_python.py +33 -0
  129. misterdev-0.3.1/tests/test_guidance_react.py +37 -0
  130. misterdev-0.3.1/tests/test_guidance_rust.py +47 -0
  131. misterdev-0.3.1/tests/test_guidance_swift.py +29 -0
  132. misterdev-0.3.1/tests/test_guidance_typescript.py +33 -0
  133. misterdev-0.3.1/tests/test_learning_semantic.py +135 -0
  134. misterdev-0.3.1/tests/test_lesson_efficacy.py +146 -0
  135. misterdev-0.3.1/tests/test_lesson_store.py +146 -0
  136. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_llm_client.py +13 -0
  137. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_lsp.py +0 -20
  138. misterdev-0.3.1/tests/test_lsp_context.py +52 -0
  139. misterdev-0.3.1/tests/test_lsp_integration.py +72 -0
  140. misterdev-0.3.1/tests/test_lsp_swift.py +155 -0
  141. misterdev-0.3.1/tests/test_metacognition.py +94 -0
  142. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_model_selector.py +19 -1
  143. misterdev-0.3.1/tests/test_native_harness.py +148 -0
  144. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_orchestrator_fixes.py +4 -3
  145. misterdev-0.3.1/tests/test_polyglot_harness.py +190 -0
  146. misterdev-0.3.1/tests/test_probe.py +150 -0
  147. misterdev-0.3.1/tests/test_reflection.py +54 -0
  148. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_report.py +54 -0
  149. misterdev-0.3.1/tests/test_reproduction_corpus.py +104 -0
  150. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_spec_tests.py +145 -4
  151. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_swebench_harness.py +4 -0
  152. misterdev-0.3.1/tests/test_tool_library.py +165 -0
  153. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_topography.py +85 -1
  154. misterdev-0.3.1/tests/test_verifier_decomposition.py +223 -0
  155. misterdev-0.3.1/tests/test_wiring_probe_staging.py +126 -0
  156. misterdev-0.2.2/misterdev/core/context/contracts/extraction.py +0 -30
  157. misterdev-0.2.2/misterdev/core/execution/governance.py +0 -283
  158. misterdev-0.2.2/misterdev/core/planning/metacognition.py +0 -103
  159. misterdev-0.2.2/tests/test_metacognition.py +0 -116
  160. {misterdev-0.2.2 → misterdev-0.3.1}/COMMERCIAL_LICENSE.md +0 -0
  161. {misterdev-0.2.2 → misterdev-0.3.1}/LICENSE +0 -0
  162. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/agent_helpers.py +0 -0
  163. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/__init__.py +0 -0
  164. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/project_analyzer/merge.py +0 -0
  165. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/project_analyzer/overview.py +0 -0
  166. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/analyzers/project_analyzer/prompts.py +0 -0
  167. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/cli.py +0 -0
  168. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/__init__.py +0 -0
  169. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/audit.py +0 -0
  170. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/config.py +0 -0
  171. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/__init__.py +0 -0
  172. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/change_tracker.py +0 -0
  173. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/_log.py +0 -0
  174. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/_text.py +0 -0
  175. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/python_generic.py +0 -0
  176. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/registry.py +0 -0
  177. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/rust_line.py +0 -0
  178. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/contracts/rust_tree_sitter.py +0 -0
  179. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/scratchpad.py +0 -0
  180. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/_log.py +0 -0
  181. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/engine.py +0 -0
  182. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/parsers.py +0 -0
  183. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/context/topography/syntax.py +0 -0
  184. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/__init__.py +0 -0
  185. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/embeddings.py +0 -0
  186. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/free_models.py +0 -0
  187. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/llm_cache.py +0 -0
  188. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/model_catalog.py +0 -0
  189. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/economics/model_ledger.py +0 -0
  190. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/__init__.py +0 -0
  191. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/bounded.py +0 -0
  192. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/container.py +0 -0
  193. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/error_resolver.py +0 -0
  194. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/outcomes.py +0 -0
  195. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/progress.py +0 -0
  196. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/project.py +0 -0
  197. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/registry.py +0 -0
  198. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/execution/runtime.py +0 -0
  199. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/gitcmd.py +0 -0
  200. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/integration/__init__.py +0 -0
  201. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/integration/mcp.py +0 -0
  202. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/integration/mcp_gather.py +0 -0
  203. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/models.py +0 -0
  204. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/modes.py +0 -0
  205. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/__init__.py +0 -0
  206. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/advisor.py +0 -0
  207. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/sovereign.py +0 -0
  208. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/planning/targets.py +0 -0
  209. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/reporting/__init__.py +0 -0
  210. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/reporting/report_view.py +0 -0
  211. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/task.py +0 -0
  212. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/__init__.py +0 -0
  213. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/claim_verifier.py +0 -0
  214. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/critic.py +0 -0
  215. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/gatekeeper/constants.py +0 -0
  216. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/gatekeeper/helpers.py +0 -0
  217. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/goal_check.py +0 -0
  218. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/independent.py +0 -0
  219. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/mutation_gate.py +0 -0
  220. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/preflight.py +0 -0
  221. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/validator.py +0 -0
  222. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/vision_verify.py +0 -0
  223. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/core/verification/web_verify.py +0 -0
  224. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/environments/__init__.py +0 -0
  225. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/environments/base_env.py +0 -0
  226. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/environments/container_env.py +0 -0
  227. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/environments/venv_env.py +0 -0
  228. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/__init__.py +0 -0
  229. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/__init__.py +0 -0
  230. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/edits.py +0 -0
  231. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/embeddings.py +0 -0
  232. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/errors.py +0 -0
  233. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/providers.py +0 -0
  234. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/client/response.py +0 -0
  235. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/prompt_manager.py +0 -0
  236. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/responses/__init__.py +0 -0
  237. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/responses/apply.py +0 -0
  238. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/responses/json_extract.py +0 -0
  239. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/responses/models.py +0 -0
  240. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/llm/responses/parsing.py +0 -0
  241. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/logging_setup.py +0 -0
  242. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/mcp_server.py +0 -0
  243. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/nl_cli.py +0 -0
  244. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/plugins.py +0 -0
  245. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/py.typed +0 -0
  246. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/__init__.py +0 -0
  247. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/base_executor.py +0 -0
  248. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/__init__.py +0 -0
  249. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/context_mixin.py +0 -0
  250. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/git_mixin.py +0 -0
  251. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/llm_mixin.py +0 -0
  252. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/task_executors/markdown_plan_executor/results_mixin.py +0 -0
  253. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/base_tool.py +0 -0
  254. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/command.py +0 -0
  255. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/file_io.py +0 -0
  256. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/formatter.py +0 -0
  257. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/tools/git_tool.py +0 -0
  258. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/utils/__init__.py +0 -0
  259. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/utils/file_utils.py +0 -0
  260. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev/utils/process.py +0 -0
  261. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev.egg-info/dependency_links.txt +0 -0
  262. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev.egg-info/entry_points.txt +0 -0
  263. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev.egg-info/requires.txt +0 -0
  264. {misterdev-0.2.2 → misterdev-0.3.1}/misterdev.egg-info/top_level.txt +0 -0
  265. {misterdev-0.2.2 → misterdev-0.3.1}/setup.cfg +0 -0
  266. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_advisor.py +0 -0
  267. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_agent_helpers.py +0 -0
  268. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_assessment.py +0 -0
  269. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_audit.py +0 -0
  270. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_bounded.py +0 -0
  271. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_budget_halt.py +0 -0
  272. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_change_tracker.py +0 -0
  273. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_claim_verifier.py +0 -0
  274. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_command_tool.py +0 -0
  275. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_config.py +0 -0
  276. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_container.py +0 -0
  277. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_context_budget.py +0 -0
  278. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_critic.py +0 -0
  279. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_decomposer.py +0 -0
  280. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_dynamic_model_integration.py +0 -0
  281. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_embeddings.py +0 -0
  282. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_error_resolver.py +0 -0
  283. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_executor_git.py +0 -0
  284. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_extensibility.py +0 -0
  285. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_file_utils.py +0 -0
  286. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_free_models.py +0 -0
  287. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_gatekeeper.py +0 -0
  288. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_gitcmd.py +0 -0
  289. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_goal_check.py +0 -0
  290. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_goal_check_wiring.py +0 -0
  291. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_hms_integration.py +0 -0
  292. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_independent.py +0 -0
  293. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_integration_gate_count.py +0 -0
  294. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_llm_cache.py +0 -0
  295. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_mcp.py +0 -0
  296. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_mcp_remote.py +0 -0
  297. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_mcp_server.py +0 -0
  298. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_model_catalog.py +0 -0
  299. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_model_ledger.py +0 -0
  300. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_modes.py +0 -0
  301. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_mutation_gate.py +0 -0
  302. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_nl_cli.py +0 -0
  303. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_orchestrator_config.py +0 -0
  304. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_outcomes.py +0 -0
  305. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_plugins.py +0 -0
  306. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_preflight.py +0 -0
  307. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_process.py +0 -0
  308. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_progress.py +0 -0
  309. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_prompt_manager.py +0 -0
  310. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_registry.py +0 -0
  311. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_report_view.py +0 -0
  312. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_responses.py +0 -0
  313. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_runtime.py +0 -0
  314. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_scratchpad.py +0 -0
  315. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_security.py +0 -0
  316. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_sovereign.py +0 -0
  317. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_targets.py +0 -0
  318. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_task_manager.py +0 -0
  319. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_topography_cache.py +0 -0
  320. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_validator.py +0 -0
  321. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_vision_verify.py +0 -0
  322. {misterdev-0.2.2 → misterdev-0.3.1}/tests/test_web_verify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: misterdev
3
- Version: 0.2.2
3
+ Version: 0.3.1
4
4
  Summary: An autonomous, extensible LLM build orchestrator that plans, edits, and verifies code across languages.
5
5
  Author-email: David Condrey <david@writerslogic.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -138,12 +138,20 @@ Every change runs through an ordered gate sequence: **build → lint → tests
138
138
 
139
139
  ### Dynamic model selection
140
140
 
141
- misterdev keeps a per-model **performance ledger** and pairs it with a **cost-aware selector** that picks for quality-per-dollar, **harvests free models** where they hold up, and caches responses to avoid paying twice. It runs against **OpenRouter or Anthropic** with automatic failover, and token budgeting keeps spend inside the ceiling you set.
141
+ misterdev keeps a per-model **performance ledger** and pairs it with a **cost-aware selector** that picks for quality-per-dollar across the **full breadth of OpenRouter** routing each task up a **capability ladder** (harvested free / cheap → a strong mid-tier → a frontier tier) and **escalating to a stronger model only when a cheaper one can't clear the gates**. The strongest tier is reserved for the final attempt, so frontier spend is the rare safety net, not the default; a hard task that a mid model stalls on is finished by a frontier model, while easy tasks resolve on free/cheap ones. Quality never drops because a weak model that writes bad code fails the gate and the policy climbs. It runs against **OpenRouter or Anthropic** with automatic failover, caches responses to avoid paying twice, and token budgeting keeps spend inside the ceiling you set.
142
142
 
143
143
  ### Parallel worktrees
144
144
 
145
145
  Disjoint tasks run concurrently, each in its own **isolated git worktree**, so independent work doesn't contend for the tree. An **integration gate** re-checks each wave against the full suite and reverts any task that regresses it — parallelism without cross-contamination.
146
146
 
147
+ ### Self-improving
148
+
149
+ misterdev keeps a durable, fingerprinted stream of its own real failures and runs an **AlphaEvolve-style keep-if-better loop** over its own source: it attributes what breaks, classifies *why* (harness artifact vs observation gap vs capability), proposes a targeted structural self-edit, and promotes it only when it beats the champion on a **held-out task set it never optimized against** — with zero regressions. A reward-hacking guardrail walls off the tests and benchmark. The result is a loop that removes whole failure classes over time **without overfitting** to any one benchmark. See [docs/path-to-100.md](docs/path-to-100.md).
150
+
151
+ On the correctness side, misterdev works **reproduction-first**: for an issue-driven task it synthesizes a failing test from the acceptance criteria, **validates that the test actually fails on the clean tree** (a test that reproduces nothing is discarded rather than trusted), then drives the fix to turn it green — so the model edits toward a concrete, verified target instead of a description.
152
+
153
+ **Two-timescale evolution** *(design; see [docs/two-timescale-evolution.md](docs/two-timescale-evolution.md))* takes the self-improvement further than a memoryless runtime agent can: the agent invents task-specific tools at runtime, and the ones that **prove they generalize** are consolidated — through the same held-out promotion gate — into a **persistent, best-per-capability tool library that future runs start from**. Fast loop explores; slow loop keeps the winners; the held-out gate keeps the library general rather than benchmark-overfit. Capability compounds across runs instead of being reinvented each task.
154
+
147
155
  ### Extensibility
148
156
 
149
157
  Tools, gates, and targets **self-register through Python entry points**. `pip install misterdev-plugin-x` adds a capability with **zero edits to the core** — misterdev discovers the entry point at runtime and wires it in. A working example lives at [`examples/misterdev-plugin-hello`](examples/misterdev-plugin-hello). See [Extending misterdev](#extending-misterdev).
@@ -152,6 +160,18 @@ Tools, gates, and targets **self-register through Python entry points**. `pip in
152
160
 
153
161
  misterdev can connect to **Model Context Protocol** servers and let the model call their discovered tools mid-build — bounded, opt-in, and constrained by a tool allowlist. Transports include stdio and **remote streamable-http with auth**, so you can point it at a hosted MCP gateway like **Glama** and give the build access to a whole catalog of tools without running any of them locally.
154
162
 
163
+ ## Benchmarks
164
+
165
+ Gate-verified pass@1 on [Aider's polyglot benchmark](https://github.com/Aider-AI/polyglot-benchmark) (Exercism exercises with hidden test suites), `anthropic/claude-sonnet-4-6`:
166
+
167
+ | Language | Solved | Rate |
168
+ | --- | --- | --- |
169
+ | JavaScript | 9 / 10 | **90%** |
170
+ | Python | 8 / 10 | **80%** |
171
+ | Rust | 7 / 10 | **70%** |
172
+
173
+ A continuous stress run has solved **20/20** across the three languages with zero failures — including the exercises usually cited as hard (bowling, forth, arbitrary-precision decimal). Every solve is judged by the exercise's own hidden tests, not the model's say-so. Full numbers, methodology, and how to reproduce: **[docs/benchmark-results.md](docs/benchmark-results.md)**. Test suite: **1,897 passing** — **[docs/TESTING.md](docs/TESTING.md)**.
174
+
155
175
  ## CLI reference
156
176
 
157
177
  **Don't want to remember flags?** If the first argument isn't a subcommand,
@@ -85,12 +85,20 @@ Every change runs through an ordered gate sequence: **build → lint → tests
85
85
 
86
86
  ### Dynamic model selection
87
87
 
88
- misterdev keeps a per-model **performance ledger** and pairs it with a **cost-aware selector** that picks for quality-per-dollar, **harvests free models** where they hold up, and caches responses to avoid paying twice. It runs against **OpenRouter or Anthropic** with automatic failover, and token budgeting keeps spend inside the ceiling you set.
88
+ misterdev keeps a per-model **performance ledger** and pairs it with a **cost-aware selector** that picks for quality-per-dollar across the **full breadth of OpenRouter** routing each task up a **capability ladder** (harvested free / cheap → a strong mid-tier → a frontier tier) and **escalating to a stronger model only when a cheaper one can't clear the gates**. The strongest tier is reserved for the final attempt, so frontier spend is the rare safety net, not the default; a hard task that a mid model stalls on is finished by a frontier model, while easy tasks resolve on free/cheap ones. Quality never drops because a weak model that writes bad code fails the gate and the policy climbs. It runs against **OpenRouter or Anthropic** with automatic failover, caches responses to avoid paying twice, and token budgeting keeps spend inside the ceiling you set.
89
89
 
90
90
  ### Parallel worktrees
91
91
 
92
92
  Disjoint tasks run concurrently, each in its own **isolated git worktree**, so independent work doesn't contend for the tree. An **integration gate** re-checks each wave against the full suite and reverts any task that regresses it — parallelism without cross-contamination.
93
93
 
94
+ ### Self-improving
95
+
96
+ misterdev keeps a durable, fingerprinted stream of its own real failures and runs an **AlphaEvolve-style keep-if-better loop** over its own source: it attributes what breaks, classifies *why* (harness artifact vs observation gap vs capability), proposes a targeted structural self-edit, and promotes it only when it beats the champion on a **held-out task set it never optimized against** — with zero regressions. A reward-hacking guardrail walls off the tests and benchmark. The result is a loop that removes whole failure classes over time **without overfitting** to any one benchmark. See [docs/path-to-100.md](docs/path-to-100.md).
97
+
98
+ On the correctness side, misterdev works **reproduction-first**: for an issue-driven task it synthesizes a failing test from the acceptance criteria, **validates that the test actually fails on the clean tree** (a test that reproduces nothing is discarded rather than trusted), then drives the fix to turn it green — so the model edits toward a concrete, verified target instead of a description.
99
+
100
+ **Two-timescale evolution** *(design; see [docs/two-timescale-evolution.md](docs/two-timescale-evolution.md))* takes the self-improvement further than a memoryless runtime agent can: the agent invents task-specific tools at runtime, and the ones that **prove they generalize** are consolidated — through the same held-out promotion gate — into a **persistent, best-per-capability tool library that future runs start from**. Fast loop explores; slow loop keeps the winners; the held-out gate keeps the library general rather than benchmark-overfit. Capability compounds across runs instead of being reinvented each task.
101
+
94
102
  ### Extensibility
95
103
 
96
104
  Tools, gates, and targets **self-register through Python entry points**. `pip install misterdev-plugin-x` adds a capability with **zero edits to the core** — misterdev discovers the entry point at runtime and wires it in. A working example lives at [`examples/misterdev-plugin-hello`](examples/misterdev-plugin-hello). See [Extending misterdev](#extending-misterdev).
@@ -99,6 +107,18 @@ Tools, gates, and targets **self-register through Python entry points**. `pip in
99
107
 
100
108
  misterdev can connect to **Model Context Protocol** servers and let the model call their discovered tools mid-build — bounded, opt-in, and constrained by a tool allowlist. Transports include stdio and **remote streamable-http with auth**, so you can point it at a hosted MCP gateway like **Glama** and give the build access to a whole catalog of tools without running any of them locally.
101
109
 
110
+ ## Benchmarks
111
+
112
+ Gate-verified pass@1 on [Aider's polyglot benchmark](https://github.com/Aider-AI/polyglot-benchmark) (Exercism exercises with hidden test suites), `anthropic/claude-sonnet-4-6`:
113
+
114
+ | Language | Solved | Rate |
115
+ | --- | --- | --- |
116
+ | JavaScript | 9 / 10 | **90%** |
117
+ | Python | 8 / 10 | **80%** |
118
+ | Rust | 7 / 10 | **70%** |
119
+
120
+ A continuous stress run has solved **20/20** across the three languages with zero failures — including the exercises usually cited as hard (bowling, forth, arbitrary-precision decimal). Every solve is judged by the exercise's own hidden tests, not the model's say-so. Full numbers, methodology, and how to reproduce: **[docs/benchmark-results.md](docs/benchmark-results.md)**. Test suite: **1,897 passing** — **[docs/TESTING.md](docs/TESTING.md)**.
121
+
102
122
  ## CLI reference
103
123
 
104
124
  **Don't want to remember flags?** If the first argument isn't a subcommand,
@@ -1,3 +1,3 @@
1
1
  """misterdev — an autonomous, extensible LLM build orchestrator."""
2
2
 
3
- __version__ = "0.2.2"
3
+ __version__ = "0.3.1"
@@ -38,6 +38,7 @@ from misterdev.core.planning.sovereign import (
38
38
  ProbeGenerator,
39
39
  )
40
40
  from misterdev.core.planning.metacognition import SessionAuditor
41
+ from misterdev.core.learning import FailureLog, SolvedTaskIndex
41
42
  from misterdev.core.context.contracts import ContractRegistry
42
43
  from misterdev.core.verification.preflight import PreflightValidator
43
44
  from misterdev.core.execution.progress import (
@@ -51,6 +52,10 @@ from misterdev.core.models import Task
51
52
  from misterdev.analyzers.project_analyzer import (
52
53
  analyze_project,
53
54
  )
55
+ from misterdev.analyzers.project_analyzer.detection import (
56
+ detect_lint_command,
57
+ detect_typecheck_command,
58
+ )
54
59
  from misterdev.core.planning.advisor import recommend_work
55
60
  from misterdev.llm.client import BudgetExceededError
56
61
  from misterdev.task_executors.markdown_plan_executor import (
@@ -86,6 +91,7 @@ class ProjectOrchestrator:
86
91
  def __init__(self):
87
92
  self.registry = ProjectRegistry()
88
93
  self.last_build_succeeded = True
94
+ self.last_build_cost = 0.0
89
95
 
90
96
  def scan_directory(self, path: str | Path):
91
97
  self.registry.discover_projects(path)
@@ -428,16 +434,40 @@ class ProjectOrchestrator:
428
434
  )
429
435
  report.key_decisions.append(f"Halted by budget ceiling: {error}")
430
436
  report.finalize()
431
- usage = project.llm_client.cumulative_usage
432
- report.llm_calls = usage.call_count
433
- report.llm_tokens = usage.total_tokens
434
- report.llm_prompt_tokens = getattr(usage, "prompt_tokens", 0)
435
- report.llm_completion_tokens = getattr(usage, "completion_tokens", 0)
436
- report.llm_cache_read_tokens = getattr(usage, "cache_read_tokens", 0)
437
- report.llm_cost = usage.estimated_cost
437
+ report.apply_llm_usage(project.llm_client.cumulative_usage)
438
+ self._persist_learning(project, report)
438
439
  report.save(project.path)
439
440
  return report.to_markdown()
440
441
 
442
+ def _persist_learning(self, project: Project, report: BuildReport) -> None:
443
+ """Record this build's spend, real failures, and solved tasks.
444
+
445
+ Runs on EVERY terminated build — normal completion and budget halt alike.
446
+ A budget-exhausted run spent the whole cap and still failed, so it is the
447
+ highest-signal failure; dropping it would blind the exact features
448
+ (evolution-from-failures, warm-start) that learn from real use. Each write
449
+ is best-effort so bookkeeping never turns a finished build into a crash.
450
+ """
451
+ # Expose this build's spend so a caller (e.g. the benchmark runner) can
452
+ # attribute per-run cost without re-deriving it from the saved report.
453
+ self.last_build_cost = float(
454
+ getattr(project.llm_client.cumulative_usage, "estimated_cost", 0.0)
455
+ )
456
+ try:
457
+ FailureLog(
458
+ project.path / ".orchestrator" / "failures.jsonl"
459
+ ).record_failures(report.failed_tasks)
460
+ except Exception as e:
461
+ logger.warning(f"Failure logging failed (non-fatal): {e}")
462
+ report.degraded_subsystems.append(f"Failure logging: {e}")
463
+ try:
464
+ SolvedTaskIndex(
465
+ project.path / ".orchestrator" / "solved_tasks.jsonl"
466
+ ).record(report.completed_tasks)
467
+ except Exception as e:
468
+ logger.warning(f"Solved-task indexing failed (non-fatal): {e}")
469
+ report.degraded_subsystems.append(f"Solved-task indexing: {e}")
470
+
441
471
  def interactive_plan(self, project_path: str | Path, args: str = "") -> str:
442
472
  """Analyze the project, recommend work, and compose a plan with the user.
443
473
 
@@ -649,15 +679,33 @@ class ProjectOrchestrator:
649
679
  # Sovereign enhancements (metacognition, AB-MCTS) are best-effort: they
650
680
  # refine the spec but must not crash the build, so each degrades to the
651
681
  # current spec on failure rather than aborting before any work is done.
652
- auditor = SessionAuditor(project.path, project.llm_client)
682
+ # One embedder, shared by lesson retrieval and warm-start, so a similar
683
+ # lesson/task surfaces by MEANING, not just shared tokens. Best-effort:
684
+ # None (no fastembed / disabled) degrades both to lexical ranking.
685
+ embedder = self._learning_embedder(project)
686
+ auditor = SessionAuditor(project.path, project.llm_client, embedder=embedder)
653
687
  try:
654
- lessons = auditor.get_lessons_context()
688
+ # Bias retrieval toward lessons relevant to this build's goal.
689
+ lessons = auditor.get_lessons_context(prompt)
655
690
  if lessons:
656
691
  spec = f"{lessons}\n\n{spec}"
657
692
  except Exception as e:
658
693
  logger.warning(f"Lesson injection failed (non-fatal): {e}")
659
694
  report.degraded_subsystems.append(f"Lesson injection: {e}")
660
695
 
696
+ # Warm-start: seed the spec with how similar tasks were solved before, so a
697
+ # recurring shape starts from a proven approach instead of cold.
698
+ solved_index = SolvedTaskIndex(
699
+ project.path / ".orchestrator" / "solved_tasks.jsonl", embedder=embedder
700
+ )
701
+ try:
702
+ priors = solved_index.context(prompt)
703
+ if priors:
704
+ spec = f"{priors}\n\n{spec}"
705
+ except Exception as e:
706
+ logger.warning(f"Warm-start injection failed (non-fatal): {e}")
707
+ report.degraded_subsystems.append(f"Warm-start injection: {e}")
708
+
661
709
  # AB-MCTS branch-and-evaluate is off by default: it fires several serial
662
710
  # LLM calls before any work begins (observed ~30 min on one build) for
663
711
  # marginal spec refinement. Opt in with orchestrator.enable_ab_mcts.
@@ -690,6 +738,7 @@ class ProjectOrchestrator:
690
738
  max_tasks=max_tasks,
691
739
  file_map=file_map,
692
740
  targets=targets,
741
+ staging_hint=self._staging_hint(project),
693
742
  )
694
743
  tasks = topological_sort(tasks)
695
744
 
@@ -760,7 +809,11 @@ class ProjectOrchestrator:
760
809
  commands = {
761
810
  "build_command": assessment.structure.build_command,
762
811
  "test_command": assessment.structure.test_command,
763
- "lint_command": assessment.structure.lint_command,
812
+ "lint_command": assessment.structure.lint_command
813
+ or detect_lint_command(project.path),
814
+ "audit_command": assessment.structure.audit_command,
815
+ "typecheck_command": project.config.get("typecheck_command")
816
+ or detect_typecheck_command(project.path),
764
817
  "golden_command": get_setting(
765
818
  project.config, "orchestrator", "golden_command"
766
819
  ),
@@ -863,18 +916,31 @@ class ProjectOrchestrator:
863
916
  logger.warning(f"Session audit failed (non-fatal): {e}")
864
917
  report.degraded_subsystems.append(f"Session audit: {e}")
865
918
 
866
- usage = project.llm_client.cumulative_usage
867
- report.llm_calls = usage.call_count
868
- report.llm_tokens = usage.total_tokens
869
- report.llm_prompt_tokens = getattr(usage, "prompt_tokens", 0)
870
- report.llm_completion_tokens = getattr(usage, "completion_tokens", 0)
871
- report.llm_cache_read_tokens = getattr(usage, "cache_read_tokens", 0)
872
- report.llm_cost = usage.estimated_cost
919
+ report.apply_llm_usage(project.llm_client.cumulative_usage)
873
920
  report.cost_by_task = dict(getattr(project.llm_client, "cost_by_task", {}))
921
+ # Learning writes + spend accounting, shared with the budget-halt path so
922
+ # a budget-exhausted run (the highest-signal failure) is not silently
923
+ # dropped from the streams the self-improvement features learn from.
924
+ self._persist_learning(project, report)
874
925
 
875
926
  report.save(project.path)
876
927
  return report.to_markdown()
877
928
 
929
+ def _learning_embedder(self, project: Project):
930
+ """A shared embedder for lesson/warm-start retrieval, or None.
931
+
932
+ Reuses the project's embedding-backend config (which prefers a free,
933
+ offline local model and honours "none"), so semantic ranking is opt-in via
934
+ the same setting that governs context ranking. Any failure returns None,
935
+ degrading retrieval to lexical rather than breaking the build."""
936
+ try:
937
+ from misterdev.llm.client.embeddings import create_embedding_client
938
+
939
+ return create_embedding_client(project.config)
940
+ except Exception as e:
941
+ logger.debug(f"Learning embedder unavailable, using lexical ranking: {e}")
942
+ return None
943
+
878
944
  def _capture_head(self, project: Project) -> Optional[str]:
879
945
  """Best-effort current HEAD sha, or None outside a git repo / on error."""
880
946
  if not (project.path / ".git").exists():
@@ -1723,6 +1789,108 @@ class ProjectOrchestrator:
1723
1789
  choice = Prompt.ask("Proceed?", choices=["y", "n", "s", "q"], default="y")
1724
1790
  return {"y": "proceed", "q": "quit", "s": "skip", "n": "quit"}[choice]
1725
1791
 
1792
+ def _staging_hint(self, project: Project) -> str:
1793
+ """Dense-reward staging suggestion for a single complex source file.
1794
+
1795
+ Uses the already-built symbol graph: when every public symbol lives in ONE
1796
+ non-test source file, that is a single-file goal — synthesize ordered
1797
+ construction->mutation->query stages so the decomposer can split it into a
1798
+ few sequential, independently-verifiable sub-tasks (raises per-attempt
1799
+ success on state-heavy files). Empty for multi-file goals or when nothing
1800
+ stages; never raises.
1801
+ """
1802
+ try:
1803
+ from misterdev.core.planning.verifier_decomposition import (
1804
+ render_stages,
1805
+ synthesize_stages,
1806
+ )
1807
+
1808
+ graph = getattr(getattr(project, "topography", None), "graph", None)
1809
+ symbols = list(getattr(graph, "symbols", {}).values()) if graph else []
1810
+ src = [
1811
+ s
1812
+ for s in symbols
1813
+ if getattr(s, "file_path", "") and "test" not in s.file_path.lower()
1814
+ ]
1815
+ if len({s.file_path for s in src}) != 1:
1816
+ return "" # staging only applies to a single-file goal
1817
+ stages = synthesize_stages(src)
1818
+ if len(stages) < 2:
1819
+ return ""
1820
+ return (
1821
+ "\n## Suggested staging (dense-reward decomposition)\n"
1822
+ "This file's public API splits into ordered, independently-"
1823
+ "verifiable stages. Prefer ONE sequential sub-task per stage, in "
1824
+ "this order (each must compile and leave the suite no worse):\n"
1825
+ f"{render_stages(stages)}\n"
1826
+ )
1827
+ except Exception as e: # a staging hint must never break decomposition
1828
+ logger.debug(f"Staging hint skipped (non-fatal): {e}")
1829
+ return ""
1830
+
1831
+ def _ground_completion_spec(
1832
+ self, assessment: ProjectAssessment, project: Project
1833
+ ) -> str:
1834
+ """Build a COMPLETE-mode spec grounded in objective signals.
1835
+
1836
+ A vague "complete everything" goal on a real codebase otherwise churns:
1837
+ the completeness analyzer flags "incomplete"/"stub" items from a lossy
1838
+ overview and mislabels deliberate design (graceful degradation, platform
1839
+ no-ops) as work, so the spec becomes a pile of speculative tasks. Instead
1840
+ lead with HARD signals — a failing build, failing tests, located
1841
+ TODO/FIXME markers, broken references — which are objective and
1842
+ verifiable, add features the docs promise but are absent, and demote the
1843
+ analyzer's guesses to an explicit "do NOT task these unless corroborated"
1844
+ advisory. When nothing hard or documented exists, the goal is ill-posed:
1845
+ emit zero-task guidance rather than fabricate work.
1846
+ """
1847
+ h = assessment.health
1848
+ f = assessment.features
1849
+ hard: list[str] = []
1850
+ if not h.builds and h.build_output:
1851
+ hard.append(
1852
+ f"- The build is FAILING; fix it first:\n{h.build_output[:400]}"
1853
+ )
1854
+ if not h.tests_pass and h.test_output:
1855
+ hard.append(f"- Tests are FAILING:\n{h.test_output[:400]}")
1856
+ hard.extend(f"- Broken: {item}" for item in f.broken)
1857
+ hard.extend(
1858
+ f"- {t.get('file', '?')}:{t.get('line', '?')} {t.get('text', '')}"
1859
+ for t in f.todos[:20]
1860
+ )
1861
+ documented = [f"- {m.name}: {m.description}" for m in f.missing]
1862
+ speculative = [f"- {i.name}: {i.description}" for i in f.incomplete]
1863
+ speculative += [f"- Stub: {s}" for s in f.stubs]
1864
+
1865
+ parts = [f"# Completion Spec\n## Project: {project.name}\n"]
1866
+ if hard:
1867
+ parts.append(
1868
+ "## Must Fix — objective, verifiable failures\n" + "\n".join(hard)
1869
+ )
1870
+ if documented:
1871
+ parts.append(
1872
+ "\n## Should Add — promised by the docs but absent\n"
1873
+ + "\n".join(documented)
1874
+ )
1875
+ if not hard and not documented:
1876
+ parts.append(
1877
+ "## No concrete objective found\n"
1878
+ "The build and tests pass and there are no TODO/FIXME markers or "
1879
+ "documented-but-missing features. A vague 'complete everything' goal "
1880
+ "has no well-posed work here. Do NOT fabricate tasks from speculation: "
1881
+ "produce ZERO tasks and report that a specific objective (a feature, a "
1882
+ "bug to fix, or --focus <area>) is required."
1883
+ )
1884
+ if speculative:
1885
+ parts.append(
1886
+ "\n## Advisory — analyzer guesses, NOT tasks\n"
1887
+ "Inferred as incomplete/stub from a lossy overview; these often "
1888
+ "mislabel deliberate design. Do NOT create a task for any of these "
1889
+ "unless a failing test or build error above corroborates it.\n"
1890
+ + "\n".join(speculative[:15])
1891
+ )
1892
+ return "\n".join(parts)
1893
+
1726
1894
  def _generate_spec(
1727
1895
  self,
1728
1896
  mode: BuildMode,
@@ -1751,28 +1919,7 @@ class ProjectOrchestrator:
1751
1919
  return "\n".join(parts)
1752
1920
 
1753
1921
  if mode == BuildMode.COMPLETE:
1754
- parts = [
1755
- f"# Completion Spec\n## Project: {project.name}",
1756
- "## Goal: Complete all work\n",
1757
- "### Must Complete",
1758
- ]
1759
- for f in assessment.features.incomplete:
1760
- parts.append(f"- {f.name}: {f.description}")
1761
- parts.append("\n### Must Fix")
1762
- for item in assessment.features.broken:
1763
- parts.append(f"- {item}")
1764
- for item in assessment.features.stubs:
1765
- parts.append(f"- Stub: {item}")
1766
- parts.append("\n### Should Add")
1767
- for f in assessment.features.missing:
1768
- parts.append(f"- {f.name}: {f.description}")
1769
- if assessment.features.todos:
1770
- parts.append(f"\n### TODOs ({len(assessment.features.todos)} items)")
1771
- for todo in assessment.features.todos[:20]:
1772
- parts.append(
1773
- f"- {todo.get('file', '?')}:{todo.get('line', '?')} {todo.get('text', '')}"
1774
- )
1775
- return "\n".join(parts)
1922
+ return self._ground_completion_spec(assessment, project)
1776
1923
 
1777
1924
  if mode == BuildMode.SPEC:
1778
1925
  spec_path = project.path / prompt.strip()
@@ -17,6 +17,7 @@ from misterdev.llm.client import BaseLLMClient
17
17
  from misterdev.logging_setup import setup_logger
18
18
 
19
19
  from .detection import (
20
+ detect_audit_command,
20
21
  detect_build_command,
21
22
  detect_test_command,
22
23
  has_test_files,
@@ -109,6 +110,7 @@ def analyze_project(
109
110
  )
110
111
  assessment.structure.build_command = bc
111
112
  assessment.structure.test_command = tc
113
+ assessment.structure.audit_command = detect_audit_command(project_path)
112
114
  health_ground = _health_ground_truth(assessment.health)
113
115
 
114
116
  def analyze_structure():
@@ -131,6 +131,110 @@ def detect_build_command(project_path: Path) -> Optional[str]:
131
131
  return None
132
132
 
133
133
 
134
+ def detect_audit_command(project_path: Path) -> Optional[str]:
135
+ """Detect a dependency/security-audit command from project markers.
136
+
137
+ Supply-chain scanning (the layer above lint): surfaces known-vulnerable
138
+ dependencies. Returns a runnable command, or None when no recognized
139
+ ecosystem is found. The audit gate is advisory and SKIPs when the tool is
140
+ absent, so returning a command the environment may lack is safe.
141
+ """
142
+ p = project_path
143
+ if (p / "Cargo.toml").exists():
144
+ return "cargo audit"
145
+ if (p / "package.json").exists():
146
+ return "npm audit --omit=dev"
147
+ if (p / "pyproject.toml").exists() or (p / "requirements.txt").exists():
148
+ return "uv run pip-audit" if (p / "uv.lock").exists() else "pip-audit"
149
+ if any(p.glob("*.sln")) or any(p.glob("*.csproj")):
150
+ return "dotnet list package --vulnerable --include-transitive"
151
+ return None
152
+
153
+
154
+ def detect_lint_command(project_path: Path) -> Optional[str]:
155
+ """Detect a strict linter command from project markers.
156
+
157
+ Fallback used when no ``lint_command`` is configured — so the strict tools
158
+ the guidance recommends actually run in the G2 gate. Conservative: only
159
+ returns a command when the tool is standard for the ecosystem (clippy ships
160
+ with rustup) or a config file proves it is set up, so an absent linter never
161
+ produces a false lint failure.
162
+ """
163
+ p = project_path
164
+ if (p / "Cargo.toml").exists():
165
+ return "cargo clippy --all-targets --all-features -- -D warnings"
166
+ ruff_cfg = (p / "ruff.toml").exists() or (p / ".ruff.toml").exists()
167
+ if ruff_cfg or (
168
+ (p / "pyproject.toml").exists() and _file_mentions(p / "pyproject.toml", "ruff")
169
+ ):
170
+ return "uv run ruff check ." if (p / "uv.lock").exists() else "ruff check ."
171
+ if (p / "package.json").exists() and any(
172
+ any(p.glob(pat)) for pat in ("eslint.config.*", ".eslintrc", ".eslintrc.*")
173
+ ):
174
+ return "npx --no-install eslint . --max-warnings 0"
175
+ if (p / "Package.swift").exists() and (p / ".swiftlint.yml").exists():
176
+ return "swiftlint --strict"
177
+ if (p / "detekt.yml").exists() or (p / "detekt-config.yml").exists():
178
+ return "detekt"
179
+ return None
180
+
181
+
182
+ def detect_typecheck_command(project_path: Path) -> Optional[str]:
183
+ """Detect a standalone type-check command, distinct from the build.
184
+
185
+ Only for ecosystems where type-checking is separate from compilation
186
+ (TypeScript's ``tsc --noEmit``, Python's mypy/pyright) — for compiled
187
+ languages the build gate already type-checks, so returning one would just
188
+ duplicate G1. Gated on a config file; the G4 gate SKIPs when the tool is
189
+ absent, so an uninstalled checker never blocks.
190
+ """
191
+ p = project_path
192
+ if (p / "tsconfig.json").exists():
193
+ return "npx --no-install tsc --noEmit"
194
+ mypy_cfg = (
195
+ (p / "mypy.ini").exists()
196
+ or (p / ".mypy.ini").exists()
197
+ or (
198
+ (p / "pyproject.toml").exists()
199
+ and _file_mentions(p / "pyproject.toml", "[tool.mypy]")
200
+ )
201
+ )
202
+ if mypy_cfg:
203
+ return "uv run mypy ." if (p / "uv.lock").exists() else "mypy ."
204
+ if (p / "pyrightconfig.json").exists():
205
+ return "pyright"
206
+ return None
207
+
208
+
209
+ def dependency_add_command(project_path: Path, package: str) -> Optional[str]:
210
+ """Return the command to add a dependency, respecting the lock/manager in use.
211
+
212
+ None when the ecosystem edits its manifest by hand (SwiftPM) or is
213
+ unrecognized. Callers use this for deliberate dependency additions; a
214
+ refactor must not touch the lock file, only a genuine add.
215
+ """
216
+ p = project_path
217
+ if (p / "Cargo.toml").exists():
218
+ return f"cargo add {package}"
219
+ if (p / "package.json").exists():
220
+ if (p / "pnpm-lock.yaml").exists():
221
+ return f"pnpm add {package}"
222
+ if (p / "yarn.lock").exists():
223
+ return f"yarn add {package}"
224
+ if (p / "bun.lockb").exists():
225
+ return f"bun add {package}"
226
+ return f"npm install {package}"
227
+ if (p / "pyproject.toml").exists():
228
+ return (
229
+ f"uv add {package}"
230
+ if (p / "uv.lock").exists()
231
+ else f"pip install {package}"
232
+ )
233
+ if any(p.glob("*.csproj")):
234
+ return f"dotnet add package {package}"
235
+ return None
236
+
237
+
134
238
  def _file_mentions(path: Path, needle: str) -> bool:
135
239
  try:
136
240
  return needle in path.read_text(encoding="utf-8")
@@ -41,7 +41,23 @@ class LLMSettings:
41
41
  # models maps tier name -> model id (or a list of candidate ids). Empty =
42
42
  # use the default model.
43
43
  routing: Dict[str, Any] = field(default_factory=dict)
44
- models: Dict[str, Any] = field(default_factory=dict)
44
+ # Default capability ladder (grounded in the live OpenRouter catalog). The
45
+ # cheapest rung also receives auto-harvested free models (use_free_models);
46
+ # the strongest rung is reached ONLY on the final attempt (see ModelSelector),
47
+ # so frontier spend is the rare safety net, not the default. Each rung lists
48
+ # candidates cheapest-strong first so a quality-per-dollar tie breaks toward
49
+ # the cheaper option and the ledger learns which model wins each cell.
50
+ models: Dict[str, Any] = field(
51
+ default_factory=lambda: {
52
+ "cheap": ["deepseek/deepseek-r1-0528"],
53
+ "mid": ["anthropic/claude-sonnet-4.6"],
54
+ "frontier": [
55
+ "openai/gpt-5.1-codex",
56
+ "google/gemini-3.1-pro-preview",
57
+ "anthropic/claude-opus-4.8",
58
+ ],
59
+ }
60
+ )
45
61
  # Ledger-driven dynamic model selection. False = off (default), True = on
46
62
  # using selection_posture, "auto" = self-activating: explore cheap/free
47
63
  # models on easy tasks while a (category, complexity) cell is immature, then
@@ -51,7 +67,7 @@ class LLMSettings:
51
67
  # resolves through `models`. The policy uses a cheaper model on early
52
68
  # attempts and climbs to the strongest tier by the final attempt.
53
69
  dynamic_selection: Any = "auto"
54
- escalation: List[str] = field(default_factory=list)
70
+ escalation: List[str] = field(default_factory=lambda: ["cheap", "mid", "frontier"])
55
71
  # A cheaper model is trusted for a first attempt only once it has at least
56
72
  # min_observations recorded first-try attempts and a first-try success rate
57
73
  # at or above first_try_floor.
@@ -228,9 +244,11 @@ class OrchestratorSettings:
228
244
  # off by default (marginal value, large latency/cost).
229
245
  enable_ab_mcts: bool = False
230
246
  # Empirical probe discovery (SMART/CREATE Phase 1.5) runs an LLM call plus
231
- # ephemeral scripts to verify facts before planning. On by default (it grounds
232
- # the spec), but set false for a cheaper/faster run that skips the pre-work.
233
- enable_probes: bool = True
247
+ # ephemeral scripts to verify facts before planning. OFF by default: measured
248
+ # to balloon the pre-execution context (~900K tokens over ~9 calls on a
249
+ # trivial task) and exhaust the whole budget before any code is written. Worth
250
+ # enabling only for complex work against an unfamiliar live codebase.
251
+ enable_probes: bool = False
234
252
  # Auto-detect polyglot sub-projects (targets) when none are declared, so a
235
253
  # monorepo gets per-toolchain gate routing with zero config. Off by default
236
254
  # (explicit ``targets`` is more precise); detected commands are best-effort.
@@ -301,6 +319,15 @@ class OrchestratorSettings:
301
319
  critic_auto_categories: List[str] = field(
302
320
  default_factory=lambda: ["refactor", "fix", "integration"]
303
321
  )
322
+ # Self-reflection on a failed attempt (the Reflexion pattern). When on, a
323
+ # failed gate triggers a short model reflection on the ROOT CAUSE and what to
324
+ # do differently, accumulated across attempts and fed into the next one — so a
325
+ # retry debugs the underlying problem instead of re-patching the symptom. On
326
+ # by default: it only ADDS guidance on a failure (never on a first attempt or
327
+ # a success), is timeout-bounded, and SKIPs cleanly with no client. Costs one
328
+ # extra short call per failed attempt; set false to disable entirely.
329
+ reflection: bool = True
330
+ reflection_timeout: int = 45
304
331
  # Independent completeness-claim verifier. Before a build composes its spec
305
332
  # and tasks, each feature the analyzer flagged "incomplete" and each "stub"
306
333
  # file is rechecked against the REAL file + tests by a second component
@@ -314,6 +341,11 @@ class OrchestratorSettings:
314
341
  # claim's judgment.
315
342
  verify_claims: bool = True
316
343
  verify_claims_timeout: int = 45
344
+ # Failure-triggered probe: on a red test gate, re-run ONLY the first failing
345
+ # test in isolation and append its fresh, uncluttered trace to the retry
346
+ # context. Off by default — the re-run costs a test invocation (cheap for
347
+ # pytest/jest, a full compile for cargo/swift/dotnet), so it is opt-in.
348
+ failure_probe: bool = False
317
349
 
318
350
 
319
351
  PROMPT_TEMPLATES = {
@@ -34,6 +34,13 @@ from .rust_tree_sitter import (
34
34
  _ts_variant_names,
35
35
  _walk_rust_ts,
36
36
  )
37
+ from .c_tree_sitter import _extract_c_symbols_ts
38
+ from .cpp_tree_sitter import _extract_cpp_symbols_ts
39
+ from .csharp_tree_sitter import _extract_csharp_symbols_ts
40
+ from .javascript_tree_sitter import _extract_javascript_symbols_ts
41
+ from .kotlin_tree_sitter import _extract_kotlin_symbols_ts
42
+ from .swift_tree_sitter import _extract_swift_symbols_ts
43
+ from .typescript_tree_sitter import _extract_typescript_symbols_ts
37
44
 
38
45
  __all__ = [
39
46
  "logger",
@@ -60,4 +67,11 @@ __all__ = [
60
67
  "_ts_pub_members",
61
68
  "_ts_variant_names",
62
69
  "_ts_trait_methods",
70
+ "_extract_swift_symbols_ts",
71
+ "_extract_kotlin_symbols_ts",
72
+ "_extract_typescript_symbols_ts",
73
+ "_extract_javascript_symbols_ts",
74
+ "_extract_cpp_symbols_ts",
75
+ "_extract_c_symbols_ts",
76
+ "_extract_csharp_symbols_ts",
63
77
  ]