@r1z4x/tezgah 1.9.2 → 1.13.0

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 (445) hide show
  1. package/CHANGELOG.md +415 -1
  2. package/MANIFEST +404 -144
  3. package/README.de.md +1 -1
  4. package/README.es.md +1 -1
  5. package/README.fr.md +1 -1
  6. package/README.md +5 -4
  7. package/README.tr.md +1 -1
  8. package/bin/codegen +5 -2
  9. package/bin/tezgah-design +288 -1
  10. package/bin/tezgah-docs +1 -1
  11. package/bin/tezgah-doctor +39 -2
  12. package/bin/tezgah-import-ai-research +26 -12
  13. package/bin/tezgah-ocr-review +296 -0
  14. package/bin/tezgah-research +255 -44
  15. package/bin/tezgah-review-quote +185 -0
  16. package/bin/tezgah-setup +1365 -55
  17. package/bin/tezgah-skill +1 -1
  18. package/bin/tezgah-status +201 -3
  19. package/bin/tezgah-task +258 -20
  20. package/commands/adhd.md +2 -2
  21. package/commands/ponytail.md +4 -4
  22. package/docs/architecture.md +2 -2
  23. package/docs/citations-baseline.json +3 -3
  24. package/docs/clarity-baseline.json +11 -5
  25. package/docs/contract.md +91 -43
  26. package/docs/environment.md +5 -2
  27. package/docs/evidence.md +109 -17
  28. package/docs/feature-audit.md +2 -2
  29. package/docs/gate.md +60 -33
  30. package/docs/glossary.md +6 -3
  31. package/docs/hosts.md +313 -17
  32. package/docs/index.json +34 -8
  33. package/docs/judge.md +4 -2
  34. package/docs/layers.md +4 -4
  35. package/docs/models.md +37 -9
  36. package/docs/operations.md +141 -5
  37. package/docs/research.md +815 -8
  38. package/docs/skills.md +137 -13
  39. package/docs/status-line.md +121 -1
  40. package/docs/testing.md +3 -1
  41. package/hooks/hooks.json +2 -2
  42. package/hooks/lang/en.json +21 -0
  43. package/hooks/lang/tr.json +22 -1
  44. package/hooks/projects-stop.py +2 -1
  45. package/hooks/tezgah_agents.py +65 -25
  46. package/hooks/tezgah_apps.py +18 -0
  47. package/hooks/tezgah_attest.py +79 -10
  48. package/hooks/tezgah_components.py +4 -0
  49. package/hooks/tezgah_context.py +207 -55
  50. package/hooks/tezgah_extension.py +337 -0
  51. package/hooks/tezgah_gate.py +267 -79
  52. package/hooks/tezgah_integrity.py +864 -143
  53. package/hooks/tezgah_judge.py +6 -4
  54. package/hooks/tezgah_models.py +59 -19
  55. package/hooks/tezgah_orca.py +1 -1
  56. package/hooks/tezgah_paths.py +145 -8
  57. package/hooks/tezgah_policy.py +128 -57
  58. package/hooks/tezgah_rank.py +9 -6
  59. package/hooks/tezgah_replay.py +12 -6
  60. package/hooks/tezgah_research.py +1414 -76
  61. package/hooks/tezgah_research_capture.py +1544 -0
  62. package/hooks/tezgah_research_evidence.py +842 -0
  63. package/hooks/tezgah_research_stats.py +258 -0
  64. package/hooks/tezgah_skill_pick.py +408 -106
  65. package/hooks/tezgah_stack.py +236 -1
  66. package/hooks/tezgah_stopspec.py +8 -1
  67. package/hooks/tezgah_task.py +14 -5
  68. package/hooks/tezgah_taste_ledger.py +1 -1
  69. package/hosts/amp/hook.py +217 -0
  70. package/hosts/amp/tezgah-plugin.ts.in +386 -0
  71. package/hosts/antigravity/hook.py +255 -0
  72. package/hosts/codex/hook.py +2 -1
  73. package/hosts/commandcode/hook.py +239 -0
  74. package/hosts/copilot/hook.py +284 -0
  75. package/hosts/cursor/hook.py +31 -3
  76. package/hosts/droid/hook.py +259 -0
  77. package/hosts/dsh/hooks.json +1 -1
  78. package/hosts/gemini/hook.py +213 -0
  79. package/hosts/goose/hook.py +145 -0
  80. package/hosts/omp/hook.py +4 -1
  81. package/hosts/omp/tezgah-hook.ts.in +30 -7
  82. package/hosts/opencode/plugins/tezgah.js +309 -48
  83. package/hosts/opencode/tui/cli/tui.tsx +100 -0
  84. package/hosts/opencode/tui/tezgah-tui.tsx +2 -1
  85. package/hosts/qwen/hook.py +206 -0
  86. package/output-styles/tezgah.md +20 -15
  87. package/package.json +1 -1
  88. package/skills/ai-research/SKILL.md +21 -14
  89. package/skills/ai-research/SOURCE +7 -5
  90. package/skills/ai-research/index/1-frame.md +6 -6
  91. package/skills/ai-research/index/2-data.md +9 -9
  92. package/skills/ai-research/index/3-train.md +36 -36
  93. package/skills/ai-research/index/4-measure.md +13 -13
  94. package/skills/ai-research/index/5-run.md +11 -11
  95. package/skills/ai-research/index/6-write.md +23 -23
  96. package/skills/ai-research/library.json +104 -104
  97. package/skills/analyze-app/SKILL.md +17 -12
  98. package/skills/design-contract/SKILL.md +42 -7
  99. package/skills/design-contract/data-views.md +2 -2
  100. package/skills/design-library/EVALS.md +1 -1
  101. package/skills/design-library/INDEX.md +39 -39
  102. package/skills/design-library/SKILL.md +19 -13
  103. package/skills/design-library/SOURCE +45 -43
  104. package/skills/feature-audit/SKILL.md +20 -14
  105. package/skills/hallmark/LICENSE +21 -0
  106. package/skills/hallmark/SKILL.md +154 -0
  107. package/skills/hallmark/SOURCE +207 -0
  108. package/skills/hallmark/agents/openai.yaml +13 -0
  109. package/skills/hallmark/references/anatomy.md +71 -0
  110. package/skills/hallmark/references/brand-truth.md +40 -0
  111. package/skills/hallmark/references/comp.md +104 -0
  112. package/skills/hallmark/references/craft.md +116 -0
  113. package/skills/hallmark/references/dark-mode.md +49 -0
  114. package/skills/hallmark/references/data-viz.md +48 -0
  115. package/skills/hallmark/references/design-md.md +53 -0
  116. package/skills/hallmark/references/direction.md +52 -0
  117. package/skills/hallmark/references/export-formats.md +80 -0
  118. package/skills/hallmark/references/flow.md +131 -0
  119. package/skills/hallmark/references/fonts.md +58 -0
  120. package/skills/hallmark/references/gates.md +243 -0
  121. package/skills/hallmark/references/genres/atmospheric.md +24 -0
  122. package/skills/hallmark/references/genres/editorial.md +24 -0
  123. package/skills/hallmark/references/genres/modern-minimal.md +24 -0
  124. package/skills/hallmark/references/genres/playful.md +24 -0
  125. package/skills/hallmark/references/imagery.md +99 -0
  126. package/skills/hallmark/references/interaction-and-states.md +89 -0
  127. package/skills/hallmark/references/layout.md +104 -0
  128. package/skills/hallmark/references/macrostructures/01-bento-grid.md +21 -0
  129. package/skills/hallmark/references/macrostructures/02-long-document.md +35 -0
  130. package/skills/hallmark/references/macrostructures/03-marquee-hero.md +21 -0
  131. package/skills/hallmark/references/macrostructures/04-stat-led.md +21 -0
  132. package/skills/hallmark/references/macrostructures/05-workbench.md +21 -0
  133. package/skills/hallmark/references/macrostructures/06-conversational-faq.md +28 -0
  134. package/skills/hallmark/references/macrostructures/07-manifesto.md +28 -0
  135. package/skills/hallmark/references/macrostructures/08-photographic.md +21 -0
  136. package/skills/hallmark/references/macrostructures/09-quote-led.md +21 -0
  137. package/skills/hallmark/references/macrostructures/10-specimen.md +21 -0
  138. package/skills/hallmark/references/macrostructures/11-catalogue.md +21 -0
  139. package/skills/hallmark/references/macrostructures/12-letter.md +21 -0
  140. package/skills/hallmark/references/macrostructures/13-index-first.md +21 -0
  141. package/skills/hallmark/references/macrostructures/14-narrative-workflow.md +21 -0
  142. package/skills/hallmark/references/macrostructures/15-split-studio.md +21 -0
  143. package/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -0
  144. package/skills/hallmark/references/macrostructures/17-type-specimen.md +19 -0
  145. package/skills/hallmark/references/macrostructures/18-portfolio-grid.md +21 -0
  146. package/skills/hallmark/references/macrostructures/19-map-diagram.md +21 -0
  147. package/skills/hallmark/references/macrostructures/20-ecosystem-index.md +19 -0
  148. package/skills/hallmark/references/macrostructures/21-component-playground.md +21 -0
  149. package/skills/hallmark/references/macrostructures.md +119 -0
  150. package/skills/hallmark/references/microinteractions.md +80 -0
  151. package/skills/hallmark/references/patterns.md +202 -0
  152. package/skills/hallmark/references/redesign.md +88 -0
  153. package/skills/hallmark/references/responsive.md +46 -0
  154. package/skills/hallmark/references/review-finish.md +19 -0
  155. package/skills/hallmark/references/review-hero.md +20 -0
  156. package/skills/hallmark/references/scroll-choreography.md +110 -0
  157. package/skills/hallmark/references/texture.md +90 -0
  158. package/skills/hallmark/references/themes/README.md +58 -0
  159. package/skills/hallmark/references/themes/almanac.jpg +0 -0
  160. package/skills/hallmark/references/themes/almanac.md +103 -0
  161. package/skills/hallmark/references/themes/arcade.jpg +0 -0
  162. package/skills/hallmark/references/themes/arcade.md +102 -0
  163. package/skills/hallmark/references/themes/atelier.jpg +0 -0
  164. package/skills/hallmark/references/themes/atelier.md +98 -0
  165. package/skills/hallmark/references/themes/bloom.jpg +0 -0
  166. package/skills/hallmark/references/themes/bloom.md +102 -0
  167. package/skills/hallmark/references/themes/blueprint.jpg +0 -0
  168. package/skills/hallmark/references/themes/blueprint.md +103 -0
  169. package/skills/hallmark/references/themes/broadside.jpg +0 -0
  170. package/skills/hallmark/references/themes/broadside.md +108 -0
  171. package/skills/hallmark/references/themes/brutal.jpg +0 -0
  172. package/skills/hallmark/references/themes/brutal.md +95 -0
  173. package/skills/hallmark/references/themes/carnival.jpg +0 -0
  174. package/skills/hallmark/references/themes/carnival.md +104 -0
  175. package/skills/hallmark/references/themes/cobalt.jpg +0 -0
  176. package/skills/hallmark/references/themes/cobalt.md +101 -0
  177. package/skills/hallmark/references/themes/console.jpg +0 -0
  178. package/skills/hallmark/references/themes/console.md +99 -0
  179. package/skills/hallmark/references/themes/coral.jpg +0 -0
  180. package/skills/hallmark/references/themes/coral.md +102 -0
  181. package/skills/hallmark/references/themes/darkroom.jpg +0 -0
  182. package/skills/hallmark/references/themes/darkroom.md +99 -0
  183. package/skills/hallmark/references/themes/dose.jpg +0 -0
  184. package/skills/hallmark/references/themes/dose.md +98 -0
  185. package/skills/hallmark/references/themes/dusk.jpg +0 -0
  186. package/skills/hallmark/references/themes/dusk.md +105 -0
  187. package/skills/hallmark/references/themes/editorial.jpg +0 -0
  188. package/skills/hallmark/references/themes/editorial.md +97 -0
  189. package/skills/hallmark/references/themes/formwork.jpg +0 -0
  190. package/skills/hallmark/references/themes/formwork.md +107 -0
  191. package/skills/hallmark/references/themes/furrow.jpg +0 -0
  192. package/skills/hallmark/references/themes/furrow.md +98 -0
  193. package/skills/hallmark/references/themes/garden.jpg +0 -0
  194. package/skills/hallmark/references/themes/garden.md +97 -0
  195. package/skills/hallmark/references/themes/grid.jpg +0 -0
  196. package/skills/hallmark/references/themes/grid.md +101 -0
  197. package/skills/hallmark/references/themes/halftone.jpg +0 -0
  198. package/skills/hallmark/references/themes/halftone.md +106 -0
  199. package/skills/hallmark/references/themes/hedgerow.jpg +0 -0
  200. package/skills/hallmark/references/themes/hedgerow.md +104 -0
  201. package/skills/hallmark/references/themes/hum.jpg +0 -0
  202. package/skills/hallmark/references/themes/hum.md +99 -0
  203. package/skills/hallmark/references/themes/index.json +2191 -0
  204. package/skills/hallmark/references/themes/ink.jpg +0 -0
  205. package/skills/hallmark/references/themes/ink.md +106 -0
  206. package/skills/hallmark/references/themes/kiln.jpg +0 -0
  207. package/skills/hallmark/references/themes/kiln.md +108 -0
  208. package/skills/hallmark/references/themes/loom.jpg +0 -0
  209. package/skills/hallmark/references/themes/loom.md +106 -0
  210. package/skills/hallmark/references/themes/lumen.jpg +0 -0
  211. package/skills/hallmark/references/themes/lumen.md +103 -0
  212. package/skills/hallmark/references/themes/manifesto.jpg +0 -0
  213. package/skills/hallmark/references/themes/manifesto.md +101 -0
  214. package/skills/hallmark/references/themes/midnight.jpg +0 -0
  215. package/skills/hallmark/references/themes/midnight.md +97 -0
  216. package/skills/hallmark/references/themes/newsprint.jpg +0 -0
  217. package/skills/hallmark/references/themes/newsprint.md +102 -0
  218. package/skills/hallmark/references/themes/overprint.jpg +0 -0
  219. package/skills/hallmark/references/themes/overprint.md +101 -0
  220. package/skills/hallmark/references/themes/pasteup.jpg +0 -0
  221. package/skills/hallmark/references/themes/pasteup.md +100 -0
  222. package/skills/hallmark/references/themes/piste.jpg +0 -0
  223. package/skills/hallmark/references/themes/piste.md +99 -0
  224. package/skills/hallmark/references/themes/ribbon.jpg +0 -0
  225. package/skills/hallmark/references/themes/ribbon.md +106 -0
  226. package/skills/hallmark/references/themes/rim.jpg +0 -0
  227. package/skills/hallmark/references/themes/rim.md +96 -0
  228. package/skills/hallmark/references/themes/riso.jpg +0 -0
  229. package/skills/hallmark/references/themes/riso.md +98 -0
  230. package/skills/hallmark/references/themes/solstice.jpg +0 -0
  231. package/skills/hallmark/references/themes/solstice.md +104 -0
  232. package/skills/hallmark/references/themes/specimen.jpg +0 -0
  233. package/skills/hallmark/references/themes/specimen.md +100 -0
  234. package/skills/hallmark/references/themes/spore.jpg +0 -0
  235. package/skills/hallmark/references/themes/spore.md +104 -0
  236. package/skills/hallmark/references/themes/sport.jpg +0 -0
  237. package/skills/hallmark/references/themes/sport.md +101 -0
  238. package/skills/hallmark/references/themes/squeeze.jpg +0 -0
  239. package/skills/hallmark/references/themes/squeeze.md +99 -0
  240. package/skills/hallmark/references/themes/sticker.jpg +0 -0
  241. package/skills/hallmark/references/themes/sticker.md +106 -0
  242. package/skills/hallmark/references/themes/studio.jpg +0 -0
  243. package/skills/hallmark/references/themes/studio.md +99 -0
  244. package/skills/hallmark/references/themes/terminal.jpg +0 -0
  245. package/skills/hallmark/references/themes/terminal.md +96 -0
  246. package/skills/hallmark/references/themes/terrazzo.jpg +0 -0
  247. package/skills/hallmark/references/themes/terrazzo.md +106 -0
  248. package/skills/hallmark/references/themes/ultraviolet.jpg +0 -0
  249. package/skills/hallmark/references/themes/ultraviolet.md +106 -0
  250. package/skills/hallmark/references/themes/vellum.jpg +0 -0
  251. package/skills/hallmark/references/themes/vellum.md +105 -0
  252. package/skills/hallmark/references/themes/wayfind.jpg +0 -0
  253. package/skills/hallmark/references/themes/wayfind.md +105 -0
  254. package/skills/hallmark/references/themes/werkstatt.jpg +0 -0
  255. package/skills/hallmark/references/themes/werkstatt.md +105 -0
  256. package/skills/hallmark/scripts/capture.mjs +125 -0
  257. package/skills/hallmark/scripts/fixtures/exemplars/atmospheric.html +324 -0
  258. package/skills/hallmark/scripts/fixtures/exemplars/editorial.html +363 -0
  259. package/skills/hallmark/scripts/fixtures/exemplars/modern-minimal.html +527 -0
  260. package/skills/hallmark/scripts/fixtures/exemplars/playful.html +353 -0
  261. package/skills/hallmark/scripts/fixtures/eyebrow-fail/index.html +118 -0
  262. package/skills/hallmark/scripts/fixtures/eyebrow-pass/index.html +137 -0
  263. package/skills/hallmark/scripts/fixtures/kept/after.html +27 -0
  264. package/skills/hallmark/scripts/fixtures/kept/before.html +26 -0
  265. package/skills/hallmark/scripts/fixtures/slopped.html +145 -0
  266. package/skills/hallmark/scripts/fixtures/tailwind-fail/Feature.vue +14 -0
  267. package/skills/hallmark/scripts/fixtures/tailwind-fail/Hero.tsx +33 -0
  268. package/skills/hallmark/scripts/fixtures/tailwind-fail/index.html +74 -0
  269. package/skills/hallmark/scripts/fixtures/tailwind-fail/style.css +6 -0
  270. package/skills/hallmark/scripts/fixtures/tailwind-pass/Hero.tsx +33 -0
  271. package/skills/hallmark/scripts/fixtures/tailwind-pass/index.html +57 -0
  272. package/skills/hallmark/scripts/fixtures/tailwind-pass/style.css +15 -0
  273. package/skills/hallmark/scripts/fixtures/waiver/index.html +54 -0
  274. package/skills/hallmark/scripts/imagegen.mjs +85 -0
  275. package/skills/hallmark/scripts/install-hook.mjs +70 -0
  276. package/skills/hallmark/scripts/install.mjs +141 -0
  277. package/skills/hallmark/scripts/lint-hook.mjs +49 -0
  278. package/skills/hallmark/scripts/photos.json +1 -0
  279. package/skills/hallmark/scripts/picture.mjs +71 -0
  280. package/skills/hallmark/scripts/refcheck.mjs +352 -0
  281. package/skills/hallmark/scripts/sloplint-render.mjs +1252 -0
  282. package/skills/hallmark/scripts/sloplint.mjs +4422 -0
  283. package/skills/hallmark/scripts/theme.mjs +650 -0
  284. package/skills/harness/SKILL.md +17 -8
  285. package/skills/i-have-adhd/SKILL.md +32 -12
  286. package/skills/no-ai-slop/SKILL.md +15 -1
  287. package/skills/plan-add/SKILL.md +38 -27
  288. package/skills/plan-status/SKILL.md +13 -7
  289. package/skills/plan-sync/SKILL.md +18 -12
  290. package/skills/pm-frameworks/SKILL.md +19 -10
  291. package/skills/pm-frameworks/SOURCE +7 -5
  292. package/skills/ponytail/SKILL.md +19 -14
  293. package/skills/product-analysis/SKILL.md +22 -18
  294. package/skills/product-flow/SKILL.md +14 -9
  295. package/skills/research/SKILL.md +97 -48
  296. package/skills/rl-env/SKILL.md +25 -13
  297. package/skills/rl-env/SOURCE +8 -6
  298. package/skills/tezgah-contract/SKILL.md +65 -47
  299. package/statusline.py +20 -9
  300. package/workflows/graph-review.js +14 -2
  301. package/bin/tezgah-skill.py +0 -59
  302. /package/skills/ai-research/0-autoresearch-skill/{SKILL.md → ENTRY.md} +0 -0
  303. /package/skills/ai-research/01-model-architecture/litgpt/{SKILL.md → ENTRY.md} +0 -0
  304. /package/skills/ai-research/01-model-architecture/mamba/{SKILL.md → ENTRY.md} +0 -0
  305. /package/skills/ai-research/01-model-architecture/nanogpt/{SKILL.md → ENTRY.md} +0 -0
  306. /package/skills/ai-research/01-model-architecture/rwkv/{SKILL.md → ENTRY.md} +0 -0
  307. /package/skills/ai-research/01-model-architecture/torchtitan/{SKILL.md → ENTRY.md} +0 -0
  308. /package/skills/ai-research/02-tokenization/huggingface-tokenizers/{SKILL.md → ENTRY.md} +0 -0
  309. /package/skills/ai-research/02-tokenization/sentencepiece/{SKILL.md → ENTRY.md} +0 -0
  310. /package/skills/ai-research/03-fine-tuning/axolotl/{SKILL.md → ENTRY.md} +0 -0
  311. /package/skills/ai-research/03-fine-tuning/llama-factory/{SKILL.md → ENTRY.md} +0 -0
  312. /package/skills/ai-research/03-fine-tuning/peft/{SKILL.md → ENTRY.md} +0 -0
  313. /package/skills/ai-research/03-fine-tuning/unsloth/{SKILL.md → ENTRY.md} +0 -0
  314. /package/skills/ai-research/04-mechanistic-interpretability/nnsight/{SKILL.md → ENTRY.md} +0 -0
  315. /package/skills/ai-research/04-mechanistic-interpretability/pyvene/{SKILL.md → ENTRY.md} +0 -0
  316. /package/skills/ai-research/04-mechanistic-interpretability/saelens/{SKILL.md → ENTRY.md} +0 -0
  317. /package/skills/ai-research/04-mechanistic-interpretability/transformer-lens/{SKILL.md → ENTRY.md} +0 -0
  318. /package/skills/ai-research/05-data-processing/nemo-curator/{SKILL.md → ENTRY.md} +0 -0
  319. /package/skills/ai-research/05-data-processing/ray-data/{SKILL.md → ENTRY.md} +0 -0
  320. /package/skills/ai-research/06-post-training/grpo-rl-training/{SKILL.md → ENTRY.md} +0 -0
  321. /package/skills/ai-research/06-post-training/miles/{SKILL.md → ENTRY.md} +0 -0
  322. /package/skills/ai-research/06-post-training/openrlhf/{SKILL.md → ENTRY.md} +0 -0
  323. /package/skills/ai-research/06-post-training/simpo/{SKILL.md → ENTRY.md} +0 -0
  324. /package/skills/ai-research/06-post-training/slime/{SKILL.md → ENTRY.md} +0 -0
  325. /package/skills/ai-research/06-post-training/torchforge/{SKILL.md → ENTRY.md} +0 -0
  326. /package/skills/ai-research/06-post-training/trl-fine-tuning/{SKILL.md → ENTRY.md} +0 -0
  327. /package/skills/ai-research/06-post-training/verl/{SKILL.md → ENTRY.md} +0 -0
  328. /package/skills/ai-research/07-safety-alignment/constitutional-ai/{SKILL.md → ENTRY.md} +0 -0
  329. /package/skills/ai-research/07-safety-alignment/llamaguard/{SKILL.md → ENTRY.md} +0 -0
  330. /package/skills/ai-research/07-safety-alignment/nemo-guardrails/{SKILL.md → ENTRY.md} +0 -0
  331. /package/skills/ai-research/07-safety-alignment/prompt-guard/{SKILL.md → ENTRY.md} +0 -0
  332. /package/skills/ai-research/08-distributed-training/accelerate/{SKILL.md → ENTRY.md} +0 -0
  333. /package/skills/ai-research/08-distributed-training/deepspeed/{SKILL.md → ENTRY.md} +0 -0
  334. /package/skills/ai-research/08-distributed-training/megatron-core/{SKILL.md → ENTRY.md} +0 -0
  335. /package/skills/ai-research/08-distributed-training/pytorch-fsdp2/{SKILL.md → ENTRY.md} +0 -0
  336. /package/skills/ai-research/08-distributed-training/pytorch-lightning/{SKILL.md → ENTRY.md} +0 -0
  337. /package/skills/ai-research/08-distributed-training/ray-train/{SKILL.md → ENTRY.md} +0 -0
  338. /package/skills/ai-research/09-infrastructure/lambda-labs/{SKILL.md → ENTRY.md} +0 -0
  339. /package/skills/ai-research/09-infrastructure/modal/{SKILL.md → ENTRY.md} +0 -0
  340. /package/skills/ai-research/09-infrastructure/skypilot/{SKILL.md → ENTRY.md} +0 -0
  341. /package/skills/ai-research/10-optimization/awq/{SKILL.md → ENTRY.md} +0 -0
  342. /package/skills/ai-research/10-optimization/bitsandbytes/{SKILL.md → ENTRY.md} +0 -0
  343. /package/skills/ai-research/10-optimization/flash-attention/{SKILL.md → ENTRY.md} +0 -0
  344. /package/skills/ai-research/10-optimization/gguf/{SKILL.md → ENTRY.md} +0 -0
  345. /package/skills/ai-research/10-optimization/gptq/{SKILL.md → ENTRY.md} +0 -0
  346. /package/skills/ai-research/10-optimization/hqq/{SKILL.md → ENTRY.md} +0 -0
  347. /package/skills/ai-research/10-optimization/ml-training-recipes/{SKILL.md → ENTRY.md} +0 -0
  348. /package/skills/ai-research/11-evaluation/bigcode-evaluation-harness/{SKILL.md → ENTRY.md} +0 -0
  349. /package/skills/ai-research/11-evaluation/lm-evaluation-harness/{SKILL.md → ENTRY.md} +0 -0
  350. /package/skills/ai-research/11-evaluation/nemo-evaluator/{SKILL.md → ENTRY.md} +0 -0
  351. /package/skills/ai-research/12-inference-serving/llama-cpp/{SKILL.md → ENTRY.md} +0 -0
  352. /package/skills/ai-research/12-inference-serving/sglang/{SKILL.md → ENTRY.md} +0 -0
  353. /package/skills/ai-research/12-inference-serving/tensorrt-llm/{SKILL.md → ENTRY.md} +0 -0
  354. /package/skills/ai-research/12-inference-serving/vllm/{SKILL.md → ENTRY.md} +0 -0
  355. /package/skills/ai-research/13-mlops/mlflow/{SKILL.md → ENTRY.md} +0 -0
  356. /package/skills/ai-research/13-mlops/swanlab/{SKILL.md → ENTRY.md} +0 -0
  357. /package/skills/ai-research/13-mlops/tensorboard/{SKILL.md → ENTRY.md} +0 -0
  358. /package/skills/ai-research/13-mlops/weights-and-biases/{SKILL.md → ENTRY.md} +0 -0
  359. /package/skills/ai-research/14-agents/a-evolve/{SKILL.md → ENTRY.md} +0 -0
  360. /package/skills/ai-research/14-agents/autogpt/{SKILL.md → ENTRY.md} +0 -0
  361. /package/skills/ai-research/14-agents/crewai/{SKILL.md → ENTRY.md} +0 -0
  362. /package/skills/ai-research/14-agents/langchain/{SKILL.md → ENTRY.md} +0 -0
  363. /package/skills/ai-research/14-agents/llamaindex/{SKILL.md → ENTRY.md} +0 -0
  364. /package/skills/ai-research/15-rag/chroma/{SKILL.md → ENTRY.md} +0 -0
  365. /package/skills/ai-research/15-rag/faiss/{SKILL.md → ENTRY.md} +0 -0
  366. /package/skills/ai-research/15-rag/pinecone/{SKILL.md → ENTRY.md} +0 -0
  367. /package/skills/ai-research/15-rag/qdrant/{SKILL.md → ENTRY.md} +0 -0
  368. /package/skills/ai-research/15-rag/sentence-transformers/{SKILL.md → ENTRY.md} +0 -0
  369. /package/skills/ai-research/16-prompt-engineering/dspy/{SKILL.md → ENTRY.md} +0 -0
  370. /package/skills/ai-research/16-prompt-engineering/guidance/{SKILL.md → ENTRY.md} +0 -0
  371. /package/skills/ai-research/16-prompt-engineering/instructor/{SKILL.md → ENTRY.md} +0 -0
  372. /package/skills/ai-research/16-prompt-engineering/outlines/{SKILL.md → ENTRY.md} +0 -0
  373. /package/skills/ai-research/17-observability/langsmith/{SKILL.md → ENTRY.md} +0 -0
  374. /package/skills/ai-research/17-observability/phoenix/{SKILL.md → ENTRY.md} +0 -0
  375. /package/skills/ai-research/18-multimodal/audiocraft/{SKILL.md → ENTRY.md} +0 -0
  376. /package/skills/ai-research/18-multimodal/blip-2/{SKILL.md → ENTRY.md} +0 -0
  377. /package/skills/ai-research/18-multimodal/clip/{SKILL.md → ENTRY.md} +0 -0
  378. /package/skills/ai-research/18-multimodal/cosmos-policy/{SKILL.md → ENTRY.md} +0 -0
  379. /package/skills/ai-research/18-multimodal/llava/{SKILL.md → ENTRY.md} +0 -0
  380. /package/skills/ai-research/18-multimodal/openpi/{SKILL.md → ENTRY.md} +0 -0
  381. /package/skills/ai-research/18-multimodal/openvla-oft/{SKILL.md → ENTRY.md} +0 -0
  382. /package/skills/ai-research/18-multimodal/segment-anything/{SKILL.md → ENTRY.md} +0 -0
  383. /package/skills/ai-research/18-multimodal/stable-diffusion/{SKILL.md → ENTRY.md} +0 -0
  384. /package/skills/ai-research/18-multimodal/whisper/{SKILL.md → ENTRY.md} +0 -0
  385. /package/skills/ai-research/19-emerging-techniques/knowledge-distillation/{SKILL.md → ENTRY.md} +0 -0
  386. /package/skills/ai-research/19-emerging-techniques/long-context/{SKILL.md → ENTRY.md} +0 -0
  387. /package/skills/ai-research/19-emerging-techniques/model-merging/{SKILL.md → ENTRY.md} +0 -0
  388. /package/skills/ai-research/19-emerging-techniques/model-pruning/{SKILL.md → ENTRY.md} +0 -0
  389. /package/skills/ai-research/19-emerging-techniques/moe-training/{SKILL.md → ENTRY.md} +0 -0
  390. /package/skills/ai-research/19-emerging-techniques/speculative-decoding/{SKILL.md → ENTRY.md} +0 -0
  391. /package/skills/ai-research/20-ml-paper-writing/academic-plotting/{SKILL.md → ENTRY.md} +0 -0
  392. /package/skills/ai-research/20-ml-paper-writing/ml-paper-writing/{SKILL.md → ENTRY.md} +0 -0
  393. /package/skills/ai-research/20-ml-paper-writing/presenting-conference-talks/{SKILL.md → ENTRY.md} +0 -0
  394. /package/skills/ai-research/20-ml-paper-writing/systems-paper-writing/{SKILL.md → ENTRY.md} +0 -0
  395. /package/skills/ai-research/21-research-ideation/brainstorming-research-ideas/{SKILL.md → ENTRY.md} +0 -0
  396. /package/skills/ai-research/21-research-ideation/creative-thinking-for-research/{SKILL.md → ENTRY.md} +0 -0
  397. /package/skills/ai-research/22-agent-native-research-artifact/compiler/{SKILL.md → ENTRY.md} +0 -0
  398. /package/skills/ai-research/22-agent-native-research-artifact/research-manager/{SKILL.md → ENTRY.md} +0 -0
  399. /package/skills/ai-research/22-agent-native-research-artifact/rigor-reviewer/{SKILL.md → ENTRY.md} +0 -0
  400. /package/skills/design-library/adaptive-interfaces/skills/colour-independence/{SKILL.md → ENTRY.md} +0 -0
  401. /package/skills/design-library/adaptive-interfaces/skills/flexible-typography/{SKILL.md → ENTRY.md} +0 -0
  402. /package/skills/design-library/adaptive-interfaces/skills/information-density/{SKILL.md → ENTRY.md} +0 -0
  403. /package/skills/design-library/adaptive-interfaces/skills/preference-audit/{SKILL.md → ENTRY.md} +0 -0
  404. /package/skills/design-library/adaptive-interfaces/skills/responsive-accessibility/{SKILL.md → ENTRY.md} +0 -0
  405. /package/skills/design-library/adaptive-interfaces/skills/responsive-review/{SKILL.md → ENTRY.md} +0 -0
  406. /package/skills/design-library/adaptive-interfaces/skills/simplified-views/{SKILL.md → ENTRY.md} +0 -0
  407. /package/skills/design-library/adaptive-interfaces/skills/specify/{SKILL.md → ENTRY.md} +0 -0
  408. /package/skills/design-library/adaptive-interfaces/skills/user-preference-respect/{SKILL.md → ENTRY.md} +0 -0
  409. /package/skills/design-library/cognitive-accessibility/skills/adaptive-personalisation/{SKILL.md → ENTRY.md} +0 -0
  410. /package/skills/design-library/cognitive-accessibility/skills/assess-load/{SKILL.md → ENTRY.md} +0 -0
  411. /package/skills/design-library/cognitive-accessibility/skills/cognitive-load-assessment/{SKILL.md → ENTRY.md} +0 -0
  412. /package/skills/design-library/cognitive-accessibility/skills/contextual-help-design/{SKILL.md → ENTRY.md} +0 -0
  413. /package/skills/design-library/cognitive-accessibility/skills/error-prevention-recovery/{SKILL.md → ENTRY.md} +0 -0
  414. /package/skills/design-library/cognitive-accessibility/skills/focus-attention-design/{SKILL.md → ENTRY.md} +0 -0
  415. /package/skills/design-library/cognitive-accessibility/skills/memory-load-reduction/{SKILL.md → ENTRY.md} +0 -0
  416. /package/skills/design-library/cognitive-accessibility/skills/plain-language-design/{SKILL.md → ENTRY.md} +0 -0
  417. /package/skills/design-library/cognitive-accessibility/skills/review/{SKILL.md → ENTRY.md} +0 -0
  418. /package/skills/design-library/cognitive-accessibility/skills/simplify/{SKILL.md → ENTRY.md} +0 -0
  419. /package/skills/design-library/cognitive-accessibility/skills/wayfinding-navigation/{SKILL.md → ENTRY.md} +0 -0
  420. /package/skills/design-library/design-research/skills/behavioural-analytics/{SKILL.md → ENTRY.md} +0 -0
  421. /package/skills/design-library/design-research/skills/qual-quant-triangulation/{SKILL.md → ENTRY.md} +0 -0
  422. /package/skills/design-library/inclusive-interaction/skills/audit/{SKILL.md → ENTRY.md} +0 -0
  423. /package/skills/design-library/inclusive-interaction/skills/design-flow/{SKILL.md → ENTRY.md} +0 -0
  424. /package/skills/design-library/inclusive-interaction/skills/feedback-and-status/{SKILL.md → ENTRY.md} +0 -0
  425. /package/skills/design-library/inclusive-interaction/skills/gesture-alternatives/{SKILL.md → ENTRY.md} +0 -0
  426. /package/skills/design-library/inclusive-interaction/skills/keyboard-navigation/{SKILL.md → ENTRY.md} +0 -0
  427. /package/skills/design-library/inclusive-interaction/skills/keyboard-review/{SKILL.md → ENTRY.md} +0 -0
  428. /package/skills/design-library/inclusive-interaction/skills/motion-sensitivity/{SKILL.md → ENTRY.md} +0 -0
  429. /package/skills/design-library/inclusive-interaction/skills/multi-modal-input/{SKILL.md → ENTRY.md} +0 -0
  430. /package/skills/design-library/inclusive-interaction/skills/touch-target-design/{SKILL.md → ENTRY.md} +0 -0
  431. /package/skills/design-library/inclusive-interaction/skills/voice-interaction/{SKILL.md → ENTRY.md} +0 -0
  432. /package/skills/design-library/visual-critique/skills/critique-affordance/{SKILL.md → ENTRY.md} +0 -0
  433. /package/skills/design-library/visual-critique/skills/critique-brand-consistency/{SKILL.md → ENTRY.md} +0 -0
  434. /package/skills/design-library/visual-critique/skills/critique-color/{SKILL.md → ENTRY.md} +0 -0
  435. /package/skills/design-library/visual-critique/skills/critique-composition/{SKILL.md → ENTRY.md} +0 -0
  436. /package/skills/design-library/visual-critique/skills/critique-information-density/{SKILL.md → ENTRY.md} +0 -0
  437. /package/skills/design-library/visual-critique/skills/critique-typography/{SKILL.md → ENTRY.md} +0 -0
  438. /package/skills/design-library/visual-critique/skills/critique-visual-hierarchy/{SKILL.md → ENTRY.md} +0 -0
  439. /package/skills/pm-frameworks/intended-vs-implemented/{SKILL.md → ENTRY.md} +0 -0
  440. /package/skills/pm-frameworks/opportunity-solution-tree/{SKILL.md → ENTRY.md} +0 -0
  441. /package/skills/rl-env/generate-nemo-gym-env/{SKILL.md → ENTRY.md} +0 -0
  442. /package/skills/rl-env/generate-openenv-env/{SKILL.md → ENTRY.md} +0 -0
  443. /package/skills/rl-env/generate-ors-env/{SKILL.md → ENTRY.md} +0 -0
  444. /package/skills/rl-env/generate-verifiers-env/{SKILL.md → ENTRY.md} +0 -0
  445. /package/skills/rl-env/rl-env-from-description/{SKILL.md → ENTRY.md} +0 -0
