@r1z4x/tezgah 1.9.0 → 1.11.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 (429) hide show
  1. package/CHANGELOG.md +98 -1
  2. package/MANIFEST +382 -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 +1 -1
  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 +216 -40
  15. package/bin/tezgah-review-quote +185 -0
  16. package/bin/tezgah-setup +136 -33
  17. package/bin/tezgah-skill +1 -1
  18. package/bin/tezgah-status +201 -3
  19. package/bin/tezgah-task +203 -3
  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 +2 -2
  24. package/docs/clarity-baseline.json +2 -2
  25. package/docs/contract.md +87 -42
  26. package/docs/environment.md +5 -3
  27. package/docs/evidence.md +28 -9
  28. package/docs/feature-audit.md +2 -2
  29. package/docs/gate.md +54 -31
  30. package/docs/glossary.md +5 -2
  31. package/docs/hosts.md +17 -3
  32. package/docs/index.json +34 -8
  33. package/docs/judge.md +4 -2
  34. package/docs/layers.md +3 -3
  35. package/docs/models.md +31 -9
  36. package/docs/operations.md +148 -8
  37. package/docs/research.md +786 -5
  38. package/docs/skills.md +137 -13
  39. package/docs/status-line.md +115 -1
  40. package/hooks/hooks.json +1 -1
  41. package/hooks/lang/en.json +10 -0
  42. package/hooks/lang/tr.json +11 -1
  43. package/hooks/tezgah_agents.py +38 -22
  44. package/hooks/tezgah_apps.py +18 -0
  45. package/hooks/tezgah_components.py +4 -0
  46. package/hooks/tezgah_context.py +189 -50
  47. package/hooks/tezgah_extension.py +337 -0
  48. package/hooks/tezgah_gate.py +188 -56
  49. package/hooks/tezgah_integrity.py +652 -105
  50. package/hooks/tezgah_judge.py +6 -4
  51. package/hooks/tezgah_models.py +59 -19
  52. package/hooks/tezgah_orca.py +1 -1
  53. package/hooks/tezgah_paths.py +102 -6
  54. package/hooks/tezgah_policy.py +94 -45
  55. package/hooks/tezgah_rank.py +9 -6
  56. package/hooks/tezgah_replay.py +4 -4
  57. package/hooks/tezgah_research.py +1260 -65
  58. package/hooks/tezgah_research_capture.py +1544 -0
  59. package/hooks/tezgah_research_evidence.py +842 -0
  60. package/hooks/tezgah_research_stats.py +258 -0
  61. package/hooks/tezgah_skill_pick.py +408 -106
  62. package/hooks/tezgah_stopspec.py +8 -1
  63. package/hooks/tezgah_task.py +12 -4
  64. package/hooks/tezgah_taste_ledger.py +1 -1
  65. package/hosts/cursor/hook.py +29 -2
  66. package/hosts/opencode/plugins/tezgah.js +307 -46
  67. package/hosts/opencode/tui/cli/tui.tsx +100 -0
  68. package/hosts/opencode/tui/tezgah-tui.tsx +2 -1
  69. package/output-styles/tezgah.md +10 -10
  70. package/package.json +1 -1
  71. package/packaging/install.ps1 +36 -3
  72. package/packaging/install.sh +13 -3
  73. package/packaging/upgrade.sh +61 -7
  74. package/skills/ai-research/SKILL.md +21 -14
  75. package/skills/ai-research/SOURCE +7 -5
  76. package/skills/ai-research/index/1-frame.md +6 -6
  77. package/skills/ai-research/index/2-data.md +9 -9
  78. package/skills/ai-research/index/3-train.md +36 -36
  79. package/skills/ai-research/index/4-measure.md +13 -13
  80. package/skills/ai-research/index/5-run.md +11 -11
  81. package/skills/ai-research/index/6-write.md +23 -23
  82. package/skills/ai-research/library.json +104 -104
  83. package/skills/analyze-app/SKILL.md +17 -12
  84. package/skills/design-contract/SKILL.md +42 -7
  85. package/skills/design-contract/data-views.md +2 -2
  86. package/skills/design-library/EVALS.md +1 -1
  87. package/skills/design-library/INDEX.md +39 -39
  88. package/skills/design-library/SKILL.md +19 -13
  89. package/skills/design-library/SOURCE +45 -43
  90. package/skills/feature-audit/SKILL.md +20 -14
  91. package/skills/hallmark/LICENSE +21 -0
  92. package/skills/hallmark/SKILL.md +154 -0
  93. package/skills/hallmark/SOURCE +207 -0
  94. package/skills/hallmark/agents/openai.yaml +13 -0
  95. package/skills/hallmark/references/anatomy.md +71 -0
  96. package/skills/hallmark/references/brand-truth.md +40 -0
  97. package/skills/hallmark/references/comp.md +104 -0
  98. package/skills/hallmark/references/craft.md +116 -0
  99. package/skills/hallmark/references/dark-mode.md +49 -0
  100. package/skills/hallmark/references/data-viz.md +48 -0
  101. package/skills/hallmark/references/design-md.md +53 -0
  102. package/skills/hallmark/references/direction.md +52 -0
  103. package/skills/hallmark/references/export-formats.md +80 -0
  104. package/skills/hallmark/references/flow.md +131 -0
  105. package/skills/hallmark/references/fonts.md +58 -0
  106. package/skills/hallmark/references/gates.md +243 -0
  107. package/skills/hallmark/references/genres/atmospheric.md +24 -0
  108. package/skills/hallmark/references/genres/editorial.md +24 -0
  109. package/skills/hallmark/references/genres/modern-minimal.md +24 -0
  110. package/skills/hallmark/references/genres/playful.md +24 -0
  111. package/skills/hallmark/references/imagery.md +99 -0
  112. package/skills/hallmark/references/interaction-and-states.md +89 -0
  113. package/skills/hallmark/references/layout.md +104 -0
  114. package/skills/hallmark/references/macrostructures/01-bento-grid.md +21 -0
  115. package/skills/hallmark/references/macrostructures/02-long-document.md +35 -0
  116. package/skills/hallmark/references/macrostructures/03-marquee-hero.md +21 -0
  117. package/skills/hallmark/references/macrostructures/04-stat-led.md +21 -0
  118. package/skills/hallmark/references/macrostructures/05-workbench.md +21 -0
  119. package/skills/hallmark/references/macrostructures/06-conversational-faq.md +28 -0
  120. package/skills/hallmark/references/macrostructures/07-manifesto.md +28 -0
  121. package/skills/hallmark/references/macrostructures/08-photographic.md +21 -0
  122. package/skills/hallmark/references/macrostructures/09-quote-led.md +21 -0
  123. package/skills/hallmark/references/macrostructures/10-specimen.md +21 -0
  124. package/skills/hallmark/references/macrostructures/11-catalogue.md +21 -0
  125. package/skills/hallmark/references/macrostructures/12-letter.md +21 -0
  126. package/skills/hallmark/references/macrostructures/13-index-first.md +21 -0
  127. package/skills/hallmark/references/macrostructures/14-narrative-workflow.md +21 -0
  128. package/skills/hallmark/references/macrostructures/15-split-studio.md +21 -0
  129. package/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -0
  130. package/skills/hallmark/references/macrostructures/17-type-specimen.md +19 -0
  131. package/skills/hallmark/references/macrostructures/18-portfolio-grid.md +21 -0
  132. package/skills/hallmark/references/macrostructures/19-map-diagram.md +21 -0
  133. package/skills/hallmark/references/macrostructures/20-ecosystem-index.md +19 -0
  134. package/skills/hallmark/references/macrostructures/21-component-playground.md +21 -0
  135. package/skills/hallmark/references/macrostructures.md +119 -0
  136. package/skills/hallmark/references/microinteractions.md +80 -0
  137. package/skills/hallmark/references/patterns.md +202 -0
  138. package/skills/hallmark/references/redesign.md +88 -0
  139. package/skills/hallmark/references/responsive.md +46 -0
  140. package/skills/hallmark/references/review-finish.md +19 -0
  141. package/skills/hallmark/references/review-hero.md +20 -0
  142. package/skills/hallmark/references/scroll-choreography.md +110 -0
  143. package/skills/hallmark/references/texture.md +90 -0
  144. package/skills/hallmark/references/themes/README.md +58 -0
  145. package/skills/hallmark/references/themes/almanac.jpg +0 -0
  146. package/skills/hallmark/references/themes/almanac.md +103 -0
  147. package/skills/hallmark/references/themes/arcade.jpg +0 -0
  148. package/skills/hallmark/references/themes/arcade.md +102 -0
  149. package/skills/hallmark/references/themes/atelier.jpg +0 -0
  150. package/skills/hallmark/references/themes/atelier.md +98 -0
  151. package/skills/hallmark/references/themes/bloom.jpg +0 -0
  152. package/skills/hallmark/references/themes/bloom.md +102 -0
  153. package/skills/hallmark/references/themes/blueprint.jpg +0 -0
  154. package/skills/hallmark/references/themes/blueprint.md +103 -0
  155. package/skills/hallmark/references/themes/broadside.jpg +0 -0
  156. package/skills/hallmark/references/themes/broadside.md +108 -0
  157. package/skills/hallmark/references/themes/brutal.jpg +0 -0
  158. package/skills/hallmark/references/themes/brutal.md +95 -0
  159. package/skills/hallmark/references/themes/carnival.jpg +0 -0
  160. package/skills/hallmark/references/themes/carnival.md +104 -0
  161. package/skills/hallmark/references/themes/cobalt.jpg +0 -0
  162. package/skills/hallmark/references/themes/cobalt.md +101 -0
  163. package/skills/hallmark/references/themes/console.jpg +0 -0
  164. package/skills/hallmark/references/themes/console.md +99 -0
  165. package/skills/hallmark/references/themes/coral.jpg +0 -0
  166. package/skills/hallmark/references/themes/coral.md +102 -0
  167. package/skills/hallmark/references/themes/darkroom.jpg +0 -0
  168. package/skills/hallmark/references/themes/darkroom.md +99 -0
  169. package/skills/hallmark/references/themes/dose.jpg +0 -0
  170. package/skills/hallmark/references/themes/dose.md +98 -0
  171. package/skills/hallmark/references/themes/dusk.jpg +0 -0
  172. package/skills/hallmark/references/themes/dusk.md +105 -0
  173. package/skills/hallmark/references/themes/editorial.jpg +0 -0
  174. package/skills/hallmark/references/themes/editorial.md +97 -0
  175. package/skills/hallmark/references/themes/formwork.jpg +0 -0
  176. package/skills/hallmark/references/themes/formwork.md +107 -0
  177. package/skills/hallmark/references/themes/furrow.jpg +0 -0
  178. package/skills/hallmark/references/themes/furrow.md +98 -0
  179. package/skills/hallmark/references/themes/garden.jpg +0 -0
  180. package/skills/hallmark/references/themes/garden.md +97 -0
  181. package/skills/hallmark/references/themes/grid.jpg +0 -0
  182. package/skills/hallmark/references/themes/grid.md +101 -0
  183. package/skills/hallmark/references/themes/halftone.jpg +0 -0
  184. package/skills/hallmark/references/themes/halftone.md +106 -0
  185. package/skills/hallmark/references/themes/hedgerow.jpg +0 -0
  186. package/skills/hallmark/references/themes/hedgerow.md +104 -0
  187. package/skills/hallmark/references/themes/hum.jpg +0 -0
  188. package/skills/hallmark/references/themes/hum.md +99 -0
  189. package/skills/hallmark/references/themes/index.json +2191 -0
  190. package/skills/hallmark/references/themes/ink.jpg +0 -0
  191. package/skills/hallmark/references/themes/ink.md +106 -0
  192. package/skills/hallmark/references/themes/kiln.jpg +0 -0
  193. package/skills/hallmark/references/themes/kiln.md +108 -0
  194. package/skills/hallmark/references/themes/loom.jpg +0 -0
  195. package/skills/hallmark/references/themes/loom.md +106 -0
  196. package/skills/hallmark/references/themes/lumen.jpg +0 -0
  197. package/skills/hallmark/references/themes/lumen.md +103 -0
  198. package/skills/hallmark/references/themes/manifesto.jpg +0 -0
  199. package/skills/hallmark/references/themes/manifesto.md +101 -0
  200. package/skills/hallmark/references/themes/midnight.jpg +0 -0
  201. package/skills/hallmark/references/themes/midnight.md +97 -0
  202. package/skills/hallmark/references/themes/newsprint.jpg +0 -0
  203. package/skills/hallmark/references/themes/newsprint.md +102 -0
  204. package/skills/hallmark/references/themes/overprint.jpg +0 -0
  205. package/skills/hallmark/references/themes/overprint.md +101 -0
  206. package/skills/hallmark/references/themes/pasteup.jpg +0 -0
  207. package/skills/hallmark/references/themes/pasteup.md +100 -0
  208. package/skills/hallmark/references/themes/piste.jpg +0 -0
  209. package/skills/hallmark/references/themes/piste.md +99 -0
  210. package/skills/hallmark/references/themes/ribbon.jpg +0 -0
  211. package/skills/hallmark/references/themes/ribbon.md +106 -0
  212. package/skills/hallmark/references/themes/rim.jpg +0 -0
  213. package/skills/hallmark/references/themes/rim.md +96 -0
  214. package/skills/hallmark/references/themes/riso.jpg +0 -0
  215. package/skills/hallmark/references/themes/riso.md +98 -0
  216. package/skills/hallmark/references/themes/solstice.jpg +0 -0
  217. package/skills/hallmark/references/themes/solstice.md +104 -0
  218. package/skills/hallmark/references/themes/specimen.jpg +0 -0
  219. package/skills/hallmark/references/themes/specimen.md +100 -0
  220. package/skills/hallmark/references/themes/spore.jpg +0 -0
  221. package/skills/hallmark/references/themes/spore.md +104 -0
  222. package/skills/hallmark/references/themes/sport.jpg +0 -0
  223. package/skills/hallmark/references/themes/sport.md +101 -0
  224. package/skills/hallmark/references/themes/squeeze.jpg +0 -0
  225. package/skills/hallmark/references/themes/squeeze.md +99 -0
  226. package/skills/hallmark/references/themes/sticker.jpg +0 -0
  227. package/skills/hallmark/references/themes/sticker.md +106 -0
  228. package/skills/hallmark/references/themes/studio.jpg +0 -0
  229. package/skills/hallmark/references/themes/studio.md +99 -0
  230. package/skills/hallmark/references/themes/terminal.jpg +0 -0
  231. package/skills/hallmark/references/themes/terminal.md +96 -0
  232. package/skills/hallmark/references/themes/terrazzo.jpg +0 -0
  233. package/skills/hallmark/references/themes/terrazzo.md +106 -0
  234. package/skills/hallmark/references/themes/ultraviolet.jpg +0 -0
  235. package/skills/hallmark/references/themes/ultraviolet.md +106 -0
  236. package/skills/hallmark/references/themes/vellum.jpg +0 -0
  237. package/skills/hallmark/references/themes/vellum.md +105 -0
  238. package/skills/hallmark/references/themes/wayfind.jpg +0 -0
  239. package/skills/hallmark/references/themes/wayfind.md +105 -0
  240. package/skills/hallmark/references/themes/werkstatt.jpg +0 -0
  241. package/skills/hallmark/references/themes/werkstatt.md +105 -0
  242. package/skills/hallmark/scripts/capture.mjs +125 -0
  243. package/skills/hallmark/scripts/fixtures/exemplars/atmospheric.html +324 -0
  244. package/skills/hallmark/scripts/fixtures/exemplars/editorial.html +363 -0
  245. package/skills/hallmark/scripts/fixtures/exemplars/modern-minimal.html +527 -0
  246. package/skills/hallmark/scripts/fixtures/exemplars/playful.html +353 -0
  247. package/skills/hallmark/scripts/fixtures/eyebrow-fail/index.html +118 -0
  248. package/skills/hallmark/scripts/fixtures/eyebrow-pass/index.html +137 -0
  249. package/skills/hallmark/scripts/fixtures/kept/after.html +27 -0
  250. package/skills/hallmark/scripts/fixtures/kept/before.html +26 -0
  251. package/skills/hallmark/scripts/fixtures/slopped.html +145 -0
  252. package/skills/hallmark/scripts/fixtures/tailwind-fail/Feature.vue +14 -0
  253. package/skills/hallmark/scripts/fixtures/tailwind-fail/Hero.tsx +33 -0
  254. package/skills/hallmark/scripts/fixtures/tailwind-fail/index.html +74 -0
  255. package/skills/hallmark/scripts/fixtures/tailwind-fail/style.css +6 -0
  256. package/skills/hallmark/scripts/fixtures/tailwind-pass/Hero.tsx +33 -0
  257. package/skills/hallmark/scripts/fixtures/tailwind-pass/index.html +57 -0
  258. package/skills/hallmark/scripts/fixtures/tailwind-pass/style.css +15 -0
  259. package/skills/hallmark/scripts/fixtures/waiver/index.html +54 -0
  260. package/skills/hallmark/scripts/imagegen.mjs +85 -0
  261. package/skills/hallmark/scripts/install-hook.mjs +70 -0
  262. package/skills/hallmark/scripts/install.mjs +141 -0
  263. package/skills/hallmark/scripts/lint-hook.mjs +49 -0
  264. package/skills/hallmark/scripts/photos.json +1 -0
  265. package/skills/hallmark/scripts/picture.mjs +71 -0
  266. package/skills/hallmark/scripts/refcheck.mjs +352 -0
  267. package/skills/hallmark/scripts/sloplint-render.mjs +1252 -0
  268. package/skills/hallmark/scripts/sloplint.mjs +4422 -0
  269. package/skills/hallmark/scripts/theme.mjs +650 -0
  270. package/skills/harness/SKILL.md +15 -8
  271. package/skills/i-have-adhd/SKILL.md +22 -11
  272. package/skills/no-ai-slop/SKILL.md +15 -1
  273. package/skills/plan-add/SKILL.md +33 -26
  274. package/skills/plan-status/SKILL.md +13 -7
  275. package/skills/plan-sync/SKILL.md +18 -12
  276. package/skills/pm-frameworks/SKILL.md +19 -10
  277. package/skills/pm-frameworks/SOURCE +7 -5
  278. package/skills/ponytail/SKILL.md +19 -14
  279. package/skills/product-analysis/SKILL.md +22 -18
  280. package/skills/product-flow/SKILL.md +14 -9
  281. package/skills/research/SKILL.md +75 -39
  282. package/skills/rl-env/SKILL.md +25 -13
  283. package/skills/rl-env/SOURCE +8 -6
  284. package/skills/tezgah-contract/SKILL.md +47 -42
  285. package/bin/tezgah-skill.py +0 -59
  286. /package/skills/ai-research/0-autoresearch-skill/{SKILL.md → ENTRY.md} +0 -0
  287. /package/skills/ai-research/01-model-architecture/litgpt/{SKILL.md → ENTRY.md} +0 -0
  288. /package/skills/ai-research/01-model-architecture/mamba/{SKILL.md → ENTRY.md} +0 -0
  289. /package/skills/ai-research/01-model-architecture/nanogpt/{SKILL.md → ENTRY.md} +0 -0
  290. /package/skills/ai-research/01-model-architecture/rwkv/{SKILL.md → ENTRY.md} +0 -0
  291. /package/skills/ai-research/01-model-architecture/torchtitan/{SKILL.md → ENTRY.md} +0 -0
  292. /package/skills/ai-research/02-tokenization/huggingface-tokenizers/{SKILL.md → ENTRY.md} +0 -0
  293. /package/skills/ai-research/02-tokenization/sentencepiece/{SKILL.md → ENTRY.md} +0 -0
  294. /package/skills/ai-research/03-fine-tuning/axolotl/{SKILL.md → ENTRY.md} +0 -0
  295. /package/skills/ai-research/03-fine-tuning/llama-factory/{SKILL.md → ENTRY.md} +0 -0
  296. /package/skills/ai-research/03-fine-tuning/peft/{SKILL.md → ENTRY.md} +0 -0
  297. /package/skills/ai-research/03-fine-tuning/unsloth/{SKILL.md → ENTRY.md} +0 -0
  298. /package/skills/ai-research/04-mechanistic-interpretability/nnsight/{SKILL.md → ENTRY.md} +0 -0
  299. /package/skills/ai-research/04-mechanistic-interpretability/pyvene/{SKILL.md → ENTRY.md} +0 -0
  300. /package/skills/ai-research/04-mechanistic-interpretability/saelens/{SKILL.md → ENTRY.md} +0 -0
  301. /package/skills/ai-research/04-mechanistic-interpretability/transformer-lens/{SKILL.md → ENTRY.md} +0 -0
  302. /package/skills/ai-research/05-data-processing/nemo-curator/{SKILL.md → ENTRY.md} +0 -0
  303. /package/skills/ai-research/05-data-processing/ray-data/{SKILL.md → ENTRY.md} +0 -0
  304. /package/skills/ai-research/06-post-training/grpo-rl-training/{SKILL.md → ENTRY.md} +0 -0
  305. /package/skills/ai-research/06-post-training/miles/{SKILL.md → ENTRY.md} +0 -0
  306. /package/skills/ai-research/06-post-training/openrlhf/{SKILL.md → ENTRY.md} +0 -0
  307. /package/skills/ai-research/06-post-training/simpo/{SKILL.md → ENTRY.md} +0 -0
  308. /package/skills/ai-research/06-post-training/slime/{SKILL.md → ENTRY.md} +0 -0
  309. /package/skills/ai-research/06-post-training/torchforge/{SKILL.md → ENTRY.md} +0 -0
  310. /package/skills/ai-research/06-post-training/trl-fine-tuning/{SKILL.md → ENTRY.md} +0 -0
  311. /package/skills/ai-research/06-post-training/verl/{SKILL.md → ENTRY.md} +0 -0
  312. /package/skills/ai-research/07-safety-alignment/constitutional-ai/{SKILL.md → ENTRY.md} +0 -0
  313. /package/skills/ai-research/07-safety-alignment/llamaguard/{SKILL.md → ENTRY.md} +0 -0
  314. /package/skills/ai-research/07-safety-alignment/nemo-guardrails/{SKILL.md → ENTRY.md} +0 -0
  315. /package/skills/ai-research/07-safety-alignment/prompt-guard/{SKILL.md → ENTRY.md} +0 -0
  316. /package/skills/ai-research/08-distributed-training/accelerate/{SKILL.md → ENTRY.md} +0 -0
  317. /package/skills/ai-research/08-distributed-training/deepspeed/{SKILL.md → ENTRY.md} +0 -0
  318. /package/skills/ai-research/08-distributed-training/megatron-core/{SKILL.md → ENTRY.md} +0 -0
  319. /package/skills/ai-research/08-distributed-training/pytorch-fsdp2/{SKILL.md → ENTRY.md} +0 -0
  320. /package/skills/ai-research/08-distributed-training/pytorch-lightning/{SKILL.md → ENTRY.md} +0 -0
  321. /package/skills/ai-research/08-distributed-training/ray-train/{SKILL.md → ENTRY.md} +0 -0
  322. /package/skills/ai-research/09-infrastructure/lambda-labs/{SKILL.md → ENTRY.md} +0 -0
  323. /package/skills/ai-research/09-infrastructure/modal/{SKILL.md → ENTRY.md} +0 -0
  324. /package/skills/ai-research/09-infrastructure/skypilot/{SKILL.md → ENTRY.md} +0 -0
  325. /package/skills/ai-research/10-optimization/awq/{SKILL.md → ENTRY.md} +0 -0
  326. /package/skills/ai-research/10-optimization/bitsandbytes/{SKILL.md → ENTRY.md} +0 -0
  327. /package/skills/ai-research/10-optimization/flash-attention/{SKILL.md → ENTRY.md} +0 -0
  328. /package/skills/ai-research/10-optimization/gguf/{SKILL.md → ENTRY.md} +0 -0
  329. /package/skills/ai-research/10-optimization/gptq/{SKILL.md → ENTRY.md} +0 -0
  330. /package/skills/ai-research/10-optimization/hqq/{SKILL.md → ENTRY.md} +0 -0
  331. /package/skills/ai-research/10-optimization/ml-training-recipes/{SKILL.md → ENTRY.md} +0 -0
  332. /package/skills/ai-research/11-evaluation/bigcode-evaluation-harness/{SKILL.md → ENTRY.md} +0 -0
  333. /package/skills/ai-research/11-evaluation/lm-evaluation-harness/{SKILL.md → ENTRY.md} +0 -0
  334. /package/skills/ai-research/11-evaluation/nemo-evaluator/{SKILL.md → ENTRY.md} +0 -0
  335. /package/skills/ai-research/12-inference-serving/llama-cpp/{SKILL.md → ENTRY.md} +0 -0
  336. /package/skills/ai-research/12-inference-serving/sglang/{SKILL.md → ENTRY.md} +0 -0
  337. /package/skills/ai-research/12-inference-serving/tensorrt-llm/{SKILL.md → ENTRY.md} +0 -0
  338. /package/skills/ai-research/12-inference-serving/vllm/{SKILL.md → ENTRY.md} +0 -0
  339. /package/skills/ai-research/13-mlops/mlflow/{SKILL.md → ENTRY.md} +0 -0
  340. /package/skills/ai-research/13-mlops/swanlab/{SKILL.md → ENTRY.md} +0 -0
  341. /package/skills/ai-research/13-mlops/tensorboard/{SKILL.md → ENTRY.md} +0 -0
  342. /package/skills/ai-research/13-mlops/weights-and-biases/{SKILL.md → ENTRY.md} +0 -0
  343. /package/skills/ai-research/14-agents/a-evolve/{SKILL.md → ENTRY.md} +0 -0
  344. /package/skills/ai-research/14-agents/autogpt/{SKILL.md → ENTRY.md} +0 -0
  345. /package/skills/ai-research/14-agents/crewai/{SKILL.md → ENTRY.md} +0 -0
  346. /package/skills/ai-research/14-agents/langchain/{SKILL.md → ENTRY.md} +0 -0
  347. /package/skills/ai-research/14-agents/llamaindex/{SKILL.md → ENTRY.md} +0 -0
  348. /package/skills/ai-research/15-rag/chroma/{SKILL.md → ENTRY.md} +0 -0
  349. /package/skills/ai-research/15-rag/faiss/{SKILL.md → ENTRY.md} +0 -0
  350. /package/skills/ai-research/15-rag/pinecone/{SKILL.md → ENTRY.md} +0 -0
  351. /package/skills/ai-research/15-rag/qdrant/{SKILL.md → ENTRY.md} +0 -0
  352. /package/skills/ai-research/15-rag/sentence-transformers/{SKILL.md → ENTRY.md} +0 -0
  353. /package/skills/ai-research/16-prompt-engineering/dspy/{SKILL.md → ENTRY.md} +0 -0
  354. /package/skills/ai-research/16-prompt-engineering/guidance/{SKILL.md → ENTRY.md} +0 -0
  355. /package/skills/ai-research/16-prompt-engineering/instructor/{SKILL.md → ENTRY.md} +0 -0
  356. /package/skills/ai-research/16-prompt-engineering/outlines/{SKILL.md → ENTRY.md} +0 -0
  357. /package/skills/ai-research/17-observability/langsmith/{SKILL.md → ENTRY.md} +0 -0
  358. /package/skills/ai-research/17-observability/phoenix/{SKILL.md → ENTRY.md} +0 -0
  359. /package/skills/ai-research/18-multimodal/audiocraft/{SKILL.md → ENTRY.md} +0 -0
  360. /package/skills/ai-research/18-multimodal/blip-2/{SKILL.md → ENTRY.md} +0 -0
  361. /package/skills/ai-research/18-multimodal/clip/{SKILL.md → ENTRY.md} +0 -0
  362. /package/skills/ai-research/18-multimodal/cosmos-policy/{SKILL.md → ENTRY.md} +0 -0
  363. /package/skills/ai-research/18-multimodal/llava/{SKILL.md → ENTRY.md} +0 -0
  364. /package/skills/ai-research/18-multimodal/openpi/{SKILL.md → ENTRY.md} +0 -0
  365. /package/skills/ai-research/18-multimodal/openvla-oft/{SKILL.md → ENTRY.md} +0 -0
  366. /package/skills/ai-research/18-multimodal/segment-anything/{SKILL.md → ENTRY.md} +0 -0
  367. /package/skills/ai-research/18-multimodal/stable-diffusion/{SKILL.md → ENTRY.md} +0 -0
  368. /package/skills/ai-research/18-multimodal/whisper/{SKILL.md → ENTRY.md} +0 -0
  369. /package/skills/ai-research/19-emerging-techniques/knowledge-distillation/{SKILL.md → ENTRY.md} +0 -0
  370. /package/skills/ai-research/19-emerging-techniques/long-context/{SKILL.md → ENTRY.md} +0 -0
  371. /package/skills/ai-research/19-emerging-techniques/model-merging/{SKILL.md → ENTRY.md} +0 -0
  372. /package/skills/ai-research/19-emerging-techniques/model-pruning/{SKILL.md → ENTRY.md} +0 -0
  373. /package/skills/ai-research/19-emerging-techniques/moe-training/{SKILL.md → ENTRY.md} +0 -0
  374. /package/skills/ai-research/19-emerging-techniques/speculative-decoding/{SKILL.md → ENTRY.md} +0 -0
  375. /package/skills/ai-research/20-ml-paper-writing/academic-plotting/{SKILL.md → ENTRY.md} +0 -0
  376. /package/skills/ai-research/20-ml-paper-writing/ml-paper-writing/{SKILL.md → ENTRY.md} +0 -0
  377. /package/skills/ai-research/20-ml-paper-writing/presenting-conference-talks/{SKILL.md → ENTRY.md} +0 -0
  378. /package/skills/ai-research/20-ml-paper-writing/systems-paper-writing/{SKILL.md → ENTRY.md} +0 -0
  379. /package/skills/ai-research/21-research-ideation/brainstorming-research-ideas/{SKILL.md → ENTRY.md} +0 -0
  380. /package/skills/ai-research/21-research-ideation/creative-thinking-for-research/{SKILL.md → ENTRY.md} +0 -0
  381. /package/skills/ai-research/22-agent-native-research-artifact/compiler/{SKILL.md → ENTRY.md} +0 -0
  382. /package/skills/ai-research/22-agent-native-research-artifact/research-manager/{SKILL.md → ENTRY.md} +0 -0
  383. /package/skills/ai-research/22-agent-native-research-artifact/rigor-reviewer/{SKILL.md → ENTRY.md} +0 -0
  384. /package/skills/design-library/adaptive-interfaces/skills/colour-independence/{SKILL.md → ENTRY.md} +0 -0
  385. /package/skills/design-library/adaptive-interfaces/skills/flexible-typography/{SKILL.md → ENTRY.md} +0 -0
  386. /package/skills/design-library/adaptive-interfaces/skills/information-density/{SKILL.md → ENTRY.md} +0 -0
  387. /package/skills/design-library/adaptive-interfaces/skills/preference-audit/{SKILL.md → ENTRY.md} +0 -0
  388. /package/skills/design-library/adaptive-interfaces/skills/responsive-accessibility/{SKILL.md → ENTRY.md} +0 -0
  389. /package/skills/design-library/adaptive-interfaces/skills/responsive-review/{SKILL.md → ENTRY.md} +0 -0
  390. /package/skills/design-library/adaptive-interfaces/skills/simplified-views/{SKILL.md → ENTRY.md} +0 -0
  391. /package/skills/design-library/adaptive-interfaces/skills/specify/{SKILL.md → ENTRY.md} +0 -0
  392. /package/skills/design-library/adaptive-interfaces/skills/user-preference-respect/{SKILL.md → ENTRY.md} +0 -0
  393. /package/skills/design-library/cognitive-accessibility/skills/adaptive-personalisation/{SKILL.md → ENTRY.md} +0 -0
  394. /package/skills/design-library/cognitive-accessibility/skills/assess-load/{SKILL.md → ENTRY.md} +0 -0
  395. /package/skills/design-library/cognitive-accessibility/skills/cognitive-load-assessment/{SKILL.md → ENTRY.md} +0 -0
  396. /package/skills/design-library/cognitive-accessibility/skills/contextual-help-design/{SKILL.md → ENTRY.md} +0 -0
  397. /package/skills/design-library/cognitive-accessibility/skills/error-prevention-recovery/{SKILL.md → ENTRY.md} +0 -0
  398. /package/skills/design-library/cognitive-accessibility/skills/focus-attention-design/{SKILL.md → ENTRY.md} +0 -0
  399. /package/skills/design-library/cognitive-accessibility/skills/memory-load-reduction/{SKILL.md → ENTRY.md} +0 -0
  400. /package/skills/design-library/cognitive-accessibility/skills/plain-language-design/{SKILL.md → ENTRY.md} +0 -0
  401. /package/skills/design-library/cognitive-accessibility/skills/review/{SKILL.md → ENTRY.md} +0 -0
  402. /package/skills/design-library/cognitive-accessibility/skills/simplify/{SKILL.md → ENTRY.md} +0 -0
  403. /package/skills/design-library/cognitive-accessibility/skills/wayfinding-navigation/{SKILL.md → ENTRY.md} +0 -0
  404. /package/skills/design-library/design-research/skills/behavioural-analytics/{SKILL.md → ENTRY.md} +0 -0
  405. /package/skills/design-library/design-research/skills/qual-quant-triangulation/{SKILL.md → ENTRY.md} +0 -0
  406. /package/skills/design-library/inclusive-interaction/skills/audit/{SKILL.md → ENTRY.md} +0 -0
  407. /package/skills/design-library/inclusive-interaction/skills/design-flow/{SKILL.md → ENTRY.md} +0 -0
  408. /package/skills/design-library/inclusive-interaction/skills/feedback-and-status/{SKILL.md → ENTRY.md} +0 -0
  409. /package/skills/design-library/inclusive-interaction/skills/gesture-alternatives/{SKILL.md → ENTRY.md} +0 -0
  410. /package/skills/design-library/inclusive-interaction/skills/keyboard-navigation/{SKILL.md → ENTRY.md} +0 -0
  411. /package/skills/design-library/inclusive-interaction/skills/keyboard-review/{SKILL.md → ENTRY.md} +0 -0
  412. /package/skills/design-library/inclusive-interaction/skills/motion-sensitivity/{SKILL.md → ENTRY.md} +0 -0
  413. /package/skills/design-library/inclusive-interaction/skills/multi-modal-input/{SKILL.md → ENTRY.md} +0 -0
  414. /package/skills/design-library/inclusive-interaction/skills/touch-target-design/{SKILL.md → ENTRY.md} +0 -0
  415. /package/skills/design-library/inclusive-interaction/skills/voice-interaction/{SKILL.md → ENTRY.md} +0 -0
  416. /package/skills/design-library/visual-critique/skills/critique-affordance/{SKILL.md → ENTRY.md} +0 -0
  417. /package/skills/design-library/visual-critique/skills/critique-brand-consistency/{SKILL.md → ENTRY.md} +0 -0
  418. /package/skills/design-library/visual-critique/skills/critique-color/{SKILL.md → ENTRY.md} +0 -0
  419. /package/skills/design-library/visual-critique/skills/critique-composition/{SKILL.md → ENTRY.md} +0 -0
  420. /package/skills/design-library/visual-critique/skills/critique-information-density/{SKILL.md → ENTRY.md} +0 -0
  421. /package/skills/design-library/visual-critique/skills/critique-typography/{SKILL.md → ENTRY.md} +0 -0
  422. /package/skills/design-library/visual-critique/skills/critique-visual-hierarchy/{SKILL.md → ENTRY.md} +0 -0
  423. /package/skills/pm-frameworks/intended-vs-implemented/{SKILL.md → ENTRY.md} +0 -0
  424. /package/skills/pm-frameworks/opportunity-solution-tree/{SKILL.md → ENTRY.md} +0 -0
  425. /package/skills/rl-env/generate-nemo-gym-env/{SKILL.md → ENTRY.md} +0 -0
  426. /package/skills/rl-env/generate-openenv-env/{SKILL.md → ENTRY.md} +0 -0
  427. /package/skills/rl-env/generate-ors-env/{SKILL.md → ENTRY.md} +0 -0
  428. /package/skills/rl-env/generate-verifiers-env/{SKILL.md → ENTRY.md} +0 -0
  429. /package/skills/rl-env/rl-env-from-description/{SKILL.md → ENTRY.md} +0 -0
