@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/bin/tezgah-skill CHANGED
@@ -25,7 +25,7 @@ import json
25
25
  import os
26
26
  import sys
27
27
 
28
- HERE = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
28
+ HERE = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
29
29
  sys.path.insert(0, os.path.join(HERE, "hooks"))
30
30
  import tezgah_skill_pick as sp # noqa: E402
31
31
 
package/bin/tezgah-status CHANGED
@@ -29,6 +29,22 @@ their status line; this CLI is how every host (and a human) gets it:
29
29
  The MCP half of a retirement decision is manual:
30
30
  `tezgah-setup --mcp-schemas` measures what a server
31
31
  costs, this counts what it fires.
32
+ tezgah-status --rates --since DATE --until DATE [--json]
33
+ every real ledger's rows in [since, until), folded per
34
+ window and per calendar day: turns, `claim` rows and
35
+ the Stop classes that blocked them, the shape flags
36
+ every judged reply carried, denies by rule, and the
37
+ rates (blocks per 100 turns, denies per 100 sessions,
38
+ the claim block and Stop shape shares, blocked claims
39
+ per 100 sessions by class). A repeated `--since`/
40
+ `--until` pair prints one block each and the pp delta
41
+ between adjacent windows - the unit plan 066's 056 row
42
+ states its bar in. A window that read more than one
43
+ row contract prints the split, and a delta across two
44
+ contracts says so (plan 135). `--json` prints
45
+ `{"windows": [...]}`.
46
+ `--until` is exclusive, so adjacent windows partition
47
+ their span.
32
48
  tezgah-status --skill-fitness
33
49
  per shipped skill, over the recorded sessions: how
34
50
  many opened it and which were never opened. A
@@ -78,6 +94,16 @@ their status line; this CLI is how every host (and a human) gets it:
78
94
  the set renders as dim "no state" instead of claiming
79
95
  "armed, not used yet". A host that cannot see a skill
80
96
  read (dsh) passes the tool-use four.
97
+ tezgah-status --manifest=FILE
98
+ read the repository extension from FILE instead of
99
+ the `.tezgah/extension.json` discovered from PATH (a
100
+ manifest outside the tree, e.g. an engagement's).
101
+ With `statusline.override: true` in the manifest the
102
+ project owns its line and points its own statusLine
103
+ here: the host's status-line payload on stdin (its
104
+ `cwd`/`workspace.current_dir` and `session_id`) is
105
+ read when no PATH is given, so this is the only line
106
+ and it keeps the built-in marks and the chips.
81
107
 
82
108
  The session id may be passed as the second argument or via TEZGAH_SESSION;
83
109
  without it the "used" marks cannot light up, so a host that knows the id should
