loopmath 0.0.1__tar.gz → 0.1.0__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 (337) hide show
  1. loopmath-0.1.0/LICENSE +21 -0
  2. loopmath-0.1.0/PKG-INFO +239 -0
  3. loopmath-0.1.0/README.md +201 -0
  4. loopmath-0.1.0/pyproject.toml +110 -0
  5. loopmath-0.1.0/setup.cfg +4 -0
  6. loopmath-0.1.0/spec/ocp-v0.2.schema.json +373 -0
  7. loopmath-0.1.0/spec/ocp-v0.schema.json +244 -0
  8. loopmath-0.1.0/spec/ocp_conformance.py +22 -0
  9. loopmath-0.1.0/src/loopmath/__init__.py +8 -0
  10. loopmath-0.1.0/src/loopmath/__main__.py +7 -0
  11. loopmath-0.1.0/src/loopmath/adapter_host.py +311 -0
  12. loopmath-0.1.0/src/loopmath/adapters/__init__.py +44 -0
  13. loopmath-0.1.0/src/loopmath/adapters/atrium.py +494 -0
  14. loopmath-0.1.0/src/loopmath/adapters/base.py +349 -0
  15. loopmath-0.1.0/src/loopmath/adapters/bb.py +450 -0
  16. loopmath-0.1.0/src/loopmath/adapters/bb_support.py +253 -0
  17. loopmath-0.1.0/src/loopmath/adapters/omp.py +458 -0
  18. loopmath-0.1.0/src/loopmath/adapters/omp_facts.py +357 -0
  19. loopmath-0.1.0/src/loopmath/adapters/omp_links.py +158 -0
  20. loopmath-0.1.0/src/loopmath/adapters/omp_parse.py +246 -0
  21. loopmath-0.1.0/src/loopmath/adapters/omp_types.py +89 -0
  22. loopmath-0.1.0/src/loopmath/adapters/opencode.py +477 -0
  23. loopmath-0.1.0/src/loopmath/adapters/opencode_store.py +368 -0
  24. loopmath-0.1.0/src/loopmath/adapters/orca.py +483 -0
  25. loopmath-0.1.0/src/loopmath/adapters/otel_genai.py +480 -0
  26. loopmath-0.1.0/src/loopmath/adapters/otel_genai_graph.py +377 -0
  27. loopmath-0.1.0/src/loopmath/adapters/otel_genai_parse.py +237 -0
  28. loopmath-0.1.0/src/loopmath/adapters/otel_genai_types.py +216 -0
  29. loopmath-0.1.0/src/loopmath/adapters/otel_genai_usage.py +282 -0
  30. loopmath-0.1.0/src/loopmath/adapters/paseo.py +441 -0
  31. loopmath-0.1.0/src/loopmath/adapters/pi.py +240 -0
  32. loopmath-0.1.0/src/loopmath/adapters/pi_support.py +466 -0
  33. loopmath-0.1.0/src/loopmath/adapters/registry.py +86 -0
  34. loopmath-0.1.0/src/loopmath/belief/__init__.py +6 -0
  35. loopmath-0.1.0/src/loopmath/belief/check_pymc.py +111 -0
  36. loopmath-0.1.0/src/loopmath/belief/commands.py +136 -0
  37. loopmath-0.1.0/src/loopmath/belief/compose.py +209 -0
  38. loopmath-0.1.0/src/loopmath/belief/design.py +733 -0
  39. loopmath-0.1.0/src/loopmath/belief/fit.py +582 -0
  40. loopmath-0.1.0/src/loopmath/belief/forest.py +217 -0
  41. loopmath-0.1.0/src/loopmath/belief/gaussian.py +405 -0
  42. loopmath-0.1.0/src/loopmath/belief/lookahead.py +347 -0
  43. loopmath-0.1.0/src/loopmath/belief/outcome.py +154 -0
  44. loopmath-0.1.0/src/loopmath/belief/priors.py +125 -0
  45. loopmath-0.1.0/src/loopmath/belief/state.py +762 -0
  46. loopmath-0.1.0/src/loopmath/cli.py +493 -0
  47. loopmath-0.1.0/src/loopmath/cli_graph.py +341 -0
  48. loopmath-0.1.0/src/loopmath/cli_registry.py +374 -0
  49. loopmath-0.1.0/src/loopmath/cli_support.py +405 -0
  50. loopmath-0.1.0/src/loopmath/e0/__init__.py +1 -0
  51. loopmath-0.1.0/src/loopmath/e0/arms.py +222 -0
  52. loopmath-0.1.0/src/loopmath/e0/cli_e0.py +206 -0
  53. loopmath-0.1.0/src/loopmath/e0/estimate.py +462 -0
  54. loopmath-0.1.0/src/loopmath/e0/estimate_rework.py +153 -0
  55. loopmath-0.1.0/src/loopmath/e0/figures.py +463 -0
  56. loopmath-0.1.0/src/loopmath/e0/io.py +194 -0
  57. loopmath-0.1.0/src/loopmath/e0/verb.py +30 -0
  58. loopmath-0.1.0/src/loopmath/explain.py +86 -0
  59. loopmath-0.1.0/src/loopmath/fit.py +279 -0
  60. loopmath-0.1.0/src/loopmath/fit_assembly.py +258 -0
  61. loopmath-0.1.0/src/loopmath/fit_bayes.py +184 -0
  62. loopmath-0.1.0/src/loopmath/fit_masks.py +160 -0
  63. loopmath-0.1.0/src/loopmath/fit_predict.py +118 -0
  64. loopmath-0.1.0/src/loopmath/fit_pricing.py +363 -0
  65. loopmath-0.1.0/src/loopmath/fit_transfer.py +300 -0
  66. loopmath-0.1.0/src/loopmath/gaps.py +182 -0
  67. loopmath-0.1.0/src/loopmath/grade.py +407 -0
  68. loopmath-0.1.0/src/loopmath/grade_support.py +338 -0
  69. loopmath-0.1.0/src/loopmath/graph/__init__.py +8 -0
  70. loopmath-0.1.0/src/loopmath/graph/artifact_git.py +198 -0
  71. loopmath-0.1.0/src/loopmath/graph/artifact_join.py +238 -0
  72. loopmath-0.1.0/src/loopmath/graph/artifact_kinds.py +155 -0
  73. loopmath-0.1.0/src/loopmath/graph/artifacts.py +63 -0
  74. loopmath-0.1.0/src/loopmath/graph/bashparse.py +229 -0
  75. loopmath-0.1.0/src/loopmath/graph/bashread_ops.py +159 -0
  76. loopmath-0.1.0/src/loopmath/graph/bashwrite_ops.py +125 -0
  77. loopmath-0.1.0/src/loopmath/graph/bashwrites.py +10 -0
  78. loopmath-0.1.0/src/loopmath/graph/cache.py +269 -0
  79. loopmath-0.1.0/src/loopmath/graph/codexio.py +12 -0
  80. loopmath-0.1.0/src/loopmath/graph/codexio_parse.py +390 -0
  81. loopmath-0.1.0/src/loopmath/graph/codexio_scan.py +473 -0
  82. loopmath-0.1.0/src/loopmath/graph/dataset.py +15 -0
  83. loopmath-0.1.0/src/loopmath/graph/dataset_build.py +422 -0
  84. loopmath-0.1.0/src/loopmath/graph/dataset_core.py +368 -0
  85. loopmath-0.1.0/src/loopmath/graph/dataset_edges.py +386 -0
  86. loopmath-0.1.0/src/loopmath/graph/dataset_nodes.py +401 -0
  87. loopmath-0.1.0/src/loopmath/graph/extract.py +232 -0
  88. loopmath-0.1.0/src/loopmath/graph/html_common.py +422 -0
  89. loopmath-0.1.0/src/loopmath/graph/html_costcurve.py +65 -0
  90. loopmath-0.1.0/src/loopmath/graph/html_css.py +132 -0
  91. loopmath-0.1.0/src/loopmath/graph/html_data.py +484 -0
  92. loopmath-0.1.0/src/loopmath/graph/html_force.py +57 -0
  93. loopmath-0.1.0/src/loopmath/graph/html_render.py +93 -0
  94. loopmath-0.1.0/src/loopmath/graph/html_swimlanes.py +86 -0
  95. loopmath-0.1.0/src/loopmath/graph/labeler.py +83 -0
  96. loopmath-0.1.0/src/loopmath/graph/labeler_cli.py +163 -0
  97. loopmath-0.1.0/src/loopmath/graph/labeler_common.py +166 -0
  98. loopmath-0.1.0/src/loopmath/graph/labeler_parse.py +186 -0
  99. loopmath-0.1.0/src/loopmath/graph/labeler_pricing.py +224 -0
  100. loopmath-0.1.0/src/loopmath/graph/labeler_prompt.py +82 -0
  101. loopmath-0.1.0/src/loopmath/graph/labeler_prompt_build.py +479 -0
  102. loopmath-0.1.0/src/loopmath/graph/labeler_prompt_dispatch.py +375 -0
  103. loopmath-0.1.0/src/loopmath/graph/labeler_prompt_evidence.py +294 -0
  104. loopmath-0.1.0/src/loopmath/graph/labeler_prompt_node.py +444 -0
  105. loopmath-0.1.0/src/loopmath/graph/labeler_prompt_records.py +449 -0
  106. loopmath-0.1.0/src/loopmath/graph/labeler_prompt_result.py +157 -0
  107. loopmath-0.1.0/src/loopmath/graph/labeler_prompt_session.py +477 -0
  108. loopmath-0.1.0/src/loopmath/graph/labeler_prompt_tools.py +370 -0
  109. loopmath-0.1.0/src/loopmath/graph/labeler_prompt_validation.py +69 -0
  110. loopmath-0.1.0/src/loopmath/graph/labeler_prompt_workflow.py +429 -0
  111. loopmath-0.1.0/src/loopmath/graph/labeler_report.py +87 -0
  112. loopmath-0.1.0/src/loopmath/graph/labeler_score.py +485 -0
  113. loopmath-0.1.0/src/loopmath/graph/labels.py +115 -0
  114. loopmath-0.1.0/src/loopmath/graph/launch.py +487 -0
  115. loopmath-0.1.0/src/loopmath/graph/launch_origin.py +291 -0
  116. loopmath-0.1.0/src/loopmath/graph/ocp.py +9 -0
  117. loopmath-0.1.0/src/loopmath/graph/ocp_emit.py +264 -0
  118. loopmath-0.1.0/src/loopmath/graph/ocp_support.py +439 -0
  119. loopmath-0.1.0/src/loopmath/graph/render.py +68 -0
  120. loopmath-0.1.0/src/loopmath/graph/runfile.py +11 -0
  121. loopmath-0.1.0/src/loopmath/graph/runfile_export.py +300 -0
  122. loopmath-0.1.0/src/loopmath/graph/runfile_finish.py +299 -0
  123. loopmath-0.1.0/src/loopmath/graph/scan.py +259 -0
  124. loopmath-0.1.0/src/loopmath/graph/schema.py +152 -0
  125. loopmath-0.1.0/src/loopmath/graph/token_completeness.py +26 -0
  126. loopmath-0.1.0/src/loopmath/ingest/__init__.py +442 -0
  127. loopmath-0.1.0/src/loopmath/ingest/base.py +483 -0
  128. loopmath-0.1.0/src/loopmath/ingest/claude_code.py +521 -0
  129. loopmath-0.1.0/src/loopmath/ingest/claude_code_support.py +70 -0
  130. loopmath-0.1.0/src/loopmath/ingest/codex.py +535 -0
  131. loopmath-0.1.0/src/loopmath/ingest/codex_support.py +209 -0
  132. loopmath-0.1.0/src/loopmath/ingest/ocp.py +153 -0
  133. loopmath-0.1.0/src/loopmath/ingest/ocp_analysis.py +78 -0
  134. loopmath-0.1.0/src/loopmath/ingest/ocp_artifact.py +128 -0
  135. loopmath-0.1.0/src/loopmath/ingest/ocp_common.py +242 -0
  136. loopmath-0.1.0/src/loopmath/ingest/ocp_convert.py +496 -0
  137. loopmath-0.1.0/src/loopmath/ingest/ocp_projection.py +95 -0
  138. loopmath-0.1.0/src/loopmath/logmatch/__init__.py +6 -0
  139. loopmath-0.1.0/src/loopmath/logmatch/artifacts.py +92 -0
  140. loopmath-0.1.0/src/loopmath/logmatch/clip.py +193 -0
  141. loopmath-0.1.0/src/loopmath/logmatch/costs.py +188 -0
  142. loopmath-0.1.0/src/loopmath/logmatch/match.py +557 -0
  143. loopmath-0.1.0/src/loopmath/logmatch/settle.py +300 -0
  144. loopmath-0.1.0/src/loopmath/logmatch/tariff.py +84 -0
  145. loopmath-0.1.0/src/loopmath/ocp/__init__.py +17 -0
  146. loopmath-0.1.0/src/loopmath/ocp/canonical.py +137 -0
  147. loopmath-0.1.0/src/loopmath/ocp/commands.py +199 -0
  148. loopmath-0.1.0/src/loopmath/ocp/conformance.py +1139 -0
  149. loopmath-0.1.0/src/loopmath/ocp/contractv3.py +252 -0
  150. loopmath-0.1.0/src/loopmath/ocp/emit.py +429 -0
  151. loopmath-0.1.0/src/loopmath/ocp/migrate.py +133 -0
  152. loopmath-0.1.0/src/loopmath/ocp/schema/ocp-v0.2.schema.json +373 -0
  153. loopmath-0.1.0/src/loopmath/ocp/schema/ocp-v0.3.schema.json +2213 -0
  154. loopmath-0.1.0/src/loopmath/ocp/schema/ocp-v0.schema.json +244 -0
  155. loopmath-0.1.0/src/loopmath/ocp/version.py +34 -0
  156. loopmath-0.1.0/src/loopmath/onboard/__init__.py +6 -0
  157. loopmath-0.1.0/src/loopmath/onboard/commands.py +451 -0
  158. loopmath-0.1.0/src/loopmath/onboard/history.py +466 -0
  159. loopmath-0.1.0/src/loopmath/onboard/label.py +392 -0
  160. loopmath-0.1.0/src/loopmath/onboard/usual.py +88 -0
  161. loopmath-0.1.0/src/loopmath/output.py +78 -0
  162. loopmath-0.1.0/src/loopmath/price.py +587 -0
  163. loopmath-0.1.0/src/loopmath/price_validation.py +337 -0
  164. loopmath-0.1.0/src/loopmath/prices.toml +277 -0
  165. loopmath-0.1.0/src/loopmath/priors/__init__.py +57 -0
  166. loopmath-0.1.0/src/loopmath/priors/benchmarks.py +107 -0
  167. loopmath-0.1.0/src/loopmath/priors/benchmarks.toml +677 -0
  168. loopmath-0.1.0/src/loopmath/priors/build.py +247 -0
  169. loopmath-0.1.0/src/loopmath/priors/bundle/README.md +1 -0
  170. loopmath-0.1.0/src/loopmath/priors/bundle/e0.jsonl.gz +0 -0
  171. loopmath-0.1.0/src/loopmath/priors/bundle/manifest.json +202 -0
  172. loopmath-0.1.0/src/loopmath/priors/bundle/rq1.jsonl.gz +0 -0
  173. loopmath-0.1.0/src/loopmath/priors/bundle/sweep.jsonl.gz +0 -0
  174. loopmath-0.1.0/src/loopmath/priors/commands.py +101 -0
  175. loopmath-0.1.0/src/loopmath/priors/e0.py +207 -0
  176. loopmath-0.1.0/src/loopmath/priors/history.py +698 -0
  177. loopmath-0.1.0/src/loopmath/priors/ocpdoc.py +206 -0
  178. loopmath-0.1.0/src/loopmath/priors/reduce.py +136 -0
  179. loopmath-0.1.0/src/loopmath/priors/registry.py +70 -0
  180. loopmath-0.1.0/src/loopmath/priors/rq1.py +111 -0
  181. loopmath-0.1.0/src/loopmath/priors/show.py +72 -0
  182. loopmath-0.1.0/src/loopmath/priors/sweep.py +393 -0
  183. loopmath-0.1.0/src/loopmath/priors/validate.py +57 -0
  184. loopmath-0.1.0/src/loopmath/receipts.py +183 -0
  185. loopmath-0.1.0/src/loopmath/recommend/__init__.py +6 -0
  186. loopmath-0.1.0/src/loopmath/recommend/backlog.py +661 -0
  187. loopmath-0.1.0/src/loopmath/recommend/commands.py +554 -0
  188. loopmath-0.1.0/src/loopmath/recommend/curve.py +131 -0
  189. loopmath-0.1.0/src/loopmath/recommend/engine.py +330 -0
  190. loopmath-0.1.0/src/loopmath/recommend/gain.py +165 -0
  191. loopmath-0.1.0/src/loopmath/recommend/message.py +159 -0
  192. loopmath-0.1.0/src/loopmath/recommend/receipts.py +311 -0
  193. loopmath-0.1.0/src/loopmath/recommend/stats.py +54 -0
  194. loopmath-0.1.0/src/loopmath/recommend/storeread.py +280 -0
  195. loopmath-0.1.0/src/loopmath/report/__init__.py +1 -0
  196. loopmath-0.1.0/src/loopmath/report/html.py +344 -0
  197. loopmath-0.1.0/src/loopmath/report/terminal.py +500 -0
  198. loopmath-0.1.0/src/loopmath/report/terminal_exclusions.py +70 -0
  199. loopmath-0.1.0/src/loopmath/report/terminal_format.py +253 -0
  200. loopmath-0.1.0/src/loopmath/report/terminal_read.py +172 -0
  201. loopmath-0.1.0/src/loopmath/research_paths.py +68 -0
  202. loopmath-0.1.0/src/loopmath/scoring.py +302 -0
  203. loopmath-0.1.0/src/loopmath/scoring_comparisons.py +447 -0
  204. loopmath-0.1.0/src/loopmath/scoring_predictive.py +377 -0
  205. loopmath-0.1.0/src/loopmath/share/__init__.py +6 -0
  206. loopmath-0.1.0/src/loopmath/share/commands.py +90 -0
  207. loopmath-0.1.0/src/loopmath/share/export.py +599 -0
  208. loopmath-0.1.0/src/loopmath/share/import_.py +432 -0
  209. loopmath-0.1.0/src/loopmath/skill/SKILL.md +157 -0
  210. loopmath-0.1.0/src/loopmath/skill/__init__.py +6 -0
  211. loopmath-0.1.0/src/loopmath/skill/commands.py +61 -0
  212. loopmath-0.1.0/src/loopmath/skill/doctor.py +207 -0
  213. loopmath-0.1.0/src/loopmath/skill/install.py +242 -0
  214. loopmath-0.1.0/src/loopmath/store/__init__.py +15 -0
  215. loopmath-0.1.0/src/loopmath/store/budget.py +86 -0
  216. loopmath-0.1.0/src/loopmath/store/commands.py +784 -0
  217. loopmath-0.1.0/src/loopmath/store/config.py +420 -0
  218. loopmath-0.1.0/src/loopmath/store/finish.py +406 -0
  219. loopmath-0.1.0/src/loopmath/store/fitjob.py +227 -0
  220. loopmath-0.1.0/src/loopmath/store/home.py +514 -0
  221. loopmath-0.1.0/src/loopmath/store/ids.py +157 -0
  222. loopmath-0.1.0/src/loopmath/store/lock.py +200 -0
  223. loopmath-0.1.0/src/loopmath/store/report.py +297 -0
  224. loopmath-0.1.0/src/loopmath/store/runs.py +450 -0
  225. loopmath-0.1.0/src/loopmath/store/status.py +189 -0
  226. loopmath-0.1.0/src/loopmath/surface.py +211 -0
  227. loopmath-0.1.0/src/loopmath/surface_bootstrap.py +164 -0
  228. loopmath-0.1.0/src/loopmath/surface_estimation.py +389 -0
  229. loopmath-0.1.0/src/loopmath/surface_frame.py +157 -0
  230. loopmath-0.1.0/src/loopmath/surface_presentation.py +205 -0
  231. loopmath-0.1.0/src/loopmath/surface_support.py +132 -0
  232. loopmath-0.1.0/src/loopmath/taskmodel.py +254 -0
  233. loopmath-0.1.0/src/loopmath/types.py +384 -0
  234. loopmath-0.1.0/src/loopmath/views/__init__.py +6 -0
  235. loopmath-0.1.0/src/loopmath/views/assets/README.md +1 -0
  236. loopmath-0.1.0/src/loopmath/views/assets/base.css +94 -0
  237. loopmath-0.1.0/src/loopmath/views/assets/common.js +89 -0
  238. loopmath-0.1.0/src/loopmath/views/assets/graph.css +28 -0
  239. loopmath-0.1.0/src/loopmath/views/assets/graph.js +357 -0
  240. loopmath-0.1.0/src/loopmath/views/assets/plans.css +27 -0
  241. loopmath-0.1.0/src/loopmath/views/assets/plans.js +331 -0
  242. loopmath-0.1.0/src/loopmath/views/assets/runs.js +239 -0
  243. loopmath-0.1.0/src/loopmath/views/common.py +486 -0
  244. loopmath-0.1.0/src/loopmath/views/plans.py +146 -0
  245. loopmath-0.1.0/src/loopmath/views/posterior.py +1737 -0
  246. loopmath-0.1.0/src/loopmath/views/runs.py +460 -0
  247. loopmath-0.1.0/src/loopmath/workflows/__init__.py +48 -0
  248. loopmath-0.1.0/src/loopmath/workflows/candidates.py +294 -0
  249. loopmath-0.1.0/src/loopmath/workflows/catalog/best_of_n.toml +46 -0
  250. loopmath-0.1.0/src/loopmath/workflows/catalog/implement_review.toml +47 -0
  251. loopmath-0.1.0/src/loopmath/workflows/catalog/plan_implement.toml +42 -0
  252. loopmath-0.1.0/src/loopmath/workflows/catalog/plan_implement_review.toml +61 -0
  253. loopmath-0.1.0/src/loopmath/workflows/catalog/solo.toml +29 -0
  254. loopmath-0.1.0/src/loopmath/workflows/catalog/swarm.toml +61 -0
  255. loopmath-0.1.0/src/loopmath/workflows/commands.py +399 -0
  256. loopmath-0.1.0/src/loopmath/workflows/diff.py +161 -0
  257. loopmath-0.1.0/src/loopmath/workflows/format.py +526 -0
  258. loopmath-0.1.0/src/loopmath/workflows/graphview.py +34 -0
  259. loopmath-0.1.0/src/loopmath/workflows/ids.py +47 -0
  260. loopmath-0.1.0/src/loopmath/workflows/infer.py +630 -0
  261. loopmath-0.1.0/src/loopmath/workflows/models.py +138 -0
  262. loopmath-0.1.0/src/loopmath/workflows/ocp.py +268 -0
  263. loopmath-0.1.0/src/loopmath/workflows/shapes.py +203 -0
  264. loopmath-0.1.0/src/loopmath.egg-info/PKG-INFO +239 -0
  265. loopmath-0.1.0/src/loopmath.egg-info/SOURCES.txt +331 -0
  266. loopmath-0.1.0/src/loopmath.egg-info/dependency_links.txt +1 -0
  267. loopmath-0.1.0/src/loopmath.egg-info/entry_points.txt +3 -0
  268. loopmath-0.1.0/src/loopmath.egg-info/requires.txt +13 -0
  269. loopmath-0.1.0/src/loopmath.egg-info/top_level.txt +1 -0
  270. loopmath-0.1.0/tests/test_adapter_atrium.py +256 -0
  271. loopmath-0.1.0/tests/test_adapter_bb.py +701 -0
  272. loopmath-0.1.0/tests/test_adapter_omp.py +745 -0
  273. loopmath-0.1.0/tests/test_adapter_opencode.py +409 -0
  274. loopmath-0.1.0/tests/test_adapter_orca.py +248 -0
  275. loopmath-0.1.0/tests/test_adapter_otel_genai.py +772 -0
  276. loopmath-0.1.0/tests/test_adapter_paseo.py +290 -0
  277. loopmath-0.1.0/tests/test_adapter_services.py +420 -0
  278. loopmath-0.1.0/tests/test_adapters.py +166 -0
  279. loopmath-0.1.0/tests/test_adapters_pi.py +324 -0
  280. loopmath-0.1.0/tests/test_arms.py +60 -0
  281. loopmath-0.1.0/tests/test_cli_graph.py +658 -0
  282. loopmath-0.1.0/tests/test_cli_labeler.py +32 -0
  283. loopmath-0.1.0/tests/test_cli_main_module.py +32 -0
  284. loopmath-0.1.0/tests/test_cli_prices.py +88 -0
  285. loopmath-0.1.0/tests/test_cli_startup.py +35 -0
  286. loopmath-0.1.0/tests/test_color_proof.py +46 -0
  287. loopmath-0.1.0/tests/test_duplicate_guards.py +359 -0
  288. loopmath-0.1.0/tests/test_estimate.py +125 -0
  289. loopmath-0.1.0/tests/test_explain.py +37 -0
  290. loopmath-0.1.0/tests/test_fit.py +535 -0
  291. loopmath-0.1.0/tests/test_gaps.py +108 -0
  292. loopmath-0.1.0/tests/test_grade.py +809 -0
  293. loopmath-0.1.0/tests/test_graph_artifact_recording.py +338 -0
  294. loopmath-0.1.0/tests/test_graph_artifacts.py +516 -0
  295. loopmath-0.1.0/tests/test_graph_bashwrites.py +142 -0
  296. loopmath-0.1.0/tests/test_graph_cache.py +783 -0
  297. loopmath-0.1.0/tests/test_graph_codexio.py +484 -0
  298. loopmath-0.1.0/tests/test_graph_dataset.py +946 -0
  299. loopmath-0.1.0/tests/test_graph_extract.py +486 -0
  300. loopmath-0.1.0/tests/test_graph_glue.py +56 -0
  301. loopmath-0.1.0/tests/test_graph_html.py +487 -0
  302. loopmath-0.1.0/tests/test_graph_labeler.py +1461 -0
  303. loopmath-0.1.0/tests/test_graph_labeler_evidence_matrix.py +1961 -0
  304. loopmath-0.1.0/tests/test_graph_launch.py +566 -0
  305. loopmath-0.1.0/tests/test_graph_ocp.py +601 -0
  306. loopmath-0.1.0/tests/test_graph_render.py +156 -0
  307. loopmath-0.1.0/tests/test_graph_runfile.py +504 -0
  308. loopmath-0.1.0/tests/test_graph_schema.py +232 -0
  309. loopmath-0.1.0/tests/test_html.py +69 -0
  310. loopmath-0.1.0/tests/test_ingest.py +469 -0
  311. loopmath-0.1.0/tests/test_ingest_claude_code.py +761 -0
  312. loopmath-0.1.0/tests/test_ingest_codex.py +687 -0
  313. loopmath-0.1.0/tests/test_ingest_ocp.py +830 -0
  314. loopmath-0.1.0/tests/test_io.py +42 -0
  315. loopmath-0.1.0/tests/test_not_run_summary.py +62 -0
  316. loopmath-0.1.0/tests/test_ocp_conformance.py +866 -0
  317. loopmath-0.1.0/tests/test_ocp_golden.py +39 -0
  318. loopmath-0.1.0/tests/test_ocp_open_enums.py +85 -0
  319. loopmath-0.1.0/tests/test_ocp_versioning.py +43 -0
  320. loopmath-0.1.0/tests/test_packaging_metadata.py +101 -0
  321. loopmath-0.1.0/tests/test_packaging_smoke.py +305 -0
  322. loopmath-0.1.0/tests/test_preview_script.py +35 -0
  323. loopmath-0.1.0/tests/test_price.py +1015 -0
  324. loopmath-0.1.0/tests/test_receipts.py +89 -0
  325. loopmath-0.1.0/tests/test_release_paths.py +79 -0
  326. loopmath-0.1.0/tests/test_runfile_privacy_n1b.py +251 -0
  327. loopmath-0.1.0/tests/test_scoring.py +699 -0
  328. loopmath-0.1.0/tests/test_split_rebindings.py +535 -0
  329. loopmath-0.1.0/tests/test_surface.py +1369 -0
  330. loopmath-0.1.0/tests/test_terminal.py +1570 -0
  331. loopmath-0.1.0/tests/test_types_control.py +22 -0
  332. loopmath-0.1.0/tests/test_types_piece_prediction.py +25 -0
  333. loopmath-0.1.0/tests/test_v01_scaffold.py +122 -0
  334. loopmath-0.0.1/PKG-INFO +0 -18
  335. loopmath-0.0.1/README.md +0 -7
  336. loopmath-0.0.1/pyproject.toml +0 -19
  337. loopmath-0.0.1/src/loopmath/__init__.py +0 -3