package/docs/research.md CHANGED
@@ -68,11 +68,16 @@ are the standards rules. Rules 3 add the ask contract. Rules 4 add the protocol
68
68
  sections below. Rules 5 add the scope lock. Rules 6 add the selection warnings
69
69
  ("Held-out set, repeats and noise band" below). Rules 7 add the `exploratory`
70
70
  method ("Rules 7: exploratory lines" below). A bump never weakens an older set.
71
+ Rules 8 (`EVIDENCE_RULES`) add captured evidence and a computed certainty per
72
+ claim ("Rules 8: captured evidence and computed certainty" below). Rules 9
73
+ (`OWNER_CHOICE_RULES`) split a decision's pick: the line writes `recommended:`,
74
+ and `chosen:` is the owner's ("Variants of the deliverable" below). `init` writes 9
75
+ now: `RULES` is `OWNER_CHOICE_RULES` (`hooks/tezgah_research.py::OWNER_CHOICE_RULES`).
71
76
 
72
77
  A `rules` above `RULES` means a later tezgah wrote the line. `check` then reports
73
78
  one error that names both numbers and reads nothing else. The writers refuse the
74
79
  line too: `claim`, `predict`, `compare`, `source --run`, `verdict`, `conclude`,
75
- `close` and `migrate` (`newer_rules`). Upgrade tezgah to work on such a line.
80
+ `close`, `choose` and `migrate` (`newer_rules`). Upgrade tezgah to work on such a line.
76
81
 