@@ -97,6 +123,26 @@ from tezgah_context import ( # noqa: E402
97
123
  # the line and `--json` carries every row, so a reader can always see what was
98
124
  # cut.
99
125
  TOP = 15
126
+ # The host payload an override reads on stdin: a status-line host writes one
127
+ # small JSON object and closes the pipe, so the read is bounded in bytes and in
128
+ # how long an empty pipe is waited for - a caller that never writes costs this
129
+ # long, never a hang.
130
+ PAYLOAD_MAX = 65536
131
+ PAYLOAD_WAIT = 0.2
132
+
133
+
134
+ def host_payload():
135
+ """The status-line host's JSON payload on stdin, or {} - a terminal, an
136
+ empty or silent pipe, malformed JSON or no stdin at all."""
137
+ import select
138
+ try:
139
+ if sys.stdin.isatty() or not select.select([sys.stdin], [], [],
140
+ PAYLOAD_WAIT)[0]:
141
+ return {}
142
+ payload = json.loads(sys.stdin.read(PAYLOAD_MAX) or "{}")
143
+ except (OSError, ValueError, AttributeError):
144
+ return {}
145
+ return payload if isinstance(payload, dict) else {}
100
146
 
101
147
 
102
148
  def weeks_arg(args):
@@ -241,6 +287,115 @@ def print_orca(cwd, as_json):
241
287
  return 0
242
288
 
243
289
 
290
+ def window_pairs(args):
291
+ """`args` with the `--since`/`--until` pairs folded out, and the pairs in the
292
+ order written. Each `--until` closes the `--since` before it, and a flag
293
+ without its partner is ValueError: half a window is a question the reader
294
+ did not finish asking.
295
+
296
+ The spaced form is read here for the reason `--weeks`' is: the split in
297
+ `main` sends every non-`--` argument to `pos`, where a date would be read as
298
+ a session id."""
299
+ out, pairs, since, i = [], [], None, 0
300
+ while i < len(args):
301
+ a = args[i]
302
+ name = a.split("=", 1)[0]
303
+ if name not in ("--since", "--until"):
304
+ out.append(a)
305
+ i += 1
306
+ continue
307
+ if "=" in a:
308
+ value, i = a.split("=", 1)[1], i + 1
309
+ else:
310
+ value = args[i + 1] if i + 1 < len(args) else ""
311
+ i += 2 if i + 1 < len(args) else 1
312
+ if name == "--since":
313
+ if since is not None:
314
+ raise ValueError("--since %s has no --until" % since)
315
+ since = value
316
+ else:
317
+ if since is None:
318
+ raise ValueError("--until %s has no --since" % value)
319
+ pairs.append((since, value))
320
+ since = None
321
+ if since is not None:
322
+ raise ValueError("--since %s has no --until" % since)
323
+ return out, pairs
324
+
325
+
326
+ def share(value, numerator, denominator):
327
+ """A share in the unit 056's `+2 pp` bar reads, or `n/a` with no
328
+ denominator - a window that decided nothing has no rate."""
329
+ return ("n/a" if value is None
330
+ else "%.2f%% (%d/%d)" % (100 * value, numerator, denominator))
331
+
332
+
333
+ def dominant_contract(window):
334
+ """The row contract that wrote most of a window's rows, or `-` for a window
335
+ that read none. `claims` is one quantity under a contract and another across
336
+ a change to it (plan 135), so the delta line names both sides' contract."""
337
+ counts = window.get("row_versions") or {}
338
+ if not counts:
339
+ return "-"
340
+ return max(sorted(counts), key=lambda name: counts[name])
341
+
342
+
343
+ def print_rates(found):
344
+ """The windowed rates, for `--rates`: one block per window, then the pp delta
345
+ between each adjacent pair - the unit plan 066's rows state their bars in."""
346
+ for w in found:
347
+ rates = w["rates"]
348
+ print("window %s..%s: %d days, %d sessions, %d turns, %d claims, %d "
349
+ "replies" % (w["since"], w["until"], w["days"], w["sessions"],
350
+ w["turns"], w["claims"], w["replies"]))
351
+ for key, label in (("blocked_claims", "blocked_claims"),
352
+ ("shapes", "stop shapes"), ("denies", "denies")):
353
+ print(" %-15s %s" % (label, ", ".join(
354
+ "%s=%d" % kv for kv in sorted(w[key].items())) or "none"))
355
+ print(" %-15s %d" % ("shape_blocked", w["shape_blocked"]))
356
+ print(" %-15s blocks/100 turns %s, denies/100 sessions %s" % (
357
+ "rates", "n/a" if rates["blocks_per_100_turns"] is None
358
+ else "%.4f" % rates["blocks_per_100_turns"],
359
+ "n/a" if rates["denies_per_100_sessions"] is None
360
+ else "%.4f" % rates["denies_per_100_sessions"]))
361
+ print(" %-15s claim block %s, stop shape %s" % (
362
+ "shares", share(rates["claim_block_rate"],
363
+ sum(w["blocked_claims"].values()), w["claims"]),
364
+ share(rates["stop_shape_rate"], w["shape_flagged"], w["replies"])))
365
+ print(" %-15s %s" % ("blocked/100 sess", ", ".join(
366
+ "%s=%.4f" % kv for kv in
367
+ sorted(rates["blocked_claims_per_100_sessions"].items()))
368
+ or "none"))
369
+ # Which row contract wrote the rows, printed only when a window mixes
370
+ # two: `claims` means "every judged reply" before ROW_VERSION 3 and "a
371
+ # reply that claimed" after it, so a share read off a mixed or shifted
372
+ # window is not the same quantity as its neighbour's (plan 135).
373
+ if len(w["row_versions"]) > 1:
374
+ print(" %-15s %s" % ("contracts", ", ".join(
375
+ "%s=%d" % kv for kv in sorted(w["row_versions"].items()))))
376
+ for before, after in zip(found, found[1:]):
377
+ parts, unknown, over = [], False, False
378
+ for key, label in (("claim_block_rate", "claim block"),
379
+ ("stop_shape_rate", "stop shape")):
380
+ a, b = before["rates"][key], after["rates"][key]
381
+ if a is None or b is None:
382
+ unknown = True
383
+ parts.append("%s n/a" % label)
384
+ continue
385
+ parts.append("%s %+.2f pp" % (label, 100 * (b - a)))
386
+ over = over or round(b - a, 4) > 0.02
387
+ shift = dominant_contract(before) != dominant_contract(after)
388
+ print("delta %s..%s -> %s..%s: %s; 056 bar (+2 pp): %s%s" % (
389
+ before["since"], before["until"], after["since"], after["until"],
390
+ ", ".join(parts),
391
+ "unreadable (no denominator in a window)" if unknown
392
+ else "FAILS" if over else "holds",
393
+ "; the two windows' rows come from different contracts (%s vs %s), "
394
+ "so the shares are not one quantity" % (
395
+ dominant_contract(before), dominant_contract(after))
396
+ if shift else ""))
397
+
398
+
244
399
  def main():
245
400
  # `--` ends the options: what follows is PATH and SESSION_ID even when it
246
401
  # starts with a dash. The dsh route and the MCP tool hand caller-chosen
@@ -250,6 +405,11 @@ def main():
250
405
  rest = argv[argv.index("--") + 1:] if "--" in argv else []
251
406
  argv = argv[:argv.index("--")] if "--" in argv else argv
252
407
  args, weeks = weeks_arg(argv)
408
+ try:
409
+ args, windows = window_pairs(args)
410
+ except ValueError as err:
411
+ sys.stderr.write("tezgah-status: %s\n" % err)
412
+ return 2
253
413
  # A sanity bound, not a policy: ten years of weeks is longer than any ledger
254
414
  # this machine holds, and a number the reader mistyped should say so rather
255
415
  # than print a thousand rows of nothing.
@@ -260,9 +420,11 @@ def main():
260
420
  pos = [a for a in args if not a.startswith("--")] + rest
261
421
  known = {"--legend", "--json", "--color", "--no-color", "--counters",
262
422
  "--all", "--trend", "--skill-fitness", "--failure-shapes",
263
- "--rule-yield", "--enforcers", "--orca", "--judge", "--help"}
423
+ "--rule-yield", "--enforcers", "--orca", "--judge", "--rates",
424
+ "--help"}
264
425
  unknown = sorted(f for f in flags
265
- if f not in known and not f.startswith("--observable="))
426
+ if f not in known
427
+ and not f.startswith(("--observable=", "--manifest=")))
266
428
  if unknown:
267
429
  sys.stderr.write("tezgah-status: unknown option(s): %s (try --help)\n"
268
430
  % ", ".join(unknown))
@@ -293,6 +455,26 @@ def main():
293
455
  sys.stderr.write("tezgah-status: %s only means something with "
294
456
  "--counters\n" % modifier)
295
457
  return 2
458
+ if windows and "--rates" not in flags:
459
+ sys.stderr.write("tezgah-status: --since/--until only mean something "
460
+ "with --rates\n")
461
+ return 2
462
+ if "--rates" in flags and not windows:
463
+ sys.stderr.write("tezgah-status: --rates wants --since and --until\n")
464
+ return 2
465
+ if "--rates" in flags:
466
+ import tezgah_integrity as ti
467
+ try:
468
+ found = [ti.rates(since, until) for since, until in windows]
469
+ except ValueError as err:
470
+ sys.stderr.write("tezgah-status: %s\n" % err)
471
+ return 2
472
+ if "--json" in flags:
473
+ # one shape for one window and for many: a consumer never branches
474
+ print(json.dumps({"windows": found}, sort_keys=True))
475
+ return 0
476
+ print_rates(found)
477
+ return 0
296
478
  if "--judge" in flags:
297
479
  import tezgah_judge as tj
298
480
  last = tj.last_use()
@@ -430,7 +612,23 @@ def main():
430
612
  spec = next((f.split("=", 1)[1] for f in flags
431
613
  if f.startswith("--observable=")), None)
432
614
  observable = set(spec.split(",")) if spec else None
433
- segs = health_segments(cwd, session, observable=observable)
615
+ manifest = next((f.split("=", 1)[1] for f in flags
616
+ if f.startswith("--manifest=")), None) or None
617
+ if not pos:
618
+ import tezgah_extension
619
+ if tezgah_extension.override(cwd, manifest):
620
+ # the project's own statusLine runs this renderer: the host says
621
+ # which directory and session the line is for
622
+ payload = host_payload()
623
+ workspace = payload.get("workspace")
624
+ where = ((workspace.get("current_dir")
625
+ if isinstance(workspace, dict) else None)
626
+ or payload.get("cwd"))
627
+ if isinstance(where, str) and where:
628
+ cwd = os.path.realpath(where)
629
+ if isinstance(payload.get("session_id"), str) and payload["session_id"]:
630
+ session = payload["session_id"]
631
+ segs = health_segments(cwd, session, observable=observable, manifest=manifest)
434
632
  if "--json" in flags:
435
633
  print(json.dumps(segs))
436
634
  return 0
package/bin/tezgah-task CHANGED
@@ -6,7 +6,7 @@
6
6
  tezgah-task allow GLOB ... | --any-path --why REASON replace the allowlist, recording why