package/README.de.md CHANGED
@@ -49,7 +49,7 @@ auf dieselbe Weise.
49
49
  - **Forschung kommt mit eigener Bibliothek.** Forschungsaufgaben laufen über
50
50
  OpenResearch, mit einer integrierten Bibliothek aus 98 Upstream-Skills, die
51
51
  Eintrag für Eintrag geladen wird, damit der Kontext klein bleibt.
52
- - **Jede Regel hat einen Ausschalter.** Sechzehn Kill-Switches — dazu
52
+ - **Jede Regel hat einen Ausschalter.** Siebzehn Kill-Switches — dazu
53
53
  Repo-Markierungen — entfernen den Regeltext aus der Sitzung; die Regel
54
54
  stoppt damit wirklich, statt nur als aus zu erscheinen.
55
55
  - **Eine feste Antwortform.** Antworten sind türkisch, sofern Sie keine andere Sprache wählen, und
package/README.es.md CHANGED
@@ -49,7 +49,7 @@ en un lugar llega a todos los hosts de la misma manera.
49
49
  dirigen a través de OpenResearch con una biblioteca incorporada de 98
50
50
  habilidades upstream, cargada de una en una para que el contexto siga
51
51
  siendo pequeño.
52
- - **Cada regla tiene un interruptor de apagado.** Dieciséis interruptores — más
52
+ - **Cada regla tiene un interruptor de apagado.** Diecisiete interruptores — más
53
53
  las marcas por repositorio — eliminan el texto de la regla de la sesión, de