loopmath-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 QKV Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,239 @@
1
+ Metadata-Version: 2.4
2
+ Name: loopmath
3
+ Version: 0.1.0
4
+ Summary: Plan agent workflows, record how they went, and learn from your own Claude Code and Codex logs
5
+ Author: QKV Labs
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/loopmath/loopmath
8
+ Project-URL: Issues, https://github.com/loopmath/loopmath/issues
9
+ Project-URL: Repository, https://github.com/loopmath/loopmath.git
10
+ Keywords: agents,claude code,codex,cost analysis,developer tools,workflow analysis
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Software Development
22
+ Classifier: Topic :: Software Development :: Quality Assurance
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: jsonschema>=4
27
+ Requires-Dist: numpy
28
+ Requires-Dist: pandas
29
+ Requires-Dist: scipy
30
+ Provides-Extra: bayes
31
+ Requires-Dist: pymc>=5; extra == "bayes"
32
+ Requires-Dist: pytensor; extra == "bayes"
33
+ Requires-Dist: arviz; extra == "bayes"
34
+ Requires-Dist: h5netcdf; extra == "bayes"
35
+ Provides-Extra: e0
36
+ Requires-Dist: matplotlib; extra == "e0"
37
+ Dynamic: license-file
38
+
39
+ # loopmath
40
+
41
+ loopmath helps an orchestrator agent choose how to run a coding task, and learns from how it went.
42
+
43
+ Before a task, it predicts how the user's usual agent workflow will do: the chance of an accepted result, and the cost in tokens and dollars. It shows the other workflows on a success-cost curve and offers two exploration picks. Each pick comes with its gain on every future similar run, its one-time price, and the number of runs it takes to pay back. After the task, the orchestrator records what ran and what came of it. loopmath fills in the token costs from the Claude Code and Codex logs, writes a receipt of predicted against actual, and refits.
44
+
45
+ loopmath never starts or coordinates agents. Claude Code, Codex, herdr or your own tool does that; loopmath is a CLI they call. Everything runs locally. No command opens a network connection, the logs are opened read only, and loopmath writes only to its store (`~/.loopmath`) and to paths you name.
46
+
47
+ The package installs two commands: `loopmath` and its short alias `loop`. If another `loop` is already on your PATH, use `loopmath`.
48
+
49
+ ## Install
50
+
51
+ Python 3.11 or newer.
52
+
53
+ ```sh
54
+ pipx install loopmath # or: uv tool install loopmath, or pip install loopmath in a venv
55
+ loopmath --version
56
+ ```
57
+
58
+ From a clone of this repository:
59
+
60
+ ```sh
61
+ python3 -m venv .venv
62
+ .venv/bin/python -m pip install -e .
63
+ ```
64
+
65
+ ## First run
66
+
67
+ ```sh
68
+ loopmath doctor # what loopmath can see: logs, agents, store, fit, prices, skill
69
+ loopmath skill install --target both # teach Claude Code and Codex how to use loopmath
70
+ ```
71
+
72
+ `skill install` writes one `SKILL.md` for Claude Code (under `~/.claude/skills/loopmath/`) and one for Codex (under `~/.codex/skills/loopmath/`). If your Codex has no skills folder, it writes the file to `~/.codex/loopmath/SKILL.md` instead and adds a short marked block to `~/.codex/AGENTS.md` that points to it. Add `--scope project` to install into the current repository. It is safe to run again, and it rewrites only its own files. `loopmath skill uninstall` removes them.
73
+
74
+ Next, turn your history into a starting point:
75
+
76
+ ```sh
77
+ loopmath onboard --labeler claude:claude-haiku-4-5 --dry-run # see what it found and what labelling costs
78
+ loopmath onboard --labeler claude:claude-haiku-4-5 --yes # record it and run a first fit
79
+ ```
80
+
81
+ `onboard` reads your recent Claude Code and Codex sessions (the last 90 days unless you pass `--since`). It groups them into runs, labels each group's task type with a model you choose, names your usual workflow per task type and repository, and fits. loopmath never picks the labelling model for you. `--labeler` takes one of:
82
+
83
+ - `claude:<model>`, through your `claude` CLI;
84
+ - `codex:<model>`, through your `codex` CLI;
85
+ - `command:<cmd>`, any local command such as `command:ollama run <model>`, so nothing leaves the machine;
86
+ - `none`, to skip labelling.
87
+
88
+ loopmath ships with a prior built from our own sweeps and experiments, so `recommend` gives an answer before you have any history. Your own runs then move it.
89
+
90
+ ## The loop
91
+
92
+ The skill tells an orchestrator agent to follow these steps. You can run the same commands by hand.
93
+
94
+ ```sh
95
+ # 1. Plan: classify the task, then ask.
96
+ loopmath task-types
97
+ loopmath recommend --type bug_fix --repo acme/api --feature size=s --feature lang=python --json
98
+ # the usual workflow, the success-cost curve, alternatives, two exploration picks, a suggested pair
99
+
100
+ # 2. Record: one run per workflow you run, one attempt per agent you launch.
101
+ loopmath run start --type bug_fix --repo acme/api --base-commit SHA --config CFG --source usual --rec REC
102
+ loopmath run attempt --run RUN --piece implement --harness claude-code --model claude-opus-5-5 \
103
+ --effort high --cwd . --session UUID # launch the agent with: claude --session-id UUID
104
+ loopmath run attempt --run RUN --end ATT --status done
105
+ loopmath run artifact --run RUN --kind commit --path SHA --by ATT
106
+
107
+ # 3. Outcome: verdicts, scores, and later events.
108
+ loopmath outcome --run RUN --signal tests=pass --kind verdict --tier verified
109
+ loopmath outcome --run RUN --signal runtime_s=182 --kind score --unit s --better lower
110
+
111
+ # 4. Finish: costs from the logs, a receipt, a refit.
112
+ loopmath run finish --run RUN
113
+
114
+ # Later: an incident or revert traced back to the run that made the commit.
115
+ loopmath outcome --commit SHA --signal incident=INC-42 --kind event --source tracker
116
+ ```
117
+
118
+ A pair runs the goal workflow and an exploration pick from the same base commit, in separate worktrees. Save the recommendation (`recommend ... --json > rec.json`) and start both runs from it with `run start --task-file rec.json`, so they share one task: the first with `--new-slate`, the second with `--slate SLT`. A blinded referee then picks the better change, which you record with `loopmath outcome --slate SLT --prefer RUN --judge referee --blinded`.
119
+
120
+ A run counts as a success when it is accepted under your rule. By default that means the task's tests pass. A rule can also be a score target: `loopmath recommend ... --target 'heldout_perf>=2400'` or `--target 'runtime_s<=200'` gives the expected score and the chance of reaching the target. Set standing rules and other options with `loopmath config set KEY VALUE`, and the spending cap with `loopmath budget --usd X --period month`.
121
+
122
+ ## The three views
123
+
124
+ Each view is a self-contained HTML file written by a command; there is no server. The same numbers are available with `--json`.
125
+
126
+ - **Previous runs:** `loopmath runs --html`. Every recorded run with its workflow graph, costs, signals and receipt.
127
+ - **Plans for a task:** `loopmath recommend ... --html`. The candidates on a success-cost chart. Click one to see its workflow graph with per-piece predictions.
128
+ - **Current estimates:** `loopmath posterior --html`. What loopmath believes at each level (model, effort, role, topology, task type, repository, feature), each with a range. Add `--workflow CFG` (a configuration id from `loopmath recommend` or your runs) to see the estimate for each piece of one workflow.
129
+
130
+ Without a path, `--html` writes the page under `~/.loopmath/views/` and prints where it went.
131
+
132
+ ## Commands
133
+
134
+ | Group | Commands |
135
+ |---|---|
136
+ | Plan | `task-types`, `workflows` (list, show, validate, diff), `recommend`, `plan` |
137
+ | Record | `run` (start, attempt, artifact, finish, import), `outcome`, `budget`, `config` (get, set) |
138
+ | Learn | `fit`, `onboard`, `share` |
139
+ | View | `runs`, `posterior`, `status`, `report`, `doctor` |
140
+ | Skill | `skill` (install, uninstall, show) |
141
+ | OCP | `ocp` (validate, migrate) |
142
+ | Log analysis | `analyze`, `graph`, `adapt`, `prices`, `validate-prices`, `scan`, `verify-receipts` |
143
+
144
+ Each command prints a short summary by default. With `--json`, it prints exactly one JSON object instead. Exit codes: 0 ok, 1 user error, 2 not found, 3 not implemented, 4 store locked, 5 no fit yet. For flags, `loopmath <command> --help` is the source of truth.
145
+
146
+ A workflow is a TOML file. `loopmath workflows list` shows the catalog and yours, which live in `~/.loopmath/workflows/`. This one implements, then sends a rejected change back once or twice:
147
+
148
+ ```toml
149
+ id = "implement_review_mine"
150
+ version = 1
151
+ title = "Implement, then review"
152
+ edges = ["issue -> implement", "repo -> implement", "implement -> diff", "diff -> review", "review -> verdict"]
153
+
154
+ [[pieces]]
155
+ id = "implement"
156
+ role = "implementer"
157
+
158
+ [[pieces]]
159
+ id = "review"
160
+ role = "reviewer"
161
+
162
+ [[artifacts]]
163
+ id = "issue"
164
+ kind = "issue"
165
+
166
+ [[artifacts]]
167
+ id = "repo"
168
+ kind = "repo"
169
+
170
+ [[artifacts]]
171
+ id = "diff"
172
+ kind = "diff"
173
+
174
+ [[artifacts]]
175
+ id = "verdict"
176
+ kind = "verdict"
177
+
178
+ [control]
179
+ budget_rounds = 3 # rounds, counting the first; 1 means no repair
180
+
181
+ [[control.gates]]
182
+ after = "review" # the review's verdict decides
183
+ on_fail = "implement" # a rejected change goes back to implement
184
+
185
+ [settings.implement] # optional; with a setting for every piece, the file is a configuration
186
+ harness = "claude-code"
187
+ model = "claude-opus-5-5"
188
+ effort = "high"
189
+
190
+ [settings.review]
191
+ harness = "codex"
192
+ model = "gpt-5.6-sol"
193
+ effort = "high"
194
+ ```
195
+
196
+ Check it with `loopmath workflows validate FILE`, compare it with `loopmath workflows diff implement_review FILE`, and pass it to `recommend --workflow FILE` to have it considered, or to `run start --workflow FILE` to record a run with its settings (`--set PIECE=HARNESS:MODEL:EFFORT` overrides a piece).
197
+
198
+ ## The store and privacy
199
+
200
+ The store is `~/.loopmath`. Set `LOOPMATH_HOME` or pass `--home` to put it elsewhere; the log parse cache moves with it, to `cache/` inside the store, unless you set `LOOPMATH_CACHE_DIR`. It holds:
201
+
202
+ - one OCP v0.3 document per recorded run;
203
+ - signals, receipts and fits;
204
+ - your config and your workflows;
205
+ - the views you write;
206
+ - the log parse cache.
207
+
208
+ Do not edit the store by hand; use the commands.
209
+
210
+ Run files use the `metadata_only` privacy profile. They keep structure, models, tokens, dollars, paths and verdicts, but not transcript text.
211
+
212
+ `loopmath share --out FILE` writes a reduced copy you can send to us. It keeps task types, workflows, models, tokens, dollars and outcomes. Repository names are hashed. Titles, paths, commands, session ids and commit shas are removed. `loopmath share --preview` prints exactly what would leave.
213
+
214
+ ## Analyzing logs without recording
215
+
216
+ The log commands work on their own, with no store or fit:
217
+
218
+ ```sh
219
+ loopmath analyze # cost per accepted run from the last 14 days of local logs
220
+ loopmath graph --workspace NAME --format html --out graph.html
221
+ ```
222
+
223
+ `analyze` reads `~/.claude/projects` and `~/.codex/sessions`. It grades the outcome evidence it finds, prices known models, and prints cost per accepted run with an 80% band. It also lists what it could not use and why.
224
+
225
+ `graph` rebuilds which agent launched which, and which session read what another wrote. Its formats are `ocp`, `json`, `dot`, `run` and `html`. See the [workflow graph guide](docs/graph.md) and [adapters](docs/adapters.md).
226
+
227
+ ## Research data
228
+
229
+ `loopmath research fit|transfer-test` and `loopmath analyze-e0` read data folders that are not part of the package. Name them with a flag (`--sweep-dir`, `--corpus`), an environment variable (`LOOPMATH_SWEEP_DIR`, `LOOPMATH_E0_CORPUS`), or config (`loopmath config set research.sweep_dir PATH`, `research.e0_corpus`). The research verbs need the `bayes` extra (`pip install 'loopmath[bayes]'`).
230
+
231
+ ## More
232
+
233
+ - [OCP, the run format](spec/OCP.md), with its [schemas](spec/) and [versioning promise](spec/VERSIONING.md)
234
+ - [Release policy](docs/release.md)
235
+ - [Packaged model prices](src/loopmath/prices.toml)
236
+
237
+ ## License
238
+
239
+ MIT.
@@ -0,0 +1,201 @@
1
+ # loopmath
2
+
3
+ loopmath helps an orchestrator agent choose how to run a coding task, and learns from how it went.
4
+
5
+ Before a task, it predicts how the user's usual agent workflow will do: the chance of an accepted result, and the cost in tokens and dollars. It shows the other workflows on a success-cost curve and offers two exploration picks. Each pick comes with its gain on every future similar run, its one-time price, and the number of runs it takes to pay back. After the task, the orchestrator records what ran and what came of it. loopmath fills in the token costs from the Claude Code and Codex logs, writes a receipt of predicted against actual, and refits.
6
+
7
+ loopmath never starts or coordinates agents. Claude Code, Codex, herdr or your own tool does that; loopmath is a CLI they call. Everything runs locally. No command opens a network connection, the logs are opened read only, and loopmath writes only to its store (`~/.loopmath`) and to paths you name.
8
+
9
+ The package installs two commands: `loopmath` and its short alias `loop`. If another `loop` is already on your PATH, use `loopmath`.
10
+
11
+ ## Install
12
+
13
+ Python 3.11 or newer.
14
+
15
+ ```sh
16
+ pipx install loopmath # or: uv tool install loopmath, or pip install loopmath in a venv
17
+ loopmath --version
18
+ ```
19
+
20
+ From a clone of this repository:
21
+
22
+ ```sh
23
+ python3 -m venv .venv
24
+ .venv/bin/python -m pip install -e .
25
+ ```
26
+
27
+ ## First run
28
+
29
+ ```sh
30
+ loopmath doctor # what loopmath can see: logs, agents, store, fit, prices, skill
31
+ loopmath skill install --target both # teach Claude Code and Codex how to use loopmath
32
+ ```
33
+
34
+ `skill install` writes one `SKILL.md` for Claude Code (under `~/.claude/skills/loopmath/`) and one for Codex (under `~/.codex/skills/loopmath/`). If your Codex has no skills folder, it writes the file to `~/.codex/loopmath/SKILL.md` instead and adds a short marked block to `~/.codex/AGENTS.md` that points to it. Add `--scope project` to install into the current repository. It is safe to run again, and it rewrites only its own files. `loopmath skill uninstall` removes them.
35
+
36
+ Next, turn your history into a starting point:
37
+
38
+ ```sh
39
+ loopmath onboard --labeler claude:claude-haiku-4-5 --dry-run # see what it found and what labelling costs
40
+ loopmath onboard --labeler claude:claude-haiku-4-5 --yes # record it and run a first fit
41
+ ```
42
+
43
+ `onboard` reads your recent Claude Code and Codex sessions (the last 90 days unless you pass `--since`). It groups them into runs, labels each group's task type with a model you choose, names your usual workflow per task type and repository, and fits. loopmath never picks the labelling model for you. `--labeler` takes one of:
44
+
45
+ - `claude:<model>`, through your `claude` CLI;
46
+ - `codex:<model>`, through your `codex` CLI;
47
+ - `command:<cmd>`, any local command such as `command:ollama run <model>`, so nothing leaves the machine;
48
+ - `none`, to skip labelling.
49
+
50
+ loopmath ships with a prior built from our own sweeps and experiments, so `recommend` gives an answer before you have any history. Your own runs then move it.
51
+
52
+ ## The loop
53
+
54
+ The skill tells an orchestrator agent to follow these steps. You can run the same commands by hand.
55
+
56
+ ```sh
57
+ # 1. Plan: classify the task, then ask.
58
+ loopmath task-types
59
+ loopmath recommend --type bug_fix --repo acme/api --feature size=s --feature lang=python --json
60
+ # the usual workflow, the success-cost curve, alternatives, two exploration picks, a suggested pair
61
+
62
+ # 2. Record: one run per workflow you run, one attempt per agent you launch.
63
+ loopmath run start --type bug_fix --repo acme/api --base-commit SHA --config CFG --source usual --rec REC
64
+ loopmath run attempt --run RUN --piece implement --harness claude-code --model claude-opus-5-5 \
65
+ --effort high --cwd . --session UUID # launch the agent with: claude --session-id UUID
66
+ loopmath run attempt --run RUN --end ATT --status done
67
+ loopmath run artifact --run RUN --kind commit --path SHA --by ATT
68
+
69
+ # 3. Outcome: verdicts, scores, and later events.
70
+ loopmath outcome --run RUN --signal tests=pass --kind verdict --tier verified
71
+ loopmath outcome --run RUN --signal runtime_s=182 --kind score --unit s --better lower
72
+
73
+ # 4. Finish: costs from the logs, a receipt, a refit.
74
+ loopmath run finish --run RUN
75
+
76
+ # Later: an incident or revert traced back to the run that made the commit.
77
+ loopmath outcome --commit SHA --signal incident=INC-42 --kind event --source tracker
78
+ ```
79
+
80
+ A pair runs the goal workflow and an exploration pick from the same base commit, in separate worktrees. Save the recommendation (`recommend ... --json > rec.json`) and start both runs from it with `run start --task-file rec.json`, so they share one task: the first with `--new-slate`, the second with `--slate SLT`. A blinded referee then picks the better change, which you record with `loopmath outcome --slate SLT --prefer RUN --judge referee --blinded`.
81
+
82
+ A run counts as a success when it is accepted under your rule. By default that means the task's tests pass. A rule can also be a score target: `loopmath recommend ... --target 'heldout_perf>=2400'` or `--target 'runtime_s<=200'` gives the expected score and the chance of reaching the target. Set standing rules and other options with `loopmath config set KEY VALUE`, and the spending cap with `loopmath budget --usd X --period month`.
83
+
84
+ ## The three views
85
+
86
+ Each view is a self-contained HTML file written by a command; there is no server. The same numbers are available with `--json`.
87
+
88
+ - **Previous runs:** `loopmath runs --html`. Every recorded run with its workflow graph, costs, signals and receipt.
89
+ - **Plans for a task:** `loopmath recommend ... --html`. The candidates on a success-cost chart. Click one to see its workflow graph with per-piece predictions.
90
+ - **Current estimates:** `loopmath posterior --html`. What loopmath believes at each level (model, effort, role, topology, task type, repository, feature), each with a range. Add `--workflow CFG` (a configuration id from `loopmath recommend` or your runs) to see the estimate for each piece of one workflow.
91
+
92
+ Without a path, `--html` writes the page under `~/.loopmath/views/` and prints where it went.
93
+
94
+ ## Commands
95
+
96
+ | Group | Commands |
97
+ |---|---|
98
+ | Plan | `task-types`, `workflows` (list, show, validate, diff), `recommend`, `plan` |
99
+ | Record | `run` (start, attempt, artifact, finish, import), `outcome`, `budget`, `config` (get, set) |
100
+ | Learn | `fit`, `onboard`, `share` |
101
+ | View | `runs`, `posterior`, `status`, `report`, `doctor` |
102
+ | Skill | `skill` (install, uninstall, show) |
103
+ | OCP | `ocp` (validate, migrate) |
104
+ | Log analysis | `analyze`, `graph`, `adapt`, `prices`, `validate-prices`, `scan`, `verify-receipts` |
105
+
106
+ Each command prints a short summary by default. With `--json`, it prints exactly one JSON object instead. Exit codes: 0 ok, 1 user error, 2 not found, 3 not implemented, 4 store locked, 5 no fit yet. For flags, `loopmath <command> --help` is the source of truth.
107
+
108
+ A workflow is a TOML file. `loopmath workflows list` shows the catalog and yours, which live in `~/.loopmath/workflows/`. This one implements, then sends a rejected change back once or twice:
109
+
110
+ ```toml
111
+ id = "implement_review_mine"
112
+ version = 1
113
+ title = "Implement, then review"
114
+ edges = ["issue -> implement", "repo -> implement", "implement -> diff", "diff -> review", "review -> verdict"]
115
+
116
+ [[pieces]]
117
+ id = "implement"
118
+ role = "implementer"
119
+
120
+ [[pieces]]
121
+ id = "review"
122
+ role = "reviewer"
123
+
124
+ [[artifacts]]
125
+ id = "issue"
126
+ kind = "issue"
127
+
128
+ [[artifacts]]
129
+ id = "repo"
130
+ kind = "repo"
131
+
132
+ [[artifacts]]
133
+ id = "diff"
134
+ kind = "diff"
135
+
136
+ [[artifacts]]
137
+ id = "verdict"
138
+ kind = "verdict"
139
+
140
+ [control]
141
+ budget_rounds = 3 # rounds, counting the first; 1 means no repair
142
+
143
+ [[control.gates]]
144
+ after = "review" # the review's verdict decides
145
+ on_fail = "implement" # a rejected change goes back to implement
146
+
147
+ [settings.implement] # optional; with a setting for every piece, the file is a configuration
148
+ harness = "claude-code"
149
+ model = "claude-opus-5-5"
150
+ effort = "high"
151
+
152
+ [settings.review]
153
+ harness = "codex"
154
+ model = "gpt-5.6-sol"
155
+ effort = "high"
156
+ ```
157
+
158
+ Check it with `loopmath workflows validate FILE`, compare it with `loopmath workflows diff implement_review FILE`, and pass it to `recommend --workflow FILE` to have it considered, or to `run start --workflow FILE` to record a run with its settings (`--set PIECE=HARNESS:MODEL:EFFORT` overrides a piece).
159
+
160
+ ## The store and privacy
161
+
162
+ The store is `~/.loopmath`. Set `LOOPMATH_HOME` or pass `--home` to put it elsewhere; the log parse cache moves with it, to `cache/` inside the store, unless you set `LOOPMATH_CACHE_DIR`. It holds:
163
+
164
+ - one OCP v0.3 document per recorded run;
165
+ - signals, receipts and fits;
166
+ - your config and your workflows;
167
+ - the views you write;
168
+ - the log parse cache.
169
+
170
+ Do not edit the store by hand; use the commands.
171
+
172
+ Run files use the `metadata_only` privacy profile. They keep structure, models, tokens, dollars, paths and verdicts, but not transcript text.
173
+
174
+ `loopmath share --out FILE` writes a reduced copy you can send to us. It keeps task types, workflows, models, tokens, dollars and outcomes. Repository names are hashed. Titles, paths, commands, session ids and commit shas are removed. `loopmath share --preview` prints exactly what would leave.
175
+
176
+ ## Analyzing logs without recording
177
+
178
+ The log commands work on their own, with no store or fit:
179
+
180
+ ```sh
181
+ loopmath analyze # cost per accepted run from the last 14 days of local logs
182
+ loopmath graph --workspace NAME --format html --out graph.html
183
+ ```
184
+
185
+ `analyze` reads `~/.claude/projects` and `~/.codex/sessions`. It grades the outcome evidence it finds, prices known models, and prints cost per accepted run with an 80% band. It also lists what it could not use and why.
186
+
187
+ `graph` rebuilds which agent launched which, and which session read what another wrote. Its formats are `ocp`, `json`, `dot`, `run` and `html`. See the [workflow graph guide](docs/graph.md) and [adapters](docs/adapters.md).
188
+
189
+ ## Research data
190
+
191
+ `loopmath research fit|transfer-test` and `loopmath analyze-e0` read data folders that are not part of the package. Name them with a flag (`--sweep-dir`, `--corpus`), an environment variable (`LOOPMATH_SWEEP_DIR`, `LOOPMATH_E0_CORPUS`), or config (`loopmath config set research.sweep_dir PATH`, `research.e0_corpus`). The research verbs need the `bayes` extra (`pip install 'loopmath[bayes]'`).
192
+
193
+ ## More
194
+
195
+ - [OCP, the run format](spec/OCP.md), with its [schemas](spec/) and [versioning promise](spec/VERSIONING.md)
196
+ - [Release policy](docs/release.md)
197
+ - [Packaged model prices](src/loopmath/prices.toml)
198
+
199
+ ## License
200
+
201
+ MIT.
@@ -0,0 +1,110 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "loopmath"
7
+ version = "0.1.0"
8
+ description = "Plan agent workflows, record how they went, and learn from your own Claude Code and Codex logs"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.11"
13
+ authors = [
14
+ { name = "QKV Labs" },
15
+ ]
16
+ keywords = [
17
+ "agents",
18
+ "claude code",
19
+ "codex",
20
+ "cost analysis",
21
+ "developer tools",
22
+ "workflow analysis",
23
+ ]
24
+ classifiers = [
25
+ "Development Status :: 3 - Alpha",
26
+ "Environment :: Console",
27
+ "Intended Audience :: Developers",
28
+ "Operating System :: OS Independent",
29
+ "Programming Language :: Python :: 3",
30
+ "Programming Language :: Python :: 3 :: Only",
31
+ "Programming Language :: Python :: 3.11",
32
+ "Programming Language :: Python :: 3.12",
33
+ "Programming Language :: Python :: 3.13",
34
+ "Programming Language :: Python :: 3.14",
35
+ "Topic :: Software Development",
36
+ "Topic :: Software Development :: Quality Assurance",
37
+ ]
38
+ # Core: everything the loop needs (onboard, recommend, run, outcome, finish, the
39
+ # views). The default belief engine behind `fit`, `recommend` and receipts is
40
+ # Gaussian and uses scipy (spec 00 section 4, `loopmath/belief/`); jsonschema
41
+ # checks OCP documents; `analyze` runs on numpy and pandas. A plotting stack
42
+ # stays out: matplotlib is only for the E0 figure writer (the `e0` extra).
43
+ dependencies = [
44
+ "jsonschema>=4",
45
+ "numpy",
46
+ "pandas",
47
+ "scipy",
48
+ ]
49
+
50
+ # The research verbs (`loopmath research fit|transfer-test`) use the older PyMC
51
+ # engine and need the [bayes] extra; they say so when it is missing. The default
52
+ # engine does not.
53
+ [project.optional-dependencies]
54
+ bayes = [
55
+ "pymc>=5",
56
+ # `fit_bayes.py` imports pytensor directly. Do not rely on pymc's
57
+ # transitive dependency to supply a module loopmath itself imports.
58
+ "pytensor",
59
+ "arviz",
60
+ # arviz writes a fit with `to_netcdf`, which needs a NetCDF backend it does
61
+ # not itself depend on. Without one, `loopmath research fit --out PATH` samples fine and
62
+ # then dies on the write. Declared here so a fresh install of the extra can
63
+ # actually use `--out`; the CLI still catches the missing backend and says
64
+ # which package to install rather than surfacing a raw ValueError.
65
+ "h5netcdf",
66
+ ]
67
+
68
+ # The E0 walkdown verb writes figures, which is the only thing in the package
69
+ # that needs a plotting stack. Without this extra, `loopmath analyze-e0` is simply
70
+ # not registered and every other verb works unchanged.
71
+ e0 = [
72
+ "matplotlib",
73
+ ]
74
+
75
+ [project.scripts]
76
+ loopmath = "loopmath.cli:main"
77
+ loop = "loopmath.cli:main"
78
+
79
+ [project.urls]
80
+ Homepage = "https://github.com/loopmath/loopmath"
81
+ Issues = "https://github.com/loopmath/loopmath/issues"
82
+ Repository = "https://github.com/loopmath/loopmath.git"
83
+
84
+ [tool.setuptools.packages.find]
85
+ where = ["src"]
86
+
87
+ [tool.setuptools.package-data]
88
+ loopmath = [
89
+ "prices.toml",
90
+ "workflows/catalog/*.toml",
91
+ "skill/SKILL.md",
92
+ "priors/*.toml",
93
+ "priors/bundle/*",
94
+ "views/assets/*",
95
+ "ocp/schema/*.json",
96
+ ]
97
+
98
+ [tool.setuptools.data-files]
99
+ spec = [
100
+ "spec/ocp_conformance.py",
101
+ "spec/ocp-v0.schema.json",
102
+ "spec/ocp-v0.2.schema.json",
103
+ ]
104
+
105
+ [tool.pytest.ini_options]
106
+ testpaths = ["tests"]
107
+ addopts = '-m "not packaging"'
108
+ markers = [
109
+ "packaging: builds and installs a distribution artifact in an isolated environment",
110
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+