7
7
  tezgah-task stop deactivate (clear phase)
8
8
  tezgah-task status [--json] the active task, then every open plan: progress, what it waits on, what can run at once
9
- tezgah-task review <NNN|path> <reviewer> approve|changes record a fresh review's verdict
9
+ tezgah-task review <NNN|path> <reviewer> approve|changes [--no-slice WHY] record a fresh review's verdict; approve needs the reviewer's slice record, or WHY it has none
10
10
  tezgah-task close <NNN|path> done|discarded [--resolved TEXT] move a plan to .tezgah/plans/done, deactivate it, remove merged worktrees
11
11
  tezgah-task tick <NNN|path> <n> [--undo] tick (or untick) Acceptance item n, counted from 1
12
12
  tezgah-task note <NNN|path> state|next "<text>" replace the body of `## State` (the newest one) or `## Next`
@@ -122,7 +122,10 @@ history) is printed as `not judged` and the exit is 1. `review ... approve`
122
122
  is refused while a record whose id or agent is that reviewer is not done.
123
123
 
124
124
  Exit codes: 0 ok, 1 a refusal or a problem - one `FAIL <what>` line per problem,
125
- with nothing written - 2 misuse.
125
+ with nothing written - 2 misuse. In a repository whose `tezgah.owner` says
126
+ `tasks: off` (or `harness: excluded`) every command above that writes a record
127
+ is refused, and the read-only ones still answer
128
+ (`bin/tezgah-task::owner_mark`).
126
129
  """
127
130
  import glob
128
131
  import json
@@ -136,7 +139,12 @@ import time
136
139
  HERE = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
137
140
  sys.path.insert(0, os.path.join(HERE, "hooks"))
138
141
  import tezgah_task as tt # noqa: E402
139
- from tezgah_paths import project_top, say, work_tree # noqa: E402
142
+ from tezgah_paths import config, ocr_bin, omp_bin, project_top, say, work_tree # noqa: E402
143
+
144
+ # Mirrors hooks/tezgah_gate.py::PLAN_TRUNKS: the gate reads these as unplanned
145
+ # whatever a plan declares, so `start --branch` refuses them (plan 113). Not
146
+ # imported: the gate hook pulls in every rule module for this one tuple.
147
+ PLAN_TRUNKS = ("main", "master")
140
148
 
141
149
 
142
150
  def repo_root(path):
@@ -152,6 +160,43 @@ def repo_root(path):
152
160
  return os.path.realpath(path)
153
161
 
154
162
 
163
+ # Commands that write a plan's record. A repository that carries `tezgah.owner`
164
+ # saying `tasks: off` (or `harness: excluded`) keeps its records to itself: the
165
+ # phase would arm nothing there - `tezgah_task._phased` answers no task
166
+ # (`hooks/tezgah_paths.py::tasks_disabled`) - so writing one would report
167
+ # success for a guard that never fired. `writes_a_record` reads both tuples, and
168
+ # the read-only commands are untouched.
169
+ RECORD_COMMANDS = ("start", "phase", "allow", "stop", "review", "close",
170
+ "tick", "note", "spike", "unmet")
171
+ # The journal's own writers, and `sweep`, which clears an orphan `phase:` and
172
+ # closes the slices of the worktrees it prunes. The rest of `slice` only reads
173
+ # (stats, board, merge-plan), and so does `status`.
174
+ SLICE_WRITERS = ("open", "done", "stop", "reconcile", "resume")
175
+
176
+
177
+ def writes_a_record(cmd, rest):
178
+ """True when this invocation writes the task machine's records: the plan
179
+ file, the slice journal, or the phases and slices `sweep` clears. The
180
+ readers write none, so a repository that is not this harness's still answers
181
+ them (`status`, `slice stats`, `slice board`, `slice merge-plan`)."""
182
+ if cmd in RECORD_COMMANDS:
183
+ return True
184
+ if cmd == "slice":
185
+ return bool(rest) and rest[0] in SLICE_WRITERS
186
+ return cmd == "sweep"
187
+
188
+
189
+ def owner_mark(root):
190
+ """Why this repository's records are not this machine's to write, else
191
+ None. Through `tasks_disabled`, so the CLI and the gate read one answer."""
192
+ from tezgah_paths import OWNER_MARKER, tasks_disabled
193
+ if not tasks_disabled(root):
194
+ return None
195
+ return ("%s says `tasks: off` in %s: its records are the repository's own, so "
196
+ "this machine writes none there - edit them directly"
197
+ % (root, os.path.join(root, OWNER_MARKER)))
198
+
199
+
155
200
  def misuse(message):
156
201
  """Misuse exits 2, so a caller can tell it from a record that refuses."""
157
202
  print("tezgah-task: %s" % message, file=sys.stderr)
@@ -434,6 +479,139 @@ MERGE_CHECKS = (
434
479
  "python3 skills/plan-add/render_table.py --acceptance --strict"),
435
480
  )
436
481
 
482
+ # OCR's texts vendored with tezgah (plan 125): the review prompt each per-group
483
+ # reviewer reads as an appendix, the filter prompt the refuter pass follows
484
+ OCR_PROMPTS = os.path.join(HERE, "third_party", "open-code-review", "prompts")
485
+
486
+
487
+ def ocr_json(ocr, args):
488
+ """One `ocr delegate ... --format json` answer as a dict, or the reason it
489
+ is not one: a non-zero exit, a timeout, output that is not a JSON object."""
490
+ try:
491
+ out = subprocess.run([ocr, "delegate"] + args, capture_output=True,
492
+ text=True, timeout=30,
493
+ env=dict(os.environ, OCR_NO_UPDATE="1"))
494
+ except subprocess.TimeoutExpired:
495
+ return "`ocr delegate %s` timed out after 30 s" % args[0]
496
+ except OSError as exc:
497
+ return "`ocr delegate %s` did not start: %s" % (args[0], exc)
498
+ if out.returncode:
499
+ return "`ocr delegate %s` exited %d" % (args[0], out.returncode)
500
+ try:
501
+ data = json.loads(out.stdout)
502
+ except ValueError:
503
+ data = None
504
+ return data if isinstance(data, dict) else \
505
+ "`ocr delegate %s` printed no JSON object" % args[0]
506
+
507
+
508
+ def ocr_spec(where, base):
509
+ """OCR's deterministic review spec for `base..HEAD`: (preview, rule groups,
510
+ the rule command), the reason it is skipped, or None without `ocr` or with
511
+ the `ocr` feature not enabled (`tezgah-setup --enable ocr`) - the step is
512
+ then today's."""
513
+ ocr = ocr_bin()
514
+ if ocr is None or "ocr" not in (config().get("features") or []):
515
+ return None
516
+ if base == "<base>":
517
+ return "no diff base to preview"
518
+ preview = ocr_json(ocr, ["preview", "--format", "json", "--from", base,
519
+ "--to", "HEAD", "--repo", where])
520
+ if isinstance(preview, str):
521
+ return preview
522
+ # the JSON shape this reader was written against (OCR 375f64c / 1.13.2)
523
+ if preview.get("schema_version") != "1":
524
+ return "`ocr delegate preview` schema_version %r is not \"1\"" % (
525
+ preview.get("schema_version"),)
526
+ files = preview.get("reviewable_files")
527
+ excluded = preview.get("excluded_files", [])
528
+ if not isinstance(files, list) or not isinstance(excluded, list):
529
+ return "`ocr delegate preview` JSON has no file lists"
530
+ # a row with no string path is dropped here, so neither the rule argv nor
531
+ # the printed list can meet a None
532
+ files = [f for f in files if isinstance(f, dict) and isinstance(f.get("path"), str)]
533
+ preview["reviewable_files"] = files
534
+ paths = [f["path"] for f in files]
535
+ groups = []
536
+ # `--` ends OCR's options, so a changed file named like a flag stays a path
537
+ rule_cmd = [ocr, "delegate", "rule", "--format", "json", "--repo", where, "--"] + paths
538
+ if paths:
539
+ rule = ocr_json(ocr, rule_cmd[2:])
540
+ if isinstance(rule, str):
541
+ return rule
542
+ if rule.get("schema_version") != "1":
543
+ return "`ocr delegate rule` schema_version %r is not \"1\"" % (
544
+ rule.get("schema_version"),)
545
+ groups = rule.get("groups")
546
+ if not isinstance(groups, list):
547
+ return "`ocr delegate rule` JSON has no groups"
548
+ return preview, groups, rule_cmd
549
+
550
+
551
+ def print_ocr_spec(where, base):
552
+ """Step 2's OCR lines: the reviewable files, the exclusions (still in scope),
553
+ one reviewer per rule group, the refuter pass and the quote check. Prints
554
+ nothing without `ocr`, one `OCR spec skipped:` line when it fails."""
555
+ spec = ocr_spec(where, base)
556
+ if spec is None:
557
+ return
558
+ if isinstance(spec, str):
559
+ print(" OCR spec skipped: %s" % spec)
560
+ return
561
+ preview, groups, rule_cmd = spec
562
+ paths = [f.get("path") for f in preview["reviewable_files"] if isinstance(f, dict)]
563
+ print(" OCR review spec (`ocr delegate`; its output is input to the "
564
+ "review, never a verdict):")
565
+ print(" - reviewable files (%d): %s" % (len(paths), ", ".join(paths) or "none"))
566
+ out = ["%s (%s)" % (f.get("path"), f.get("exclude_reason", "no reason"))
567
+ for f in preview.get("excluded_files", []) if isinstance(f, dict)]
568
+ print(" - excluded by OCR, NOT covered by OCR rules but still in the "
569
+ "reviewer's scope (tests and docs stay in scope; one more "
570
+ "tezgah-reviewer reads them over the dimensions above): %s"
571
+ % (", ".join(out) or "none"))
572
+ if groups:
573
+ # OCR's own bundling below its LLM-grouping threshold (task_template.json
574
+ # GROUPING_MIN_FILES 4, GROUPING_BUNDLE_LINE_THRESHOLD 200): fewer than 4
575
+ # files are one bundle under 200 changed lines, else one file each.
576
+ churn = sum(n for f in preview["reviewable_files"]
577
+ for n in (f.get("insertions"), f.get("deletions"))
578
+ if isinstance(n, int) and not isinstance(n, bool))
579
+ if len(paths) < 4 and churn < 200:
580
+ who = ("one tezgah-reviewer for the whole small change set (%d files, "
581
+ "%d changed lines), its brief carrying every group's rule text"
582
+ % (len(paths), churn))
583
+ elif len(paths) < 4:
584
+ who = "one tezgah-reviewer per file, in ONE message"
585
+ else:
586
+ who = "one tezgah-reviewer per rule group below, in ONE message"
587
+ print(" - instead of one reviewer per dimension, spawn %s: a brief "
588
+ "carries its group's rule text verbatim (`groups[].rule` of `%s`) "
589
+ "and names %s as an appendix to read; each reviewer accounts for "
590
+ "every file it owns as reviewed or skipped-with-reason"
591
+ % (who, shlex.join(rule_cmd),
592
+ os.path.join(OCR_PROMPTS, "main_task_system.md")))
593
+ for g in groups:
594
+ if isinstance(g, dict):
595
+ print(" - rule group %s: source %s, pattern %s, files %s"
596
+ % (g.get("group_id"), g.get("source"), g.get("pattern"),
597
+ ", ".join(g.get("files") or []) or "none"))
598
+ else:
599
+ print(" - no OCR rule group: the dimension fan-out above stands")
600
+ print(" - refuter pass: after merging the findings, one fresh "
601
+ "tezgah-reviewer reads %s as its instructions and removes only "
602
+ "findings the diff proves wrong"
603
+ % os.path.join(OCR_PROMPTS, "review_filter_task_system.md"))
604
+ print(" - quote check: `tezgah-review-quote --repo %s --from %s "
605
+ "FINDINGS.json` over the merged findings (a JSON list of path, quote, "
606
+ "start_line, end_line); an `unlocated` finding goes back to its "
607
+ "reviewer" % (shlex.quote(where), base))
608
+ # V4, omp only: OCR's own loop on omp's model; candidates, never findings
609
+ if os.environ.get("OMPCODE") and omp_bin():
610
+ print(" - omp: `tezgah-ocr-review --repo %s --from %s --to HEAD "
611
+ "--output OCR.json` runs OCR's own review on omp's model; hand its "
612
+ "comments to the reviewers as candidates to confirm or refute, "
613
+ "never as findings" % (shlex.quote(where), base))
614
+
437
615
 