54
54
  modo que la regla realmente se detiene en lugar de limitarse a figurar como
55
55
  desactivada.
package/README.fr.md CHANGED
@@ -48,7 +48,7 @@ modifiée à un endroit atteint chaque hôte de la même façon.
48
48
  - **La recherche arrive avec sa bibliothèque.** Les tâches de recherche
49
49
  passent par OpenResearch avec une bibliothèque intégrée de 98 compétences
50
50
  upstream, chargée une entrée à la fois pour que le contexte reste petit.
51
- - **Chaque règle a un interrupteur.** Seize interrupteurs — plus des
51
+ - **Chaque règle a un interrupteur.** Dix-sept interrupteurs — plus des
52
52
  marques par dépôt — retirent le texte de la règle de la session ; la règle
53
53
  s'arrête vraiment au lieu de simplement figurer comme désactivée.
54
54
  - **Une forme de réponse fixe.** Les réponses sont en turc, sauf si vous choisissez une autre langue, et
package/README.md CHANGED
@@ -46,7 +46,7 @@ reaches every host the same way.
46
46
  - **Research ships with its library.** Research tasks route through
47
47
  OpenResearch with a vendored library of 98 upstream skills, loaded one entry
48
48
  at a time so the context stays small.
49
- - **Every rule has an off switch.** Sixteen kill switches — plus per-repo
49
+ - **Every rule has an off switch.** Seventeen kill switches — plus per-repo
50
50
  marks — remove a rule's text from the session, so the rule actually stops