77
82
  ## Protocol sections (rules 4)
78
83
 
@@ -148,6 +153,68 @@ no line. Cite each finding's source with a confidence. The host-subagent fallbac
148
153
  gets the question, its scope and its method in its brief. The research skill's
149
154
  "Scope and method" section is the long form.
150
155
 
156
+ ## Variants of the deliverable
157
+
158
+ `state.json` `deliverable` names what the line delivers. Its `kind` is `design`,
159
+ `plan`, `code`, `analysis` or `finding`
160
+ (`hooks/tezgah_research.py::DELIVERABLE_KINDS`). A design or plan takes 3 compared
161
+ variants by default and code takes 2 (`hooks/tezgah_research.py::deliverable_problems`).
162
+ On a rules-5 line an analysis and a finding take none. `min_variants` changes the
163
+ count. A count below the default needs `single_variant_reason`, which says why
164
+ the line weighed no alternative. `check` compares any decision across at least 2
165
+ produced variants (`hooks/tezgah_research.py::_check_decisions`).
166
+
167
+ One comparison lives in `decisions/<id>/`, and one loader reads its files
168
+ (`hooks/tezgah_research.py::load_decision`):
169
+
170
+ | File | What it holds |
171
+ |---|---|
172
+ | `criteria.json` | `criteria`: a list of `{id, kind, direction}`, with `kind` `measured` or `judged` and `direction` `max`, `min` or `pass`. `baseline_variant`: the id of the status-quo variant in `variants.jsonl` |
173
+ | `variants.jsonl` | one `{id, status}` row per variant. A `produced` variant names its `artifact`: a file in the line or the repository, `git:<rev>` or `orx:<id>`. A `dropped` one gives `drop_reason` |
174
+ | `comparison.jsonl` | one cell per variant and criterion, written by `compare` |
175
+ | `decision.md` | the line's pick (`recommended:`), the owner's (`chosen:` with `owner:`) and why the others lost |
176
+
177
+ Write and commit `criteria.json` and `variants.jsonl` before the first cell. Then
178
+ record each cell with `tezgah-research compare <slug> <decision>`, one JSON object
179
+ on stdin (`hooks/tezgah_research.py::append_comparison`). A cell names a produced
180
+ `variant` and a defined `criterion`. It carries either a `value` with its `source`,
181
+ or `not_checked` with the reason. A cell source has to resolve in the line or the
182
+ repository. An optional `rater` names who judged it
183
+ (`hooks/tezgah_research.py::comparison_problems`). The writer and `check` apply
184
+ this same rule.
185
+
186
+ `check` reads the whole decision
187
+ (`hooks/tezgah_research.py::_check_decision`):
188
+
189
+ - `check` refuses two produced variants that are the same file.
190
+ - A matrix cell neither measured nor marked `not_checked` warns. It refuses once
191
+ `decision.md` exists or the line concludes.
192
+ - A judged cell with fewer than two distinct raters warns.
193
+ - The criteria have to enter the history before the first cell, and
194
+ `comparison.jsonl` only grows.
195
+ - `decision.md` names a produced variant on a `chosen: <id>` line, else on a
196
+ `recommended: <id>` line (`hooks/tezgah_research.py::decision_pick`).
197
+ - On a rules-9 line the line writes its own pick as `recommended:`. A `chosen:`
198
+ line with no `owner:` line fails with `names no owner choice`. Choosing a
199
+ variant or option a research, analysis or review recommends is the owner's
200
+ call. `tezgah-research choose <slug> <decision> <variant> --ack
201
+ "<the owner's words>"` writes `chosen:` and `owner: <date> "<words>"` and one
202
+ `log.md` line (`hooks/tezgah_research.py::choose_line`). It works on a done
203
+ line too: the order seal hashes the experiments alone. It keeps the line's
204
+ own pick. A pick a rules-8 line wrote as `chosen:` becomes `recommended:`. A
205
+ rules-8 line's `chosen:` is read as before.
206
+ - `conclude` prints `report to the owner: <id> is recommended, not chosen` for
207
+ each decision still waiting (`hooks/tezgah_research.py::owner_waits`).
208
+ - The three rules below judge the line's own pick, never the owner's
209
+ (`hooks/tezgah_research.py::line_pick`). An owner may take a dominated
210
+ variant, and that is no error of the line.
211
+ - Each other produced variant shares a line of `decision.md` with a criterion id
212
+ that ruled it out. Else: `rejects <id> on no criterion`.
213
+ - `decision.md` has a `flip:` line, the result that would reverse the choice.
214
+ - When every criterion is `max` or `min` and scored, no produced variant may
215
+ dominate the picked one. A dominating variant is at least as good on every
216
+ criterion and better on one (`hooks/tezgah_research.py::dominated_by`).
217
+
151
218
  ## One line, one directory