438
616
  def verification_steps(text, path):
439
617
  """What the verification phase requires before the plan is done: the plan's
@@ -510,6 +688,7 @@ def verification_steps(text, path):
510
688
  "without a new round, or recorded fix-later under ## State only "
511
689
  "when it waits on a user decision (%s), and the verdict is "
512
690
  "`approve`" % say()["decision"])
691
+ print_ocr_spec(where, base)
513
692
  print(" 3. record its verdict: `tezgah-task review %s <reviewer> approve|changes`"
514
693
  " (records the reviewed sha);"
515
694
  " `tezgah-task close %s done` refuses without an approve" % (ident, ident))
@@ -552,6 +731,11 @@ def cmd_start(args):
552
731
  if i + 1 >= len(rest) or rest[i + 1].startswith("--"):
553
732
  return misuse("--branch needs the branch name to bind the plan to")
554
733
  branch = rest[i + 1]
734
+ if branch in PLAN_TRUNKS:
735
+ return misuse("--branch %s: a trunk (%s) never binds a plan - the gate "
736
+ "reads every PLAN_TRUNKS name as unplanned; bind a "
737
+ "plan/NNN-slug branch instead"
738
+ % (branch, ", ".join(PLAN_TRUNKS)))
555
739
  i += 2
556
740
  continue
557
741
  if rest[i] == ANY_PATH:
@@ -619,7 +803,19 @@ def cmd_start(args):
619
803
  bad = write_fields(path, **fields)
620
804
  if bad:
621
805
  return problems(bad)
622
- return show(path)
806
+ shown = show(path)
807
+ top = repo_root(os.getcwd())
808
+ if main_root(top) != top:
809
+ # a worktree bound to a plan gets its graph now, seeded from the main
810
+ # checkout's (plan 118); an index that cannot start costs the line, never
811
+ # the start the record already holds
812
+ try:
813
+ from tezgah_context import autoindex, under
814
+ if under(top):
815
+ print("graph: %s" % autoindex(top))
816
+ except Exception:
817
+ pass
818
+ return shown
623
819
 
624
820
 
625
821
  def cmd_phase(args):
@@ -886,7 +1082,7 @@ def budget_spent(path, ident):
886
1082
  % (path, REVIEW_ROUNDS, ident, say()["decision"], ident))
887
1083
 
888
1084
 
889
- def unfinished_review(root, reviewer, plan="", since=0):
1085
+ def unfinished_review(root, reviewer, plan="", since=0, no_slice="", ran_since=0):
890
1086
  """The refusal of an `approve` while a slice journal record whose id or agent