51
51
  rather than merely showing as off.
52
52
  - **A fixed reply shape.** Replies lead with the outcome, in Turkish unless
package/README.tr.md CHANGED
@@ -48,7 +48,7 @@ değiştirdiğinizde her barındırıcıya aynı şekilde ulaşır.
48
48
  - **Araştırma kütüphanesiyle birlikte gelir.** Araştırma görevleri,
49
49
  bağlamın küçük kalması için tek tek yüklenen 98 becerilik gömülü
50
50
  bir kütüphaneyle OpenResearch üzerinden yürütülür.
51
- - **Her kuralın bir kapatma anahtarı vardır.** On altı kapatma anahtarı — ve
51
+ - **Her kuralın bir kapatma anahtarı vardır.** On yedi kapatma anahtarı — ve
52
52
  depo başına işaretler — kuralın metnini oturumdan kaldırır; böylece kural
53
53
  yalnızca kapalı görünmez, gerçekten durur.
54
54
  - **Sabit bir yanıt biçimi.** Yanıtlar, başka bir dil seçmediyseniz Türkçedir ve sonuçla
package/bin/codegen CHANGED
@@ -49,7 +49,7 @@ import urllib.request
49
49
  import json
50
50
 
51
51
  HOOKS = os.path.join(
52
- os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "hooks")
52
+ os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "hooks")
53
53
  sys.path.insert(0, HOOKS)
