poisson-tasks 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 (395) hide show
  1. poisson_tasks-0.1.0/.github/workflows/ci.yml +109 -0
  2. poisson_tasks-0.1.0/.gitignore +61 -0
  3. poisson_tasks-0.1.0/CHANGELOG.md +85 -0
  4. poisson_tasks-0.1.0/CONTRIBUTING.md +87 -0
  5. poisson_tasks-0.1.0/LICENSE +21 -0
  6. poisson_tasks-0.1.0/NOTICE +370 -0
  7. poisson_tasks-0.1.0/PKG-INFO +276 -0
  8. poisson_tasks-0.1.0/README.md +217 -0
  9. poisson_tasks-0.1.0/calibration/gpt-5-nano-2025-08-07/artifact.json +2498 -0
  10. poisson_tasks-0.1.0/calibration/gpt-5-nano-2025-08-07/episodes.jsonl +4200 -0
  11. poisson_tasks-0.1.0/calibration/qwen3-8b-b968826d/artifact.json +2517 -0
  12. poisson_tasks-0.1.0/calibration/qwen3-8b-b968826d/episodes.jsonl +4200 -0
  13. poisson_tasks-0.1.0/calibration/qwen3-8b-b968826d/tallies.json +16 -0
  14. poisson_tasks-0.1.0/docs/calibration.md +389 -0
  15. poisson_tasks-0.1.0/docs/cli-look.md +96 -0
  16. poisson_tasks-0.1.0/docs/commands.md +697 -0
  17. poisson_tasks-0.1.0/docs/config.md +178 -0
  18. poisson_tasks-0.1.0/docs/images/generate-show.png +0 -0
  19. poisson_tasks-0.1.0/docs/knobs-and-arms.md +211 -0
  20. poisson_tasks-0.1.0/docs/own-tools.md +224 -0
  21. poisson_tasks-0.1.0/docs/proofload.md +29 -0
  22. poisson_tasks-0.1.0/docs/python.md +217 -0
  23. poisson_tasks-0.1.0/docs/reading-a-card.md +153 -0
  24. poisson_tasks-0.1.0/docs/repo-hygiene.md +101 -0
  25. poisson_tasks-0.1.0/docs/the-task.md +100 -0
  26. poisson_tasks-0.1.0/docs/verifiers-export.md +236 -0
  27. poisson_tasks-0.1.0/examples/README.md +52 -0
  28. poisson_tasks-0.1.0/examples/a_contrast.py +84 -0
  29. poisson_tasks-0.1.0/examples/calibration_card.py +128 -0
  30. poisson_tasks-0.1.0/examples/one_task.py +115 -0
  31. poisson_tasks-0.1.0/examples/proofload_sweep/run.py +221 -0
  32. poisson_tasks-0.1.0/gap-log.md +436 -0
  33. poisson_tasks-0.1.0/notebooks/calibration_model_b.ipynb +434 -0
  34. poisson_tasks-0.1.0/notebooks/requirements-colab.txt +105 -0
  35. poisson_tasks-0.1.0/pyproject.toml +176 -0
  36. poisson_tasks-0.1.0/src/poisson_tasks/__init__.py +27 -0
  37. poisson_tasks-0.1.0/src/poisson_tasks/__main__.py +5 -0
  38. poisson_tasks-0.1.0/src/poisson_tasks/_driver_args.py +200 -0
  39. poisson_tasks-0.1.0/src/poisson_tasks/_open_files.py +128 -0
  40. poisson_tasks-0.1.0/src/poisson_tasks/adapter.py +818 -0
  41. poisson_tasks-0.1.0/src/poisson_tasks/arms.py +314 -0
  42. poisson_tasks-0.1.0/src/poisson_tasks/calibration.py +3901 -0
  43. poisson_tasks-0.1.0/src/poisson_tasks/calibration_run.py +2152 -0
  44. poisson_tasks-0.1.0/src/poisson_tasks/cards.py +134 -0
  45. poisson_tasks-0.1.0/src/poisson_tasks/cli/__init__.py +301 -0
  46. poisson_tasks-0.1.0/src/poisson_tasks/cli/_banner.py +60 -0
  47. poisson_tasks-0.1.0/src/poisson_tasks/cli/_card.py +526 -0
  48. poisson_tasks-0.1.0/src/poisson_tasks/cli/_common.py +276 -0
  49. poisson_tasks-0.1.0/src/poisson_tasks/cli/_doctor.py +322 -0
  50. poisson_tasks-0.1.0/src/poisson_tasks/cli/_export.py +88 -0
  51. poisson_tasks-0.1.0/src/poisson_tasks/cli/_format.py +68 -0
  52. poisson_tasks-0.1.0/src/poisson_tasks/cli/_generate.py +407 -0
  53. poisson_tasks-0.1.0/src/poisson_tasks/cli/_init.py +839 -0
  54. poisson_tasks-0.1.0/src/poisson_tasks/cli/_parser.py +423 -0
  55. poisson_tasks-0.1.0/src/poisson_tasks/cli/_plain.py +365 -0
  56. poisson_tasks-0.1.0/src/poisson_tasks/cli/_pretty.py +598 -0
  57. poisson_tasks-0.1.0/src/poisson_tasks/cli/_result.py +118 -0
  58. poisson_tasks-0.1.0/src/poisson_tasks/cli/_run.py +497 -0
  59. poisson_tasks-0.1.0/src/poisson_tasks/cli/_session.py +1058 -0
  60. poisson_tasks-0.1.0/src/poisson_tasks/cli/_verify.py +212 -0
  61. poisson_tasks-0.1.0/src/poisson_tasks/config.py +2071 -0
  62. poisson_tasks-0.1.0/src/poisson_tasks/data/vocabulary-v2.json +1027 -0
  63. poisson_tasks-0.1.0/src/poisson_tasks/engine.py +441 -0
  64. poisson_tasks-0.1.0/src/poisson_tasks/export.py +988 -0
  65. poisson_tasks-0.1.0/src/poisson_tasks/fetch_encoding.py +150 -0
  66. poisson_tasks-0.1.0/src/poisson_tasks/folder.py +278 -0
  67. poisson_tasks-0.1.0/src/poisson_tasks/knob_probe.py +1847 -0
  68. poisson_tasks-0.1.0/src/poisson_tasks/knob_status.json +509 -0
  69. poisson_tasks-0.1.0/src/poisson_tasks/knobs.py +1670 -0
  70. poisson_tasks-0.1.0/src/poisson_tasks/outcomes.py +44 -0
  71. poisson_tasks-0.1.0/src/poisson_tasks/own/__init__.py +260 -0
  72. poisson_tasks-0.1.0/src/poisson_tasks/own/_readers.py +416 -0
  73. poisson_tasks-0.1.0/src/poisson_tasks/own/_schema.py +223 -0
  74. poisson_tasks-0.1.0/src/poisson_tasks/own/_server.py +100 -0
  75. poisson_tasks-0.1.0/src/poisson_tasks/own/_types.py +101 -0
  76. poisson_tasks-0.1.0/src/poisson_tasks/own/card.py +257 -0
  77. poisson_tasks-0.1.0/src/poisson_tasks/own/export.py +415 -0
  78. poisson_tasks-0.1.0/src/poisson_tasks/own/generator.py +1157 -0
  79. poisson_tasks-0.1.0/src/poisson_tasks/own/recipes.py +124 -0
  80. poisson_tasks-0.1.0/src/poisson_tasks/own/simulator.py +767 -0
  81. poisson_tasks-0.1.0/src/poisson_tasks/own/verdict.py +114 -0
  82. poisson_tasks-0.1.0/src/poisson_tasks/providers.py +609 -0
  83. poisson_tasks-0.1.0/src/poisson_tasks/py.typed +0 -0
  84. poisson_tasks-0.1.0/src/poisson_tasks/runs.py +1463 -0
  85. poisson_tasks-0.1.0/src/poisson_tasks/surface.py +560 -0
  86. poisson_tasks-0.1.0/src/poisson_tasks/tasks.py +2658 -0
  87. poisson_tasks-0.1.0/src/poisson_tasks/taskset.py +79 -0
  88. poisson_tasks-0.1.0/src/poisson_tasks/tokenizer.py +119 -0
  89. poisson_tasks-0.1.0/src/poisson_tasks/transcripts.py +230 -0
  90. poisson_tasks-0.1.0/src/poisson_tasks_own/__init__.py +29 -0
  91. poisson_tasks-0.1.0/src/poisson_tasks_own/py.typed +0 -0
  92. poisson_tasks-0.1.0/tests/conftest.py +135 -0
  93. poisson_tasks-0.1.0/tests/fake_vllm.py +212 -0
  94. poisson_tasks-0.1.0/tests/fd2_fakes.py +245 -0
  95. poisson_tasks-0.1.0/tests/fd3_child.py +92 -0
  96. poisson_tasks-0.1.0/tests/fd3_support.py +456 -0
  97. poisson_tasks-0.1.0/tests/fd4_support.py +490 -0
  98. poisson_tasks-0.1.0/tests/fd5_child.py +124 -0
  99. poisson_tasks-0.1.0/tests/fd5_support.py +882 -0
  100. poisson_tasks-0.1.0/tests/fd6_support.py +139 -0
  101. poisson_tasks-0.1.0/tests/fd9_support.py +925 -0
  102. poisson_tasks-0.1.0/tests/fixtures/fd9/banner-R-16.ans +2 -0
  103. poisson_tasks-0.1.0/tests/fixtures/fd9/banner-R-256.ans +2 -0
  104. poisson_tasks-0.1.0/tests/fixtures/fd9/banner-R-monochrome.ans +2 -0
  105. poisson_tasks-0.1.0/tests/fixtures/fd9/banner-R-truecolor.ans +2 -0
  106. poisson_tasks-0.1.0/tests/fixtures/fd9/banner.txt +2 -0
  107. poisson_tasks-0.1.0/tests/fixtures/k1/published-tasks.json.gz +0 -0
  108. poisson_tasks-0.1.0/tests/fixtures/model_server.py +485 -0
  109. poisson_tasks-0.1.0/tests/fixtures/o1/acme-mcp-envelope.json +194 -0
  110. poisson_tasks-0.1.0/tests/fixtures/o1/acme-mcp-tools-list.json +190 -0
  111. poisson_tasks-0.1.0/tests/fixtures/o1/acme-openai-chat.json +112 -0
  112. poisson_tasks-0.1.0/tests/fixtures/o1/acme-openai-responses.json +109 -0
  113. poisson_tasks-0.1.0/tests/fixtures/o1/acme-openapi-3.0.json +270 -0
  114. poisson_tasks-0.1.0/tests/fixtures/o1/acme-openapi-3.1.yaml +154 -0
  115. poisson_tasks-0.1.0/tests/fixtures/o1/fake_mcp_server.py +121 -0
  116. poisson_tasks-0.1.0/tests/fixtures/o1/mcp-everything-tools-list.json +394 -0
  117. poisson_tasks-0.1.0/tests/fixtures/o1/petstore-openapi-3.0.json +1 -0
  118. poisson_tasks-0.1.0/tests/fixtures/qwen3-8b-chat-template.json +9 -0
  119. poisson_tasks-0.1.0/tests/fixtures/vllm-serve-ninja-failure.log +104 -0
  120. poisson_tasks-0.1.0/tests/helpers.py +307 -0
  121. poisson_tasks-0.1.0/tests/k2_support.py +113 -0
  122. poisson_tasks-0.1.0/tests/k3_support.py +237 -0
  123. poisson_tasks-0.1.0/tests/k4_support.py +89 -0
  124. poisson_tasks-0.1.0/tests/k5_support.py +88 -0
  125. poisson_tasks-0.1.0/tests/k6_support.py +119 -0
  126. poisson_tasks-0.1.0/tests/k7_support.py +145 -0
  127. poisson_tasks-0.1.0/tests/k8_support.py +156 -0
  128. poisson_tasks-0.1.0/tests/k9_fake.py +456 -0
  129. poisson_tasks-0.1.0/tests/k9_regate_support.py +277 -0
  130. poisson_tasks-0.1.0/tests/k9_support.py +327 -0
  131. poisson_tasks-0.1.0/tests/keymask_support.py +214 -0
  132. poisson_tasks-0.1.0/tests/nofile_child.py +104 -0
  133. poisson_tasks-0.1.0/tests/o1_support.py +175 -0
  134. poisson_tasks-0.1.0/tests/o2_support.py +342 -0
  135. poisson_tasks-0.1.0/tests/r0_support.py +141 -0
  136. poisson_tasks-0.1.0/tests/test_bare_pytest.py +37 -0
  137. poisson_tasks-0.1.0/tests/test_cal_calibration.py +2370 -0
  138. poisson_tasks-0.1.0/tests/test_cal_calibration_fix.py +515 -0
  139. poisson_tasks-0.1.0/tests/test_cal_colab_env.py +102 -0
  140. poisson_tasks-0.1.0/tests/test_cal_combined_card.py +175 -0
  141. poisson_tasks-0.1.0/tests/test_cal_committed_cards.py +61 -0
  142. poisson_tasks-0.1.0/tests/test_cal_context_16k.py +153 -0
  143. poisson_tasks-0.1.0/tests/test_cal_decoding_wire.py +97 -0
  144. poisson_tasks-0.1.0/tests/test_cal_left_to_right_sums.py +72 -0
  145. poisson_tasks-0.1.0/tests/test_cal_notebook_drive.py +29 -0
  146. poisson_tasks-0.1.0/tests/test_cal_plain_words.py +87 -0
  147. poisson_tasks-0.1.0/tests/test_cal_qwen_install_fix.py +694 -0
  148. poisson_tasks-0.1.0/tests/test_cal_qwen_prep.py +855 -0
  149. poisson_tasks-0.1.0/tests/test_cal_reach_and_stop.py +220 -0
  150. poisson_tasks-0.1.0/tests/test_cal_sampler_fix.py +196 -0
  151. poisson_tasks-0.1.0/tests/test_cal_turn_cap.py +212 -0
  152. poisson_tasks-0.1.0/tests/test_cal_verify_older_bundle.py +78 -0
  153. poisson_tasks-0.1.0/tests/test_check3_fixes.py +237 -0
  154. poisson_tasks-0.1.0/tests/test_distractor_experimental.py +41 -0
  155. poisson_tasks-0.1.0/tests/test_fd1_arms.py +172 -0
  156. poisson_tasks-0.1.0/tests/test_fd1_build_clauses.py +253 -0
  157. poisson_tasks-0.1.0/tests/test_fd1_config.py +1126 -0
  158. poisson_tasks-0.1.0/tests/test_fd1_config_value_lines.py +50 -0
  159. poisson_tasks-0.1.0/tests/test_fd1_export_arm.py +272 -0
  160. poisson_tasks-0.1.0/tests/test_fd1_export_arm_ladder.py +82 -0
  161. poisson_tasks-0.1.0/tests/test_fd1_export_arm_note_wider.py +56 -0
  162. poisson_tasks-0.1.0/tests/test_fd1_export_build_clauses.py +54 -0
  163. poisson_tasks-0.1.0/tests/test_fd1_export_knob_pending.py +75 -0
  164. poisson_tasks-0.1.0/tests/test_fd2_anthropic_version.py +51 -0
  165. poisson_tasks-0.1.0/tests/test_fd2_environment.py +205 -0
  166. poisson_tasks-0.1.0/tests/test_fd2_key.py +729 -0
  167. poisson_tasks-0.1.0/tests/test_fd2_key_prefix.py +139 -0
  168. poisson_tasks-0.1.0/tests/test_fd2_key_safety.py +338 -0
  169. poisson_tasks-0.1.0/tests/test_fd2_ollama_latest.py +80 -0
  170. poisson_tasks-0.1.0/tests/test_fd2_server.py +218 -0
  171. poisson_tasks-0.1.0/tests/test_fd3_cap.py +369 -0
  172. poisson_tasks-0.1.0/tests/test_fd3_config.py +281 -0
  173. poisson_tasks-0.1.0/tests/test_fd3_estimate.py +233 -0
  174. poisson_tasks-0.1.0/tests/test_fd3_folders.py +421 -0
  175. poisson_tasks-0.1.0/tests/test_fd3_key_mask.py +263 -0
  176. poisson_tasks-0.1.0/tests/test_fd3_machine.py +289 -0
  177. poisson_tasks-0.1.0/tests/test_fd3_pending_failed_episode.py +62 -0
  178. poisson_tasks-0.1.0/tests/test_fd3_resume.py +353 -0
  179. poisson_tasks-0.1.0/tests/test_fd3_stops.py +288 -0
  180. poisson_tasks-0.1.0/tests/test_fd4_card.py +475 -0
  181. poisson_tasks-0.1.0/tests/test_fd4_claims.py +176 -0
  182. poisson_tasks-0.1.0/tests/test_fd4_compare.py +214 -0
  183. poisson_tasks-0.1.0/tests/test_fd4_design.py +244 -0
  184. poisson_tasks-0.1.0/tests/test_fd4_outcomes.py +81 -0
  185. poisson_tasks-0.1.0/tests/test_fd4_pending_budget.py +29 -0
  186. poisson_tasks-0.1.0/tests/test_fd4_pending_partly_covered.py +30 -0
  187. poisson_tasks-0.1.0/tests/test_fd4_pending_published_page.py +24 -0
  188. poisson_tasks-0.1.0/tests/test_fd4_pending_strictness_split.py +35 -0
  189. poisson_tasks-0.1.0/tests/test_fd4_published.py +113 -0
  190. poisson_tasks-0.1.0/tests/test_fd5_build.py +173 -0
  191. poisson_tasks-0.1.0/tests/test_fd5_card.py +346 -0
  192. poisson_tasks-0.1.0/tests/test_fd5_codes.py +302 -0
  193. poisson_tasks-0.1.0/tests/test_fd5_doctor.py +193 -0
  194. poisson_tasks-0.1.0/tests/test_fd5_export.py +180 -0
  195. poisson_tasks-0.1.0/tests/test_fd5_fresh.py +536 -0
  196. poisson_tasks-0.1.0/tests/test_fd5_generate.py +310 -0
  197. poisson_tasks-0.1.0/tests/test_fd5_help.py +403 -0
  198. poisson_tasks-0.1.0/tests/test_fd5_init.py +437 -0
  199. poisson_tasks-0.1.0/tests/test_fd5_look.py +700 -0
  200. poisson_tasks-0.1.0/tests/test_fd5_pending_aliases_public.py +31 -0
  201. poisson_tasks-0.1.0/tests/test_fd5_pending_doctor_without_config.py +31 -0
  202. poisson_tasks-0.1.0/tests/test_fd5_pending_export_offline.py +36 -0
  203. poisson_tasks-0.1.0/tests/test_fd5_pending_key_name_wording.py +77 -0
  204. poisson_tasks-0.1.0/tests/test_fd5_pending_knob_wording.py +51 -0
  205. poisson_tasks-0.1.0/tests/test_fd5_pending_next_config.py +43 -0
  206. poisson_tasks-0.1.0/tests/test_fd5_pending_overwrite.py +71 -0
  207. poisson_tasks-0.1.0/tests/test_fd5_pending_owed_done_line.py +60 -0
  208. poisson_tasks-0.1.0/tests/test_fd5_run.py +712 -0
  209. poisson_tasks-0.1.0/tests/test_fd5_verify.py +310 -0
  210. poisson_tasks-0.1.0/tests/test_fd6_docs.py +591 -0
  211. poisson_tasks-0.1.0/tests/test_fd6_scripts.py +263 -0
  212. poisson_tasks-0.1.0/tests/test_fd6_wheel.py +323 -0
  213. poisson_tasks-0.1.0/tests/test_fd6f1_card_next.py +63 -0
  214. poisson_tasks-0.1.0/tests/test_fd6f1_own_counts.py +141 -0
  215. poisson_tasks-0.1.0/tests/test_fd6f2_card_line.py +116 -0
  216. poisson_tasks-0.1.0/tests/test_fd9_build.py +67 -0
  217. poisson_tasks-0.1.0/tests/test_fd9_session.py +1092 -0
  218. poisson_tasks-0.1.0/tests/test_fd9_verbs.py +525 -0
  219. poisson_tasks-0.1.0/tests/test_frozen_generator.py +157 -0
  220. poisson_tasks-0.1.0/tests/test_handson_fixes.py +134 -0
  221. poisson_tasks-0.1.0/tests/test_k0_card.py +532 -0
  222. poisson_tasks-0.1.0/tests/test_k0_first_request_cached.py +57 -0
  223. poisson_tasks-0.1.0/tests/test_k0_published_concurrency.py +25 -0
  224. poisson_tasks-0.1.0/tests/test_k0_record.py +279 -0
  225. poisson_tasks-0.1.0/tests/test_k1_calibration.py +202 -0
  226. poisson_tasks-0.1.0/tests/test_k1_content.py +170 -0
  227. poisson_tasks-0.1.0/tests/test_k1_hash.py +116 -0
  228. poisson_tasks-0.1.0/tests/test_k1_knobs.py +201 -0
  229. poisson_tasks-0.1.0/tests/test_k1_ledger.py +862 -0
  230. poisson_tasks-0.1.0/tests/test_k1_pending_level_bounds.py +38 -0
  231. poisson_tasks-0.1.0/tests/test_k1_plain_words.py +81 -0
  232. poisson_tasks-0.1.0/tests/test_k1_surface.py +272 -0
  233. poisson_tasks-0.1.0/tests/test_k1_verify.py +260 -0
  234. poisson_tasks-0.1.0/tests/test_k2_block.py +350 -0
  235. poisson_tasks-0.1.0/tests/test_k2_eval.py +122 -0
  236. poisson_tasks-0.1.0/tests/test_k2_fingerprint.py +189 -0
  237. poisson_tasks-0.1.0/tests/test_k2_pending_census.py +47 -0
  238. poisson_tasks-0.1.0/tests/test_k2_server.py +227 -0
  239. poisson_tasks-0.1.0/tests/test_k2_verdicts.py +116 -0
  240. poisson_tasks-0.1.0/tests/test_k3_control.py +98 -0
  241. poisson_tasks-0.1.0/tests/test_k3_counting.py +154 -0
  242. poisson_tasks-0.1.0/tests/test_k3_eval.py +141 -0
  243. poisson_tasks-0.1.0/tests/test_k3_kept.py +60 -0
  244. poisson_tasks-0.1.0/tests/test_k3_live.py +200 -0
  245. poisson_tasks-0.1.0/tests/test_k3_pending_refused_retry.py +25 -0
  246. poisson_tasks-0.1.0/tests/test_k3_plan.py +192 -0
  247. poisson_tasks-0.1.0/tests/test_k3_records.py +229 -0
  248. poisson_tasks-0.1.0/tests/test_k4_eval.py +125 -0
  249. poisson_tasks-0.1.0/tests/test_k4_kept.py +77 -0
  250. poisson_tasks-0.1.0/tests/test_k4_kind.py +101 -0
  251. poisson_tasks-0.1.0/tests/test_k4_records.py +80 -0
  252. poisson_tasks-0.1.0/tests/test_k4_size.py +79 -0
  253. poisson_tasks-0.1.0/tests/test_k4_wire.py +92 -0
  254. poisson_tasks-0.1.0/tests/test_k5_aliases.py +122 -0
  255. poisson_tasks-0.1.0/tests/test_k5_block.py +156 -0
  256. poisson_tasks-0.1.0/tests/test_k5_eval.py +141 -0
  257. poisson_tasks-0.1.0/tests/test_k5_fixed.py +65 -0
  258. poisson_tasks-0.1.0/tests/test_k5_kept.py +69 -0
  259. poisson_tasks-0.1.0/tests/test_k5_length.py +85 -0
  260. poisson_tasks-0.1.0/tests/test_k5_pending_upper_bound.py +50 -0
  261. poisson_tasks-0.1.0/tests/test_k5_records.py +100 -0
  262. poisson_tasks-0.1.0/tests/test_k6_check.py +145 -0
  263. poisson_tasks-0.1.0/tests/test_k6_eval.py +160 -0
  264. poisson_tasks-0.1.0/tests/test_k6_fixed.py +126 -0
  265. poisson_tasks-0.1.0/tests/test_k6_kept.py +74 -0
  266. poisson_tasks-0.1.0/tests/test_k6_live.py +188 -0
  267. poisson_tasks-0.1.0/tests/test_k6_pending_census.py +44 -0
  268. poisson_tasks-0.1.0/tests/test_k6_pending_distinct.py +33 -0
  269. poisson_tasks-0.1.0/tests/test_k6_pending_empty.py +41 -0
  270. poisson_tasks-0.1.0/tests/test_k6_pending_nested.py +33 -0
  271. poisson_tasks-0.1.0/tests/test_k6_pending_request.py +34 -0
  272. poisson_tasks-0.1.0/tests/test_k6_schema.py +110 -0
  273. poisson_tasks-0.1.0/tests/test_k6_stated.py +151 -0
  274. poisson_tasks-0.1.0/tests/test_k7_block.py +66 -0
  275. poisson_tasks-0.1.0/tests/test_k7_calls.py +198 -0
  276. poisson_tasks-0.1.0/tests/test_k7_eval.py +152 -0
  277. poisson_tasks-0.1.0/tests/test_k7_fixed.py +84 -0
  278. poisson_tasks-0.1.0/tests/test_k7_kept.py +74 -0
  279. poisson_tasks-0.1.0/tests/test_k7_live.py +215 -0
  280. poisson_tasks-0.1.0/tests/test_k7_pending_block.py +39 -0
  281. poisson_tasks-0.1.0/tests/test_k7_pending_census.py +49 -0
  282. poisson_tasks-0.1.0/tests/test_k7_pending_order.py +49 -0
  283. poisson_tasks-0.1.0/tests/test_k7_pending_system_prompt.py +26 -0
  284. poisson_tasks-0.1.0/tests/test_k7_pending_wording.py +39 -0
  285. poisson_tasks-0.1.0/tests/test_k7_request.py +110 -0
  286. poisson_tasks-0.1.0/tests/test_k7_verdict.py +207 -0
  287. poisson_tasks-0.1.0/tests/test_k8_eval.py +173 -0
  288. poisson_tasks-0.1.0/tests/test_k8_fixed.py +129 -0
  289. poisson_tasks-0.1.0/tests/test_k8_kept.py +76 -0
  290. poisson_tasks-0.1.0/tests/test_k8_live.py +223 -0
  291. poisson_tasks-0.1.0/tests/test_k8_only.py +128 -0
  292. poisson_tasks-0.1.0/tests/test_k8_parts.py +122 -0
  293. poisson_tasks-0.1.0/tests/test_k8_pending_census.py +47 -0
  294. poisson_tasks-0.1.0/tests/test_k8_pending_exact.py +47 -0
  295. poisson_tasks-0.1.0/tests/test_k8_pending_fill.py +30 -0
  296. poisson_tasks-0.1.0/tests/test_k8_pending_order.py +23 -0
  297. poisson_tasks-0.1.0/tests/test_k8_pending_parts.py +23 -0
  298. poisson_tasks-0.1.0/tests/test_k8_pending_reads.py +35 -0
  299. poisson_tasks-0.1.0/tests/test_k8_pending_wording.py +55 -0
  300. poisson_tasks-0.1.0/tests/test_k8_reads.py +164 -0
  301. poisson_tasks-0.1.0/tests/test_k8_verdict.py +111 -0
  302. poisson_tasks-0.1.0/tests/test_k8b_kept.py +71 -0
  303. poisson_tasks-0.1.0/tests/test_k9_arms.py +194 -0
  304. poisson_tasks-0.1.0/tests/test_k9_driver.py +372 -0
  305. poisson_tasks-0.1.0/tests/test_k9_measures.py +165 -0
  306. poisson_tasks-0.1.0/tests/test_k9_notebook.py +424 -0
  307. poisson_tasks-0.1.0/tests/test_k9_outcomes.py +319 -0
  308. poisson_tasks-0.1.0/tests/test_k9_pending_complete.py +38 -0
  309. poisson_tasks-0.1.0/tests/test_k9_pending_concurrency.py +33 -0
  310. poisson_tasks-0.1.0/tests/test_k9_pending_exact.py +41 -0
  311. poisson_tasks-0.1.0/tests/test_k9_pending_key.py +61 -0
  312. poisson_tasks-0.1.0/tests/test_k9_pending_lost_seed.py +32 -0
  313. poisson_tasks-0.1.0/tests/test_k9_pending_notebook_gate.py +66 -0
  314. poisson_tasks-0.1.0/tests/test_k9_pending_phase1_pooled.py +37 -0
  315. poisson_tasks-0.1.0/tests/test_k9_pending_placement.py +27 -0
  316. poisson_tasks-0.1.0/tests/test_k9_pending_rates.py +33 -0
  317. poisson_tasks-0.1.0/tests/test_k9_pending_resume.py +83 -0
  318. poisson_tasks-0.1.0/tests/test_k9_pending_runner.py +95 -0
  319. poisson_tasks-0.1.0/tests/test_k9_pending_shape_control.py +43 -0
  320. poisson_tasks-0.1.0/tests/test_k9_pending_top_easier.py +30 -0
  321. poisson_tasks-0.1.0/tests/test_k9_pending_wall_clock.py +18 -0
  322. poisson_tasks-0.1.0/tests/test_k9_phase1.py +180 -0
  323. poisson_tasks-0.1.0/tests/test_k9_regate.py +707 -0
  324. poisson_tasks-0.1.0/tests/test_k9_rule.py +190 -0
  325. poisson_tasks-0.1.0/tests/test_k9_seeds.py +133 -0
  326. poisson_tasks-0.1.0/tests/test_k9_shipped.py +264 -0
  327. poisson_tasks-0.1.0/tests/test_nofile.py +205 -0
  328. poisson_tasks-0.1.0/tests/test_o1_digest.py +102 -0
  329. poisson_tasks-0.1.0/tests/test_o1_effects.py +118 -0
  330. poisson_tasks-0.1.0/tests/test_o1_formats.py +479 -0
  331. poisson_tasks-0.1.0/tests/test_o1_mcp_command.py +120 -0
  332. poisson_tasks-0.1.0/tests/test_o1_pending_everything_fixture.py +42 -0
  333. poisson_tasks-0.1.0/tests/test_o1_pending_pyyaml.py +22 -0
  334. poisson_tasks-0.1.0/tests/test_o1_refusals.py +409 -0
  335. poisson_tasks-0.1.0/tests/test_o2_card.py +287 -0
  336. poisson_tasks-0.1.0/tests/test_o2_cli.py +299 -0
  337. poisson_tasks-0.1.0/tests/test_o2_config.py +396 -0
  338. poisson_tasks-0.1.0/tests/test_o2_determinism.py +185 -0
  339. poisson_tasks-0.1.0/tests/test_o2_fixtures.py +29 -0
  340. poisson_tasks-0.1.0/tests/test_o2_keywords.py +178 -0
  341. poisson_tasks-0.1.0/tests/test_o2_knobs.py +557 -0
  342. poisson_tasks-0.1.0/tests/test_o2_pending_arguments_free_text.py +31 -0
  343. poisson_tasks-0.1.0/tests/test_o2_pending_arguments_range.py +28 -0
  344. poisson_tasks-0.1.0/tests/test_o2_pending_arguments_target.py +40 -0
  345. poisson_tasks-0.1.0/tests/test_o2_pending_arguments_unstated.py +34 -0
  346. poisson_tasks-0.1.0/tests/test_o2_pending_base_block.py +33 -0
  347. poisson_tasks-0.1.0/tests/test_o2_pending_bite_sentence.py +34 -0
  348. poisson_tasks-0.1.0/tests/test_o2_pending_card_levels.py +26 -0
  349. poisson_tasks-0.1.0/tests/test_o2_pending_controls.py +50 -0
  350. poisson_tasks-0.1.0/tests/test_o2_pending_custom.py +66 -0
  351. poisson_tasks-0.1.0/tests/test_o2_pending_default_recipe.py +29 -0
  352. poisson_tasks-0.1.0/tests/test_o2_pending_depth_predicate.py +48 -0
  353. poisson_tasks-0.1.0/tests/test_o2_pending_doctor_digest.py +68 -0
  354. poisson_tasks-0.1.0/tests/test_o2_pending_estimate.py +59 -0
  355. poisson_tasks-0.1.0/tests/test_o2_pending_flags_table.py +26 -0
  356. poisson_tasks-0.1.0/tests/test_o2_pending_history_total.py +33 -0
  357. poisson_tasks-0.1.0/tests/test_o2_pending_mcp_consent.py +39 -0
  358. poisson_tasks-0.1.0/tests/test_o2_pending_mcp_not_kept.py +48 -0
  359. poisson_tasks-0.1.0/tests/test_o2_pending_near_duplicates.py +33 -0
  360. poisson_tasks-0.1.0/tests/test_o2_pending_no_recipe.py +40 -0
  361. poisson_tasks-0.1.0/tests/test_o2_pending_no_seq.py +62 -0
  362. poisson_tasks-0.1.0/tests/test_o2_pending_openapi_status.py +22 -0
  363. poisson_tasks-0.1.0/tests/test_o2_pending_output_keywords.py +77 -0
  364. poisson_tasks-0.1.0/tests/test_o2_pending_recipe_card.py +39 -0
  365. poisson_tasks-0.1.0/tests/test_o2_pending_recipe_levels.py +62 -0
  366. poisson_tasks-0.1.0/tests/test_o2_pending_repeat_write.py +27 -0
  367. poisson_tasks-0.1.0/tests/test_o2_pending_shape.py +49 -0
  368. poisson_tasks-0.1.0/tests/test_o2_pending_similarity_names.py +46 -0
  369. poisson_tasks-0.1.0/tests/test_o2_pending_spread_keyed_reads.py +21 -0
  370. poisson_tasks-0.1.0/tests/test_o2_pending_spread_reads.py +42 -0
  371. poisson_tasks-0.1.0/tests/test_o2_pending_taskset_id.py +41 -0
  372. poisson_tasks-0.1.0/tests/test_o2_pending_unknowns_question.py +78 -0
  373. poisson_tasks-0.1.0/tests/test_o2_request.py +147 -0
  374. poisson_tasks-0.1.0/tests/test_o2_run.py +223 -0
  375. poisson_tasks-0.1.0/tests/test_o2_server.py +245 -0
  376. poisson_tasks-0.1.0/tests/test_o2_simulator.py +498 -0
  377. poisson_tasks-0.1.0/tests/test_o2_verdict.py +268 -0
  378. poisson_tasks-0.1.0/tests/test_o2b_kept.py +206 -0
  379. poisson_tasks-0.1.0/tests/test_o2c_every_knob.py +219 -0
  380. poisson_tasks-0.1.0/tests/test_o2d_b2.py +556 -0
  381. poisson_tasks-0.1.0/tests/test_o2d_look.py +107 -0
  382. poisson_tasks-0.1.0/tests/test_plain_words_knobs_adapter.py +110 -0
  383. poisson_tasks-0.1.0/tests/test_r0_config.py +437 -0
  384. poisson_tasks-0.1.0/tests/test_r0_pending_preset_not_text.py +76 -0
  385. poisson_tasks-0.1.0/tests/test_r0_recipes.py +277 -0
  386. poisson_tasks-0.1.0/tests/test_record_id_fix.py +187 -0
  387. poisson_tasks-0.1.0/tests/test_run_refusals.py +174 -0
  388. poisson_tasks-0.1.0/tests/test_scripts_help_and_errors.py +144 -0
  389. poisson_tasks-0.1.0/tests/test_tg_m1_engine.py +1397 -0
  390. poisson_tasks-0.1.0/tests/test_tg_m2_knobs.py +1300 -0
  391. poisson_tasks-0.1.0/tests/test_tg_m3_tasks.py +2198 -0
  392. poisson_tasks-0.1.0/tests/test_tg_m4_export.py +1201 -0
  393. poisson_tasks-0.1.0/tests/test_tg_m5_bridge.py +264 -0
  394. poisson_tasks-0.1.0/tests/test_tg_m5_scripted.py +2222 -0
  395. poisson_tasks-0.1.0/tests/test_tg_m5_standalone.py +1093 -0