891
1087
  is `reviewer` is open, stopped or stale: a review slice that died on a
892
1088
  provider limit had its approve recorded anyway, and a NameError it would have
@@ -901,7 +1097,11 @@ def unfinished_review(root, reviewer, plan="", since=0):
901
1097
  `tt.open_slice`) counts too. Under TEZGAH_SESSION only this session's
902
1098
  records and unowned ones count, by id, agent or name alike: another
903
1099
  session's review is not this approve's. The refusal names the exact id,
904
- which `slice resume` and `slice done` take from any session."""
1100
+ which `slice resume` and `slice done` take from any session. No finished
1101
+ record changed at or after `ran_since` refuses too: a requested reviewer with
1102
+ no status did not run, and a plan-readiness review before the checkpoint, an
1103
+ earlier round's review or a `resumed` record with no re-run is not this
1104
+ review - unless `no_slice` says why the reviewer ran outside the journal."""
905
1105
  from tezgah_paths import off
906
1106
  if off("slices-off"):
907
1107
  return []
@@ -917,21 +1117,42 @@ def unfinished_review(root, reviewer, plan="", since=0):
917
1117
  return rec["plan"] == plan
918
1118
  return (_stamp(rec.get("updated")) or 0) >= since
919
1119
 
920
- return ["review slice %s is %s%s: let it finish, or resume it with `tezgah-task "
921
- "slice resume %s` and wait for that run; if the review was finished "
922
- "another way, record it with `tezgah-task slice done %s` - an approve "
923
- "from a review that did not finish reads nothing"
924
- % (rec["id"], rec.get("status"),
925
- (" (%s)" % rec["failure"]) if rec.get("failure") else "",
926
- rec["id"], rec["id"])
927
- for rec in tt.slices(root)
928
- if rec.get("status") in ("open", "stopped", "stale")
929
- and named(rec) and ours(rec)]
1120
+ found = [rec for rec in tt.slices(root) if named(rec) and ours(rec)]
1121
+ refusals = ["review slice %s is %s%s: let it finish, or resume it with `tezgah-task "
1122
+ "slice resume %s` and wait for that run; if the review was finished "
1123
+ "another way, record it with `tezgah-task slice done %s` - an approve "
1124
+ "from a review that did not finish reads nothing"
1125
+ % (rec["id"], rec.get("status"),
1126
+ (" (%s)" % rec["failure"]) if rec.get("failure") else "",
1127
+ rec["id"], rec["id"])
1128
+ for rec in found if rec.get("status") in ("open", "stopped", "stale")]
1129
+ ran = [rec for rec in found if rec.get("status") == "done"
1130
+ and (_stamp(rec.get("updated")) or 0) >= ran_since]
1131
+ if not ran and not refusals and not no_slice:
1132
+ # a requested reviewer with no finished record since the work is a
1133
+ # review that did not run
1134
+ refusals.append(
1135
+ "no finished review slice names %s for this plan since its work began: "
1136
+ "a reviewer with no record did not run, and a readiness review, an "
1137
+ "earlier round or a resumed record is not this review. Spawn the fresh "
1138
+ "reviewer and approve once its slice is done; a host that keeps no "
1139
+ "slice journal records why with "
1140
+ "`--no-slice \"<why: the reviewer ran outside the slice journal>\"`"
1141
+ % reviewer)
1142
+ return refusals
930
1143
 