54
54
  import tezgah_integrity as ti # noqa: E402
55
55
  import tezgah_paths as tp # noqa: E402
@@ -220,7 +220,10 @@ def ask(task, files, model, provider, timeout, max_tokens):
220
220
 
221
221
  def main():
222
222
  args = sys.argv[1:]
223
- if not args or args[0] in ("-h", "--help"):
223
+ if args and args[0] in ("-h", "--help"):
224
+ print(__doc__.strip())
225
+ return
226
+ if not args:
224
227
  sys.exit(__doc__.strip())
225
228
  task, files, model, provider, timeout, out_dir, max_tokens = \
226
229
  args[0], [], None, "openrouter", 300, None, 0
package/bin/tezgah-design CHANGED
@@ -4,12 +4,20 @@ can fail.
4
4
 
5
5
  tezgah-design derive --repo DIR [--out FILE] [--json]
6
6
  tezgah-design check --contract FILE --measured FILE|- [--json]
7
+ tezgah-design slop --repo DIR [--url URL] [--render] [--measured FILE]
8
+ [--out FILE] [--json]
7
9
 
8
10
  The contract is the floor a UI turn is judged against: the colour roles, the
9
11
  type scale, the spacing unit and the state set a repository already uses, plus
10
12
  the component inventory it owns. `derive` writes a first `.tezgah/design-contract.md`
11
13
  from the repository's own token source (CSS custom properties, a Tailwind config,
12
14
  a tokens/theme JSON) and exits 2 rather than invent a palette it did not find.
15
+ `slop` runs Hallmark's own gate list (`skills/hallmark/scripts/sloplint.mjs`)
16
+ over the repository or a running URL, writes the verdict to
17
+ `.tezgah/design/slop.json` and exits 1 on any Floor FAIL. It is the Hallmark half
18
+ of the UI floor; `check` is ours, and a contract's `precedence` says which of the
19
+ two owns each key, so neither can quietly override the other. Exit 3 when Node or
20
+ the vendored skill is missing: that is a check that did not run, never a pass.
13
21
  `check` compares a measurement - the per-component computed styles and observed
14
22
  states the analyze-app loop produces - against that file, prints every violation
15
23
  with its component and its rule, and exits non-zero when there is at least one.
@@ -26,8 +34,11 @@ repository in the artifact.
26
34
  more violations; 2 usage, IO, a bad contract or nothing judged