152
219
 
153
220
  | Path | Holds |
@@ -213,10 +280,23 @@ rule names the open lines with their reason counts on every research turn
213
280
  "<reason>"`, which writes the reason into the new line's `log.md` - an explicit
214
281
  decision on the record instead of a silent second line - and which is itself
215
282
  refused while any open line has `check` errors (`broken_open_lines`): a hatch past
216
- broken lines is how they stayed broken. What is left of a line that will not be
283
+ broken lines is how they stayed broken. A success criterion whose verdict is
284
+ still `pending` is a line in flight, not a broken one. That error alone does not
285
+ block the hatch, and any other error does. A line another session is running is
286
+ not this session's to fix or close. Both refusals say so
287
+ (`hooks/tezgah_research.py::OWNER_ASK`). The session stops and asks the owner,
288
+ never a way around a tezgah refusal (another folder, a hidden dir). A hidden dir
289
+ under `research/`, `research/open/` or `research/done/` holds no line `check` can
290
+ see. The no-slug `check` and `status` fail it by its path
291
+ (`hooks/tezgah_research.py::stray_dirs`). What is left of a line that will not be
217
292
  finished is recorded with `tezgah-research close <slug> --limit "<reason>"`
218
293
  (`close_line`), which concludes it and writes the reasons it was still open into
219
- `state.json` `closed` and `log.md` and seals it ("the order seal", below).
294
+ `state.json` `closed` and `log.md` and seals it ("the order seal", below). Such
295
+ a limit is a normal outcome, not a failure to avoid. So are a hypothesis ended
296
+ `inconclusive` and a claim narrowed to what its evidence reaches. The skill and
297
+ the policy carry no "try harder" prompting: it measured null or negative (plan
298
+ 127, 4.4). On a rules-8 line `check` caps a claim's certainty and warns on
299
+ overclaiming wording instead.
220
300
  Its errors show in `check <slug>` and `check --all-lines`; the no-slug `check`
221
301
  reads it by its seal hashes and counts it on one line (ADR 015). The
222
302
  prompt-time note reads a line's `state.json`, its experiment directory and its
@@ -234,10 +314,10 @@ through its seal.
234
314
 
235
315
  | Command | What it does | Exit |
236
316
  |---|---|---|
237
- | `tezgah-research init <slug> [--question "..."] [--allow-open "<reason>"] [--supersedes <slug>]` | scaffolds the line and makes sure `.tezgah/` is ignored by the project and has its own git repository (`tezgah_paths.ensure_workspace`). It refuses while another line is still open (see below), names each open line and its reasons one per line, and `--allow-open "<reason>"` is the way past unless an open line has `check` errors: the reason lands in the new line's `log.md` as its first entry, and an empty reason is misuse. A `--question` another line already asks is refused unless `--supersedes <that line>` says the new line is its next version (`serial_twins`). Its next-step message names the commit loop: `tezgah-research commit` for the protocol, then again for the results in a later commit (`cmd_init`, `bin/tezgah-research`) | 0, 1 refused, 2 misuse |
238
- | `tezgah-research commit <slug> "<message>"` | stages and commits only that line's path in `.tezgah`'s private repository - the commit the order rule reads (`cmd_commit`, `bin/tezgah-research`) | 0, 1 not a work tree or git failed, 2 misuse |
239
- | `tezgah-research check [<slug>] [--json] [--strict] [--orx] [--all-lines] [-- <slug>]` | the discipline checks below. With no slug it checks the open lines in full and a line under `done/` by its order seal alone (`done_seal`, `hooks/tezgah_research.py::done_seal`), naming it only when the seal fails or its `state.json` or seal cannot be read, then prints `research: <n> done line(s): <s> checked by their seal, <u> unsealed (not checked); ...`; `--all-lines` checks every line in full, and `check <slug>` always checks that line in full (ADR 015). `--json` prints the report (no-slug default: the open lines and any done line whose seal read fails), `--strict` turns the unverifiable class into a refusal, `--orx` adds the registry check that asks `orx project view` for this repository (`check_orx`, `hooks/tezgah_research.py::check_orx`); a slug after `--` is never read as a flag, which is how the MCP tool `tezgah_research_check` passes its validated `slug` | 0 clean, 1 a line failed a rule or names no line |
240
- | `tezgah-research status` | one line per line: an open line `ok` or a problem count, a line under `done/` read by its seal like the no-slug `check` - `done, seal ok`, `done, <n> seal problem(s)` or `done, unsealed (not checked)` (`summary`, `hooks/tezgah_research.py::summary`, plan 058 part 4) | 0 |
317
+ | `tezgah-research init <slug> [--question "..."] [--class R1..R12] [--allow-open "<reason>"] [--supersedes <slug>]` | scaffolds the line and makes sure `.tezgah/` is ignored by the project and has its own git repository (`tezgah_paths.ensure_workspace`). It refuses while another line is still open (see below), names each open line and its reasons one per line, and `--allow-open "<reason>"` is the way past unless an open line has `check` errors: the reason lands in the new line's `log.md` as its first entry, and an empty reason is misuse. A `--question` another line already asks is refused unless `--supersedes <that line>` says the new line is its next version (`serial_twins`). `--class` writes `state.question_class` and prints `obligations: <step>, ...` (`obligations`), the tier's `budget <slug>: sources a/b searches c/d runs e/f` (`budget`) and `overlap: <line>/<claim> <status> <similarity>` for each done claim close to the question (`overlaps`); `--class R0` exits 1 (`R0 gets no line`) before any other argument is read. Its next-step message names the commit loop: `tezgah-research commit` for the protocol, then again for the results in a later commit (`cmd_init`, `bin/tezgah-research`) | 0, 1 refused, 2 misuse |
318
+ | `tezgah-research commit <slug> "<message>"` | stages and commits only that line's path in `.tezgah`'s private repository - the commit the order rule reads (`cmd_commit`, `bin/tezgah-research`). With nothing left to commit it prints `nothing to commit: <paths> is already committed in <workspace>` and exits 0 | 0 (also with nothing to commit), 1 not a work tree or git failed, 2 misuse |
319
+ | `tezgah-research check [<slug>] [--json] [--strict] [--orx] [--online] [--all-lines] [-- <slug>]` | the discipline checks below. With no slug it checks the open lines in full and a line under `done/` by its order seal alone (`done_seal`, `hooks/tezgah_research.py::done_seal`), naming it only when the seal fails or its `state.json` or seal cannot be read, then prints `research: <n> done line(s): <s> checked by their seal, <u> unsealed (not checked); ...`; `--all-lines` checks every line in full, and `check <slug>` always checks that line in full (ADR 015). `--json` prints the report (no-slug default: the open lines and any done line whose seal read fails), `--strict` turns the unverifiable class into a refusal, `--orx` adds the registry check that asks `orx project view` for this repository (`check_orx`, `hooks/tezgah_research.py::check_orx`) and, on a rules-8 line, the run census; `--online` re-fetches a rules-8 line's citation receipts; a slug after `--` is never read as a flag, which is how the MCP tool `tezgah_research_check` passes its validated `slug`. A rules-8 line (`_check_rules8`) also prints report lines that are never counted - `certainty`, `stats`, `effect`, `instrument`, `ppi`, `stopping`, `online`, `budget` - and `--json` adds its per-claim `certainty` | 0 clean, 1 a line failed a rule or names no line |
320
+ | `tezgah-research status` | one line per line: an open line `ok` or a problem count, a line under `done/` read by its seal like the no-slug `check` - `done, seal ok`, `done, <n> seal problem(s)` or `done, unsealed (not checked)` (`summary`, `hooks/tezgah_research.py::summary`, plan 058 part 4); then one `FAIL` line per hidden dir under `research/` (`stray_dirs`) | 0 |
241
321
  | `tezgah-research --all` | every checkout of this repository (the main checkout and each linked `git worktree`, `tezgah_paths.worktrees`), one header per checkout, then ` <slug>: <phase>` per line with the reasons it is still open; a checkout with none says `no research line`. Read-only: each checkout keeps its own `.tezgah`, locks and private repository, and nothing here writes to any of them (`across`, `hooks/tezgah_research.py::across`) | 0, 2 misuse |
242
322
  | `tezgah-research claim <slug>` | reads one claim from stdin and either appends it under an exclusive lock or refuses it, printing one reason per problem | 0, 1 refused, 2 misuse |
243
323
  | `tezgah-research predict <slug>` | reads one prediction row from stdin and either appends it under the same lock or refuses it with one reason per problem; a row whose `commit` git cannot place is appended with the warning printed, which is the fail-open `check` uses, and a row written now has to name at least one component the manifest defines (`append_prediction`, `hooks/tezgah_research.py::append_prediction`) | 0, 1 refused, 2 misuse |
@@ -247,7 +327,8 @@ through its seal.
247
327
  | `tezgah-research compare <slug> <decision>` | reads one variants x criteria cell from stdin and appends it to `decisions/<decision>/comparison.jsonl` under the lock, or refuses it by the rule `check` applies (`append_comparison` and `comparison_problems`, `hooks/tezgah_research.py`); it notes when `criteria.json` is not committed yet | 0, 1 refused, 2 misuse |
248
328
  | `tezgah-research close <slug> --limit "<reason>"` | concludes the line as a deliberate limit, writing the reasons it was still open into `state.json` `closed` and `log.md`, and seals it (`close_line`) | 0, 1 unreadable state, 2 misuse |
249
329
  | `tezgah-research verdict <slug> <id> met\|not-met\|unanswerable --evidence "<ref>"` | records one success criterion's verdict and the evidence it rests on in the line's `state.json`, or refuses it with one `FAIL verdict:` line per problem (`verdict_problems`, `hooks/tezgah_research.py::verdict_problems`) | 0, 1 refused or unreadable state, 2 misuse |
250
- | `tezgah-research conclude <slug>` | concludes a line once every success criterion carries a verdict, seals it and moves it to `done/` (`conclude_line`, `hooks/tezgah_research.py::conclude_line`) | 0, 1 refused, 2 misuse |
330
+ | `tezgah-research conclude <slug>` | concludes a line once every success criterion carries a verdict, seals it and moves it to `done/` (`conclude_line`, `hooks/tezgah_research.py::conclude_line`); then prints `report to the owner: <id> is recommended, not chosen; ...` for each decision with no owner choice (`owner_waits`) | 0, 1 refused, 2 misuse |
331
+ | `tezgah-research choose <slug> <decision> <variant> --ack "<the owner's words>"` | records the owner's pick: `chosen:` and `owner: <date> "<words>"` in the decision's `decision.md`, one `log.md` line; refuses empty `--ack`, a missing decision and a variant the decision did not produce, on an open or a done line (`choose_line`, `hooks/tezgah_research.py::choose_line`) | 0, 1 refused, 2 misuse |
251
332
  | `tezgah-research migrate-layout` | moves flat `research/<slug>` directories into `open/` or `done/` by each line's state, and is idempotent (`migrate_layout`, `hooks/tezgah_research.py::migrate_layout`) | 0, 2 misuse |
252
333
  | `tezgah-research seal <slug> [--history-lost] --ack "<owner decision>"` | seals a line under `done/` that was concluded before seals existed: plainly, as `conclude` would, when every experiment's order still checks; with `--history-lost`, with that verdict for every experiment whose order the lost history left undecidable. Refuses a line with a real order violation, a plain seal on any order finding, and a `history-lost` seal with nothing lost (`retro_seal`, `hooks/tezgah_research.py::retro_seal`) | 0, 1 refused, 2 misuse |
253
334
  | `tezgah-research import <checkout> [<slug>] [--allow-open "<reason>"]` | brings a line - or every line this checkout lacks - from another checkout's `.tezgah` repository with its history; an open line arrives beside open ones only with `--allow-open` (`import_line`, `hooks/tezgah_research.py::import_line`) | 0, 1 refused, 2 misuse |
@@ -777,6 +858,732 @@ The consequences:
777
858
  Rules 1-6, `FROZEN_PATHS` and ADR 009 stay as they were. Predictions and
778
859
  components take nothing new. `research-off` covers this method too.
779
860
 
861
+ ## Rules 8: captured evidence and computed certainty
862
+
863
+ A rules-7 line takes the session's word for three things. A cited paper exists, a
864
+ quote stands in it, and a number came from a run. Rules 8 make the tool fetch
865
+ and store those bytes. `check` then re-derives each claim's
866
+ support from them and computes a certainty level per claim. No claim states its
867
+ own level. The capture commands are `hooks/tezgah_research_capture.py::COMMANDS`.
868
+ The instrument, release and calibration commands are
869
+ `hooks/tezgah_research_evidence.py::COMMANDS`. The statistics in
870
+ `hooks/tezgah_research_stats.py` use the standard library only.
871
+ `_check_rules8` (`hooks/tezgah_research.py::_check_rules8`) runs the capture
872
+ checks, the core checks and the certainty engine, in that order.
873
+
874
+ A line whose `state.json` `rules` is below 8 keeps every rule it had, and nothing
875
+ in this section reads it (`hooks/tezgah_research.py::_evidence`). It still gets
876
+ the claim-number rule under `--strict` and the INDEX `verified` warning. A rules-8
877
+ line gets `untraced-number` and the receipts instead. A missing obligation there
878
+ lowers a level and never refuses, not even under `--strict`.
879
+
880
+ ### What `check` prints for a rules-8 line
881
+
882
+ `check` keeps its `FAIL <slug>:` and `warn <slug>:` lines. A rules-8 line adds
883
+ report lines after them, and they never count as problems: `certainty`, `stats`,
884
+ `effect`, `instrument`, `ppi`, `stopping`, `online` and `budget`. Under
885
+ `check --json` the line's row carries them as `report`. It also carries
886
+ `certainty`, one `{level, start, steps}` object per claim id
887
+ (`hooks/tezgah_research.py::check_line`). Every new command exits 0 when done. It
888
+ exits 1 on a refusal, prints `FAIL <slug>: <reason>` and writes nothing. It exits
889
+ 2 on misuse.
890
+
891
+ `TEZGAH_CAPTURE_MAP=<json file>` answers every HTTP call of the capture commands
892
+ and of `check --online` from a map of URL to body file. Tests and offline runs use
893
+ it (`hooks/tezgah_research_capture.py::fetch_url`). `TEZGAH_ORX_BIN` overrides
894
+ the `orx` lookup.
895
+
896
+ ### The question class: `init --class`
897
+
898
+ A complete command for a measured R6 line:
899
+
900
+ ```
901
+ tezgah-research init cache-latency --ask "does the cache cut p95?" \
902
+ --question "Does the read cache cut p95 latency of the read path?" \
903
+ --method measured --class R6 --in "p95 of the read path" --out "write path"
904
+ ```
905
+
906
+ Leave out `--question` and `check` refuses the line with
907
+ `state.json records no question`. `--class` writes `state.json` `question_class`.
908
+ `--class R0` exits 1 with `R0 gets no line` before any other argument counts
909
+ (`bin/tezgah-research::cmd_init`). An R0 question is factual or reference, and the
910
+ reply answers it. A new line owes more before `check` passes clean. It owes the
911
+ success criteria of "The ask contract" and the protocol labels of "Protocol
912
+ sections (rules 4)". It owes the scope of "Scope lock (rules 5)" and, on a
913
+ measured line, the committed evaluation lock under "What `check` refuses". It
914
+ writes four formats by hand, and `check` reads each one:
915
+
916
+ - An INDEX row's `note` is a path relative to `literature/`: `smith2020.md` names
917
+ `literature/smith2020.md`. A path with `..`, or one `literature/` does not hold,
918
+ fails with `which literature/ does not hold` (`hooks/tezgah_research.py::_read_index`).
919
+ - A claim's `provenance` and the `tag` of each `state.json` session entry take
920
+ one of four values (`hooks/tezgah_research.py::PROVENANCE`). `user`: the user
921
+ stated or confirmed it. `ai-suggested`: the session inferred it and nobody
922
+ confirmed it. `ai-executed`: the session ran or wrote it. `user-revised`: the
923
+ session suggested it and the user corrected it.
924
+ - `to_human/review.json` scores six `dimensions`: `evidence_relevance`,
925
+ `falsifiability`, `scope_calibration`, `argument_coherence`,
926
+ `exploration_integrity` and `methodological_rigour`
927
+ (`hooks/tezgah_research.py::REVIEW_DIMENSIONS`). Each score is an integer from 1
928
+ to 5. A missing score or one outside that range fails
929
+ (`hooks/tezgah_research.py::_check_review`).
930
+ - `state.json` `deliverable` is an object. Its `kind` is one of
931
+ `DELIVERABLE_KINDS`, and "Variants of the deliverable" covers its variant count.
932
+ `path` names the deliverable's file, read relative to the line first and then
933
+ to the repository (`hooks/tezgah_research.py::_deliverable_file`). `ask`, when
934
+ present, is a list of the ask's items, each a non-empty string. Anything else
935
+ fails with `state.json deliverable ask is not a list of the ask's items`
936
+ (`hooks/tezgah_research.py::deliverable_problems`).
937
+
938
+ With a class, `init` prints three more things:
939
+
940
+ - `obligations: <step>, <step>, ...` lists every certainty step the class can
941
+ trigger (`hooks/tezgah_research.py::obligations`).
942
+ - `budget <slug>: sources a/b searches c/d runs e/f` counts INDEX rows, SEARCHES
943
+ rows and `source: orx:` results rows against the tier's caps
944
+ (`hooks/tezgah_research.py::BUDGETS`). The caps are starting values: quick
945
+ 10/10/10, study 30/40/40, program 100/150/200. `check` prints the same line and
946
+ warns `over budget` past any cap (`hooks/tezgah_research.py::budget`).
947
+ - `overlap: <line>/<claim> <status> <similarity>` names each claim of a done line
948
+ whose similarity to the question reaches 0.5
949
+ (`hooks/tezgah_research.py::overlaps`).
950
+
951
+ The class fixes the methods a line may take (`hooks/tezgah_research.py::CLASS_METHODS`)
952
+ and adds its own steps (`hooks/tezgah_research.py::CLASS_STEPS`):
953
+
954
+ | Class | Methods | Class steps (each -1 on every claim) |
955
+ |---|---|---|
956
+ | R1 | qualitative | none |
957
+ | R2 | qualitative | `no-grey-quality`: a grey INDEX row without `quality` |
958
+ | R3 | qualitative, measured | `no-population`: state lacks `population` or `n` |
959
+ | R4 | measured | `no-confounders`: a protocol without `confounders:` |
960
+ | R5 | measured | `fewer-than-two-rivals`, and `no-positive-control`: a measured protocol without `control:` |
961
+ | R6 | measured | `fewer-than-two-rivals`: fewer than two `rival: <text> excludes: <text>` protocol lines |
962
+ | R7 | qualitative | `no-dual-screening`: a screened record with fewer than two screeners, and `no-recall-stopping`: `stopping.rule` is not `hypergeometric` |
963
+ | R8 | qualitative | `no-dual-screening`: under 20% of records dual-screened, or a dropped record screened once |
964
+ | R9 | qualitative | `no-amstar`: an INDEX row without `amstar` |
965
+ | R10 | qualitative | `no-codebook`: no `codebook.md` in the line |
966
+ | R11 | exploratory | none |
967
+ | R12 | qualitative, measured | `fewer-than-two-approaches`: fewer than two `state.approaches` entries with `biases` |
968
+
969
+ Every class can also take `no-question-class` (no class at all), `class-unreviewed`
970
+ (the review's `question_class` is absent or differs) and `method-not-allowed`
971
+ (`hooks/tezgah_research.py::_routing_steps`). A search line is a line of class R1,
972
+ R2 or R7 to R10, a `qualitative` line, or a line with no class.
973
+
974
+ ### Capture: `cite`, `fetch`, `search`, `source`
975
+
976
+ The tool fetches what a line cites, never the session. Each capture command
977
+ writes its files, appends its ledger rows and commits exactly those files as
978
+ `capture: <command> <slug>` (`hooks/tezgah_research_capture.py::commit_capture`).
979
+ The commit lands in the workspace's own repository, or in the project's when the
980
+ project tracks the workspace.
981
+
982
+ **`tezgah-research cite <slug>`** queries `arxiv`, `crossref`, `openalex` and
983
+ `semanticscholar` (`hooks/tezgah_research_capture.py::PROVIDERS`) for every formal
984
+ INDEX row whose `id` is an arXiv id or a DOI. A `pubmed:<pmid>` row goes to
985
+ `pubmed`. An `openalex:W<n>`, `s2:<paperId>` or `pubmed:<pmid>` id resolves through its
986
+ own registry alone, so it takes the step `one-provider`
987
+ (`hooks/tezgah_research_capture.py::receipt_urls`). Each answer of status 200
988
+ becomes a row of `literature/.receipts/RECEIPTS.jsonl`, and its raw bytes go to
989
+ `literature/.receipts/<sha256>.raw`. Any other status, such as a 404 or a 429,
990
+ prints `receipt <id> <provider>: status <n>, not recorded` and writes nothing. A
991
+ later `check --online` would read such an answer as drift, which is why it is not
992
+ recorded. A row filed by an older `cite` at another status is never compared. With no 200 at all,
993
+ `cite` prints `no registry answered 200, so nothing was written`
994
+ (`hooks/tezgah_research_capture.py::cmd_cite`). `cite` skips any other id and prints
995
+ `is not an arXiv, DOI, OpenAlex, Semantic Scholar or PubMed id`. With nothing to
996
+ cite it prints `no formal row with an arXiv, DOI, OpenAlex, Semantic Scholar or
997
+ PubMed id to cite`.
998
+ It exits 0 even when nothing resolves, because judging the receipts is `check`'s
999
+ job (`hooks/tezgah_research_capture.py::cmd_cite`). The INDEX may write an id as a bare DOI
1000
+ such as `10.1145/abc.1`. It may also write a bare arXiv id in new or old style
1001
+ (`1805.08612`, `hep-th/9901001`) or an `arxiv.org` abs, pdf or html URL. Each
1002
+ reads as `doi:` or `arXiv:<id>`. A JSON number is never an id
1003
+ (`hooks/tezgah_research_capture.py::norm_id`). `check`
1004
+ reads the receipts offline and judges only those for an id the INDEX holds now
1005
+ (`hooks/tezgah_research_capture.py::_check_receipts`):
1006
+
1007
+ - `check` refuses a receipt row that a re-parse of its raw bytes contradicts:
1008
+ `not derived from its capture`.
1009
+ - A resolved receipt counts for the INDEX id only when its raw bytes name that id
1010
+ (`hooks/tezgah_research_capture.py::receipt_ids`). A receipt whose raw bytes name
1011
+ another id for the same work does not count for it, and `check` does not refuse
1012
+ it. It warns once:
1013
+ `the <provider> receipt for <id> names <ids>, not that id, so it does not count for it`.
1014
+ The INDEX row then resolves through the other providers, or fails with
1015
+ `resolves in no registry`.
1016
+ A receipt's `url` has to be the provider's receipt URL for that id. Else the refusal
1017
+ reads `<url> is not the <provider> receipt URL for that id (<expected>)`. A
1018
+ refused receipt resolves nothing.
1019
+ - It refuses a formal row that no receipt resolves: `resolves in no registry`. A
1020
+ formal row with an empty `id` gets the same refusal. A row with
1021
+ `unindexed_reason` takes the step `unindexed-source` instead.
1022
+ - A row that one provider alone resolves, with an agreeing header, takes the step
1023
+ `one-provider` (`hooks/tezgah_research_capture.py::citation_verdict`). An
1024
+ alphaXiv or `orx paper` record counts as `arxiv`.
1025
+ - An INDEX `title`, `year` or `first_author` that agrees with no resolved
1026
+ receipt takes `header-mismatch`. Titles agree at a word overlap of 0.5 or more
1027
+ (`hooks/tezgah_research_capture.py::title_agrees`). Years agree within one, for
1028
+ a preprint against its venue year.
1029
+ - `check --online` fetches up to ten receipts recorded from a 200 again from the
1030
+ provider's receipt URL. It never compares a row of another status
1031
+ (`hooks/tezgah_research_capture.py::_check_receipts`). A changed id, title, author or year prints
1032
+ `online <slug>: <id> <provider> <field> drifted`, for instance
1033
+ `online <slug>: <id> <provider> id drifted`, and takes `online-drift`.
1034
+
1035
+ **`tezgah-research fetch <slug> <note> [--file <path> --ack "<the user's words>" | --orx]`**
1036
+ stores the passages of a source around every quote the line makes of it. The URL
1037
+ always comes from a receipt. The first step that yields text decides the capture
1038
+ (`hooks/tezgah_research_capture.py::cmd_fetch`):
1039
+
1040
+ | Step | Source | Access |
1041
+ |---|---|---|
1042
+ | 1 | `--file <path>` (needs `--ack "<the user's words>"`, else exit 2), or `--orx` | `user`, or `full` |
1043
+ | 2 | an arXiv id: `https://arxiv.org/html/<id>` answering 200 | `full` |
1044
+ | 3 | a DOI: the OpenAlex receipt's `open_access.oa_url` answering 200 with no PDF body and holding a work's body (below) | `full` |
1045
+ | 4 | `orx paper --full <id>`, when orx is installed and prints text | `full`; `abstract` when the text is short and holds none of the line's quotes |
1046
+ | 5 | the abstract of a resolved receipt | `abstract` |
1047
+ | 6 | nothing yielded text: the record names the reason, exit 0 | `none` |
1048
+
1049
+ An `oa_url` page holds a work's body when its text has `BODY_SENTENCES` (100)
1050
+ distinct sentences of `BODY_WORDS` (10) or more words
1051
+ (`hooks/tezgah_research_capture.py::body_sentences`). A repository landing page
1052
+ holds the metadata and the abstract, and falls short. When step 4 yields no text
1053
+ either, `fetch` keeps that page as access `abstract`, with the `oa_url` as its
1054
+ url. Its reason reads `the open-access page holds <n> distinct sentences of 10+
1055
+ words, under the 100 of a work's body: a landing page`. A quote that page lacks
1056
+ costs the step `abstract-only`, never a refusal.
1057
+
1058
+ Step 4 takes the same body test. Text under 100 such sentences that holds one of
1059
+ the line's quotes still backs it, so it stays `full`. Text that holds none is
1060
+ `abstract` - orx's metadata and abstract for a paper it cannot read whole - and
1061
+ its reason reads `orx held <n> distinct sentences of 10+ words, under the 100 of
1062
+ a work's body, and none of the line's <n> quotes: metadata and abstract, not full
1063
+ text`. A quote the stub lacks costs `abstract-only`, never a refusal.
1064
+
1065
+ The quotes come from three places. One is a citing claim's `quote` field. Another
1066
+ is each double-quoted span of three or more words in its `statement`. The last is
1067
+ each `> "..."` blockquote of the note. A quote splits on `...`, `…` and `[...]`.
1068
+ Each fragment of three or more words has to appear in order. `fetch` keeps the
1069
+ whole extracted text in `literature/.sources/<sha256>.txt`, and its record names
1070
+ it as `text_file` with `text_sha256`. `check` looks for each quote in that text,
1071
+ in the stored passages and in the abstracts of the receipts for the note's id
1072
+ (`hooks/tezgah_research_capture.py::_found`). Normalisation drops citation
1073
+ markers, also one split by tags or spaces such as `[ 12 ]`. A hyphen between two
1074
+ letters reads as a space. Inner quotation marks are optional: curly or straight,
1075
+ single or double, in the quote and in the text. Where an extraction dropped a
1076
+ space (`human-inthe-loop` for `human-in-the-loop`), a quote still matches with its
1077
+ spaces optional, its letters in order (`hooks/tezgah_research_capture.py::_locate`). A TeX command beside rendered
1078
+ math (`∼ \sim`) drops, `∼` reads as `~`, and a space beside a math symbol drops
1079
+ (`hooks/tezgah_research_capture.py::normalise`). `check`
1080
+ refuses a record whose text file is gone with `has no capture`, and one whose
1081
+ text file hashes otherwise with `hash mismatch`
1082
+ (`hooks/tezgah_research_capture.py::_source_text`). The record lands in
1083
+ `literature/.sources/<sha256>.json` with the 300 characters either side of each
1084
+ match, and `literature/.sources/SOURCES.jsonl` gets its row. A SOURCES row sets
1085
+ access only through its own `literature/.sources/*.json` record for that note,
1086
+ never through its own `access` field
1087
+ (`hooks/tezgah_research_capture.py::_source_records`). A claim's proof may end a
1088
+ note path with `.`, `,`, `;`, `:` or `)`, and the note still counts as cited
1089
+ (`hooks/tezgah_research_capture.py::cited_tokens`). The note's latest record
1090
+ decides what `check` does
1091
+ (`hooks/tezgah_research_capture.py::_check_sources`):
1092
+
1093
+ - `full` or `user`: `check` looks for each quote of the note's own blockquotes in
1094
+ its capture. It looks for a claim's quote in the captures of every note the
1095
+ claim cites. It refuses that quote only when every cited note holds full text
1096
+ and none of them holds the quote. A cited note without full text already
1097
+ narrows the claim by its step. The refusal names the notes it searched:
1098
+ `claim <id>: "<quote>": quote not in the captured source text (searched literature/<a>, literature/<b>; ...)`
1099
+ (`hooks/tezgah_research_capture.py::_quote_missing`). The message names the two
1100
+ exits. Rephrase a non-quote without quotation marks, or `fetch --file` the
1101
+ version quoted. `check` skips the quotes of a claim that another row
1102
+ supersedes (`hooks/tezgah_research.py::_superseded`).
1103
+ - `abstract`: claims citing the note take `abstract-only`.
1104
+ - `none`, or no capture: they take `source-not-captured`, a ceiling.
1105
+ - A concluded line with formal rows owes the share of its sources without full
1106
+ text in its report. The share counts a source with no capture, an `abstract`
1107
+ capture or a `none` capture alike. Any of `closed-access: <k> of <n>`,
1108
+ `not full text: <k> of <n>` or `abstract-only: <k> of <n>` states it. A missing
1109
+ share warns `report states no closed-access share: <k> of <n> sources have no full text`
1110
+ and names the three forms (`hooks/tezgah_research_capture.py::_check_sources`).
1111
+ The line also owes `user-supplied: <k> of <n> sources` when a latest record is `user`.
1112
+ Both rules are soft.
1113
+
1114
+ **`tezgah-research search <slug> --tag primary|snowball|counter|known [--item "<scope.in item>"] -- <connector> <args...>`**
1115
+ stores a connector's raw output in `searches/raw/<sha256>.raw` and one row of
1116
+ `searches/SEARCHES.jsonl`. Its `hits` and `ids` come from the raw bytes
1117
+ (`hooks/tezgah_research_capture.py::cmd_search`). The allowlist is the four
1118
+ registries, PubMed, Scopus, ACM DL, `orx discover` and `orx paper`. Any other
1119
+ connector exits 1 with `connector not on the allowlist`. PubMed is E-utilities
1120
+ `esearch` and yields `pubmed:<pmid>` ids. Scopus is the Elsevier search API. It
1121
+ needs an API key in `TEZGAH_SCOPUS_KEY`, and without it `search` exits 2 naming the
1122
+ variable. Its entries yield their DOIs. `dl.acm.org` answers a browser check with
1123
+ 403, so ACM DL reads through Crossref's ACM member (320) and yields its DOIs. `--tag counter` without an `--item` equal to a
1124
+ `scope.in` entry exits 2. A search that does not answer 200 exits 1 and writes
1125
+ nothing. An answer that does not parse as that connector's response exits 1 with
1126
+ `does not parse as a <connector> response; nothing was written`. An answer
1127
+ byte-identical to an earlier search's capture writes no row, and `search` says so
1128
+ and exits 0. The session screens by hand, one row per decision in
1129
+ `searches/screening.jsonl`: `{"search", "id", "decision": "kept"|"dropped", "reason", "screener"}`.
1130
+ `check` refuses a SEARCHES or SOURCES row with no `file`:
1131
+ `<SEARCHES|SOURCES> row <n> names no file, so it has no capture`
1132
+ (`hooks/tezgah_research_capture.py::_check_ledger_files`). It also refuses a
1133
+ SEARCHES row whose file lies outside `searches/raw/`, or whose capture another
1134
+ row already names. Both messages end `so it has no capture`
1135
+ (`hooks/tezgah_research_capture.py::_check_searches`). `check` refuses a capture
1136
+ that does not parse under its row's connector with `not derived from its capture:
1137
+ <file> does not parse as a <connector> response`
1138
+ (`hooks/tezgah_research_capture.py::schema_ok`). It refuses a row whose `hits` or
1139
+ `ids` a re-parse contradicts the same way. Only a row that passes these counts toward a
1140
+ connector, a counter search or saturation. A screening row for an id that no
1141
+ captured search returned takes the step `screened-outside-search`.
1142
+
1143
+ On a search line, claims that cite literature take these steps
1144
+ (`hooks/tezgah_research_capture.py::_check_searches`). `one-connector` means fewer
1145
+ than two connectors. `no-counter-search` means a `scope.in` item with no `counter`
1146
+ search. `known-item-missed` means a `state.known_items` id that no capture holds.
1147
+ The other two are `no-stopping-rule` and `stopping-not-met`. `state.stopping` names the stopping
1148
+ rule. It has to enter the history before the first search row, or the line takes
1149
+ `no-stopping-rule`:
1150
+
1151
+ - `{"rule": "hypergeometric", "recall": t, "confidence": c}` runs buscarpy's
1152
+ recall test (Callaghan and Müller-Hansen, 2020) over the screening order
1153
+ (`hooks/tezgah_research_stats.py::hypergeometric_p`). It holds when p < 1 - c,
1154
+ and `check` prints `stopping <slug>: hypergeometric p=<p> met|not met`.
1155
+ - `{"rule": "saturation", "run": R}` holds when the last R search rows add no new
1156
+ record.
1157
+ - `{"rule": "pragmatic", "risk": "<text>"}` always holds and names the risk taken.
1158
+
1159
+ **`tezgah-research source <slug> <h> --run <id> [--instrument <name>] [--arm <a>] [--item <i>] [--value <field>=<number>]... [--ack "<the user's words>"]`**
1160
+ writes its results row itself (`hooks/tezgah_research.py::source_run`). On a
1161
+ rules-8 line it first asks git for a commit that holds the evaluation lock. It
1162
+ refuses before writing anything when it finds none:
1163
+ `the evaluation lock is not committed: no committed state.json holding the metric and the baseline precedes this capture`.
1164
+ The message names the way out, `tezgah-research commit <slug> "<message>"`. A
1165
+ line with no `evaluation` is exempt, as in `check`
1166
+ (`hooks/tezgah_research.py::_orders_lock`). An exploratory line's lock is its
1167
+ arena. `source` refuses there when no committed `state.json` holding the arena
1168
+ precedes the capture: `the arena is not committed`. On a rules-8 line it also
1169
+ refuses before writing when the experiment's `protocol.md` is not committed
1170
+ (`experiments/<h>/protocol.md is not committed`), or carries an invalid record
1171
+ (`experiments/<h>/protocol.md carries an invalid record`). It refuses a protocol
1172
+ whose `metric:` list holds no locked metric, by the rule `check` applies below:
1173
+ `experiments/<h>/protocol.md registers a metric other than the locked one`
1174
+ (`hooks/tezgah_research.py::metric_problem`). The capture commits its results at
1175
+ once, and the protocol cannot change after that. Each of these messages names
1176
+ `tezgah-research commit` as the way out and ends `nothing was written`.
1177
+
1178
+ `orx logs` may print a summary in place of the log: the path to the full log
1179
+ file and its size. `source` then reads that file and checks its size against the
1180
+ count orx printed (`hooks/tezgah_research.py::_full_log`). It stores the whole
1181
+ log, printed or read from that file. A log above 16 MiB meets
1182
+ `RUN_LOG_BOUND` and exits 1
1183
+ (`hooks/tezgah_research.py::RUN_LOG_BOUND`), unless `--ack "<the user's words>"`
1184
+ says to keep it. The log then lands whole and the row records the `ack`. Four
1185
+ messages refuse a log it cannot hold:
1186
+
1187
+ - `printed the log's path without its size`
1188
+ - `bytes, above the <bound>-byte bound a receipt is committed under`, which names
1189
+ `--ack`
1190
+ - `cannot read the log orx logs <run> names`
1191
+ - `the run is still writing it or it changed since`
1192
+
1193
+ `--ack` files a log above the bound and the row records the words. The row names
1194
+ `run`, the arm, the item and each value as a number.
1195
+ `--instrument <name>` writes `instrument`, `--arm` writes `arm` and `--item`
1196
+ writes `item`, each without the others. A row with `instrument` and `item` is one
1197
+ `gold` and `label` read. When the line names an orx project
1198
+ the row also holds the engine's `status`. `source` matches `--value` against the
1199
+ whole log, by one number reader (`hooks/tezgah_research_capture.py::log_numbers`). It
1200
+ reads thousands separators, so `12,345` is 12345, and exponents such as
1201
+ `1.2e-3`, which `--value k=1.2e-3` also accepts. It reads a number with a unit
1202
+ glued on as that number: `22.3ms`, `1.2s`, `512MB`, `3.2x` and `45%`
1203
+ (`hooks/tezgah_research_capture.py::LOG_NUMBER`). A number glued to letters in
1204
+ front, such as `r1` or `h2`, stays no number. A value matches a logged number
1205
+ by numeric equality, so `1.5` matches `1.50`. A value with no equal number in the
1206
+ stored log exits 1 with
1207
+ `value not in the run log (orx logs <run> holds no number equal to <v>)`. A
1208
+ reserved key (`source`, `log`, `run`, `instrument`, `arm`, `item`, `scope`,
1209
+ `fixture`, `status`, `command`, `ack`) as `--value` exits 2. A second filing of one run
1210
+ writes `raw/<run>.<n>.log` and a second row. A refile is a correction. The latest
1211
+ row filed for the same `run`, arm, item and instrument stands for it
1212
+ (`hooks/tezgah_research.py::_live`). So a run filed once per arm or item keeps
1213
+ every row, and every count and statistic counts each such row once. A row with
1214
+ no `run` counts on its own.
1215
+ `check --orx` reads `orx runs` for the census. It takes a JSON answer, or the
1216
+ table orx 0.2.20 prints instead, which is all it has (no `--json`). The table's
1217
+ `ID` and `STATUS` columns are the run and its status
1218
+ (`hooks/tezgah_research_capture.py::_runs_table`). An answer that is neither warns
1219
+ `printed neither JSON nor a run table`. It warns `orx run <id> has no results
1220
+ row` for an engine run that no row names. A row with status `aborted` or `failed` stays a row and counts in no
1221
+ group.
1222
+
1223
+ **Write once.** The capture files live under `literature/.receipts/`,
1224
+ `literature/.sources/`, `searches/raw/`, `experiments/*/raw/` and
1225
+ `instruments/gold/`. A command whose target exists with other bytes exits 1 with
1226
+ `capture exists` (`hooks/tezgah_research_capture.py::write_captures`). The
1227
+ ledgers only grow. `check` refuses what changed anyway
1228
+ (`hooks/tezgah_research_capture.py::_check_write_once`,
1229
+ `hooks/tezgah_research_capture.py::_check_ledger_files`):
1230
+
1231
+ - a capture file that differs from the blob its first commit added
1232
+ (`changed after its first commit`)
1233
+ - a ledger row that a later version dropped, changed or moved:
1234
+ `a row changed, moved or went missing after its first commit; a ledger is append-only`.
1235
+ The rows of each earlier version have to stay in the latest one in their order.
1236
+ Two branches that appended and merged pass. `check` refuses a reordered ledger,
1237
+ because its readers take the latest SOURCES record, the first label and the
1238
+ first gold draw.
1239
+ - a ledger row whose file does not hash to its `sha256`: `hash mismatch`.
1240
+
1241
+ Each RECEIPTS and SEARCHES row records `parser`, the version of the parser that
1242
+ derived it (`hooks/tezgah_research_capture.py::PARSER`). A row without the field
1243
+ reads as version 0. `check` re-derives every row under the current parser, so no
1244
+ row is held to its hash on its own say-so. A later tezgah wrote any row that names
1245
+ a newer version than the tool's, and `check` refuses it
1246
+ (`hooks/tezgah_research_capture.py::_newer`):
1247
+ `names parser version <v>, newer than this check's 1`.
1248
+
1249
+ The append-only ledgers are read across every ref, as the results file is. The
1250
+ stopping-rule order and the capture files read the current branch's lineage only
1251
+ (`hooks/tezgah_research.py::file_versions`). A backdated side branch therefore
1252
+ cannot satisfy the stopping-rule order. These
1253
+ rules cannot see a capture that was false at its first write. `check --online` is
1254
+ the check for that case.
1255
+
1256
+ ### How a claim's certainty is computed
1257
+
1258
+ The levels, low to high, are `very-low`, `low`, `moderate` and `high`. A claim
1259
+ below `moderate` is exploratory. Its start level is the highest over the parts
1260
+ its `proof` cites (`hooks/tezgah_research_evidence.py::start_level`):
1261
+
1262
+ | Part the proof cites | Start |
1263
+ |---|---|
1264
+ | results of an experiment whose protocol says `design: experiment` (the default with a `change:` line) | `high` |
1265
+ | results of an experiment with `design: observational` (the default without `change:`) | `low` |
1266
+ | a literature note whose INDEX `class` is `formal` | `moderate` |
1267
+ | a `grey` note | `low` |
1268
+ | an `agent-report` note | `very-low` |
1269
+ | a claim of `kind: code` | `high` |
1270
+ | a claim of `kind: derivation` | `moderate` |
1271
+
1272
+ Each step `check` finds for a claim either lowers the level by one or caps it at
1273
+ `low` (`hooks/tezgah_research_evidence.py::STEPS`). The decrements apply first,
1274
+ then the ceilings, and the floor is `very-low`. A step counts once per claim even
1275
+ when two parts trigger it (`hooks/tezgah_research_evidence.py::compute`). `check`
1276
+ prints one line per claim, in `claims.jsonl` order:
1277
+
1278
+ certainty <slug>: <id> <level> start=<level> steps=<step>,<step>|none
1279
+
1280
+ A claim may declare `"certainty": "<level>"`. `check` refuses a declared level
1281
+ above the computed one: `claim <id> declares certainty <declared> above the computed
1282
+ <level> (<steps>)`. On a concluded line, `to_human/report.md` owes one line per
1283
+ claim that names its id and its computed level word. A claim below `moderate`
1284
+ also owes `exploratory` on that line. A missing line warns
1285
+ `report states no certainty for claim <id>`, and `--strict` refuses it.
1286
+
1287
+ A narrowed claim, an `inconclusive` hypothesis and `close --limit` are normal
1288
+ outcomes of a rules-8 line. Lowering what a claim says is how a line meets a
1289
+ low level, not pushing harder for a bigger one.
1290
+
1291
+ The steps, by name as `check` prints them:
1292
+
1293
+ | Step | Effect | Trigger |
1294
+ |---|---|---|
1295
+ | `header-mismatch` | -1 | the INDEX header agrees with no resolved receipt |
1296
+ | `unindexed-source` | -1 | no receipt resolves the row, and it carries `unindexed_reason` |
1297
+ | `online-drift` | -1 | `check --online` saw a stable field change |
1298
+ | `abstract-only` | -1 | the note's latest capture has access `abstract` |
1299
+ | `source-not-captured` | ceiling | the note has no capture, or its latest has access `none` |
1300
+ | `one-connector` | -1 | search line: fewer than two connectors |
1301
+ | `no-counter-search` | -1 | search line: a `scope.in` item with no `counter` search |
1302
+ | `no-stopping-rule` | -1 | search line: `state.stopping` missing, invalid or committed after the first search |
1303
+ | `stopping-not-met` | -1 | the recomputed stopping rule does not hold |
1304
+ | `known-item-missed` | -1 | a `state.known_items` id is in no captured search |
1305
+ | `screened-outside-search` | -1 | a screening row names an id that no captured search returned |
1306
+ | `one-provider` | -1 | one provider alone resolves the formal id, and its header agrees |
1307
+ | `falsifier-not-evaluable` | -1 | a measured protocol's falsifier has neither a comparator with a number nor a named test with its alpha |
1308
+ | `fewer-than-two-rivals` | -1 | R5 or R6: fewer than two `rival:` lines |
1309
+ | `no-replication` | -1 | a group of a cited experiment holds fewer than two rows |
1310
+ | `no-power-plan` | -1 | a measured protocol lacks one of `alpha:`, `power:`, `mde:`, `n:` |
1311
+ | `below-planned-n` | -1 | a `compare:` group holds fewer rows than `n:` |
1312
+ | `no-interval` | ceiling | a `compare:` group has fewer than two rows |
1313
+ | `interval-includes-zero` | ceiling | improvement claim: the interval's lower bound is 0 or less |
1314
+ | `below-achieved-mde` | ceiling | improvement claim: the effect is below the achieved MDE |
1315
+ | `no-multiplicity-correction` | -1 | more than two groups and no `correction:` |
1316
+ | `fails-multiplicity` | ceiling | the declared correction does not reject the experiment |
1317
+ | `no-sesoi` | ceiling | a no-difference claim whose protocol has no `sesoi:` |
1318
+ | `tost-not-passed` | ceiling | a no-difference claim whose TOST fails |
1319
+ | `untraced-number` | -1 | a number of an evidence claim that no cited row and log, and no `derived_from`, holds |
1320
+ | `instrument-unvalidated` | ceiling | a cited row names an `unvalidated` instrument |
1321
+ | `instrument-rejected` | ceiling | a cited row names a `rejected` instrument |
1322
+ | `judged-row-incomplete` | -1 | a cited row with `judge` lacks `generator` or `order` |
1323
+ | `uncalibrated-verifier` | ceiling | `verified_by` names an instrument that is not a validated verdict instrument |
1324
+ | `no-question-class` and the class steps | -1 | see "The question class" above |
1325
+
1326
+ ### Statistics on results rows
1327
+
1328
+ A measured protocol plans its test with `alpha:`, `power:`, `mde:` and `n:`. It may
1329
+ add `compare: <T> vs <C> on <field>, lower|higher is better`, `sesoi:` and
1330
+ `correction: bh|holm|bonferroni|e-bh`. Rows group by `arm`, else by `phase`, else
1331
+ into one group `all` (`hooks/tezgah_research.py::experiment_record`).
1332
+
1333
+ One reader takes every protocol number (`hooks/tezgah_research.py::protocol_number`).
1334
+ It reads `0.05`, `.05`, `5%` (as 0.05) and `1e-1`. `alpha:` and `power:` have to
1335
+ fall in (0, 1), and `sesoi:` and `mde:` have to be above 0. `check` refuses any
1336
+ other value, including one with no number:
1337
+
1338
+ - `experiment <h>: protocol.md <alpha|power>: <value> is not a number in (0, 1)`
1339
+ - `experiment <h>: protocol.md <sesoi|mde>: <value> is not a number above 0`
1340
+ - `protocol.md alpha: <value> leaves a quantile at 0 or 1`
1341
+
1342
+ A statistic that still fails to compute gives one refusal per experiment, never a
1343
+ traceback: `experiment <h>: statistics could not be computed: <error>`
1344
+ (`hooks/tezgah_research.py::_check_rules8`).
1345
+
1346
+ - A group whose rows all carry an `outcome` of 0 or 1 prints
1347
+ `stats <slug>: <h> <group> n=<n> k=<k> wilson=[<lo>, <hi>] cp=[<lo>, <hi>]`, the
1348
+ Wilson and Clopper-Pearson intervals at 1 - alpha. A JSON `true` or `false`
1349
+ outcome counts as 1 or 0.
1350
+ - `compare:` gives the mean difference in the better direction. The two groups
1351
+ pair by `item` when they hold the same item set, else the test is Welch's
1352
+ (`hooks/tezgah_research_stats.py::mean_diff`). The achieved MDE is
1353
+ (z(1 - alpha/2) + z(power)) times the standard error
1354
+ (`hooks/tezgah_research_stats.py::achieved_mde`). `check` prints
1355
+ `effect <slug>: <h> <T> vs <C> on <field> effect=<e> ci=[<lo>, <hi>] mde=<m>`,
1356
+ or `ci=none mde=none` when a group has fewer than two rows.
1357
+ - `check` corrects every experiment that declares a `correction:` together with
1358
+ the others of the same method (`hooks/tezgah_research.py::_multiplicity`). `e-bh`
1359
+ reads `e-value: <x>` from each `analysis.md`.
1360
+ - A claim citing the experiment is an improvement claim, unless it carries
1361
+ `"effect": "no-difference"`. Then TOST has to place the 1 - 2 alpha interval
1362
+ inside (-sesoi, +sesoi) (`hooks/tezgah_research_stats.py::tost`).
1363
+
1364
+ ### Hypotheses and falsifiers
1365
+
1366
+ On a measured line, a falsifier needs a comparator and a number, or a named test
1367
+ with its alpha (`hooks/tezgah_research.py::falsifier_testable`). Claims citing an
1368
+ experiment whose falsifier has neither take the step `falsifier-not-evaluable`.
1369
+ The structured form
1370
+ `falsifier: <field> <op> <number> [on <group>]` is the one `check` evaluates. Its
1371
+ `<op>` is `<`, `<=`, `>`, `>=`, `=`, `≤`, `≥`, `at most`, `at least`, `above`,
1372
+ `below`, `less than`, `more than`, `fewer than`, `greater than`, `exceed`,
1373
+ `exceeds`, `under` or `over` (`hooks/tezgah_research.py::FALSIFIER_OPS`). It
1374
+ fires when the mean of the field over the group's rows meets the comparison. A
1375
+ falsifier with no `on <group>` over an experiment of several groups is not
1376
+ evaluated, and its claims take `falsifier-not-evaluable`
1377
+ (`hooks/tezgah_research.py::falsifier_unscoped`). A
1378
+ `supported` claim citing an experiment whose falsifier fired fails with
1379
+ `while its falsifier fired` (`hooks/tezgah_research.py::fired_problems`). A
1380
+ prediction equal to its falsifier still fails with `say the same thing`.
1381
+
1382
+ Neither this refusal nor `does not recompute` (below) reaches a claim that another
1383
+ row supersedes. The record is append-only, so that row is the correction, and
1384
+ `claim` and `check` skip the superseded claim alike
1385
+ (`hooks/tezgah_research.py::_superseded`).
1386
+
1387
+ `state.hypotheses[]` holds `{"id", "text", "status", "probability"}` entries. A
1388
+ concluded line ends each one as `supported`, `refuted`, `weakened`, `revised`,
1389
+ `untested` or `inconclusive`. `check` refuses an entry left open with
1390
+ `has no terminal status`, and `conclude` refuses it first
1391
+ (`hooks/tezgah_research.py::hypothesis_problems`).
1392
+
1393
+ ### The execution trail
1394
+
1395
+ A number in an evidence claim's statement counts as traced when a cited row holds
1396
+ that value and the row's `log` file contains the token. The claim's `derived_from`
1397
+ can also name it (`hooks/tezgah_research.py::_untraced`). An untraced number costs
1398
+ the step `untraced-number`, and `check` never refuses it.
1399
+
1400
+ `derived_from` maps each derived number, as written, to how it came about:
1401
+ `{"<number>": {"op": "mean|sum|min|max|diff|ratio|count", "of": ["<h>/<run>:<field>", "<h>/#<row>:<field>"]}}`.
1402
+ `diff` is the first minus the second, and `ratio` the first over the second.
1403
+ `check` recomputes the value in decimal arithmetic and rounds it at the written
1404
+ precision. Either half-up or half-even rounding may match, so mean(2, 3) accepts
1405
+ both `2` and `3` (`hooks/tezgah_research.py::_rounds_to`). It refuses a mismatch:
1406
+ `does not recompute` (`hooks/tezgah_research.py::derived_problems`).
1407
+
1408
+ The protocol's other lines bind the analysis
1409
+ (`hooks/tezgah_research.py::_check_experiment8`):
1410
+
1411
+ - Each metric of the `metric:` list appears in `report.md`, or in a
1412
+ `not_reported: <metric>: <reason>` line. The list splits at the commas between
1413
+ names, never inside parentheses or between digit groups. So `10,000-piece` and
1414
+ `(median of 5 runs)` stay whole (`hooks/tezgah_research.py::METRIC_COMMA`). The
1415
+ locked metric is one name, and a comma in it never splits it
1416
+ (`hooks/tezgah_research.py::_registered`). A metric neither reported nor excused
1417
+ fails with `registered metric <m> is neither reported nor marked not_reported - <exit>`.
1418
+ Before the run the exit reads
1419
+ ``name it in to_human/report.md, or before the run mark it `not_reported: <metric>: <reason>` in protocol.md``.
1420
+ A filed run freezes `protocol.md`, so after it the exit reads
1421
+ `the run is filed, so protocol.md is frozen: name it in to_human/report.md`.
1422
+ A registered metric that matches the locked one counts as reported when the
1423
+ report names the locked metric. The match collapses whitespace in the report, so
1424
+ a name wrapped across lines still counts.
1425
+ - A `metric:` list must hold the locked metric. Else:
1426
+ `metric other than the locked one`. A protocol metric matches the lock when
1427
+ either is the other, a word-boundary prefix of it either way, or a rewording.
1428
+ A rewording holds every word of the lock in the registered name, in any order,
1429
+ with the joining words (`of`, `the`, `per`, ...) ignored
1430
+ (`hooks/tezgah_research.py::_same_metric`). So `p95 latency`, `p95 latency of
1431
+ the read path` and `read-path p95 latency` all match one another.
1432
+ - `evaluator: <path> [sha256:<hex>]` pins the scoring file to its bytes at the
1433
+ protocol's first commit. `check` looks the path up in the line, the repository
1434
+ and the checkout it runs in, in that order
1435
+ (`hooks/tezgah_research.py::evaluator_file`). A path none of them holds fails
1436
+ with `evaluator <path> is not a file in the line, the repository or the checkout`.
1437
+ `check` compares the evaluator with its last version before that commit
1438
+ (`hooks/tezgah_research.py::_check_evaluator`). Else: `evaluator file changed after lock`.
1439
+ A concluded line compares the evaluator as it stood at the conclusion. The
1440
+ order seal `conclude` writes holds the evaluator's sha256 per experiment
1441
+ (`hooks/tezgah_research.py::_seal_rows`). A seal older than that field reads
1442
+ the evaluator at the first committed `state.json` holding the seal
1443
+ (`hooks/tezgah_research.py::_sealed_evaluator`). A later project edit therefore
1444
+ does not refuse a concluded line under `--all-lines`.
1445
+ - `select: min|max <field>` picks the group with the lowest or highest mean, and
1446
+ `analysis.md` names it as `selected: <group>`. `check` refuses a different pick
1447
+ with `select rule picks`. A missing `selected:` line warns
1448
+ `analysis states no selected group`.
1449
+
1450
+ ### The instrument ledger
1451
+
1452
+ An instrument is whatever turns an item into a number: a measure or an LLM
1453
+ judge. A results row names it in `instrument` (or `judge`). An instrument that
1454
+ `instruments/INSTRUMENTS.jsonl` does not hold counts as `unvalidated`. The
1455
+ commands (`hooks/tezgah_research_evidence.py::COMMANDS`):
1456
+
1457
+ - `tezgah-research instrument add <slug> <name> --kind measure|verdict --rung R1|R2|R3|R4 --construct "<text>"`
1458
+ declares it.
1459
+ - `tezgah-research gold <slug> <instrument> --arm <a> --n N --seed S` draws the
1460
+ gold sample. It sorts the arm's items by `sha256("<S>:<a>:<item>")` and keeps
1461
+ the first N (`hooks/tezgah_research_evidence.py::seeded_draw`). The first draw
1462
+ per instrument and arm is the one every rule reads. A draw once the arm has
1463
+ labels exits 1 with `gold draw after labels` unless the owner records a
1464
+ redraw: `gold ... --redraw --ack "<the user's words>"`, which the refusal
1465
+ names. The latest redraw is the draw every rule reads. The labels of items the
1466
+ new draw drops read stale. A draw over results or verdict
1467
+ rows that are not committed exits 1 with
1468
+ `has results or verdict rows that are not committed`, names
1469
+ `tezgah-research commit` and writes nothing
1470
+ (`hooks/tezgah_research_evidence.py::cmd_gold`). `check` refuses a gold file that
1471
+ is not its seed's draw: `differs from the seeded draw`. It also refuses a GOLD
1472
+ row that disagrees with its file on instrument, arm, seed or n:
1473
+ `<file> differs from the seeded draw: its GOLD row names <i> arm <a> seed <s> n <n>, the file <i> arm <a> seed <s> n <n>`
1474
+ (`hooks/tezgah_research_evidence.py::gold_record`).
1475
+ - `tezgah-research label <slug> <instrument> --arm <a> --human "<name>" --ack "<the user's words>"`
1476
+ reads `{"item", "truth"}` rows on stdin. An item outside the gold sample exits 1
1477
+ with `not in the gold sample`.
1478
+ - `tezgah-research label <slug> <instrument> --arm <a> --provider openrouter --model <m>`
1479
+ asks the model once per gold item, at temperature 0. It needs
1480
+ `OPENROUTER_API_KEY`, else it exits 2.
1481
+ - `tezgah-research switch <slug> <instrument> --to R1|R2|R3|R4|<method> --reason "<why>"`
1482
+ records a move to another rung or method.
1483
+ `switch <slug> <instrument> --narrow "<what the claims now say>" --reason "<why>"`
1484
+ records a narrowing of the claims instead.
1485
+
1486
+ A label's `output` is the results row's `outcome`, and an error is a truth that
1487
+ differs from it. A row without both `truth` and `output` labels nothing
1488
+ (`hooks/tezgah_research_evidence.py::_is_label`). `check` refuses a label whose
1489
+ output is not the results row's outcome:
1490
+ `label output differs from its results row: <i> arm <a> item <x> output <o>, results row <r|none>`
1491
+ (`hooks/tezgah_research_evidence.py::label_problems`). A label that holds the
1492
+ outcome of a row a later refile replaced is stale
1493
+ (`hooks/tezgah_research_evidence.py::_stale`). `check` neither counts nor refuses
1494
+ it, and its item reads unlabelled until a new label arrives. The first label per
1495
+ item counts, and a later one warns. An arm
1496
+ counts as labelled when every item of its first draw has a label. Its error bound is the
1497
+ two-sided 95% Clopper-Pearson upper bound of errors over n
1498
+ (`hooks/tezgah_research_evidence.py::instrument_report`). The status follows
1499
+ (`hooks/tezgah_research_evidence.py::judge_status`):
1500
+
1501
+ | Kind | Rejected when | Validated when |
1502
+ |---|---|---|
1503
+ | `measure` | the labelled arms' bounds sum to the smallest `mde:` of the experiments using it, or more | the sum stays below it and every arm with rows is labelled |
1504
+ | `verdict` | an arm's bound is above 0.10 | every arm's bound is 0.10 or less and every arm with rows is labelled |
1505
+
1506
+ Anything else is `unvalidated`, and so is a measure with no `mde:` to compare
1507
+ against. A measure whose `mde:` is above 1 stays `unvalidated` too, because its
1508
+ threshold reads a difference of proportions
1509
+ (`hooks/tezgah_research_evidence.py::proportion_threshold`). So does a measure
1510
+ whose labelled sample is too small to decide. Say its zero-error bounds already
1511
+ sum to the `mde:` or more while its own lower bounds stay below it. Then `check`
1512
+ reports `unvalidated`, not `rejected` (`judge_status`'s `floor`). An `mde:` above 1 ends the status line
1513
+ `(mde above 1: the threshold reads a difference of proportions)`. With an MDE of
1514
+ 0.10 and two arms, 72 items per arm with no error
1515
+ validate (bound 0.0499). 71 do not. At 20 items and no error the bound is 0.1684.
1516
+ `check` prints `instrument <slug>: <name> arm <a> n=<n> errors=<k> upper=<u>` per
1517
+ labelled arm and `instrument <slug>: <name> <status> sum=|max=<x> threshold=<t>`.
1518
+ An R3 instrument also prints a PPI++ mean per labelled arm:
1519
+ `ppi <slug>: <name> arm <a> lambda=<l> estimate=<e> ci=[<lo>, <hi>]`
1520
+ (`hooks/tezgah_research_stats.py::ppi_mean`). It combines the gold truths with the
1521
+ arm's unlabelled outputs. The line prints `ci=none` when fewer than two gold items
1522
+ or fewer than two other items exist.
1523
+
1524
+ `conclude` refuses a line with a `rejected` instrument and no `switch` row for it:
1525
+ `has no switch or narrowing row` (`hooks/tezgah_research_evidence.py::conclude_problems`).
1526
+ A concluded line with human labels owes `user-supplied: <k> of <n> labels` in its
1527
+ report.
1528
+
1529
+ **Verifiers.** A claim's `verified_by: <instrument>` has to name a `verdict`
1530
+ instrument whose status is `validated`. Else the claim takes
1531
+ `uncalibrated-verifier`, a ceiling.
1532
+
1533
+ ### `release-check` and `calibration`
1534
+
1535
+ `tezgah-research release-check [--fixtures <dir>]` measures whether the checks
1536
+ catch what they claim to catch. It needs no research line and runs from any
1537
+ directory (`hooks/tezgah_research_evidence.py::cmd_release_check`). Its default
1538
+ set, `tests/fixtures/rules8-known-truth/`, holds 38 defect and 18 sound cases of
1539
+ citations, quotes and instruments. The functions `check` uses score each case,
1540
+ with the set's `capture-map.json` as the capture map. It prints
1541
+ `misses: <k>/<n> upper=<u>` and `false alarms: <k>/<n> upper=<u>`. It exits 1 when
1542
+ the misses' Clopper-Pearson upper bound passes 0.10 or the false alarms' passes
1543
+ 0.20. The CI workflow runs it on every pull request and push to `main`, and
1544
+ each release reuses that green run. On that fixture set it printed
1545
+ `misses: 0/38 upper=0.0925` and `false alarms: 0/18 upper=0.1853`.
1546
+
1547
+ `tezgah-research calibration` scores every line's hypotheses that carry a
1548
+ `probability` and end `supported` or `refuted`. It prints
1549
+ `brier: <x> over <n> resolved hypotheses` and exits 0
1550
+ (`hooks/tezgah_research_evidence.py::cmd_calibration`).
1551
+
1552
+ ### Review, overlap and the smaller rules
1553
+
1554
+ - `to_human/review.json` adds `producer_family`, `reviewer_family` and
1555
+ `question_class`. One family on both sides warns `same-family review`. A
1556
+ reviewer equal to the producer, ignoring case and spaces, fails with
1557
+ `is the producer`. When the line holds an evidence claim, a finding has to
1558
+ target a file under `experiments/*/raw/` or a code file. Else it warns
1559
+ `review quotes no raw log or code` (`hooks/tezgah_research.py::_check_review8`).
1560
+ - `check` warns `overlaps refuted claim <line>/<claim>` for a refuted claim that
1561
+ `init` reported as an overlap. A row of `related.jsonl`,
1562
+ `{"line", "claim", "relation": "builds-on"|"dismissed", "reason"}`, answers it.
1563
+ - The overclaim lint warns in both modes: `claim <id> overclaims: "<word>"`. It
1564
+ fires on a universal word (every, all, always, never, any) over fixture
1565
+ evidence. It also fires on a causal word (cause, leads to, due to, because of)
1566
+ over an observational or single-group experiment
1567
+ (`hooks/tezgah_research.py::_overclaim`).
1568
+ - A variant whose `variants.jsonl` row entered the history after the first
1569
+ `comparison.jsonl` cell is post-hoc. A `decision.md` that chooses it and never
1570
+ says `post-hoc` or `post_hoc` fails with `without saying post-hoc`
1571
+ (`hooks/tezgah_research.py::_post_hoc`).
1572
+ - The supersedes warning drops when a `report.md` line names both claim ids
1573
+ (`hooks/tezgah_research.py::_check_supersedes`). Otherwise it stays soft, so
1574
+ `--strict` refuses it.
1575
+ - A `Patterns` bullet in `findings.md` on a rules-8 line runs over its indented
1576
+ continuation lines, so a source on a wrapped line counts
1577
+ (`hooks/tezgah_research.py::_check_patterns`). An older line reads each
1578
+ bullet's first line only, as before.
1579
+
1580
+ ### What rules 8 cannot see
1581
+
1582
+ - A gold seed chosen offline after the session saw the outputs goes undetected.
1583
+ The first-draw rule only stops a redraw once a draw exists.
1584
+ - `check` reads a number that the session printed into a captured run log as
1585
+ measured. The log's bytes are real to every rule.
1586
+
780
1587
  ## What `check` refuses, and what it only warns about
781
1588
 
782
1589
  A **refusal** (exit 1) is a guarantee the checker can decide. A **warning** is a