931
1144
 
932
1145
  def cmd_review(args):
1146
+ no_slice = ""
1147
+ if "--no-slice" in args:
1148
+ i = args.index("--no-slice")
1149
+ no_slice = " ".join((args[i + 1:i + 2] or [""])[0].split())
1150
+ args = args[:i] + args[i + 2:]
1151
+ if not no_slice:
1152
+ return misuse("--no-slice takes why the reviewer ran outside the slice journal")
933
1153
  if len(args) != 3 or args[2] not in VERDICTS:
934
- return misuse("review takes <NNN|path> <reviewer> %s" % "|".join(VERDICTS))
1154
+ return misuse("review takes <NNN|path> <reviewer> %s [--no-slice WHY]"
1155
+ % "|".join(VERDICTS))
935
1156
  path, problem = open_plan(args[0])
936
1157
  if problem:
937
1158
  return problems([problem])
@@ -948,9 +1169,21 @@ def cmd_review(args):
948
1169
  mark = (fields.get("checkpoint") or "").split()
949
1170
  since = (git_out(root, "log", "-1", "--format=%ct", mark[-1])
950
1171
  if mark and mark[-1] != tt.CHECKPOINT_PENDING else None)
1172
+ since = int(since) if (since or "").isdigit() else 0
1173
+ # this round's review finished after the first commit of the work it
1174
+ # reads: past the checkpoint in round one (a plan-readiness review ran
1175
+ # before it), past the commit round one read in round two (round one's
1176
+ # reviewer finished before it); with no such commit, after the base itself
951
1177
  ident = fields.get("id") or os.path.basename(path).split("-")[0]