27
35
  """
28
36
  import json
37
+ import math
29
38
  import os
30
39
  import re
40
+ import shutil
41
+ import subprocess
31
42
  import sys
32
43
 
33
44
  HERE = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
@@ -51,6 +62,15 @@ KINDS = ("interactive", "data")
51
62
  # The floors that are not this repository's to choose: WCAG 2.2 SC 2.5.8 (the
52
63
  # 24x24 CSS px target size) and SC 1.4.3 (4.5:1, or 3:1 for large text, which is
53
64
  # 24px and up, or 18.66px bold).
65
+ # The precedence table (plan 133). A key owned by two sources is refused by
66
+ # `check`, so the tie-break cannot drift silently; `verbatim` says how far the
67
+ # user's own words reach, and it stops at style.
68
+ PRECEDENCE = {
69
+ "ours": ["states", "components", "evidence", "facts"],
70
+ "theirs": ["material", "motion-character"],
71
+ "shared": ["contrast", "focus-visible", "reduced-motion", "tap-target"],
72
+ "verbatim": "style",
73
+ }
54
74
  TAP_TARGET = 24
55
75
  CONTRAST_NORMAL = 4.5
56
76
  CONTRAST_LARGE = 3.0
@@ -506,9 +526,89 @@ def css_tokens(root, files):
506
526
  return out, sources
507
527
 
508
528
 
529
+ DESIGN_MD = ("design.md", "DESIGN.md")
530
+
531
+
532
+ def _oklch_to_hex(value):
533
+ """`oklch(L C H [/ A])` as `#rrggbb`, or None when it is not that shape.
534
+
535
+ Hallmark's locked system states its palette in OKLCH; the contract compares
536
+ measured colours as hex, so one side has to be converted and it is this one.
537
+ The conversion is Ottosson's OKLab -> linear sRGB with a clamp at the gamut,
538
+ which is what a browser paints for the same value."""
539
+ body = value.strip()
540
+ if not body.lower().startswith("oklch("):
541
+ return None
542
+ inner = body[body.index("(") + 1:body.rindex(")")]
543
+ inner = inner.split("/")[0]
544
+ parts = [p for p in re.split(r"[\s,]+", inner.strip()) if p]
545
+ if len(parts) < 3:
546
+ return None
547
+ try:
548
+ light = parts[0]
549
+ lum = float(light[:-1]) / 100.0 if light.endswith("%") else float(light)
550
+ c = float(parts[1])
551
+ hue = parts[2]
552
+ h = float(hue[:-3]) if hue.endswith("deg") else float(hue)
553
+ except ValueError:
554
+ return None
555
+ rad = math.radians(h)
556
+ a_, b_ = c * math.cos(rad), c * math.sin(rad)
557
+ l_ = (lum + 0.3963377774 * a_ + 0.2158037573 * b_) ** 3
558
+ m_ = (lum - 0.1055613458 * a_ - 0.0638541728 * b_) ** 3
559
+ s_ = (lum - 0.0894841775 * a_ - 1.2914855480 * b_) ** 3
560
+ r = 4.0767416621 * l_ - 3.3077115913 * m_ + 0.2309699292 * s_
561
+ g = -1.2684380046 * l_ + 2.6097574011 * m_ - 0.3413193965 * s_
562
+ bl = -0.0041960863 * l_ - 0.7034186147 * m_ + 1.7076147010 * s_
563
+
564
+ def gamma(x):
565
+ x = min(1.0, max(0.0, x))
566
+ return 12.92 * x if x <= 0.0031308 else 1.055 * x ** (1 / 2.4) - 0.055
567
+ return "#%02x%02x%02x" % tuple(int(round(gamma(v) * 255)) for v in (r, g, bl))
568
+
569
+
570
+ def design_md_tokens(root):
571
+ """(tokens, source) from Hallmark's locked `design.md`, or ({}, "").
572
+
573
+ Hallmark's file owns the material: the palette stated in OKLCH, the font
574
+ roles and the motion character. It owns no state set, no component
575
+ inventory and no measured evidence, which stay the contract's, so reading it
576
+ fills the tokens half and leaves the rest to `contract_data`."""
577
+ for name in DESIGN_MD:
578
+ path = os.path.join(root, name)
579
+ if not os.path.isfile(path):
580
+ continue
581
+ text = open(path, encoding="utf-8", errors="replace").read()
582
+ block = re.search(r"```css\s*(.*?)```", text, re.S)
583
+ if not block:
584
+ continue
585
+ colors, fonts = {}, {}
586
+ for var, value in re.findall(r"--([a-z0-9-]+)\s*:\s*([^;]+);", block.group(1)):
587
+ value = value.strip()
588
+ if var.startswith("color-"):
589
+ role = var[len("color-"):]
590
+ hexv = _oklch_to_hex(value) if value.lower().startswith("oklch(") else (
591
+ value if re.fullmatch(r"#[0-9a-fA-F]{3,8}", value) else None)
592
+ if hexv:
593
+ colors[role] = hexv
594
+ elif var.startswith("font-"):
595
+ fonts[var[len("font-"):]] = value
596
+ if colors:
597
+ tokens = {"colors": colors}
598
+ if fonts:
599
+ tokens["fonts"] = fonts
600
+ return tokens, "design-md"
601
+ return {}, ""
602
+
603
+
509
604
  def derive(root):
510
605
  """(tokens, source, read from) from the repository's own token source, or
511
606
  (None, reason, []) when it carries none."""
607
+ locked, locked_source = design_md_tokens(root)
608
+ if locked.get("colors"):
609
+ # a locked system wins over a re-derivation: pages share it, and a second
610
+ # floor derived beside it is the drift plan 133 exists to prevent
611
+ return locked, locked_source, [os.path.join(root, "design.md")]
512
612
  files = walk(root)
513
613
  for name, reader in (("css-custom-properties", css_tokens),
514
614
  ("tailwind-config", tailwind_tokens),
@@ -532,10 +632,19 @@ def contract_data(tokens, source):
532
632
  "colors": tokens.get("colors") or {},
533
633
  "tap_target": TAP_TARGET,
534
634
  "contrast": {"normal": CONTRAST_NORMAL, "large": CONTRAST_LARGE},
635
+ # Hallmark's design.md states the font roles; nothing else does, so
636
+ # they ride the tokens when it is the source (audit of plan 133)
637
+ **({"fonts": tokens["fonts"]} if tokens.get("fonts") else {}),
535
638
  },
536
639
  "states": {"interactive": list(STATES_INTERACTIVE),
537
640
  "data": list(STATES_DATA)},
538
641
  "components": [],
642
+ # plan 133: one machine-read precedence between this contract and
643
+ # Hallmark's design.md, so the two floors cannot drift. `ours` is what a
644
+ # Hallmark stamp, waiver or verbatim flag can never relax; `theirs` is
645
+ # the material we do not judge; `shared` states the same intent on both
646
+ # sides, our numbers and their shapes.
647
+ "precedence": dict(PRECEDENCE),
539
648
  }
540
649
 
541
650
 
@@ -614,6 +723,40 @@ def _violation(component, rule, detail):
614
723
  return {"component": component, "rule": rule, "detail": detail}
615
724
 
616
725
 
726
+ def precedence_problem(table):
727
+ """Why a contract's precedence cannot be read, or "" when it can.
728
+
729
+ Plan 133: the table is the only tie-break between this floor and Hallmark's
730
+ design.md, so an ambiguous one is refused rather than resolved by whoever
731
+ reads it next. Absent is allowed - a contract written before the table
732
+ existed keeps working - but a present one must name every key exactly once
733
+ and must not hand `facts` to the user's own words."""
734
+ if table is None:
735
+ return ""
736
+ if not isinstance(table, dict):
737
+ return "precedence must be an object of classes to keys"
738
+ seen = {}
739
+ for cls in ("ours", "theirs", "shared"):
740
+ keys = table.get(cls)
741
+ if keys is None:
742
+ continue
743
+ if not isinstance(keys, list) or not all(isinstance(k, str) for k in keys):
744
+ return "precedence.%s must be a list of key names" % cls
745
+ for key in keys:
746
+ if key in seen:
747
+ return ("precedence names %r twice (%s and %s): one key belongs "
748
+ "to one source" % (key, seen[key], cls))
749
+ seen[key] = cls
750
+ if "facts" in table.get("theirs", []) or "facts" in table.get("shared", []):
751
+ return ("precedence cannot share `facts`: an invented metric, quote or "
752
+ "logo is never licensed by a theme, a waiver or the user's words")
753
+ verbatim = table.get("verbatim")
754
+ if verbatim not in (None, "style"):
755
+ return ("precedence.verbatim may only be `style`: the user's own words "
756
+ "excuse a style gate, never a fabricated fact")
757
+ return ""
758
+
759
+
617
760
  def check(data, measured):