@@ -0,0 +1,109 @@
1
+ # The default suite, ruff and mypy on every push and pull request, twice: once without Prove,
2
+ # where the tests that drive Prove are skipped by name (tests/conftest.py), and once with Prove
3
+ # installed, where they run. Each job first checks that Prove is, or is not, importable, so a
4
+ # job's name always says what it ran against.
5
+ #
6
+ # Third-party actions are pinned to a commit, with the release it is in beside it.
7
+ name: CI
8
+
9
+ on:
10
+ push:
11
+ pull_request:
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ without-prove:
18
+ name: suite, ruff and mypy, without Prove
19
+ runs-on: ubuntu-latest
20
+ timeout-minutes: 45
21
+ defaults:
22
+ run:
23
+ working-directory: tasks
24
+ steps:
25
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
26
+ with:
27
+ path: tasks
28
+ persist-credentials: false
29
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
30
+ with:
31
+ python-version: "3.11"
32
+ # The `null` harness launches its program through uv, and the tests that run it skip
33
+ # when uv is missing. This is the uv the suite is known green on.
34
+ - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
35
+ with:
36
+ version: "0.11.14"
37
+ enable-cache: false
38
+ - name: Install
39
+ run: |
40
+ python -m venv .venv
41
+ .venv/bin/python -m pip install -e ".[dev]"
42
+ echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
43
+ - name: Fetch the reference tokenizer's encoding file
44
+ run: python -m poisson_tasks.fetch_encoding
45
+ - name: Prove is not installed
46
+ run: python -c "import importlib.util, sys; sys.exit(importlib.util.find_spec('proofload') is not None)"
47
+ - name: Ruff
48
+ run: ruff check .
49
+ - name: Mypy
50
+ run: mypy
51
+ # `python -m pytest`, as the README gives it. A bare `pytest` collects the same tests,
52
+ # because pyproject.toml's pytest table puts the repository root on the import path.
53
+ - name: Tests
54
+ run: python -m pytest -q
55
+ # The same property-test examples on every run, so a red run is reproducible.
56
+ env:
57
+ HYPOTHESIS_PROFILE: ci
58
+
59
+ with-prove:
60
+ name: suite, ruff and mypy, with Prove
61
+ # Prove is not public, so this job checks it out with a read-only token kept in the
62
+ # PROVE_READ_TOKEN secret. A pull request from a fork is given no secrets; there this job
63
+ # is skipped, and shows as skipped, rather than failing on a checkout it cannot make.
64
+ if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository
65
+ runs-on: ubuntu-latest
66
+ timeout-minutes: 45
67
+ defaults:
68
+ run:
69
+ working-directory: tasks
70
+ steps:
71
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
72
+ with:
73
+ path: tasks
74
+ persist-credentials: false
75
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
76
+ with:
77
+ repository: poisson-labs/prove
78
+ # The Prove commit the suite is known green against; moved deliberately, never floating.
79
+ ref: 98dc6af0e8b66f733c98d3867035e21bba5c219d
80
+ token: ${{ secrets.PROVE_READ_TOKEN }}
81
+ path: prove
82
+ persist-credentials: false
83
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
84
+ with:
85
+ python-version: "3.11"
86
+ - uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
87
+ with:
88
+ version: "0.11.14"
89
+ enable-cache: false
90
+ # The order the README gives: Prove from its checkout, then this package.
91
+ - name: Install
92
+ run: |
93
+ python -m venv .venv
94
+ .venv/bin/python -m pip install -e ../prove
95
+ .venv/bin/python -m pip install -e ".[dev]"
96
+ echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
97
+ - name: Fetch the reference tokenizer's encoding file
98
+ run: python -m poisson_tasks.fetch_encoding
99
+ - name: Prove is installed
100
+ run: python -c "import proofload; print('proofload', proofload.__version__, proofload.__file__)"
101
+ - name: Ruff
102
+ run: ruff check .
103
+ - name: Mypy
104
+ run: mypy
105
+ - name: Tests
106
+ run: python -m pytest -q
107
+ # The same property-test examples on every run, so a red run is reproducible.
108
+ env:
109
+ HYPOTHESIS_PROFILE: ci
@@ -0,0 +1,61 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+ *.egg
11
+ .eggs/
12
+
13
+ # Virtual environments
14
+ .venv/
15
+ venv/
16
+ env/
17
+
18
+ # Testing / tooling caches
19
+ .pytest_cache/
20
+ .hypothesis/
21
+ .mypy_cache/
22
+ .ruff_cache/
23
+ .coverage
24
+ htmlcov/
25
+
26
+ # Proofload run stores. The default store root is ./proofload-runs.
27
+ proofload-runs/
28
+
29
+ # Local working notes: a symlink. No trailing slash, or the symlink gets through.
30
+ notes
31
+
32
+ # Local working folders (scripts, run outputs). The sdist is built from this file and not from
33
+ # .git/info/exclude, so a folder left out only there ships in it.
34
+ .work/
35
+
36
+ # The second virtual environment, for the suite without Proofload. Left out here for the same
37
+ # reason as .work/.
38
+ .venv-noprove/
39
+
40
+ # Editors / OS
41
+ .vscode/
42
+ .idea/
43
+ .DS_Store
44
+
45
+ # The o200k_base encoding file. Not vendored: its redistribution terms could not be
46
+ # established (NOTICE). `python -m poisson_tasks.fetch_encoding` puts it here.
47
+ src/poisson_tasks/data/*.tiktoken
48
+
49
+ # The example sweep writes its registration, registry module and run store here.
50
+ examples/**/example-store/
51
+
52
+ # `eval` writes each run's folder (configs, traces, logs) into the working directory,
53
+ # `--dry-run` included.
54
+ outputs/
55
+
56
+ # Devlogs are kept outside the repository (docs/repo-hygiene.md, section 2.7)
57
+ devlog.md
58
+
59
+ # Local secrets. Never committed, and the live smoke reads MODEL_API_KEY from here.
60
+ .env
61
+ .env.local
@@ -0,0 +1,85 @@
1
+ # Changelog
2
+
3
+ All notable changes to Poisson Tasks.
4
+
5
+ ## 0.1.0 (2026-10-22)
6
+
7
+ ### The guided session
8
+
9
+ - **A bare `poisson-tasks` on a terminal opens a guided session**, with no AI inside. With no `tasks.toml` in the folder it walks a first run through five steps: set up (which asks first whether to test a model on the built-in tasks or on your own tools), one task, the run with its plan and cost question, the card, and what next. With a `tasks.toml` it opens on a home screen that reads the folder from disk alone (settings, runs with what each kept and spent, the latest card's levels, whether the environment is ready) and offers at most five numbered steps for the folder's state. Enter takes step 1; a short word takes any action: `run`, `again`, `card`, `more`, `replies`, `task`, `verify`, `runs`, `settings`, `setup`, `flow`, `export`, `check`, `home`, `help` and `quit`.
10
+ - **Every action is a verb's command line.** Each runs through the same parser and verb as the command, and ends with `same as <the command>`, so what the session writes is byte for byte what that command writes from a shell, and scripts are one copy away. Nothing calls a model until a yes at the run's own cost question; the session never passes `--yes` to `run`.
11
+ - **Cards are drawn, never raw Markdown.** The card view is the verb's result; `more` opens one section of `card.md` at a time, its tables drawn as tables (Rich 13.4.2 or later, now the floor); `replies` lists one arm's episodes with their outcomes and opens one, call by call, with the simulated answers and the model's last reply.
12
+ - **Ctrl-C stops the step, never the session.** At a question inside a step it stops that step as the command does (nothing written); during a run it is the run's own interrupt, and the home screen then offers the resume; at the prompt it clears the line, and twice on an empty line it leaves, as `quit` and Ctrl-D do, with exit 0.
13
+ - **The load screen** is the Poisson distribution at λ = 4 as one row of eighth-block bars in cobalt beside `poisson labs`, with `tasks` and the version beneath; monochrome under `NO_COLOR`, and the one line `Poisson Labs tasks <version>` with `--plain`, under `TERM=dumb` or below 26 columns. It shows once, only in a session.
14
+ - **Off a terminal there is no session.** A bare command in a pipe, under `CI`, with stdin redirected or with `--json` keeps its exit 2 and its error line, which now names the session and ends with `next: <the folder's first step>`. On a terminal with `--plain`, `NO_COLOR` or `TERM=dumb` the session opens in the plain look: numbered menus, a plain prompt, no escape sequence.
15
+ - **`poisson_tasks.folder.read_folder(path)`** is the library name behind the home screen: a `Folder` of facts (settings, environment, each run's kept of total, dollars, card and lock, the newest card's levels, the tool counts), read from disk with no network and without loading the tokenizer.
16
+ - **What the session changed in the verbs**, so that each is one implementation: `init`'s first question is what to test, a model on the built-in tasks or on your own tools (own tools then asks for the file before any recipe), its questions are numbered as asked, its note on flows says what a flow is and names `--own-flow` and `[[own.flow]]`, and its closing screen points at `doctor --show-command` instead of printing the 18-flag command (`--json` keeps it); `init --force` keeps the replaced file as `tasks.toml.bak` and says so; `run` holds an advisory lock on `<run folder>/run.lock` while it runs, so a second `run` on that folder is refused with nothing spent, and a lock left by a process that died does not count; `card`'s result names its run (folder, dollars spent, kept of total) and says once how it stands beside the published cards; a card on your own tools no longer suggests `card --compare published`, and that command reads the written card without `--force`, prints one verdict line, `different ...`, writes `card/compare.md` and prints neither card, on the built-in tasks too; `generate --show` with no `--arm` shows the plan's first arm's first task and names the other arms instead of refusing; `verify` with nothing to judge, or on your own tools, ends with a complete `next:` command; an overwrite refusal's `next:` keeps every flag you typed; `doctor`'s rows say `ok`, `note`, `refused` or `not ok`, each by what the row is; `export`'s warning above its commands is one plain line; and in the pretty look no path, URL, command or quoted value is ever split by a line break, and a wrapped row keeps its indent.
17
+ - **Dependencies.** `prompt_toolkit>=3.0.53` is declared (it was installed through questionary already; no package is added) and Rich's floor rises from 11.0.0 to 13.4.2.
18
+
19
+ ### The command
20
+
21
+ - **`poisson-tasks` is the way in.** It puts the library behind seven verbs (`python -m poisson_tasks` is the same command). `init` asks what to test and what to measure, in plain words, and writes one settings file, `tasks.toml` (`doctor --show-command` prints the same setup as one command that asks nothing); it offers to fetch the tokenizer file first if it is missing. `generate` makes the plan's tasks with no model and no network and writes them as files, or shows one task in full. `run` shows the plan, the expected calls and cost and the cap, asks, and runs it against the model, stopping at the cap and resuming after Ctrl-C. `card` builds a run's card and says what it means and what it does not claim. `verify` judges an answer with the task's own verifier. `export` writes the configs verifiers' `eval` runs. `doctor` says whether this environment is ready.
22
+ - **Every verb prints its result first.** A problem is one `error:` line on standard error, saying what to do; the exit codes are 0 done, 1 refused, 2 the command line is wrong, 3 stopped after work started, 4 a check you asked for did not pass, and 130 interrupted; `--json` prints the result as one document. Options may come before or after the verb, and abbreviated options are refused.
23
+ - **Two looks, one result.** On a terminal the command draws its result with Rich, with arrow-key menus in `init`. In a pipe, under `NO_COLOR` or `CI`, with `TERM=dumb`, on a standard output that is not UTF-8, or with `--json` or `--plain`, it prints plain text with the same facts in the same order. Rich and questionary are ordinary dependencies.
24
+ - **Five providers, and recipes.** `init` knows `openai`, `anthropic` (through its OpenAI-compatible endpoint), `ollama`, `vllm` and any other OpenAI-compatible endpoint, and prefills a price only for `gpt-5-nano-2025-08-07`. A recipe is a named set of arms with a task count and an attempt count (`poisson_tasks.arms.RECIPES` holds eight: `first-look`, `tool-choice`, `error-recovery`, `long-sessions`, `planning`, `reading-and-filling`, `profile` and `card`); `[measure] preset` takes the ones offered, and a recipe whose knobs are not shown to work yet is refused in one line naming them. The first run's default is `first-look`: depth at 1, 3 and 8, 10 tasks each, 30 episodes.
25
+ - **Refusals before anything is spent.** A plan expected to cost more than its cap is refused before the question, with a cap that would let it finish. `generate`, `export` and `card` refuse to overwrite their files without `--force`. A `next:` command carries the `--config` you gave. `doctor` with no settings file reports on the environment alone. A key variable written the way a shell writes it (`$OPENAI_API_KEY`) is told to write the name alone.
26
+ - **What to do after a refusal, and what a printed command costs.** `generate --show` with several arms shows the first arm's first task and names the others. A card refused because a level's attempts made no tool call says they answered in text instead, names the files in the run folder that hold the replies, and ends with the command that shows the task they answered. `export` says, right above the commands it prints, that each calls the model and spends money with no cap.
27
+ - **Library names added for the command:** `config.INIT_FLAG_ALIASES`, `providers.refuse_plain_http_key`, `poisson_tasks.transcripts` (`read_transcript` and `verdict_of`, which read an attempt in any of its three forms), `poisson_tasks.arms` (arms by their id, the generator-version constant, the recipes, `knob_status()`), `poisson_tasks.outcomes` (one plain sentence for each outcome label) and `poisson_tasks.cards` (the published cards by their model's short name).
28
+
29
+ ### Tasks on your own tools
30
+
31
+ - **Bring the tools you already have.** An OpenAI tools file (Chat Completions or Responses), an MCP tool list (or an MCP server, started once with your consent only to list its tools, which Tasks never calls) or an OpenAPI 3.0 or 3.1 document is read into one form. A tool Tasks cannot use is refused in one line, and the rest of the set still runs; a whole file is refused when it matches none of the three shapes, when fewer than 2 or more than 256 usable tools remain, or when no tool takes an argument a task could check exactly. Whether a tool reads or writes comes from the file where it says so (MCP's `readOnlyHint`, OpenAPI's methods); OpenAI tools do not say, and count as writes until the settings say otherwise; `init` and `doctor` count a tool as you declared it. PyYAML is a declared dependency, for OpenAPI documents written as YAML.
32
+ - **Tasks are made on those tools, and your backend is never called.** A simulator shaped by your schemas answers every call, deterministically, and a verdict is judged by replaying the model's calls through it. A task is a pure function of your file's bytes, the arm and the seed. The settings file keeps the tools under `[own]` (`file`, `format`, `name`, `read`, `write`, `[own.intents]` and `[[own.flow]]`), each setting has an `init` option, and `generate`, `run`, `card`, `export` and `doctor` work on them. `export` serves them as the taskset `poisson-tasks-own`.
33
+ - **Every dial is offered, within what each set supports.** Depth and shape need flows you declare; block goes up to the set's size; spread needs a read that takes a checkable argument; the decoy-tools dial and control arms are not offered. The recipes lead with the knobs that shipped, and `doctor` and `init` show the knob probe's status for each dial beside it.
34
+ - **The card on your tools says so first**: it measured your tools with simulated responses, is read level against first level within itself, and is never pooled with a published card. `card --compare published` writes it beside the published card of its model in `card/compare.md`, each whole, pooling nothing, and prints the one-line verdict `different`. `doctor` says when the newest run on the same tool file carries another digest than the file has now.
35
+ - **`verify` refuses a tasks file made on your own tools, and `--arm` in a folder set up for them, in one line.** `verify` does not judge an own-tools task on its own in this release; a run's card judges every episode by replay.
36
+ - **A request on your tools leaves nothing to guess.** On every dial but arguments it states every value of the call that Tasks can make up from your schemas, required or not, so the model is told which record to change and what to change it to; a free-text value is stated and not checked. `generate --show --arm` in a folder set up for your tools shows the task `generate` writes for that arm, on your tools.
37
+ - **Library names added:** `poisson_tasks.own` and its modules (`simulator`, `generator`, `verdict`, `recipes`, `export` and `card`), the top-level module `poisson_tasks_own`, `Provenance.tools`, `config.OwnConfig`, `ProjectConfig.own`, `Plan.own`, `runs.own_bundles`.
38
+
39
+ ### The nine knobs, and what the knob probe found
40
+
41
+ - **Nine knobs have tasks.** Beside `depth` and `distractor`, `similarity` (levels 0 to 3: how many digits of the right tool's ledger number each lookalike tool shares), `faults` (0, 1, 2 and 4 calls that answer `unavailable` and must be made again), `history` (0 to 2400 tokens of earlier tool work in the conversation), `block` (8 to 64 tools offered), `arguments` (2 to 8 values each call must carry, copied from the request), `shape` (1, 2 or 4 records advanced side by side) and `spread` (the entry code split across 1, 2 or 4 tool answers). Each has its arm ids and turn budget; faults, block, arguments and shape each have a control arm that adds the higher level's length without its difficulty. A run of any of them has its tool messages replayed against the engine when its records are read, and a disagreement scores nothing.
42
+ - **The pin ledger has thirty rows**, seventeen of them for the new knobs. Every row that can be measured from a bundle is measured on every task.
43
+ - **Every task id moved, and no task did.** The generator version is now `"1"`, and the generator hash covers the three modules that shape a task. The 840 tasks of each published card regenerate with the same prompt, tools, goal and reference solution under a new id. The generator does not change again until the cards are measured again.
44
+ - **A knob probe measured the seven newer knobs** on `gpt-5-nano` and `Qwen3-8B`: 60 tasks and 2 attempts an arm, strict pass@1, the lowest level against the highest. `faults` (bites on Qwen3-8B), `history` (bites on both) and `shape` (bites on Qwen3-8B, four wide the harder) shipped, and the recipes that measure them (`error-recovery`, `long-sessions`, `planning` and `profile`) are offered beside `first-look` and `card`. `similarity`, `block`, `arguments` and `spread` did not ship: they stay in the generator and on the command line, labelled *Available · retested in v2*.
45
+ - **Each knob's measured status is in the package.** `poisson_tasks.arms.knob_status()` reads `knob_status.json`: for each knob and model, bites, does not bite, top easier or cannot tell, the base and top arms' strict pass@1, and each contrast's drop with its 95% interval. No knob is called a non-biter on a model where its base arm passed below 0.15, since a drop of 0.15 could not show there. [`docs/knobs-and-arms.md`](docs/knobs-and-arms.md) has the table, and three things about how the probe ran that are disclosed with it: a check was changed after the first result and read again once, a crash at the start cost one arm a second run, and one model was given more time.
46
+ - **The decoy-tools dial is experimental.** It does not make tasks harder for either published model, so it is not a difficulty setting, and the export's help for the arm option says so.
47
+
48
+ ### The published cards, in the package
49
+
50
+ - **Both published cards ship inside the package**, as `poisson_tasks/cards/`: `gpt-5-nano-2025-08-07` (4,200 episodes, about $2.52) and `Qwen/Qwen3-8B` at revision `b968826d` (4,200 episodes, served with vLLM on a Colab L4). `poisson-tasks card --published` rebuilds each from its records and checks it against its stored artifact byte for byte, and the run's estimate reads them from the package. A test holds both cards to recomputing byte for byte.
51
+ - **Both say they are not current for this release.** They were measured at generator version `"0"`, before the new knobs; the tasks regenerate with the same text and other ids. A card from your own run is not set beside them (`card --compare published` says so in one line, and the card's own result carries the same row), and the next release measures the cards again on the current generator.
52
+ - **A card for any plan.** `calibration.card_from_run(folder)` builds the card of a run folder under the plan's own design: its tasks per level, attempts, decoding and turn cap. A run that did not finish gives a partial card that says how many attempts it owes; a level never reached is listed as not run, never as zero. `card_claims` says what a card means and what it does not claim; a model served by its user is recorded as such.
53
+ - **Every card shows what each level cost**: median model calls, median tokens and median episode seconds beside the rates, and three cost tables (calls and tokens, time, and token totals and dollars). A figure that was not recorded reads *not recorded*, never zero, and time is printed and never compared.
54
+ - **Depth is read on reaching the goal, with stopping at the goal beside it**, because every depth level offers the whole stage ladder and the two published models do not fail the two skills the same way. `docs/calibration.md` is one page for every published card, rendered from them: where the models' orderings agree (of 12 adjacent pairs, on none, and they disagree on one), then each card in full.
55
+ - **A level where more than 10% of attempts made no tool call is not published**, and neither is its card; the same refusal is in `poisson-tasks card`.
56
+ - **An episode ends after 32 model calls.** The taskset pins a turn limit, `agent.max_turns = 32`, beside the measured harness, so the documented `eval` command and the calibration run behave the same. An episode that reaches it is scored `turn_limit`; `--env.agent.max-turns N` changes it.
57
+ - **A card rebuilds byte for byte on Python 3.12 and 3.13, not only on 3.11.** From 3.12 Python adds a list of decimal numbers with a correction that 3.11 did not make, so on 3.12 and 3.13 a card's rates moved in their last digit and `poisson-tasks card --published` (and `card --check` on a card built on 3.11) said the card no longer rebuilt. A card now adds its figures one at a time, as 3.11 did, on every Python; the published cards and every result on 3.11 are unchanged. A test holds both published cards to rebuilding under the corrected addition.
58
+
59
+ ### The run engine
60
+
61
+ - **What a plan will cost is told before anything is spent**: `runs.estimate` reads the published card of the plan's model (`gpt-5-nano`'s for a model no card measured), and the plan names which card it read.
62
+ - **One folder per plan.** A run goes in `runs/<preset>-<model>/`, then `-2`, `-3` for a second run of the same plan or a changed one, with no hash in its name.
63
+ - **The cap is a bound on what is spent.** The spend and token caps are checked before every model call, so the final spend is at most the cap plus the calls in flight when it was reached; the cap holds the folder's total across runs. `spend.jsonl` has one line for each episode that ended.
64
+ - **Resume loses nothing and runs nothing twice.** A stopped run keeps every finished episode, and a resume runs exactly the episodes owed; a run in which some episodes failed is resumed too, and its failure stays in the instrument tally. Ctrl-C stops dispatching, gives the episodes in flight ten seconds, writes the ledger and exits 130; a second Ctrl-C stops at once.
65
+ - **Stops.** The provider saying the account is out of credit stops the run. So do five episodes in a row failing before any was scored (the message gives the first error's status and the provider's own words), and a run that makes no model call and finishes no episode in 600 seconds. A run in which every episode failed never exits 0.
66
+ - **What a run changes on your machine is listed**: the run folder, `~/.cache/verifiers`, `~/.local/bin/uv` and `uvx`, `~/.cache/uv`, uv's receipt in `~/.config/uv`, one `/tmp/vf-port-*` file per episode, and one empty uv lock file in the temporary folder. The harness runs with `PIP_REQUIRE_VIRTUALENV=1`, so its bootstrap takes uv's installer every time, and `UV_NO_MODIFY_PATH=1`, so that installer edits no shell start-up file.
67
+ - **`run` and `export` are one path.** `runs.verifiers_config` is the eval config the run uses for an arm; `export --to verifiers` writes the same one, with `push` off and a decoding field declared `"not sent"` left out of every request.
68
+ - **A fix to traces written with a project key.** The run engine masked any four characters of the key wherever they occurred in a trace line. Every OpenAI project key starts with `sk-proj-`, and the tasks' item codes hold `-pro`, so earlier runs made with a project key could have had nearly every trace line rewritten, leaving lines that were no longer JSON or that failed the replay check when the records were read. Runs made without a key, and the published cards, were not affected. A key's public prefix (`sk-proj-`, `sk-ant-api03-`, `gsk_`) no longer counts as part of the key; where a provider can put the key, any four of its characters are masked; and no file of a run folder holds twelve characters of the key in a row. Run again any run made with a key before this fix whose records you rely on.
69
+
70
+ ### The verifiers export, and the Colab driver
71
+
72
+ - **The verifiers export** (`poisson_tasks.export`): a generated task as a verifiers v1 taskset, scored by the generator's own verifier, with its tool block served over MCP. The package is the taskset id `poisson-tasks`, and `eval` runs it with the `null` harness in a local subprocess with no flag. `ExportTasksetConfig.arm` takes an arm's id or its six fields.
73
+ - **A second published card needed a Colab driver.** `poisson_tasks.calibration_run` and `notebooks/calibration_model_b.ipynb` serve `Qwen3-8B` at a pinned revision with vLLM 0.29.0 on a Colab L4 and run the same card, checkpointing to Google Drive so a dropped runtime resumes; the same driver ran the knob probe's `Qwen3-8B` half. Its help describes it without the card's old name, every option has help text, and each step lists only the options it reads (the notebook hands every step the same four, so a step accepts the rest without listing them).
74
+ - **Vocabulary v2**: the record-id word lists are drawn disjoint from every tool name.
75
+ - **The name** is `poisson-tasks` (the package `poisson_tasks`).
76
+
77
+ ### Packaging, documents and examples
78
+
79
+ - **The wheel carries the published cards** (`poisson_tasks/cards/`, mapped from the repository's `calibration/` folder), `py.typed` for `poisson_tasks` and `poisson_tasks_own`, the knob probe's table and the `poisson-tasks` command; it carries no tokenizer file, no examples and no tests. A test builds the wheel and reads its file list. The module `poisson_tasks/cards.py` and the data folder `poisson_tasks/cards/` share a name; the folder holds no Python file, so the module wins the import, and a test holds it.
80
+ - **Python 3.11 to 3.13 on macOS and Linux** is what the package claims (`requires-python = ">=3.11,<3.14"`, matching verifiers 0.3.1), and `hatchling` joins the development tools.
81
+ - **The source archive leaves out `.work/`**, a local working folder: `.gitignore` names it, since the archive is built from that file.
82
+ - **The README is for users**: install, `init`, `run` and `card` first, then who it is for, what a first run costs and changes on your machine, the nine dials and what the evidence says of each, and the published cards. Contributor material moved to `CONTRIBUTING.md`. New pages in `docs/`: `commands.md` (every command's help, held equal to what the command prints), `config.md`, `own-tools.md`, `python.md`, `proofload.md` and `cli-look.md` (the look every command of the lab's tools keeps); `calibration-guide.md` became `reading-a-card.md`. Every command block in them is marked for the check that runs them from a built wheel, and the files a user reads are held to plain words by a test.
83
+ - **`--help` and a mistaken argument need no tokenizer file**, on the three examples and on the Colab driver's `verify`: they read their command line before they load the generator. The examples use generator version `"0"`, the label the published cards carry.
84
+ - **`docs/verifiers-export.md`** says to give an arm by its id, or as its six fields in one JSON object for a leaky arm, and that the dotted `--env.taskset.arm.<field>` form is not a way to give one; it also explains `export --to verifiers` and why the bare `eval` of a shell is not verifiers' `eval`.
85
+ - **Plain words.** The card, the calibration module's and the Colab driver's messages and help, the notebook, the engine, the knobs and adapter modules, the tests' comments and `gap-log.md` cite no internal decision ids, specification sections, private notes or people.
@@ -0,0 +1,87 @@
1
+ # Contributing to Poisson Tasks
2
+
3
+ This page is for working on the package itself: cloning it, running its tests, and the few rules the repository keeps. If you only want to use it, [the README](README.md) is the page for that.
4
+
5
+ ## How to help
6
+
7
+ Anyone can open an [issue](https://github.com/poisson-labs/tasks/issues): a bug, a question or an idea. Pull requests come from invited collaborators. To help, open an issue first.
8
+
9
+ ## Set up a checkout
10
+
11
+ Python 3.11 to 3.13 on macOS or Linux. From a clone:
12
+
13
+ <!-- docs-check: skip reason="clones the repository and installs the checkout; the job installs the wheel built from the commit" -->
14
+ ```bash
15
+ git clone https://github.com/poisson-labs/tasks.git
16
+ cd tasks
17
+
18
+ python3.11 -m venv .venv
19
+ .venv/bin/pip install -e ".[dev]"
20
+ .venv/bin/python -m poisson_tasks.fetch_encoding
21
+ ```
22
+
23
+ The last step fetches the o200k_base encoding file, about 3.6 MB, once. It is not shipped in this repository or in the distribution; [`NOTICE`](NOTICE) records why and what was checked. Generating tasks touches nothing else on the network, and the tokenizer never does.
24
+
25
+ ## Run the tests
26
+
27
+ <!-- docs-check: skip reason="runs the whole test suite, which needs the checkout and PyPI" -->
28
+ ```bash
29
+ .venv/bin/python -m pytest -q
30
+ ```
31
+
32
+ Run it from the repository root. A bare `pytest` collects the same tests: `pyproject.toml` puts the root on the import path, which the tests that import one another need.
33
+
34
+ The suite needs the network: every test that runs an episode through the `null` harness needs PyPI and astral.sh, because the `verifiers` wheel installs `uv` and the harness's dependencies before each episode ([`tests/conftest.py`](tests/conftest.py) says how). Those tests skip when `uv` is missing, and the CI jobs install it. A run that starts from a background job should leave `SIGINT` at its default.
35
+
36
+ The tests that need Proofload (the adapter's, and the bridge between the two scorers) are skipped without it, and say so. With a Proofload checkout installed beside this one they run; [docs/proofload.md](docs/proofload.md) shows how.
37
+
38
+ Type checks and lint, which CI runs too:
39
+
40
+ <!-- docs-check: skip reason="needs the dev tools of a checkout" -->
41
+ ```bash
42
+ .venv/bin/mypy # strict, over src/
43
+ .venv/bin/mypy --strict src
44
+ .venv/bin/ruff check .
45
+ ```
46
+
47
+ ## The test files are frozen
48
+
49
+ Each module was built against tests written before it, and the suite is not edited to suit a build. Comments and docstrings in a test file may be corrected; assertions may not. A frozen test that looks wrong is a question for the maintainers, not an edit. [`tests/conftest.py`](tests/conftest.py) is outside that freeze and holds the skip for the tests that need Proofload.
50
+
51
+ The generator's three source files (`tasks.py`, `surface.py` and `knobs.py`) are frozen until the published cards are measured again: their bytes are in the generator hash, so an edit moves every task id and makes both published cards stale. `engine.py` and the vocabulary table do not change either. A test regenerates the 840 tasks of each published card, and every knob's kept tasks, and compares them with the recorded ones; it is the first thing to run after touching anything near them.
52
+
53
+ ## Build the wheel
54
+
55
+ The wheel is built with hatchling from the working tree, and a test builds it and reads its file list. It ships the `poisson-tasks` command, the package's marker for type checkers (`py.typed`), the knob probe's table (`knob_status.json`) and the two published cards (`poisson_tasks/cards/`, mapped from the repository's `calibration/` folder). It does not ship the tokenizer file, the examples or the tests.
56
+
57
+ <!-- docs-check: skip reason="builds the wheel from a checkout" -->
58
+ ```bash
59
+ .venv/bin/pip wheel . --no-deps --wheel-dir dist
60
+ ```
61
+
62
+ ## The docs are checked
63
+
64
+ Every fenced `bash`, `console` and `python` block in the README, in `docs/` and in this file carries a marker on the line before it, and a test fails when one does not. The clean-install job runs the marked blocks from a wheel built from the commit, in file order, in a folder of its own, and compares each block's output with the output block after it. A marker is a comment:
65
+
66
+ ```text
67
+ <!-- docs-check: run --> run it; it must exit 0
68
+ <!-- docs-check: run exit=N --> run it; it must exit N (a documented refusal)
69
+ <!-- docs-check: run tty answers="1,,,y" --> run it on a pseudo-terminal, typing the answers
70
+ <!-- docs-check: run fixture --> a block that would cost money: run it against the
71
+ fixture model, with a made-up key
72
+ <!-- docs-check: run fixture env="MODEL,MODEL_BASE_URL,MODEL_API_KEY" -->
73
+ the same, for a block that reads its own variables
74
+ <!-- docs-check: output --> the block after a run block is its expected output;
75
+ "…" in a line matches any run of characters
76
+ <!-- docs-check: skip reason="..." --> a block that cannot run in CI, with the reason
77
+ ```
78
+
79
+ Write a value that varies (a path, a duration, a date) as `…` in the output block, so the page says honestly what varies.
80
+
81
+ ## Words in the docs
82
+
83
+ The README, `docs/` (but the two standards, `repo-hygiene.md` and `cli-look.md`) and `CHANGELOG.md` are for users. They carry no internal identifiers, no decision ids and no names of work sessions; "knob", "arm" and "level" are each explained where they first appear, and a number is shown with its unit. The pin ledger's row ids (`N1` to `N35`) appear only beside their names. A test reads the files with the same pattern the card text is held to.
84
+
85
+ ## Commits and history
86
+
87
+ Commits are signed and have plain, human-written messages. Devlogs and working notes live outside the repository. [`docs/repo-hygiene.md`](docs/repo-hygiene.md) is the lab's standard for what a public repository holds and never holds, and [`docs/cli-look.md`](docs/cli-look.md) is the look every command of the lab's tools keeps.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Taylor Kolasinski / Poisson 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.