952
- bad = unfinished_review(root, args[1], ident,
953
- int(since) if (since or "").isdigit() else 0)
1178
+ base = fields.get("reviewed_sha") or (
1179
+ mark[-1] if mark and mark[-1] != tt.CHECKPOINT_PENDING else "")
1180
+ first = ""
1181
+ if base:
1182
+ after = (git_out(tt.plan_holders(root).get(ident) or root, "log",
1183
+ "--reverse", "--format=%ct", base + "..HEAD") or "").split()
1184
+ first = after[0] if after else git_out(root, "log", "-1", "--format=%ct", base)
1185
+ ran_since = max(since, int(first) if (first or "").isdigit() else 0)
1186
+ bad = unfinished_review(root, args[1], ident, since, no_slice, ran_since)
954
1187
  if bad:
955
1188
  return problems(bad)
956
1189
  # a plan held by its own worktree is built on that branch: its HEAD is the
@@ -958,7 +1191,8 @@ def cmd_review(args):
958
1191
  ident = fields.get("id") or os.path.basename(path).split("-")[0]
959
1192
  where = tt.plan_holders(root).get(ident) or root
960
1193
  sha = (git_out(where, "rev-parse", "HEAD") or "")[:12]
961
- record = {"review": "%s %s %s" % (args[1], args[2], today()),
1194
+ record = {"review": "%s %s %s%s" % (args[1], args[2], today(),
1195
+ " no-slice: " + no_slice if no_slice else ""),
962
1196
  "review_round": str(int(prior) + 1 if prior.isdigit() else 1),
963
1197
  "updated": today()}
964
1198
  if sha:
@@ -1814,6 +2048,10 @@ def main(argv):
1814
2048
  print(__doc__, file=sys.stderr)
1815
2049
  return 2
1816
2050
  cmd, rest = argv[1], argv[2:]
2051
+ if writes_a_record(cmd, rest):
2052
+ mark = owner_mark(repo_root(os.getcwd()))
2053
+ if mark:
2054
+ return problems([mark])
1817
2055
  if cmd == "start":
1818
2056
  return cmd_start(rest)
1819
2057
  if cmd == "phase":
package/commands/adhd.md CHANGED
@@ -1,4 +1,4 @@
1
- Run `tezgah-adhd $ARGUMENTS` and report the one line it prints.
1
+ Run `~/.config/tezgah/bin/tezgah-adhd $ARGUMENTS` and report the one line it prints.
2
2
 
3
3
  The installed CLI owns the state: it writes or removes
4
4
  `~/.config/tezgah/adhd-off`, the kill switch that drops the act-on-it rule from
@@ -6,7 +6,7 @@ the text every host injects. Never create or delete that file by hand, and never
6
6
  edit any other rule's switch from here.
7
7
 
8
8
  ```sh
9
- adhd=$(command -v tezgah-adhd || echo "$HOME/.config/tezgah/bin/tezgah-adhd")
9
+ adhd="$HOME/.config/tezgah/bin/tezgah-adhd"
10
10
  "$adhd" $ARGUMENTS
11
11
  ```
12
12