618
761
  """(violations, unjudged, judged): every disagreement between a measurement
619
762
  and the contract, each naming its component and its rule, the count of
@@ -806,6 +949,8 @@ def parse(argv, names):
806
949
  arg = argv[i]
807
950
  if arg == "--json":
808
951
  out["json"] = True
952
+ elif arg == "--render":
953
+ out["render"] = True
809
954
  elif arg in names:
810
955
  if i + 1 >= len(argv):
811
956
  raise Usage("%s wants a value" % arg)
@@ -881,6 +1026,140 @@ def derive_cli(opts):
881
1026
  return 0
882
1027
 
883
1028
 
1029
+ SLOPLINT = os.path.join("skills", "hallmark", "scripts", "sloplint.mjs")
1030
+
1031
+
1032
+ def sloplint_path(root):
1033
+ """The vendored linter's path, or "" when it is not installed beside us."""
1034
+ # `HERE` is the realpath of this script's checkout: `abspath(__file__)` is
1035
+ # the symlink in `~/.config/tezgah/bin` under an install, so the linter was
1036
+ # looked for in `~/.config/tezgah/skills/...`, which no install writes
1037
+ # (audit of plan 133). `root`'s own copy comes first for a vendored checkout.
1038
+ candidates = [
1039
+ os.path.join(root, SLOPLINT),
1040
+ os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(root))), SLOPLINT),
1041
+ os.path.join(HERE, SLOPLINT),
1042
+ ]
1043
+ for path in candidates:
1044
+ if os.path.isfile(path):
1045
+ return path
1046
+ return ""
1047
+
1048
+
1049
+ def slop_cli(opts):
1050
+ """Hallmark's gate list, run over this repository, into one verdict.
1051
+
1052
+ The Floor is theirs and Ours is the contract's, so this verb is the one place
1053
+ the two are merged: `sloplint --json` gives FAIL/REFLEX, and the contract's
1054
+ `check` runs when a measurement is given. A merge that hides one side would
1055
+ make a page pass here and fail in the Stop rule, so the verdict is the union
1056
+ and it is written down (`.tezgah/design/slop.json`) for that rule to read."""
1057
+ root = project_top(os.path.abspath(opts.get("repo") or ""))
1058
+ if not os.path.isdir(root):
1059
+ raise Usage("--repo must name a directory")
1060
+ linter = sloplint_path(root)
1061
+ if not linter:
1062
+ sys.stderr.write("tezgah-design: hallmark is not installed beside tezgah "
1063
+ "(%s), so only the contract check can run - no static "
1064
+ "slop tier this time\n" % SLOPLINT)
1065
+ return 3
1066
+ if not shutil.which("node"):
1067
+ sys.stderr.write("tezgah-design: node is not on PATH, so hallmark's "
1068
+ "sloplint cannot run - only the contract check can\n")
1069
+ return 3
1070
+ target = opts.get("url") or root
1071
+ argv = [shutil.which("node"), linter, "--json"]
1072
+ if opts.get("url"):
1073
+ argv += ["--url", opts["url"]] # a URL is an address, never a path
1074
+ else:
1075
+ argv.append(root)
1076
+ if opts.get("render"):
1077
+ argv.append("--render")
1078
+ if opts.get("genre"):
1079
+ argv += ["--genre", opts["genre"]]
1080
+ try:
1081
+ proc = subprocess.run(argv, capture_output=True, text=True, timeout=300)
1082
+ except (OSError, subprocess.SubprocessError) as exc:
1083
+ raise Usage("sloplint could not run: %s" % exc)
1084
+ try:
1085
+ report = json.loads(proc.stdout)
1086
+ except ValueError:
1087
+ raise Usage("sloplint printed no JSON (exit %d): %s"
1088
+ % (proc.returncode, (proc.stderr or "").strip()[:200]))
1089
+ summary = report.get("summary") or {}
1090
+ fails, reflex = int(summary.get("fails") or 0), int(summary.get("reflex") or 0)
1091
+ # What the render tier actually did, never what the flag asked for: without
1092
+ # puppeteer-core sloplint answers `not run: …` and every Floor/R and M/R gate
1093
+ # stays unjudged, so a `clean` there would excuse a page nobody measured
1094
+ # (review of plan 133 finding 2).
1095
+ rendered = str(summary.get("render") or "off")
1096
+ unjudged = rendered.startswith("not run")
1097
+ verdict = {"version": 1, "tool": "tezgah-design slop",
1098
+ "sloplint_exit": proc.returncode,
1099
+ "target": target if opts.get("url") else os.path.abspath(target),
1100
+ "render": rendered,
1101
+ "render_unjudged": unjudged,
1102
+ "fails": fails, "reflex": reflex,
1103
+ "waived": int(summary.get("waived") or 0),
1104
+ "answered": int(summary.get("answered") or 0),
1105
+ "clean": fails == 0 and reflex == 0 and not unjudged,
1106
+ "findings": [f for f in (report.get("findings") or [])
1107
+ if f.get("grade") in ("FAIL", "REFLEX")]}
1108
+ ws = linked_main(root) or root
1109
+ # The union, enforced here rather than in the Stop rule (review of plan 133
1110
+ # finding 3): a component's UI floor is Hallmark's gate list AND this
1111
+ # repository's contract, so `slop` reads the contract half too. No contract,
1112
+ # no obligation. A contract with no measurement is unjudged, never clean.
1113
+ contract_path = os.path.join(ws, ".tezgah", "design-contract.md")
1114
+ contract = {"present": os.path.isfile(contract_path), "judged": False,
1115
+ "violations": [], "unjudged": 0}
1116
+ if contract["present"]:
1117
+ data, reason = read_contract(contract_path)
1118
+ if data is None:
1119
+ raise Usage(reason)
1120
+ problem = precedence_problem(data.get("precedence"))
1121
+ if problem:
1122
+ raise Usage(problem)
1123
+ raw = ""
1124
+ measured_path = opts.get("measured") or os.path.join(
1125
+ ws, ".tezgah", "design", "measurement.json")
1126
+ if os.path.isfile(measured_path):
1127
+ with open(measured_path, encoding="utf-8") as fh:
1128
+ raw = fh.read()
1129
+ if raw.strip():
1130
+ try:
1131
+ got = json.loads(raw)
1132
+ except ValueError:
1133
+ raise Usage("the measurement is not JSON: %s" % measured_path)
1134
+ if isinstance(got, list):
1135
+ got = {"components": got} # the shape check_cli also accepts
1136
+ violations, unjudged, judged = check(data, got)
1137
+ contract.update(judged=judged > 0, unjudged=unjudged,
1138
+ violations=list(violations))
1139
+ verdict["contract"] = contract
1140
+ if contract["present"] and (not contract["judged"] or contract["violations"]):
1141
+ verdict["clean"] = False
1142
+ out = opts.get("out") or os.path.join(ws, ".tezgah", "design", "slop.json")
1143
+ try:
1144
+ os.makedirs(os.path.dirname(os.path.abspath(out)), exist_ok=True)
1145
+ with open(out, "w", encoding="utf-8") as fh:
1146
+ json.dump(verdict, fh, indent=2, sort_keys=True)
1147
+ fh.write("\n")
1148
+ except OSError as exc:
1149
+ raise Usage("cannot write %s: %s" % (out, exc))
1150
+ if opts.get("json"):
1151
+ _print_json(verdict)
1152
+ else:
1153
+ sys.stdout.write("slop: %d FAIL, %d REFLEX over %s (render %s) -> %s\n"
1154
+ % (fails, reflex, target, rendered,
1155
+ "clean" if verdict["clean"] else "not clean"))
1156
+ if contract["present"] and not contract["judged"]:
1157
+ sys.stderr.write("tezgah-design: the contract exists but no measurement "
1158
+ "judged a component, so the design half is unjudged - "
1159
+ "run the analyze-app loop and pass --measured\n")
1160
+ return 0 if verdict["clean"] and not contract["violations"] else 1
1161
+
1162
+
884
1163
  def check_cli(opts):
885
1164
  contract = opts.get("contract")
886
1165
  measured = opts.get("measured")
@@ -895,6 +1174,9 @@ def check_cli(opts):
895
1174
  data, reason = read_contract(contract)
896
1175
  if data is None:
897
1176
  raise Usage(reason)
1177
+ problem = precedence_problem(data.get("precedence"))
1178
+ if problem:
1179
+ raise Usage(problem)
898
1180
  if measured == "-":
899
1181
  raw = sys.stdin.read()
900
1182
  else:
@@ -954,12 +1236,17 @@ def main(argv):
954
1236
  sys.stdout.write(__doc__)
955
1237
  return 0 if argv else 2
956
1238
  verb, rest = argv[0], argv[1:]
1239
+ if verb in ("derive", "check") and "--render" in rest:
1240
+ sys.stderr.write("tezgah-design: --render belongs to `slop`, not %s\n" % verb)
1241
+ return 2
957
1242
  try:
958
1243
  if verb == "derive":
959
1244
  return derive_cli(parse(rest, ("--repo", "--out")))
960
1245
  if verb == "check":
961
1246
  return check_cli(parse(rest, ("--contract", "--measured")))
962
- raise Usage("unknown verb: %s (derive|check)" % verb)
1247
+ if verb == "slop":
1248
+ return slop_cli(parse(rest, ("--repo", "--url", "--out", "--genre", "--measured")))
1249
+ raise Usage("unknown verb: %s (derive|check|slop)" % verb)
963
1250
  except Usage as exc:
964
1251
  sys.stderr.write("tezgah-design: %s\n" % exc)
965
1252
  return 2
package/bin/tezgah-docs CHANGED
@@ -106,7 +106,7 @@ RUN = re.compile(r"((?:`[A-Za-z_][A-Za-z0-9_]*(?:\(\))?`\s*[/,]?\s*){1,5})$")
106
106
  CITE = re.compile(r"`([\w.-]+(?:/[\w.-]+)+|[\w-]+\.\w+):(\d+)(?:-(\d+))?`"
107
107
  r"|`(:(\d+)(?:-(\d+))?)`")
108
108
  # The symbol written after the citation instead of before it, the way a table
109
- # cell reads: `hooks/tezgah_policy.py:787-1105` (`CORE`).
109
+ # cell reads: `hooks/tezgah_policy.py:806-1135` (`CORE`).
110
110
  AFTER = re.compile(r"\s*\(`([A-Za-z_][A-Za-z0-9_]*)(?:\(\))?`\)")
111
111
  # Any `path:line`, backticked or not: what CITE does not match of these (a
112
112
  # bare token, a comma list `x.py:12,40`) is counted as unjudged, so a citation
package/bin/tezgah-doctor CHANGED
@@ -11,7 +11,9 @@ Two stores grow without bound and neither rotates on its own:
11
11
 
12
12
  It also reports the hosts' own state (~/.codex, ~/.omp, ~/.claude) and never
13
13
  touches it: those stores belong to the hosts, and the number is here so a reader
14
- can decide, not so this tool can act.
14
+ can decide, not so this tool can act. The current checkout's `.tezgah` shape is
15
+ one row: its own repository, or tracked by the project (folded), whose commits
16
+ are then the project's history.
15
17
 
16
18
  This tool is read-only by default. With --clean it vacuums the opencode database
17
19
  (only when opencode is not running, so it cannot fight a live connection).
@@ -65,7 +67,7 @@ HOME = os.path.expanduser("~")
65
67
  REPO_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
66
68
  sys.path.insert(0, os.path.join(REPO_ROOT, "hooks"))
67
69
  from tezgah_paths import (CACHE, CODEGRAPH, codegraph_bin, # noqa: E402
68
- fallback_cache, root_for, roots)
70
+ fallback_cache, project_top, root_for, roots, workspace)
69
71
 
70
72
  # the coverage rules, in the bench directory next to the hooks that own the roots
71
73
  # and the binary resolver. MANIFEST lists it, so it ships; it is also the one file
@@ -214,6 +216,37 @@ def opencode_running():
214
216
  return False
215
217
 
216
218
 
219
+ def workspace_shape(path):
220
+ """{repo, shape} for the checkout holding `path`: `own` when its `.tezgah`
221
+ holds a repository of its own (a linked worktree's link to the main
222
+ checkout's included), `tracked` when the project tracks it (folded:
223
+ `tezgah_research.folded`, the project's history carries it), else `none`;
224
+ repo is None outside a git checkout."""
225
+ import tezgah_research
226
+ try:
227
+ out = subprocess.run(["git", "-C", path, "rev-parse", "--show-toplevel"],
228
+ capture_output=True, text=True)
229
+ except OSError:
230
+ return {"repo": None, "shape": "none"}
231
+ if out.returncode or not out.stdout.strip():
232
+ return {"repo": None, "shape": "none"}
233
+ repo = project_top(out.stdout.strip())
234
+ if tezgah_research.folded(repo):
235
+ shape = "tracked"
236
+ elif os.path.isdir(os.path.join(os.path.realpath(workspace(repo)), ".git")):
237
+ shape = "own"
238
+ else:
239
+ shape = "none"
240
+ return {"repo": repo, "shape": shape}
241
+
242
+
243
+ WORKSPACE_ROWS = {
244
+ "own": "own repository (`git -C .tezgah`)",
245
+ "tracked": "tracked by the project: the project's history carries it",
246
+ "none": "none yet",
247
+ }
248
+
249
+
217
250
  def collect(pairs):
218
251
  cfg = opencode_cfg()
219
252
  repos = []
@@ -230,6 +263,7 @@ def collect(pairs):
230
263
  "codegraph_repos": repos,
231
264
  "codegraph_bytes": sum(r["bytes"] for r in repos),
232
265
  "tezgah_cache_bytes": du(TEZGAH_CACHE) if os.path.isdir(TEZGAH_CACHE) else 0,
266
+ "workspace": workspace_shape(os.getcwd()),
233
267
  **host_bytes(),
234
268
  }
235
269
 
@@ -571,6 +605,9 @@ def report(rep):
571
605
  len(rows) - indexed))
572
606
  print("tezgah")
573
607
  print(" cache %s" % human(rep["tezgah_cache_bytes"]))
608
+ ws = rep["workspace"]
609
+ print(" workspace %s" % ("%s (%s)" % (WORKSPACE_ROWS[ws["shape"]], ws["repo"])
610
+ if ws["repo"] else "not in a git checkout"))
574
611
  print("host state (the hosts' own; this tool never touches it)")
575
612
  for label, key in (("codex", "codex_bytes"), ("omp", "omp_bytes"),
576
613
  ("claude", "claude_bytes")):
@@ -9,8 +9,12 @@ upstream clone being present.
9
9
  bin/tezgah-import-ai-research --source <path-to-AI-research-SKILLs-clone> --rev 773a529
10
10
  bin/tezgah-import-ai-research --check
11
11
 
12
- A vendored path is its provenance, so the upstream layout is kept verbatim:
13
- `<category>/<skill>/SKILL.md` beside its `references/`. What is dropped, and why,
12
+ A vendored path is its provenance, so the upstream layout is kept verbatim, with
13
+ one rename: upstream's `<category>/<skill>/SKILL.md` is written as
14
+ `<category>/<skill>/ENTRY.md` beside its `references/`, bytes unchanged. codex
15
+ and Cursor list every SKILL.md below a skills directory, nested ones included,
16
+ so 98 vendored entries named SKILL.md would each be listed as a host skill and
17
+ push tezgah's own out of the host's skill budget. What is dropped, and why,
14
18
  is DROP_FILES and DROP_DIRS; everything that is not markdown is dropped by the
15
19
  `*.md` filter, so no PDF, LaTeX class, image or `.gitkeep` reaches the repo. A
16
20
  vendored file with no YAML frontmatter gets one attribution comment; upstream's
@@ -41,7 +45,7 @@ LICENCE = "MIT"
41
45
  EXPECTED_CATEGORIES, EXPECTED_SKILLS = 23, 98
42
46
 
43
47
  # Three machine-scraped reference dumps. They are concatenated official docs with
44
- # `URL:` headers, not guides, and the entry's own SKILL.md already distils them.
48
+ # `URL:` headers, not guides, and the entry's own ENTRY.md already distils them.
45
49
  DROP_FILES = (
46
50
  "03-fine-tuning/unsloth/references/llms-full.md",
47
51
  "03-fine-tuning/unsloth/references/llms-txt.md",
@@ -86,6 +90,8 @@ GENERATED_MARKS = ("automatically generated from official documentation",
86
90
  ATTRIBUTION = "<!-- vendored from orchestra-research/%s@%s %s; %s (c) Orchestra Research -->"
87
91
 
88
92
  CATEGORY_RE = re.compile(r"^(0-|[0-9]{2}-)")
93
+ # Upstream names an entry SKILL.md; the vendored copy is ENTRY.md (module docstring).
94
+ UPSTREAM_ENTRY, ENTRY = "SKILL.md", "ENTRY.md"
89
95
 
90
96
 
91
97
  def sha256(path):
@@ -155,6 +161,12 @@ def rel_of(category, skill):
155
161
  return category if skill == category else "%s/%s" % (category, skill)
156
162
 
157
163
 
164
+ def vendored(relfile):
165
+ """The path an upstream file is written to: an entry SKILL.md becomes ENTRY.md."""
166
+ head, name = os.path.split(relfile)
167
+ return os.path.join(head, ENTRY) if name == UPSTREAM_ENTRY else relfile
168
+
169
+
158
170
  def kept_files(source, rel):
159
171
  """The files this vendoring keeps from one skill dir, as relative paths."""
160
172
  base = os.path.join(source, rel)
@@ -235,8 +247,8 @@ def build(source, rev):
235
247
  "upstream_path": rel,
236
248
  }
237
249
  for relfile, body in sorted(body_texts.items()):
238
- files[relfile] = body
239
- entry["files"].append({"path": relfile, "bytes": len(body.encode()),
250
+ files[vendored(relfile)] = body
251
+ entry["files"].append({"path": vendored(relfile), "bytes": len(body.encode()),
240
252
  "sha256": hashlib.sha256(body.encode()).hexdigest()})
241
253
  entry["bytes"] = sum(f["bytes"] for f in entry["files"])
242
254
  rows.append(entry)
@@ -270,8 +282,8 @@ def build(source, rev):
270
282
  flags.append("stale-api")
271
283
  if entry["dangling_links"]:
272
284
  flags.append("dead-links: %d" % len(entry["dangling_links"]))
273
- lines.append("| `%s` | `%s/SKILL.md` | %s | %s |"
274
- % (entry["dir"], entry["upstream_path"], entry["purpose"],
285
+ lines.append("| `%s` | `%s/%s` | %s | %s |"
286
+ % (entry["dir"], entry["upstream_path"], ENTRY, entry["purpose"],
275
287
  ", ".join(flags)))
276
288
  generated["index/%s.md" % stage] = "\n".join(lines) + "\n"
277
289
 
@@ -314,10 +326,12 @@ def source_text(manifest, rev):
314
326
  "## What is vendored\n\n"
315
327
  "Every skill's `SKILL.md` and every markdown file beside it, in the upstream\n"
316
328
  "layout, because a vendored path is its provenance. %d skills across %d\n"
317
- "categories, %d files, %d bytes.\n\n"
329
+ "categories, %d files, %d bytes. One rename: each entry's `SKILL.md` sits at\n"
330
+ "the upstream path as `ENTRY.md`, bytes unchanged, so a host that lists every\n"
331
+ "`SKILL.md` below its skills directory (codex, Cursor) does not list it.\n\n"
318
332
  "## What is not, and why\n\n"
319
333
  "Files: %s - machine-scraped reference dumps, which the entry's own\n"
320
- "`SKILL.md` already distils.\n\n"
334
+ "`ENTRY.md` already distils.\n\n"
321
335
  "Directories: %s - LaTeX class/bst/bib trees and example PDFs,\n"
322
336
  "re-downloadable from each venue.\n\n"
323
337
  "Everything else that is not markdown (PDFs, images, `.gitkeep`, scripts)\n"
@@ -325,9 +339,9 @@ def source_text(manifest, rev):
325
339
  "`packages/`, `video-promo/` are upstream's repo furniture, not content.\n\n"
326
340
  "## The only modification\n\n"
327
341
  "A markdown file that carries no YAML frontmatter gets one attribution\n"
328
- "comment on its first line. `SKILL.md` files are byte-for-byte upstream,\n"
329
- "frontmatter included. `skills/ai-research/SKILL.md` is tezgah's own and is\n"
330
- "not part of the manifest.\n\n"
342
+ "comment on its first line. `ENTRY.md` files are byte-for-byte upstream\n"
343
+ "`SKILL.md`, frontmatter included. `skills/ai-research/SKILL.md` is\n"
344
+ "tezgah's own and is not part of the manifest.\n\n"
331
345
  "## Re-vendoring\n\n"
332
346
  "`bin/tezgah-import-ai-research --source <clone> --rev <sha>`, then commit\n"
333
347
  "the diff. `--check` verifies the committed tree against `library.json`\n"