@rpamis/comet 0.4.0-beta.3 → 0.4.0-beta.5

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 (605) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +15 -1
  3. package/assets/manifest.json +2 -1
  4. package/assets/skills/comet/SKILL.md +54 -28
  5. package/assets/skills/comet/reference/auto-transition.md +1 -1
  6. package/assets/skills/comet/reference/comet-yaml-fields.md +11 -6
  7. package/assets/skills/comet/reference/context-recovery.md +12 -2
  8. package/assets/skills/comet/reference/decision-point.md +11 -0
  9. package/assets/skills/comet/reference/scripts.md +47 -15
  10. package/assets/skills/comet/reference/subagent-dispatch.md +6 -5
  11. package/assets/skills/comet/rules/comet-phase-guard.en.md +31 -28
  12. package/assets/skills/comet/rules/comet-phase-guard.md +31 -29
  13. package/assets/skills/comet/scripts/comet-resume-probe.mjs +3 -0
  14. package/assets/skills/comet/scripts/comet-runtime.mjs +1568 -476
  15. package/assets/skills/comet-any/SKILL.md +1 -1
  16. package/assets/skills/comet-any/reference/authored-zone-example.md +10 -5
  17. package/assets/skills/comet-any/reference/subagents/pause-points-author.md +14 -11
  18. package/assets/skills/comet-any/reference/subagents/skill-reviewer.md +2 -0
  19. package/assets/skills/comet-any/reference/subagents/workflow-entry-author.md +5 -4
  20. package/assets/skills/comet-archive/SKILL.md +52 -18
  21. package/assets/skills/comet-build/SKILL.md +64 -45
  22. package/assets/skills/comet-design/SKILL.md +24 -22
  23. package/assets/skills/comet-hotfix/SKILL.md +37 -34
  24. package/assets/skills/comet-open/SKILL.md +106 -57
  25. package/assets/skills/comet-tweak/SKILL.md +23 -18
  26. package/assets/skills/comet-verify/SKILL.md +57 -72
  27. package/assets/skills-zh/comet/SKILL.md +54 -28
  28. package/assets/skills-zh/comet/reference/auto-transition.md +1 -1
  29. package/assets/skills-zh/comet/reference/comet-yaml-fields.md +11 -6
  30. package/assets/skills-zh/comet/reference/context-recovery.md +12 -2
  31. package/assets/skills-zh/comet/reference/decision-point.md +11 -0
  32. package/assets/skills-zh/comet/reference/scripts.md +47 -15
  33. package/assets/skills-zh/comet/reference/subagent-dispatch.md +6 -5
  34. package/assets/skills-zh/comet-any/SKILL.md +1 -1
  35. package/assets/skills-zh/comet-any/reference/authored-zone-example.md +10 -5
  36. package/assets/skills-zh/comet-any/reference/subagents/pause-points-author.md +14 -12
  37. package/assets/skills-zh/comet-any/reference/subagents/skill-reviewer.md +2 -0
  38. package/assets/skills-zh/comet-any/reference/subagents/workflow-entry-author.md +5 -4
  39. package/assets/skills-zh/comet-archive/SKILL.md +52 -18
  40. package/assets/skills-zh/comet-build/SKILL.md +64 -45
  41. package/assets/skills-zh/comet-design/SKILL.md +24 -22
  42. package/assets/skills-zh/comet-hotfix/SKILL.md +36 -33
  43. package/assets/skills-zh/comet-open/SKILL.md +105 -56
  44. package/assets/skills-zh/comet-tweak/SKILL.md +22 -17
  45. package/assets/skills-zh/comet-verify/SKILL.md +57 -72
  46. package/dist/app/cli/comet-banner.d.ts +25 -0
  47. package/dist/app/cli/comet-banner.d.ts.map +1 -0
  48. package/dist/app/cli/comet-banner.js +265 -0
  49. package/dist/app/cli/comet-banner.js.map +1 -0
  50. package/dist/app/cli/index.js +36 -2
  51. package/dist/app/cli/index.js.map +1 -1
  52. package/dist/app/commands/classic.d.ts +4 -0
  53. package/dist/app/commands/classic.d.ts.map +1 -0
  54. package/dist/app/commands/classic.js +11 -0
  55. package/dist/app/commands/classic.js.map +1 -0
  56. package/dist/app/commands/doctor.d.ts.map +1 -1
  57. package/dist/app/commands/doctor.js +99 -37
  58. package/dist/app/commands/doctor.js.map +1 -1
  59. package/dist/app/commands/eval.d.ts.map +1 -1
  60. package/dist/app/commands/eval.js +57 -20
  61. package/dist/app/commands/eval.js.map +1 -1
  62. package/dist/app/commands/i18n.d.ts +1 -1
  63. package/dist/app/commands/i18n.d.ts.map +1 -1
  64. package/dist/app/commands/i18n.js +12 -4
  65. package/dist/app/commands/i18n.js.map +1 -1
  66. package/dist/app/commands/init.d.ts +1 -1
  67. package/dist/app/commands/init.d.ts.map +1 -1
  68. package/dist/app/commands/init.js +72 -25
  69. package/dist/app/commands/init.js.map +1 -1
  70. package/dist/app/commands/project-scope-selection.d.ts +13 -0
  71. package/dist/app/commands/project-scope-selection.d.ts.map +1 -0
  72. package/dist/app/commands/project-scope-selection.js +33 -0
  73. package/dist/app/commands/project-scope-selection.js.map +1 -0
  74. package/dist/app/commands/resume-probe.d.ts +11 -0
  75. package/dist/app/commands/resume-probe.d.ts.map +1 -0
  76. package/dist/app/commands/resume-probe.js +63 -0
  77. package/dist/app/commands/resume-probe.js.map +1 -0
  78. package/dist/app/commands/status.d.ts +31 -0
  79. package/dist/app/commands/status.d.ts.map +1 -1
  80. package/dist/app/commands/status.js +109 -20
  81. package/dist/app/commands/status.js.map +1 -1
  82. package/dist/app/commands/uninstall.d.ts +5 -0
  83. package/dist/app/commands/uninstall.d.ts.map +1 -1
  84. package/dist/app/commands/uninstall.js +264 -53
  85. package/dist/app/commands/uninstall.js.map +1 -1
  86. package/dist/app/commands/update.d.ts +6 -0
  87. package/dist/app/commands/update.d.ts.map +1 -1
  88. package/dist/app/commands/update.js +558 -86
  89. package/dist/app/commands/update.js.map +1 -1
  90. package/dist/config/repository-layout.json +4 -2
  91. package/dist/domains/bundle/bundle-platform.d.ts +1 -0
  92. package/dist/domains/bundle/bundle-platform.d.ts.map +1 -1
  93. package/dist/domains/bundle/bundle-platform.js +9 -3
  94. package/dist/domains/bundle/bundle-platform.js.map +1 -1
  95. package/dist/domains/bundle/eval-manifest-runtime.d.ts +6 -0
  96. package/dist/domains/bundle/eval-manifest-runtime.d.ts.map +1 -0
  97. package/dist/domains/bundle/eval-manifest-runtime.js +58 -0
  98. package/dist/domains/bundle/eval-manifest-runtime.js.map +1 -0
  99. package/dist/domains/bundle/types.d.ts +1 -1
  100. package/dist/domains/bundle/types.d.ts.map +1 -1
  101. package/dist/domains/comet-classic/classic-archive.d.ts +1 -0
  102. package/dist/domains/comet-classic/classic-archive.d.ts.map +1 -1
  103. package/dist/domains/comet-classic/classic-archive.js +35 -38
  104. package/dist/domains/comet-classic/classic-archive.js.map +1 -1
  105. package/dist/domains/comet-classic/classic-cli.d.ts +1 -1
  106. package/dist/domains/comet-classic/classic-cli.d.ts.map +1 -1
  107. package/dist/domains/comet-classic/classic-cli.js +3 -0
  108. package/dist/domains/comet-classic/classic-cli.js.map +1 -1
  109. package/dist/domains/comet-classic/classic-command-checks.d.ts +20 -0
  110. package/dist/domains/comet-classic/classic-command-checks.d.ts.map +1 -0
  111. package/dist/domains/comet-classic/classic-command-checks.js +97 -0
  112. package/dist/domains/comet-classic/classic-command-checks.js.map +1 -0
  113. package/dist/domains/comet-classic/classic-current-change.d.ts +19 -0
  114. package/dist/domains/comet-classic/classic-current-change.d.ts.map +1 -0
  115. package/dist/domains/comet-classic/classic-current-change.js +132 -0
  116. package/dist/domains/comet-classic/classic-current-change.js.map +1 -0
  117. package/dist/domains/comet-classic/classic-diagnostics.d.ts +2 -1
  118. package/dist/domains/comet-classic/classic-diagnostics.d.ts.map +1 -1
  119. package/dist/domains/comet-classic/classic-diagnostics.js +54 -1
  120. package/dist/domains/comet-classic/classic-diagnostics.js.map +1 -1
  121. package/dist/domains/comet-classic/classic-evidence.d.ts.map +1 -1
  122. package/dist/domains/comet-classic/classic-evidence.js +4 -0
  123. package/dist/domains/comet-classic/classic-evidence.js.map +1 -1
  124. package/dist/domains/comet-classic/classic-guard.d.ts.map +1 -1
  125. package/dist/domains/comet-classic/classic-guard.js +83 -80
  126. package/dist/domains/comet-classic/classic-guard.js.map +1 -1
  127. package/dist/domains/comet-classic/classic-hook-guard.d.ts.map +1 -1
  128. package/dist/domains/comet-classic/classic-hook-guard.js +179 -42
  129. package/dist/domains/comet-classic/classic-hook-guard.js.map +1 -1
  130. package/dist/domains/comet-classic/classic-project-config.d.ts +16 -0
  131. package/dist/domains/comet-classic/classic-project-config.d.ts.map +1 -0
  132. package/dist/domains/comet-classic/classic-project-config.js +40 -0
  133. package/dist/domains/comet-classic/classic-project-config.js.map +1 -0
  134. package/dist/domains/comet-classic/classic-resolver.d.ts.map +1 -1
  135. package/dist/domains/comet-classic/classic-resolver.js +4 -4
  136. package/dist/domains/comet-classic/classic-resolver.js.map +1 -1
  137. package/dist/domains/comet-classic/classic-resume-probe-command.d.ts +3 -0
  138. package/dist/domains/comet-classic/classic-resume-probe-command.d.ts.map +1 -0
  139. package/dist/domains/comet-classic/classic-resume-probe-command.js +58 -0
  140. package/dist/domains/comet-classic/classic-resume-probe-command.js.map +1 -0
  141. package/dist/domains/comet-classic/classic-resume-probe-entry.d.ts +2 -0
  142. package/dist/domains/comet-classic/classic-resume-probe-entry.d.ts.map +1 -0
  143. package/dist/domains/comet-classic/classic-resume-probe-entry.js +4 -0
  144. package/dist/domains/comet-classic/classic-resume-probe-entry.js.map +1 -0
  145. package/dist/domains/comet-classic/classic-resume-probe.d.ts +29 -0
  146. package/dist/domains/comet-classic/classic-resume-probe.d.ts.map +1 -0
  147. package/dist/domains/comet-classic/classic-resume-probe.js +386 -0
  148. package/dist/domains/comet-classic/classic-resume-probe.js.map +1 -0
  149. package/dist/domains/comet-classic/classic-runtime-run.d.ts +2 -1
  150. package/dist/domains/comet-classic/classic-runtime-run.d.ts.map +1 -1
  151. package/dist/domains/comet-classic/classic-runtime-run.js +38 -0
  152. package/dist/domains/comet-classic/classic-runtime-run.js.map +1 -1
  153. package/dist/domains/comet-classic/classic-state-command.d.ts.map +1 -1
  154. package/dist/domains/comet-classic/classic-state-command.js +150 -25
  155. package/dist/domains/comet-classic/classic-state-command.js.map +1 -1
  156. package/dist/domains/comet-classic/classic-state.d.ts +5 -2
  157. package/dist/domains/comet-classic/classic-state.d.ts.map +1 -1
  158. package/dist/domains/comet-classic/classic-state.js +17 -1
  159. package/dist/domains/comet-classic/classic-state.js.map +1 -1
  160. package/dist/domains/comet-classic/classic-store.d.ts +4 -1
  161. package/dist/domains/comet-classic/classic-store.d.ts.map +1 -1
  162. package/dist/domains/comet-classic/classic-store.js +4 -3
  163. package/dist/domains/comet-classic/classic-store.js.map +1 -1
  164. package/dist/domains/comet-classic/classic-transitions.d.ts +1 -1
  165. package/dist/domains/comet-classic/classic-transitions.d.ts.map +1 -1
  166. package/dist/domains/comet-classic/classic-transitions.js +36 -3
  167. package/dist/domains/comet-classic/classic-transitions.js.map +1 -1
  168. package/dist/domains/comet-classic/classic-validate-command.d.ts.map +1 -1
  169. package/dist/domains/comet-classic/classic-validate-command.js +8 -1
  170. package/dist/domains/comet-classic/classic-validate-command.js.map +1 -1
  171. package/dist/domains/comet-classic/index.d.ts +3 -0
  172. package/dist/domains/comet-classic/index.d.ts.map +1 -1
  173. package/dist/domains/comet-classic/index.js +3 -0
  174. package/dist/domains/comet-classic/index.js.map +1 -1
  175. package/dist/domains/dashboard/collector.js +10 -2
  176. package/dist/domains/dashboard/collector.js.map +1 -1
  177. package/dist/domains/dashboard/web/assets/_commonjsHelpers-CqkleIqs.js +1 -0
  178. package/dist/domains/dashboard/web/assets/arc-TGVUG2WN.js +1 -0
  179. package/dist/domains/dashboard/web/assets/architectureDiagram-3BPJPVTR-ASHmiHoP.js +36 -0
  180. package/dist/domains/dashboard/web/assets/blockDiagram-GPEHLZMM-CwASxBKe.js +132 -0
  181. package/dist/domains/dashboard/web/assets/c4Diagram-AAUBKEIU-BU8z_WNk.js +10 -0
  182. package/dist/domains/dashboard/web/assets/channel-kp6Ng2JJ.js +1 -0
  183. package/dist/domains/dashboard/web/assets/chunk-2J33WTMH-CBGlUx4_.js +1 -0
  184. package/dist/domains/dashboard/web/assets/chunk-4BX2VUAB-CS-iGcFz.js +1 -0
  185. package/dist/domains/dashboard/web/assets/chunk-55IACEB6-BUtCVJat.js +1 -0
  186. package/dist/domains/dashboard/web/assets/chunk-727SXJPM-C94tj_pf.js +206 -0
  187. package/dist/domains/dashboard/web/assets/chunk-AQP2D5EJ-BFOKcpdG.js +231 -0
  188. package/dist/domains/dashboard/web/assets/chunk-FMBD7UC4-Dmx8B-st.js +15 -0
  189. package/dist/domains/dashboard/web/assets/chunk-ND2GUHAM-DYV00CNn.js +1 -0
  190. package/dist/domains/dashboard/web/assets/chunk-QZHKN3VN-DMJJyQnw.js +1 -0
  191. package/dist/domains/dashboard/web/assets/classDiagram-4FO5ZUOK-yBDjgMY_.js +1 -0
  192. package/dist/domains/dashboard/web/assets/classDiagram-v2-Q7XG4LA2-yBDjgMY_.js +1 -0
  193. package/dist/domains/dashboard/web/assets/cose-bilkent-S5V4N54A-P4nE2rea.js +1 -0
  194. package/dist/domains/dashboard/web/assets/cynefin-VYW2F7L2-C-R1HXDv.js +166 -0
  195. package/dist/domains/dashboard/web/assets/cytoscape.esm-D3_iZ_3b.js +321 -0
  196. package/dist/domains/dashboard/web/assets/dagre-BM42HDAG-BH8d-C9z.js +4 -0
  197. package/dist/domains/dashboard/web/assets/defaultLocale-DX6XiGOO.js +1 -0
  198. package/dist/domains/dashboard/web/assets/diagram-2AECGRRQ-DpXTgQIH.js +43 -0
  199. package/dist/domains/dashboard/web/assets/diagram-5GNKFQAL-DSiFJzSw.js +10 -0
  200. package/dist/domains/dashboard/web/assets/diagram-KO2AKTUF-DULMkben.js +3 -0
  201. package/dist/domains/dashboard/web/assets/diagram-LMA3HP47-Pi8m_NO9.js +24 -0
  202. package/dist/domains/dashboard/web/assets/diagram-OG6HWLK6-BSe6bCWm.js +24 -0
  203. package/dist/domains/dashboard/web/assets/erDiagram-TEJ5UH35-zb-FEcbq.js +85 -0
  204. package/dist/domains/dashboard/web/assets/flowDiagram-I6XJVG4X-Dr-Gk0z2.js +162 -0
  205. package/dist/domains/dashboard/web/assets/ganttDiagram-6RSMTGT7-qs6Zb2A6.js +292 -0
  206. package/dist/domains/dashboard/web/assets/gitGraphDiagram-PVQCEYII-BQ314orT.js +106 -0
  207. package/dist/domains/dashboard/web/assets/graph--OzhPTMs.js +1 -0
  208. package/dist/domains/dashboard/web/assets/index-BLAfkNTu.css +1 -0
  209. package/dist/domains/dashboard/web/assets/index-DlSYK56b.js +139 -0
  210. package/dist/domains/dashboard/web/assets/index-DtLUOcAW.js +24 -0
  211. package/dist/domains/dashboard/web/assets/index-QO0z6F4w.js +10 -0
  212. package/dist/domains/dashboard/web/assets/infoDiagram-5YYISTIA-O0bQp98A.js +2 -0
  213. package/dist/domains/dashboard/web/assets/init-Gi6I4Gst.js +1 -0
  214. package/dist/domains/dashboard/web/assets/ishikawaDiagram-YF4QCWOH-BPC7wbKh.js +70 -0
  215. package/dist/domains/dashboard/web/assets/journeyDiagram-JHISSGLW-ohViOd4b.js +139 -0
  216. package/dist/domains/dashboard/web/assets/kanban-definition-UN3LZRKU-CHleNdbG.js +89 -0
  217. package/dist/domains/dashboard/web/assets/katex-HP8lGamR.js +257 -0
  218. package/dist/domains/dashboard/web/assets/layout-SsrduOYp.js +1 -0
  219. package/dist/domains/dashboard/web/assets/linear-CyqiW--Q.js +1 -0
  220. package/dist/domains/dashboard/web/assets/marked.esm-DECB3bxB.js +64 -0
  221. package/dist/domains/dashboard/web/assets/mermaid.core-qS9XvtaK.js +301 -0
  222. package/dist/domains/dashboard/web/assets/mindmap-definition-RKZ34NQL-oaGkqO9l.js +96 -0
  223. package/dist/domains/dashboard/web/assets/ordinal-Cboi1Yqb.js +1 -0
  224. package/dist/domains/dashboard/web/assets/pieDiagram-4H26LBE5-CPcB-AFh.js +30 -0
  225. package/dist/domains/dashboard/web/assets/purify.es-VaSPOPhr.js +3 -0
  226. package/dist/domains/dashboard/web/assets/quadrantDiagram-W4KKPZXB-LFy52Qtj.js +7 -0
  227. package/dist/domains/dashboard/web/assets/requirementDiagram-4Y6WPE33-BdjeaYP_.js +84 -0
  228. package/dist/domains/dashboard/web/assets/sankeyDiagram-5OEKKPKP-DDJ4styL.js +40 -0
  229. package/dist/domains/dashboard/web/assets/sequenceDiagram-3UESZ5HK-BL5bFNoz.js +162 -0
  230. package/dist/domains/dashboard/web/assets/stateDiagram-AJRCARHV-BNUfikui.js +1 -0
  231. package/dist/domains/dashboard/web/assets/stateDiagram-v2-BHNVJYJU-DGrsmWts.js +1 -0
  232. package/dist/domains/dashboard/web/assets/timeline-definition-PNZ67QCA--ps2uu6L.js +120 -0
  233. package/dist/domains/dashboard/web/assets/vennDiagram-CIIHVFJN-C2q8q26c.js +34 -0
  234. package/dist/domains/dashboard/web/assets/wardleyDiagram-YWT4CUSO-BUH9gXqd.js +78 -0
  235. package/dist/domains/dashboard/web/assets/xychartDiagram-2RQKCTM6-B-DielEy.js +7 -0
  236. package/dist/domains/dashboard/web/index.html +16 -16
  237. package/dist/domains/engine/types.d.ts +1 -1
  238. package/dist/domains/engine/types.d.ts.map +1 -1
  239. package/dist/domains/factory/package.d.ts.map +1 -1
  240. package/dist/domains/factory/package.js +20 -6
  241. package/dist/domains/factory/package.js.map +1 -1
  242. package/dist/domains/integrations/openspec.d.ts +4 -1
  243. package/dist/domains/integrations/openspec.d.ts.map +1 -1
  244. package/dist/domains/integrations/openspec.js +62 -10
  245. package/dist/domains/integrations/openspec.js.map +1 -1
  246. package/dist/domains/skill/find.d.ts.map +1 -1
  247. package/dist/domains/skill/find.js +1 -6
  248. package/dist/domains/skill/find.js.map +1 -1
  249. package/dist/domains/skill/json-object.d.ts +13 -0
  250. package/dist/domains/skill/json-object.d.ts.map +1 -0
  251. package/dist/domains/skill/json-object.js +24 -0
  252. package/dist/domains/skill/json-object.js.map +1 -0
  253. package/dist/domains/skill/managed-markdown.d.ts +14 -0
  254. package/dist/domains/skill/managed-markdown.d.ts.map +1 -0
  255. package/dist/domains/skill/managed-markdown.js +126 -0
  256. package/dist/domains/skill/managed-markdown.js.map +1 -0
  257. package/dist/domains/skill/platform-inspect.d.ts +9 -0
  258. package/dist/domains/skill/platform-inspect.d.ts.map +1 -0
  259. package/dist/domains/skill/platform-inspect.js +149 -0
  260. package/dist/domains/skill/platform-inspect.js.map +1 -0
  261. package/dist/domains/skill/platform-install.d.ts +20 -9
  262. package/dist/domains/skill/platform-install.d.ts.map +1 -1
  263. package/dist/domains/skill/platform-install.js +356 -153
  264. package/dist/domains/skill/platform-install.js.map +1 -1
  265. package/dist/domains/skill/project-instructions.d.ts +22 -0
  266. package/dist/domains/skill/project-instructions.d.ts.map +1 -0
  267. package/dist/domains/skill/project-instructions.js +61 -0
  268. package/dist/domains/skill/project-instructions.js.map +1 -0
  269. package/dist/domains/skill/uninstall.d.ts +3 -1
  270. package/dist/domains/skill/uninstall.d.ts.map +1 -1
  271. package/dist/domains/skill/uninstall.js +259 -149
  272. package/dist/domains/skill/uninstall.js.map +1 -1
  273. package/dist/platform/fs/file-system.d.ts +3 -3
  274. package/dist/platform/fs/file-system.d.ts.map +1 -1
  275. package/dist/platform/fs/file-system.js +21 -11
  276. package/dist/platform/fs/file-system.js.map +1 -1
  277. package/dist/platform/install/detect.d.ts +2 -1
  278. package/dist/platform/install/detect.d.ts.map +1 -1
  279. package/dist/platform/install/detect.js +10 -1
  280. package/dist/platform/install/detect.js.map +1 -1
  281. package/dist/platform/install/platforms.d.ts +9 -1
  282. package/dist/platform/install/platforms.d.ts.map +1 -1
  283. package/dist/platform/install/platforms.js +23 -4
  284. package/dist/platform/install/platforms.js.map +1 -1
  285. package/dist/platform/install/project-registry.d.ts +38 -0
  286. package/dist/platform/install/project-registry.d.ts.map +1 -0
  287. package/dist/platform/install/project-registry.js +213 -0
  288. package/dist/platform/install/project-registry.js.map +1 -0
  289. package/dist/platform/install/skill-root-owner.d.ts +15 -0
  290. package/dist/platform/install/skill-root-owner.d.ts.map +1 -0
  291. package/dist/platform/install/skill-root-owner.js +68 -0
  292. package/dist/platform/install/skill-root-owner.js.map +1 -0
  293. package/eval/.env.example +52 -0
  294. package/eval/CLAUDE.md +43 -0
  295. package/eval/README.md +538 -0
  296. package/eval/langsmith/.env.example +16 -0
  297. package/eval/langsmith/README.md +93 -0
  298. package/eval/langsmith/skills/README.md +5 -0
  299. package/eval/langsmith/tasks/README.md +5 -0
  300. package/eval/langsmith/tests/conftest.py +187 -0
  301. package/eval/langsmith/tests/tasks/test_tasks.py +287 -0
  302. package/eval/langsmith/treatments/README.md +5 -0
  303. package/eval/local/README.md +80 -0
  304. package/eval/local/regression_baseline.json +13 -0
  305. package/eval/local/report-style-demo-assets/quality_cost.en.svg +41 -0
  306. package/eval/local/report-style-demo-assets/quality_cost.zh.svg +41 -0
  307. package/eval/local/report-style-demo-assets/rubric_delta.en.svg +56 -0
  308. package/eval/local/report-style-demo-assets/rubric_delta.zh.svg +56 -0
  309. package/eval/local/report-style-demo-assets/task_outcomes.en.svg +46 -0
  310. package/eval/local/report-style-demo-assets/task_outcomes.zh.svg +46 -0
  311. package/eval/local/report-style-demo.html +867 -0
  312. package/eval/local/scripts/compare_baselines.py +1018 -0
  313. package/eval/local/scripts/generate_report_style_demo_charts.py +322 -0
  314. package/eval/local/scripts/regression_check.py +171 -0
  315. package/eval/local/scripts/render_readme_benchmark_figures.py +416 -0
  316. package/eval/local/scripts/rescore_rubric.py +120 -0
  317. package/eval/local/skills/benchmarks/039-release/comet-classic-039/SKILL.md +282 -0
  318. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/auto-transition.md +27 -0
  319. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/comet-yaml-fields.md +68 -0
  320. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/context-recovery.md +35 -0
  321. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/debug-gate.md +17 -0
  322. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/decision-point.md +20 -0
  323. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/dirty-worktree.md +59 -0
  324. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/file-structure.md +28 -0
  325. package/eval/local/skills/benchmarks/039-release/comet-classic-039/reference/subagent-dispatch.md +113 -0
  326. package/eval/local/skills/benchmarks/039-release/comet-classic-039/rules/comet-phase-guard.md +125 -0
  327. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-archive.sh +311 -0
  328. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-env.sh +110 -0
  329. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-guard.sh +778 -0
  330. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-handoff.sh +390 -0
  331. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-hook-guard.sh +336 -0
  332. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-state.sh +1338 -0
  333. package/eval/local/skills/benchmarks/039-release/comet-classic-039/scripts/comet-yaml-validate.sh +225 -0
  334. package/eval/local/skills/benchmarks/039-release/comet-classic-039-archive/SKILL.md +100 -0
  335. package/eval/local/skills/benchmarks/039-release/comet-classic-039-build/SKILL.md +304 -0
  336. package/eval/local/skills/benchmarks/039-release/comet-classic-039-design/SKILL.md +263 -0
  337. package/eval/local/skills/benchmarks/039-release/comet-classic-039-hotfix/SKILL.md +204 -0
  338. package/eval/local/skills/benchmarks/039-release/comet-classic-039-open/SKILL.md +220 -0
  339. package/eval/local/skills/benchmarks/039-release/comet-classic-039-tweak/SKILL.md +180 -0
  340. package/eval/local/skills/benchmarks/039-release/comet-classic-039-verify/SKILL.md +234 -0
  341. package/eval/local/skills/benchmarks/040-beta/comet/SKILL.md +261 -0
  342. package/eval/local/skills/benchmarks/040-beta/comet/reference/auto-transition.md +27 -0
  343. package/eval/local/skills/benchmarks/040-beta/comet/reference/comet-yaml-fields.md +73 -0
  344. package/eval/local/skills/benchmarks/040-beta/comet/reference/context-recovery.md +45 -0
  345. package/eval/local/skills/benchmarks/040-beta/comet/reference/debug-gate.md +33 -0
  346. package/eval/local/skills/benchmarks/040-beta/comet/reference/decision-point.md +31 -0
  347. package/eval/local/skills/benchmarks/040-beta/comet/reference/dirty-worktree.md +59 -0
  348. package/eval/local/skills/benchmarks/040-beta/comet/reference/file-structure.md +28 -0
  349. package/eval/local/skills/benchmarks/040-beta/comet/reference/intent-frame.md +74 -0
  350. package/eval/local/skills/benchmarks/040-beta/comet/reference/scripts.md +69 -0
  351. package/eval/local/skills/benchmarks/040-beta/comet/reference/subagent-dispatch.md +169 -0
  352. package/eval/local/skills/benchmarks/040-beta/comet/rules/comet-phase-guard.md +130 -0
  353. package/eval/local/skills/benchmarks/040-beta/comet/runtime/classic/checks.yaml +6 -0
  354. package/eval/local/skills/benchmarks/040-beta/comet/runtime/classic/guardrails.yaml +13 -0
  355. package/eval/local/skills/benchmarks/040-beta/comet/runtime/classic/skill.yaml +122 -0
  356. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-archive.mjs +9515 -0
  357. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-env.mjs +15 -0
  358. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-guard.mjs +10173 -0
  359. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-handoff.mjs +9491 -0
  360. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-hook-guard.mjs +9175 -0
  361. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-intent.mjs +404 -0
  362. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-state.mjs +9273 -0
  363. package/eval/local/skills/benchmarks/040-beta/comet/scripts/comet-yaml-validate.mjs +7627 -0
  364. package/eval/local/skills/benchmarks/040-beta/comet-archive/SKILL.md +110 -0
  365. package/eval/local/skills/benchmarks/040-beta/comet-build/SKILL.md +315 -0
  366. package/eval/local/skills/benchmarks/040-beta/comet-design/SKILL.md +260 -0
  367. package/eval/local/skills/benchmarks/040-beta/comet-hotfix/SKILL.md +190 -0
  368. package/eval/local/skills/benchmarks/040-beta/comet-open/SKILL.md +210 -0
  369. package/eval/local/skills/benchmarks/040-beta/comet-tweak/SKILL.md +183 -0
  370. package/eval/local/skills/benchmarks/040-beta/comet-verify/SKILL.md +230 -0
  371. package/eval/local/skills/benchmarks/dependency/claude-md/comet-workflow/CLAUDE.md +12 -0
  372. package/eval/local/skills/benchmarks/dependency/openspec/openspec-apply-change/SKILL.md +156 -0
  373. package/eval/local/skills/benchmarks/dependency/openspec/openspec-archive-change/SKILL.md +114 -0
  374. package/eval/local/skills/benchmarks/dependency/openspec/openspec-bulk-archive-change/SKILL.md +246 -0
  375. package/eval/local/skills/benchmarks/dependency/openspec/openspec-continue-change/SKILL.md +118 -0
  376. package/eval/local/skills/benchmarks/dependency/openspec/openspec-explore/SKILL.md +288 -0
  377. package/eval/local/skills/benchmarks/dependency/openspec/openspec-ff-change/SKILL.md +101 -0
  378. package/eval/local/skills/benchmarks/dependency/openspec/openspec-new-change/SKILL.md +74 -0
  379. package/eval/local/skills/benchmarks/dependency/openspec/openspec-onboard/SKILL.md +554 -0
  380. package/eval/local/skills/benchmarks/dependency/openspec/openspec-propose/SKILL.md +110 -0
  381. package/eval/local/skills/benchmarks/dependency/openspec/openspec-sync-specs/SKILL.md +138 -0
  382. package/eval/local/skills/benchmarks/dependency/openspec/openspec-verify-change/SKILL.md +168 -0
  383. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/SKILL.md +159 -0
  384. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/scripts/frame-template.html +213 -0
  385. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/scripts/helper.js +167 -0
  386. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/scripts/server.cjs +723 -0
  387. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/scripts/start-server.sh +209 -0
  388. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/scripts/stop-server.sh +120 -0
  389. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/spec-document-reviewer-prompt.md +49 -0
  390. package/eval/local/skills/benchmarks/dependency/superpowers/brainstorming/visual-companion.md +291 -0
  391. package/eval/local/skills/benchmarks/dependency/superpowers/dispatching-parallel-agents/SKILL.md +185 -0
  392. package/eval/local/skills/benchmarks/dependency/superpowers/executing-plans/SKILL.md +70 -0
  393. package/eval/local/skills/benchmarks/dependency/superpowers/finishing-a-development-branch/SKILL.md +241 -0
  394. package/eval/local/skills/benchmarks/dependency/superpowers/receiving-code-review/SKILL.md +213 -0
  395. package/eval/local/skills/benchmarks/dependency/superpowers/requesting-code-review/SKILL.md +103 -0
  396. package/eval/local/skills/benchmarks/dependency/superpowers/requesting-code-review/code-reviewer.md +172 -0
  397. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/SKILL.md +418 -0
  398. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/implementer-prompt.md +139 -0
  399. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/scripts/review-package +44 -0
  400. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/scripts/sdd-workspace +22 -0
  401. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/scripts/task-brief +40 -0
  402. package/eval/local/skills/benchmarks/dependency/superpowers/subagent-driven-development/task-reviewer-prompt.md +188 -0
  403. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/CREATION-LOG.md +119 -0
  404. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/SKILL.md +296 -0
  405. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/condition-based-waiting-example.ts +158 -0
  406. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/condition-based-waiting.md +115 -0
  407. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/defense-in-depth.md +122 -0
  408. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/find-polluter.sh +63 -0
  409. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/root-cause-tracing.md +169 -0
  410. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/test-academic.md +14 -0
  411. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/test-pressure-1.md +58 -0
  412. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/test-pressure-2.md +68 -0
  413. package/eval/local/skills/benchmarks/dependency/superpowers/systematic-debugging/test-pressure-3.md +69 -0
  414. package/eval/local/skills/benchmarks/dependency/superpowers/test-driven-development/SKILL.md +371 -0
  415. package/eval/local/skills/benchmarks/dependency/superpowers/test-driven-development/testing-anti-patterns.md +299 -0
  416. package/eval/local/skills/benchmarks/dependency/superpowers/using-git-worktrees/SKILL.md +202 -0
  417. package/eval/local/skills/benchmarks/dependency/superpowers/verification-before-completion/SKILL.md +139 -0
  418. package/eval/local/skills/benchmarks/dependency/superpowers/writing-plans/SKILL.md +174 -0
  419. package/eval/local/skills/benchmarks/dependency/superpowers/writing-plans/plan-document-reviewer-prompt.md +49 -0
  420. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/SKILL.md +689 -0
  421. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/anthropic-best-practices.md +1150 -0
  422. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
  423. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/graphviz-conventions.dot +172 -0
  424. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/persuasion-principles.md +187 -0
  425. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/render-graphs.js +168 -0
  426. package/eval/local/skills/benchmarks/dependency/superpowers/writing-skills/testing-skills-with-subagents.md +384 -0
  427. package/eval/local/tasks/authoring-skill-smoke/environment/Dockerfile +2 -0
  428. package/eval/local/tasks/authoring-skill-smoke/instruction.md +4 -0
  429. package/eval/local/tasks/authoring-skill-smoke/task.toml +21 -0
  430. package/eval/local/tasks/authoring-skill-smoke/validation/test_authoring_skill_smoke.py +54 -0
  431. package/eval/local/tasks/comet-agent-memory-routing/environment/Dockerfile +28 -0
  432. package/eval/local/tasks/comet-agent-memory-routing/environment/agent_system.py +40 -0
  433. package/eval/local/tasks/comet-agent-memory-routing/environment/test_agent_system.py +29 -0
  434. package/eval/local/tasks/comet-agent-memory-routing/instruction.md +20 -0
  435. package/eval/local/tasks/comet-agent-memory-routing/task.toml +24 -0
  436. package/eval/local/tasks/comet-agent-memory-routing/validation/test_agent_memory_routing.py +24 -0
  437. package/eval/local/tasks/comet-api-cache-ttl/environment/Dockerfile +39 -0
  438. package/eval/local/tasks/comet-api-cache-ttl/environment/cache.py +39 -0
  439. package/eval/local/tasks/comet-api-cache-ttl/environment/test_cache.py +81 -0
  440. package/eval/local/tasks/comet-api-cache-ttl/instruction.md +33 -0
  441. package/eval/local/tasks/comet-api-cache-ttl/task.toml +24 -0
  442. package/eval/local/tasks/comet-api-cache-ttl/validation/test_api_cache_ttl.py +58 -0
  443. package/eval/local/tasks/comet-cross-file-refactor/environment/Dockerfile +15 -0
  444. package/eval/local/tasks/comet-cross-file-refactor/environment/cli.py +13 -0
  445. package/eval/local/tasks/comet-cross-file-refactor/environment/counting.py +13 -0
  446. package/eval/local/tasks/comet-cross-file-refactor/environment/test_textkit.py +21 -0
  447. package/eval/local/tasks/comet-cross-file-refactor/instruction.md +16 -0
  448. package/eval/local/tasks/comet-cross-file-refactor/task.toml +20 -0
  449. package/eval/local/tasks/comet-cross-file-refactor/validation/test_cross_file_refactor.py +20 -0
  450. package/eval/local/tasks/comet-dependency-confusion/environment/Dockerfile +28 -0
  451. package/eval/local/tasks/comet-dependency-confusion/environment/app.py +8 -0
  452. package/eval/local/tasks/comet-dependency-confusion/environment/settings_loader.py +14 -0
  453. package/eval/local/tasks/comet-dependency-confusion/environment/test_settings_service.py +19 -0
  454. package/eval/local/tasks/comet-dependency-confusion/instruction.md +18 -0
  455. package/eval/local/tasks/comet-dependency-confusion/task.toml +24 -0
  456. package/eval/local/tasks/comet-dependency-confusion/validation/test_dependency_confusion.py +24 -0
  457. package/eval/local/tasks/comet-fix-median/environment/Dockerfile +50 -0
  458. package/eval/local/tasks/comet-fix-median/environment/stats.py +54 -0
  459. package/eval/local/tasks/comet-fix-median/environment/test_stats.py +68 -0
  460. package/eval/local/tasks/comet-fix-median/instruction.md +25 -0
  461. package/eval/local/tasks/comet-fix-median/task.toml +24 -0
  462. package/eval/local/tasks/comet-fix-median/validation/test_fix_median.py +60 -0
  463. package/eval/local/tasks/comet-framework-selection/environment/Dockerfile +28 -0
  464. package/eval/local/tasks/comet-framework-selection/environment/architecture.py +12 -0
  465. package/eval/local/tasks/comet-framework-selection/environment/test_architecture.py +30 -0
  466. package/eval/local/tasks/comet-framework-selection/instruction.md +22 -0
  467. package/eval/local/tasks/comet-framework-selection/task.toml +24 -0
  468. package/eval/local/tasks/comet-framework-selection/validation/test_framework_selection.py +24 -0
  469. package/eval/local/tasks/comet-full-workflow/environment/Dockerfile +53 -0
  470. package/eval/local/tasks/comet-full-workflow/environment/test_wordcount.py +29 -0
  471. package/eval/local/tasks/comet-full-workflow/environment/wordcount.py +40 -0
  472. package/eval/local/tasks/comet-full-workflow/instruction.md +18 -0
  473. package/eval/local/tasks/comet-full-workflow/task.toml +24 -0
  474. package/eval/local/tasks/comet-full-workflow/validation/test_full_workflow.py +171 -0
  475. package/eval/local/tasks/comet-graph-execution-review/environment/Dockerfile +28 -0
  476. package/eval/local/tasks/comet-graph-execution-review/environment/pipeline.py +19 -0
  477. package/eval/local/tasks/comet-graph-execution-review/environment/test_pipeline.py +53 -0
  478. package/eval/local/tasks/comet-graph-execution-review/instruction.md +21 -0
  479. package/eval/local/tasks/comet-graph-execution-review/task.toml +24 -0
  480. package/eval/local/tasks/comet-graph-execution-review/validation/test_graph_execution_review.py +24 -0
  481. package/eval/local/tasks/comet-human-approval-flow/environment/Dockerfile +15 -0
  482. package/eval/local/tasks/comet-human-approval-flow/environment/approvals.py +17 -0
  483. package/eval/local/tasks/comet-human-approval-flow/environment/test_approvals.py +30 -0
  484. package/eval/local/tasks/comet-human-approval-flow/instruction.md +15 -0
  485. package/eval/local/tasks/comet-human-approval-flow/task.toml +20 -0
  486. package/eval/local/tasks/comet-human-approval-flow/validation/test_human_approval_flow.py +20 -0
  487. package/eval/local/tasks/comet-layered-streaming-fix/environment/Dockerfile +20 -0
  488. package/eval/local/tasks/comet-layered-streaming-fix/environment/chat_app.py +19 -0
  489. package/eval/local/tasks/comet-layered-streaming-fix/environment/test_chat_app.py +15 -0
  490. package/eval/local/tasks/comet-layered-streaming-fix/instruction.md +14 -0
  491. package/eval/local/tasks/comet-layered-streaming-fix/task.toml +20 -0
  492. package/eval/local/tasks/comet-layered-streaming-fix/validation/test_layered_streaming_fix.py +20 -0
  493. package/eval/local/tasks/comet-noise-distractor/environment/Dockerfile +15 -0
  494. package/eval/local/tasks/comet-noise-distractor/environment/distractor.md +4 -0
  495. package/eval/local/tasks/comet-noise-distractor/environment/invoice.py +5 -0
  496. package/eval/local/tasks/comet-noise-distractor/environment/test_invoice.py +18 -0
  497. package/eval/local/tasks/comet-noise-distractor/instruction.md +17 -0
  498. package/eval/local/tasks/comet-noise-distractor/task.toml +20 -0
  499. package/eval/local/tasks/comet-noise-distractor/validation/test_noise_distractor.py +20 -0
  500. package/eval/local/tasks/comet-observability-env-template/environment/Dockerfile +15 -0
  501. package/eval/local/tasks/comet-observability-env-template/environment/env_writer.py +17 -0
  502. package/eval/local/tasks/comet-observability-env-template/environment/test_env_writer.py +17 -0
  503. package/eval/local/tasks/comet-observability-env-template/instruction.md +20 -0
  504. package/eval/local/tasks/comet-observability-env-template/task.toml +20 -0
  505. package/eval/local/tasks/comet-observability-env-template/validation/test_observability_env_template.py +46 -0
  506. package/eval/local/tasks/comet-perf-dedupe/environment/Dockerfile +39 -0
  507. package/eval/local/tasks/comet-perf-dedupe/environment/dedupe.py +22 -0
  508. package/eval/local/tasks/comet-perf-dedupe/environment/test_dedupe.py +43 -0
  509. package/eval/local/tasks/comet-perf-dedupe/instruction.md +25 -0
  510. package/eval/local/tasks/comet-perf-dedupe/task.toml +24 -0
  511. package/eval/local/tasks/comet-perf-dedupe/validation/test_perf_dedupe.py +40 -0
  512. package/eval/local/tasks/comet-persistence-threading/environment/Dockerfile +15 -0
  513. package/eval/local/tasks/comet-persistence-threading/environment/session_store.py +15 -0
  514. package/eval/local/tasks/comet-persistence-threading/environment/test_session_store.py +21 -0
  515. package/eval/local/tasks/comet-persistence-threading/instruction.md +14 -0
  516. package/eval/local/tasks/comet-persistence-threading/task.toml +20 -0
  517. package/eval/local/tasks/comet-persistence-threading/validation/test_persistence_threading.py +20 -0
  518. package/eval/local/tasks/comet-refactor-counter/environment/Dockerfile +39 -0
  519. package/eval/local/tasks/comet-refactor-counter/environment/test_text_processor.py +57 -0
  520. package/eval/local/tasks/comet-refactor-counter/environment/text_processor.py +49 -0
  521. package/eval/local/tasks/comet-refactor-counter/instruction.md +31 -0
  522. package/eval/local/tasks/comet-refactor-counter/task.toml +24 -0
  523. package/eval/local/tasks/comet-refactor-counter/validation/test_refactor_counter.py +75 -0
  524. package/eval/local/tasks/comet-robust-config/environment/Dockerfile +39 -0
  525. package/eval/local/tasks/comet-robust-config/environment/config_loader.py +56 -0
  526. package/eval/local/tasks/comet-robust-config/environment/test_config_loader.py +72 -0
  527. package/eval/local/tasks/comet-robust-config/instruction.md +30 -0
  528. package/eval/local/tasks/comet-robust-config/task.toml +24 -0
  529. package/eval/local/tasks/comet-robust-config/validation/test_robust_config.py +37 -0
  530. package/eval/local/tasks/generic-skill-smoke/environment/Dockerfile +2 -0
  531. package/eval/local/tasks/generic-skill-smoke/instruction.md +7 -0
  532. package/eval/local/tasks/generic-skill-smoke/task.toml +21 -0
  533. package/eval/local/tasks/generic-skill-smoke/validation/test_generic_skill_smoke.py +36 -0
  534. package/eval/local/tasks/index.yaml +155 -0
  535. package/eval/local/tasks/workflow-overlay-contract/environment/Dockerfile +5 -0
  536. package/eval/local/tasks/workflow-overlay-contract/instruction.md +5 -0
  537. package/eval/local/tasks/workflow-overlay-contract/task.toml +21 -0
  538. package/eval/local/tasks/workflow-overlay-contract/validation/test_workflow_overlay_contract.py +235 -0
  539. package/eval/local/tasks/workflow-route-conformance/environment/Dockerfile +2 -0
  540. package/eval/local/tasks/workflow-route-conformance/instruction.md +5 -0
  541. package/eval/local/tasks/workflow-route-conformance/task.toml +21 -0
  542. package/eval/local/tasks/workflow-route-conformance/validation/test_workflow_route_conformance.py +84 -0
  543. package/eval/local/tests/conftest.py +1148 -0
  544. package/eval/local/tests/scaffold/test_attribution.py +48 -0
  545. package/eval/local/tests/scaffold/test_compare_baselines.py +999 -0
  546. package/eval/local/tests/scaffold/test_conftest_helpers.py +534 -0
  547. package/eval/local/tests/scaffold/test_evidence.py +15 -0
  548. package/eval/local/tests/scaffold/test_langsmith_conftest.py +244 -0
  549. package/eval/local/tests/scaffold/test_logging.py +243 -0
  550. package/eval/local/tests/scaffold/test_manifests.py +132 -0
  551. package/eval/local/tests/scaffold/test_profiles.py +866 -0
  552. package/eval/local/tests/scaffold/test_regression_check.py +19 -0
  553. package/eval/local/tests/scaffold/test_report_style_demo_charts.py +45 -0
  554. package/eval/local/tests/scaffold/test_sample_quality.py +211 -0
  555. package/eval/local/tests/scaffold/test_tasks.py +168 -0
  556. package/eval/local/tests/scaffold/test_treatments.py +244 -0
  557. package/eval/local/tests/scaffold/test_utils.py +139 -0
  558. package/eval/local/tests/tasks/test_tasks.py +445 -0
  559. package/eval/local/tests/tasks/test_validation_scripts.py +143 -0
  560. package/eval/local/treatments/comet/comet_full_039.yaml +141 -0
  561. package/eval/local/treatments/comet/comet_full_040_beta.yaml +140 -0
  562. package/eval/local/treatments/common/control.yaml +4 -0
  563. package/eval/pyproject.toml +41 -0
  564. package/eval/report-html-config.json +6 -0
  565. package/eval/scaffold/__init__.py +67 -0
  566. package/eval/scaffold/python/__init__.py +95 -0
  567. package/eval/scaffold/python/attribution.py +43 -0
  568. package/eval/scaffold/python/evidence.py +38 -0
  569. package/eval/scaffold/python/external_data_handler.py +18 -0
  570. package/eval/scaffold/python/generic_llm_judge.py +235 -0
  571. package/eval/scaffold/python/judge_config.py +168 -0
  572. package/eval/scaffold/python/llm_judge.py +191 -0
  573. package/eval/scaffold/python/logging.py +705 -0
  574. package/eval/scaffold/python/manifests.py +129 -0
  575. package/eval/scaffold/python/paper_charts.py +25 -0
  576. package/eval/scaffold/python/pass_at_k.py +107 -0
  577. package/eval/scaffold/python/paths.py +56 -0
  578. package/eval/scaffold/python/profiles.py +127 -0
  579. package/eval/scaffold/python/report_outputs.py +1391 -0
  580. package/eval/scaffold/python/sample_quality.py +339 -0
  581. package/eval/scaffold/python/schema.py +39 -0
  582. package/eval/scaffold/python/skill_parser.py +469 -0
  583. package/eval/scaffold/python/tasks.py +330 -0
  584. package/eval/scaffold/python/treatments.py +271 -0
  585. package/eval/scaffold/python/utils.py +366 -0
  586. package/eval/scaffold/python/validation/__init__.py +21 -0
  587. package/eval/scaffold/python/validation/authoring_rubric.py +326 -0
  588. package/eval/scaffold/python/validation/comet_workflow.py +187 -0
  589. package/eval/scaffold/python/validation/core.py +264 -0
  590. package/eval/scaffold/python/validation/dataset.py +337 -0
  591. package/eval/scaffold/python/validation/docker.py +106 -0
  592. package/eval/scaffold/python/validation/evaluator.py +549 -0
  593. package/eval/scaffold/python/validation/generic_rubric.py +169 -0
  594. package/eval/scaffold/python/validation/rubric.py +740 -0
  595. package/eval/scaffold/python/validation/runner.py +237 -0
  596. package/eval/scaffold/python/validation/scripts.py +58 -0
  597. package/eval/scaffold/python/validation/tracing.py +313 -0
  598. package/eval/scaffold/shell/common.sh +126 -0
  599. package/eval/scaffold/shell/docker.sh +482 -0
  600. package/eval/scaffold/shell/run-claude-loop.sh +181 -0
  601. package/eval/scaffold/shell/setup.sh +259 -0
  602. package/eval/simulator-instruction.md +9 -0
  603. package/package.json +29 -2
  604. package/dist/domains/dashboard/web/assets/index-BcO3_QlT.css +0 -1
  605. package/dist/domains/dashboard/web/assets/index-CjU3VXVu.js +0 -22
@@ -0,0 +1,740 @@
1
+ """Comet skill rubric validator.
2
+
3
+ Scores a comet workflow run across nine dimensions by analysing the
4
+ captured Claude events and the artifacts left in the test directory. Every
5
+ dimension emits a single check message of the form::
6
+
7
+ [RUBRIC] <dim>: <score> - <reason>
8
+
9
+ where ``<score>`` is 0.0-1.0 (pass rate of binary checks) and ``<reason>`` is a
10
+ short human-readable justification. The logging layer parses these messages to
11
+ build per-dimension columns in the experiment summary.
12
+
13
+ Scoring methodology (aligned with industry best practices from Galileo, Hebbia,
14
+ τ-bench):
15
+ - Each dimension contains N binary pass/fail checks
16
+ - Dimension score = passed / total checks (0.0-1.0)
17
+ - Final weighted score = Σ(dimension_score × weight) / Σ(weight)
18
+ - Weights reflect dimension importance to workflow quality
19
+
20
+ Dimensions
21
+ ----------
22
+ 1. main_flow - how many workflow-specific phases left evidence (weight 1.5)
23
+ 2. gate_guard - whether comet-guard / comet-state transition / --apply were used (weight 1.5)
24
+ 3. skill_invocation - whether the comet entry, nested stage skills, and dependency skills were invoked (weight 1.0)
25
+ 4. spec_drift - whether delta specs created during build were reconciled before archive (weight 1.0)
26
+ 5. business_completion - fraction of business validators that passed (weight 2.0)
27
+ 6. workflow_completion - fraction of workflow validators that passed (weight 1.0)
28
+ 7. efficiency - normalised cost (turns / tool calls / duration; lower is better) (weight 0.8)
29
+ 8. decision_point_compliance - whether agent paused at blocking decision points instead of auto-deciding (weight 1.0)
30
+ 9. artifact_quality - whether proposal/design/tasks/test artefacts have substantive content (weight 1.2)
31
+ 10. recovery_resilience - whether the agent preserved and restored state correctly across interruptions (weight 1.0)
32
+ """
33
+
34
+ from __future__ import annotations
35
+
36
+ import json
37
+ import os
38
+ import re
39
+ from pathlib import Path
40
+ from typing import Any
41
+
42
+ from scaffold.python.validation.core import ValidatorFn
43
+
44
+ # All nine rubric dimensions, in display order.
45
+ RUBRIC_DIMENSIONS = (
46
+ "main_flow",
47
+ "gate_guard",
48
+ "skill_invocation",
49
+ "spec_drift",
50
+ "business_completion",
51
+ "workflow_completion",
52
+ "efficiency",
53
+ "decision_point_compliance",
54
+ "artifact_quality",
55
+ "recovery_resilience",
56
+ )
57
+
58
+ # Dimension weights: critical dimensions get higher relative weight.
59
+ # Raw weights need not sum to 1.0; they are normalized during aggregation.
60
+ _DIMENSION_WEIGHTS: dict[str, float] = {
61
+ "business_completion": 2.0, # Must complete the user-visible task
62
+ "workflow_completion": 1.0, # Workflow-specific validator completion
63
+ "main_flow": 1.5, # Core 5-phase workflow
64
+ "gate_guard": 1.5, # Quality gate enforcement
65
+ "artifact_quality": 1.2, # Substantive deliverables
66
+ "skill_invocation": 1.0, # Correct skill ordering
67
+ "spec_drift": 1.0, # Spec reconciliation
68
+ "decision_point_compliance": 1.0, # User confirmation at gates
69
+ "recovery_resilience": 1.0, # State preservation
70
+ "efficiency": 0.8, # Nice-to-have, not critical
71
+ }
72
+
73
+ # Comet stage skills and dependency skills that should be observable as real
74
+ # Skill tool invocations, not inferred from generated artifacts.
75
+ _COMET_STAGE_SKILLS = (
76
+ "comet-open",
77
+ "comet-design",
78
+ "comet-build",
79
+ "comet-verify",
80
+ "comet-archive",
81
+ "comet-hotfix",
82
+ "comet-tweak",
83
+ )
84
+
85
+ _SUPERPOWERS_DEPENDENCY_SKILLS = (
86
+ "brainstorming",
87
+ "dispatching-parallel-agents",
88
+ "executing-plans",
89
+ "finishing-a-development-branch",
90
+ "requesting-code-review",
91
+ "subagent-driven-development",
92
+ "systematic-debugging",
93
+ "test-driven-development",
94
+ "using-git-worktrees",
95
+ "verification-before-completion",
96
+ "writing-plans",
97
+ )
98
+
99
+ # Decision-point state mutations that must be preceded by an explicit user
100
+ # confirmation (per comet/reference/decision-point.md). If any of these appear
101
+ # in commands_run without a nearby "ask"/"confirm" tool signal it is a
102
+ # compliance smell.
103
+ _DECISION_MUTATIONS = (
104
+ re.compile(r"transition\s+\S+\s+(?:open-complete|design-complete|build-complete|verify-pass|verify-fail|preset-escalate)"),
105
+ re.compile(r"set\s+\S+\s+(?:build_mode|isolation|tdd_mode|review_mode|build_pause)\s"),
106
+ )
107
+
108
+ # Files whose creation signals a given phase produced artefacts.
109
+ # Comet writes to several locations; cover both the canonical openspec/changes
110
+ # layout and the docs/superpowers/ + openspec/archive/ layouts actually used.
111
+ _PHASE_SIGNALS = {
112
+ "open": (
113
+ re.compile(r"openspec/changes/[^/]+/(?:proposal|tasks)\.md"),
114
+ re.compile(r"openspec/changes/archive/[^/]+/(?:proposal|tasks)\.md"),
115
+ ),
116
+ "design": (
117
+ re.compile(r"docs/superpowers/specs/.+\.md"),
118
+ re.compile(r"openspec/changes/(?:archive/)?[^/]+/design\.md"),
119
+ ),
120
+ "build": (
121
+ re.compile(r"openspec/changes/(?:archive/)?[^/]+/plan\.md"),
122
+ re.compile(r"docs/superpowers/plans/.+\.md"),
123
+ re.compile(r"openspec/changes/(?:archive/)?[^/]+/\.comet/"),
124
+ ),
125
+ "verify": (
126
+ re.compile(r"openspec/changes/(?:archive/)?[^/]+/verification\.md"),
127
+ re.compile(r"docs/superpowers/reports/.+\.md"),
128
+ ),
129
+ "archive": (
130
+ re.compile(r"openspec/changes/archive/"),
131
+ re.compile(r"openspec/archive/"),
132
+ ),
133
+ }
134
+
135
+ # Substantive-content keywords for the design doc (brainstorming depth signals).
136
+ _DESIGN_DEPTH_KEYWORDS = (
137
+ "tradeoff",
138
+ "alternative",
139
+ "risk",
140
+ "consider",
141
+ "option",
142
+ "权衡",
143
+ "替代",
144
+ "风险",
145
+ "考虑",
146
+ "方案",
147
+ )
148
+
149
+ _WORKFLOW_PHASES = {
150
+ "full": ("open", "design", "build", "verify", "archive"),
151
+ "hotfix": ("open", "build", "verify", "archive"),
152
+ "tweak": ("open", "build", "verify", "archive"),
153
+ }
154
+
155
+ _PRESET_DECISION_MUTATIONS = (
156
+ re.compile(r"transition\s+\S+\s+(?:verify-fail|preset-escalate|archive-reopen)"),
157
+ )
158
+
159
+
160
+ def _fmt(dim: str, score: float, reason: str) -> str:
161
+ return f"[RUBRIC] {dim}: {score:.2f} - {reason}"
162
+
163
+
164
+ def _fmt_na(dim: str, reason: str) -> str:
165
+ return f"[RUBRIC] {dim}: N/A - {reason}"
166
+
167
+
168
+ def _fmt_weighted(score: float) -> str:
169
+ return f"[RUBRIC] weighted_score: {score:.2f}"
170
+
171
+
172
+ def _join_commands(events: dict[str, Any]) -> str:
173
+ return "\n".join(events.get("commands_run", []) or [])
174
+
175
+
176
+ def _binary_score(checks: list[bool]) -> tuple[float, str]:
177
+ """Convert a list of binary checks to a pass-rate score.
178
+
179
+ Returns (pass_rate, summary) where pass_rate = passed / total.
180
+ """
181
+ total = len(checks)
182
+ if total == 0:
183
+ return 0.0, "no checks"
184
+ passed = sum(1 for c in checks if c)
185
+ return passed / total, f"{passed}/{total} passed"
186
+
187
+
188
+ def _find_change_dir(test_dir: Path) -> Path | None:
189
+ """Find the comet change directory (active or archived)."""
190
+ changes_root = test_dir / "openspec" / "changes"
191
+ if not changes_root.exists():
192
+ return None
193
+
194
+ for d in changes_root.iterdir():
195
+ if not d.is_dir():
196
+ continue
197
+ if d.name == "archive":
198
+ for sub in d.iterdir():
199
+ if sub.is_dir() and (
200
+ (sub / ".comet.yaml").exists()
201
+ or (sub / ".comet").exists()
202
+ or (sub / "proposal.md").exists()
203
+ or (sub / "tasks.md").exists()
204
+ ):
205
+ return sub
206
+ elif (
207
+ (d / ".comet.yaml").exists()
208
+ or (d / ".comet").exists()
209
+ or (d / "proposal.md").exists()
210
+ or (d / "tasks.md").exists()
211
+ ):
212
+ return d
213
+ return None
214
+
215
+
216
+ def _detect_workflow_kind(events: dict[str, Any], test_dir: Path) -> str:
217
+ """Detect full/hotfix/tweak from observed Skill calls or .comet.yaml."""
218
+ invoked = events.get("skills_invoked", []) or []
219
+ if "comet-hotfix" in invoked:
220
+ return "hotfix"
221
+ if "comet-tweak" in invoked:
222
+ return "tweak"
223
+
224
+ cdir = _find_change_dir(test_dir)
225
+ yaml_path = cdir / ".comet.yaml" if cdir else None
226
+ if yaml_path and yaml_path.exists():
227
+ try:
228
+ yaml_content = yaml_path.read_text(errors="ignore")
229
+ match = re.search(
230
+ r"(?m)^\s*(?:workflow|classic_profile):\s*(full|hotfix|tweak)\b",
231
+ yaml_content,
232
+ )
233
+ if match:
234
+ return match.group(1)
235
+ except Exception:
236
+ pass
237
+
238
+ state_events_path = cdir / ".comet" / "state-events.jsonl" if cdir else None
239
+ if state_events_path and state_events_path.exists():
240
+ try:
241
+ state_events = state_events_path.read_text(errors="ignore")
242
+ match = re.search(r'"workflow"\s*:\s*"(full|hotfix|tweak)"', state_events)
243
+ if match:
244
+ return match.group(1)
245
+ except Exception:
246
+ pass
247
+
248
+ return "full"
249
+
250
+
251
+ def _artifact_haystack(events: dict[str, Any], test_dir: Path) -> str:
252
+ files = list(events.get("files_created", [])) + list(events.get("files_modified", []))
253
+ try:
254
+ on_disk = [
255
+ str(p.relative_to(test_dir)).replace("\\", "/")
256
+ for p in test_dir.rglob("*")
257
+ if p.is_file()
258
+ ]
259
+ except Exception:
260
+ on_disk = []
261
+ return "\n".join(files + on_disk)
262
+
263
+
264
+ def _score_main_flow(
265
+ events: dict[str, Any], test_dir: Path, workflow: str
266
+ ) -> tuple[float, str]:
267
+ """Check which workflow-specific phases left evidence."""
268
+ haystack = _artifact_haystack(events, test_dir)
269
+
270
+ expected_phases = _WORKFLOW_PHASES[workflow]
271
+ phase_checks: list[bool] = []
272
+ phases_reached: list[str] = []
273
+ for phase in expected_phases:
274
+ patterns = _PHASE_SIGNALS[phase]
275
+ found = any(p.search(haystack) for p in patterns)
276
+ phase_checks.append(found)
277
+ if found:
278
+ phases_reached.append(phase)
279
+
280
+ score, _ = _binary_score(phase_checks)
281
+ return (
282
+ score,
283
+ "workflow={workflow} {reached}/{total} phases ({phases})".format(
284
+ workflow=workflow,
285
+ reached=len(phases_reached),
286
+ total=len(expected_phases),
287
+ phases=", ".join(phases_reached) if phases_reached else "none",
288
+ ),
289
+ )
290
+
291
+
292
+ def _score_gate_guard(events: dict[str, Any]) -> tuple[float, str]:
293
+ """Check guard/state/apply usage. Binary checks: guard used, transitions used, apply used."""
294
+ cmds = _join_commands(events)
295
+ if not cmds:
296
+ return 0.0, "no commands captured"
297
+
298
+ guard_used = bool(re.search(r"comet-guard", cmds))
299
+ transition_used = bool(re.search(r"transition\s+\S+\s+(?:open|design|build|verify|archive)", cmds))
300
+ apply_used = bool(re.search(r"--apply", cmds))
301
+
302
+ checks = [guard_used, transition_used, apply_used]
303
+ score, _ = _binary_score(checks)
304
+
305
+ guard_hits = len(re.findall(r"comet-guard", cmds))
306
+ transition_hits = len(re.findall(r"transition\s+\S+\s+(?:open|design|build|verify|archive)", cmds))
307
+ apply_hits = len(re.findall(r"--apply", cmds))
308
+
309
+ return score, f"guard={guard_hits} transition={transition_hits} apply={apply_hits}"
310
+
311
+
312
+ def _score_skill_invocation(events: dict[str, Any]) -> tuple[float, str]:
313
+ """Check real Skill tool usage across Comet stage and dependency layers."""
314
+ invoked = events.get("skills_invoked", []) or []
315
+ if not invoked:
316
+ return 0.0, "no skills invoked"
317
+
318
+ comet_entry = "comet" in invoked
319
+ comet_stage_invoked = [skill for skill in invoked if skill in _COMET_STAGE_SKILLS]
320
+ openspec_invoked = [skill for skill in invoked if skill.startswith("openspec-")]
321
+ superpowers_invoked = [
322
+ skill for skill in invoked if skill in _SUPERPOWERS_DEPENDENCY_SKILLS
323
+ ]
324
+ if comet_stage_invoked:
325
+ first_stage_index = min(invoked.index(skill) for skill in comet_stage_invoked)
326
+ else:
327
+ first_stage_index = -1
328
+ entry_before_stage = comet_entry and first_stage_index > invoked.index("comet")
329
+
330
+ checks = [
331
+ comet_entry,
332
+ bool(comet_stage_invoked),
333
+ bool(openspec_invoked),
334
+ bool(superpowers_invoked),
335
+ entry_before_stage,
336
+ ]
337
+ score, _ = _binary_score(checks)
338
+
339
+ return (
340
+ score,
341
+ "entry={entry} comet_stage={stage} openspec={openspec} "
342
+ "superpowers={superpowers} order={order}".format(
343
+ entry="comet" if comet_entry else "missing",
344
+ stage=", ".join(comet_stage_invoked) if comet_stage_invoked else "missing",
345
+ openspec=", ".join(openspec_invoked) if openspec_invoked else "missing",
346
+ superpowers=", ".join(superpowers_invoked) if superpowers_invoked else "missing",
347
+ order="entry-before-stage" if entry_before_stage else "missing",
348
+ ),
349
+ )
350
+
351
+
352
+ def _score_spec_drift(events: dict[str, Any], test_dir: Path) -> tuple[float, str]:
353
+ """Check delta spec reconciliation. Binary: spec written AND synced."""
354
+ cmds = _join_commands(events)
355
+ files = list(events.get("files_modified", [])) + list(events.get("files_created", []))
356
+
357
+ spec_touched = any("specs/" in f and "openspec/changes" in f for f in files)
358
+ spec_synced = bool(re.search(r"openspec\s+(?:sync|archive)", cmds))
359
+
360
+ if not spec_touched:
361
+ # No delta spec needed — neutral pass (not applicable)
362
+ return 1.0, "no delta spec needed (n/a)"
363
+
364
+ # Binary: was it synced?
365
+ checks = [spec_touched, spec_synced]
366
+ score, _ = _binary_score(checks)
367
+ return score, f"spec_written={spec_touched} spec_synced={spec_synced}"
368
+
369
+
370
+ def _score_completion(outputs: dict[str, Any], key: str = "completion") -> tuple[float, str]:
371
+ """Check validator pass rate. Already a ratio (0.0-1.0)."""
372
+ checks = outputs.get(key) or {}
373
+ passed = checks.get("passed", [])
374
+ failed = checks.get("failed", [])
375
+ total = len(passed) + len(failed)
376
+ if total == 0:
377
+ return 0.0, "no baseline checks ran"
378
+ ratio = len(passed) / total
379
+ return float(ratio), f"{len(passed)}/{total} baseline checks passed"
380
+
381
+
382
+ def _score_efficiency(events: dict[str, Any]) -> tuple[float, str]:
383
+ """Check efficiency via binary thresholds. Each metric is pass/fail at threshold."""
384
+ turns = events.get("num_turns") or 0
385
+ tool_calls = len(events.get("tool_calls", []))
386
+ duration = events.get("duration_seconds") or 0
387
+
388
+ # Binary thresholds: "good enough" vs "too expensive"
389
+ turns_ok = turns <= 80
390
+ tools_ok = tool_calls <= 150
391
+ duration_ok = duration <= 600
392
+
393
+ checks = [turns_ok, tools_ok, duration_ok]
394
+ score, _ = _binary_score(checks)
395
+ return score, f"turns={turns} tools={tool_calls} dur={duration:.0f}s"
396
+
397
+
398
+ def _score_decision_point_compliance(
399
+ events: dict[str, Any], workflow: str
400
+ ) -> tuple[float, str]:
401
+ """Check if agent asked user at decision points. Binary: ratio >= 0.5."""
402
+ cmds = _join_commands(events)
403
+ tool_calls = events.get("tool_calls", []) or []
404
+
405
+ if not cmds:
406
+ return 0.0, "no commands captured"
407
+
408
+ ask_signals = sum(
409
+ 1
410
+ for tc in tool_calls
411
+ if tc.get("tool") in {"AskUserQuestion", "ask_user", "AskFollowUpQuestion"}
412
+ )
413
+
414
+ mutation_patterns = (
415
+ _DECISION_MUTATIONS if workflow == "full" else _PRESET_DECISION_MUTATIONS
416
+ )
417
+ mutations = sum(len(rx.findall(cmds)) for rx in mutation_patterns)
418
+
419
+ if mutations == 0:
420
+ # No decision points reached — neutral pass
421
+ return 1.0, f"no {workflow} decision mutations observed"
422
+
423
+ # Binary: did the agent ask at least once per mutation?
424
+ ratio = ask_signals / max(mutations, 1)
425
+ checks = [ratio >= 0.5]
426
+ score, _ = _binary_score(checks)
427
+ return (
428
+ score,
429
+ f"workflow={workflow} {ask_signals} asks for {mutations} mutations "
430
+ f"(ratio={ratio:.2f})",
431
+ )
432
+
433
+
434
+ def _score_artifact_quality(test_dir: Path, workflow: str) -> tuple[float, str]:
435
+ """Check artifact quality via binary checks per artifact type."""
436
+ changes_root = test_dir / "openspec" / "changes"
437
+ change_dirs: list[Path] = []
438
+ if changes_root.exists():
439
+ for d in changes_root.iterdir():
440
+ if not d.is_dir():
441
+ continue
442
+ if d.name == "archive":
443
+ change_dirs.extend(s for s in d.iterdir() if s.is_dir())
444
+ elif (d / "proposal.md").exists() or (d / "tasks.md").exists():
445
+ change_dirs.append(d)
446
+
447
+ if not change_dirs:
448
+ return 0.0, "no openspec change directory"
449
+
450
+ cdir = change_dirs[0]
451
+ checks: list[bool] = []
452
+ notes: list[str] = []
453
+
454
+ # Check 1: Proposal has substance (>= 10 lines)
455
+ prop = cdir / "proposal.md"
456
+ prop_text = prop.read_text(errors="ignore") if prop.exists() else ""
457
+ prop_ok = prop_text.count("\n") >= 10
458
+ checks.append(prop_ok)
459
+ notes.append(f"workflow={workflow} proposal={'ok' if prop_ok else 'stub'}")
460
+
461
+ # Check 2: Design doc exists with depth keywords
462
+ design = cdir / "design.md"
463
+ if workflow == "full":
464
+ dtext = design.read_text(errors="ignore").lower() if design.exists() else ""
465
+ depth_hits = sum(1 for kw in _DESIGN_DEPTH_KEYWORDS if kw in dtext)
466
+ design_ok = design.exists() and depth_hits >= 2
467
+ checks.append(design_ok)
468
+ notes.append(f"design={'deep' if design_ok else 'shallow'}")
469
+ elif design.exists():
470
+ notes.append("design=preset-optional")
471
+
472
+ # Check 3: Tasks has checkboxes
473
+ tasks = cdir / "tasks.md"
474
+ if tasks.exists():
475
+ ttext = tasks.read_text(errors="ignore")
476
+ checkboxes = len(re.findall(r"- \[[ x]\]", ttext))
477
+ min_tasks = 3 if workflow == "full" else 1
478
+ tasks_ok = checkboxes >= min_tasks
479
+ checks.append(tasks_ok)
480
+ notes.append(f"tasks={checkboxes} boxes")
481
+
482
+ # Check 4: Tests have assertions
483
+ test_files = list(test_dir.glob("test_*.py")) + list(test_dir.glob("**/test_*.py"))
484
+ test_has_assert = False
485
+ for tf in test_files:
486
+ try:
487
+ if "assert" in tf.read_text(errors="ignore").lower():
488
+ test_has_assert = True
489
+ break
490
+ except Exception:
491
+ continue
492
+ if workflow in {"full", "hotfix"} or test_files:
493
+ checks.append(test_has_assert)
494
+ notes.append(f"tests={'w/ assert' if test_has_assert else 'no assert'}")
495
+ else:
496
+ notes.append("tests=n/a")
497
+
498
+ score, _ = _binary_score(checks)
499
+ return score, "; ".join(notes)
500
+
501
+
502
+ def _score_recovery_resilience(
503
+ events: dict[str, Any], test_dir: Path, workflow: str
504
+ ) -> tuple[float, str]:
505
+ """Check recovery artifacts via binary checks."""
506
+ cdir = _find_change_dir(test_dir)
507
+ if not cdir:
508
+ return 0.0, "no comet change directory"
509
+
510
+ comet_dir = cdir / ".comet"
511
+ checks: list[bool] = []
512
+ notes: list[str] = []
513
+
514
+ # Check 1: Checkpoint exists and valid
515
+ checkpoint_path = comet_dir / "checkpoint.json"
516
+ state_events_path = comet_dir / "state-events.jsonl"
517
+ run_state_path = comet_dir / "run-state.json"
518
+ if checkpoint_path.exists():
519
+ try:
520
+ checkpoint = json.loads(checkpoint_path.read_text(errors="ignore"))
521
+ checkpoint_ok = (
522
+ bool(checkpoint.get("runId"))
523
+ and "contextHash" in checkpoint
524
+ and bool(checkpoint.get("artifactsHash"))
525
+ and bool(checkpoint.get("createdAt"))
526
+ )
527
+ checks.append(checkpoint_ok)
528
+ notes.append(f"checkpoint={'valid' if checkpoint_ok else 'invalid'}")
529
+ except Exception:
530
+ checks.append(False)
531
+ notes.append("checkpoint=unreadable")
532
+ elif state_events_path.exists() or run_state_path.exists():
533
+ checks.append(True)
534
+ notes.append("checkpoint=state-events")
535
+ else:
536
+ checks.append(False)
537
+ notes.append("checkpoint=missing")
538
+
539
+ # Check 2: Trajectory exists
540
+ trajectory_files = list(comet_dir.glob("trajectory*.jsonl"))
541
+ trajectory_ok = bool(trajectory_files)
542
+ checks.append(trajectory_ok)
543
+ notes.append(f"trajectory={'exists' if trajectory_ok else 'missing'}")
544
+
545
+ # Check 3: Context snapshot exists
546
+ context_files = list(comet_dir.glob("**/context.*"))
547
+ handoff_dir = comet_dir / "handoff"
548
+ handoff_files = list(handoff_dir.glob("*.md")) + list(handoff_dir.glob("*.json")) if handoff_dir.exists() else []
549
+ context_ok = bool(context_files or handoff_files)
550
+ if workflow == "full":
551
+ checks.append(context_ok)
552
+ notes.append(f"context={'exists' if context_ok else 'missing'}")
553
+ else:
554
+ notes.append(f"context={'exists' if context_ok else 'preset-n/a'}")
555
+
556
+ # Check 4: No orphaned pending actions
557
+ pending_files = list(comet_dir.glob("**/pending*.json"))
558
+ pending_clean = True
559
+ for pf in pending_files:
560
+ try:
561
+ content = json.loads(pf.read_text(errors="ignore"))
562
+ if content:
563
+ pending_clean = False
564
+ break
565
+ except Exception:
566
+ pass
567
+ checks.append(pending_clean)
568
+ notes.append(f"pending={'clean' if pending_clean else 'orphaned'}")
569
+
570
+ # Check 5: .comet.yaml has phase field
571
+ yaml_path = cdir / ".comet.yaml"
572
+ if yaml_path.exists():
573
+ try:
574
+ yaml_content = yaml_path.read_text(errors="ignore")
575
+ yaml_ok = bool(re.search(r"phase:\s*\w+", yaml_content))
576
+ checks.append(yaml_ok)
577
+ notes.append(f"state={'ok' if yaml_ok else 'incomplete'}")
578
+ except Exception:
579
+ checks.append(False)
580
+ notes.append("state=unreadable")
581
+ elif run_state_path.exists():
582
+ try:
583
+ run_state = json.loads(run_state_path.read_text(errors="ignore"))
584
+ state_ok = run_state.get("status") == "completed" or bool(
585
+ run_state.get("currentStep")
586
+ )
587
+ checks.append(state_ok)
588
+ notes.append(f"state={'ok' if state_ok else 'incomplete'}")
589
+ except Exception:
590
+ checks.append(False)
591
+ notes.append("state=unreadable")
592
+ else:
593
+ checks.append(False)
594
+ notes.append("state=missing")
595
+
596
+ score, _ = _binary_score(checks)
597
+ return score, "; ".join(notes)
598
+
599
+
600
+ def _compute_weighted_score(dimension_scores: dict[str, float | None]) -> float:
601
+ """Compute weighted average across applicable dimensions."""
602
+ total_weight = 0.0
603
+ weighted_sum = 0.0
604
+ for dim in RUBRIC_DIMENSIONS:
605
+ score = dimension_scores.get(dim)
606
+ if score is None:
607
+ continue
608
+ weight = _DIMENSION_WEIGHTS.get(dim, 1.0)
609
+ weighted_sum += score * weight
610
+ total_weight += weight
611
+ return weighted_sum / total_weight if total_weight > 0 else 0.0
612
+
613
+
614
+ def _is_control_business_only(outputs: dict[str, Any]) -> bool:
615
+ return (outputs or {}).get("treatment_name") == "CONTROL"
616
+
617
+
618
+ def _completion_input(outputs: dict[str, Any], key: str) -> dict[str, list[str]] | None:
619
+ if key in outputs:
620
+ return outputs.get(key) or {"passed": [], "failed": []}
621
+ if key == "business_completion":
622
+ return outputs.get("completion") or {"passed": [], "failed": []}
623
+ return None
624
+
625
+
626
+ def comet_rubric_validator(test_dir: Path, outputs: dict) -> tuple[list[str], list[str]]:
627
+ """Run all rubric dimensions and return (passed_messages, []).
628
+
629
+ Rubric dimensions are informational scores (never hard failures); the
630
+ comparison report aggregates them across treatments. Every dimension always
631
+ emits exactly one ``[RUBRIC]`` message.
632
+
633
+ Scoring: each dimension uses binary checks, score = pass rate (0.0-1.0).
634
+ Final weighted score uses dimension weights to aggregate.
635
+ """
636
+ events = (outputs or {}).get("events", {}) or {}
637
+ business_completion = _completion_input(outputs or {}, "business_completion")
638
+ workflow_completion = _completion_input(outputs or {}, "workflow_completion")
639
+ is_control = _is_control_business_only(outputs or {})
640
+ workflow = _detect_workflow_kind(events, test_dir)
641
+
642
+ if is_control:
643
+ na_reason = "CONTROL business-only baseline"
644
+ scored: list[tuple[str, float | None, str]] = [
645
+ ("main_flow", None, na_reason),
646
+ ("gate_guard", None, na_reason),
647
+ ("skill_invocation", None, na_reason),
648
+ ("spec_drift", None, na_reason),
649
+ (
650
+ "business_completion",
651
+ *_score_completion(
652
+ {"business_completion": business_completion},
653
+ "business_completion",
654
+ ),
655
+ ),
656
+ ("workflow_completion", None, na_reason),
657
+ ("efficiency", *_score_efficiency(events)),
658
+ ("decision_point_compliance", None, na_reason),
659
+ ("artifact_quality", None, na_reason),
660
+ ("recovery_resilience", None, na_reason),
661
+ ]
662
+ else:
663
+ scored = [
664
+ ("main_flow", *_score_main_flow(events, test_dir, workflow)),
665
+ ("gate_guard", *_score_gate_guard(events)),
666
+ ("skill_invocation", *_score_skill_invocation(events)),
667
+ ("spec_drift", *_score_spec_drift(events, test_dir)),
668
+ (
669
+ "business_completion",
670
+ *_score_completion(
671
+ {"business_completion": business_completion},
672
+ "business_completion",
673
+ ),
674
+ ),
675
+ (
676
+ "workflow_completion",
677
+ None,
678
+ "workflow validators not available",
679
+ )
680
+ if workflow_completion is None
681
+ else (
682
+ "workflow_completion",
683
+ *_score_completion(
684
+ {"workflow_completion": workflow_completion},
685
+ "workflow_completion",
686
+ ),
687
+ ),
688
+ ("efficiency", *_score_efficiency(events)),
689
+ ("decision_point_compliance", *_score_decision_point_compliance(events, workflow)),
690
+ ("artifact_quality", *_score_artifact_quality(test_dir, workflow)),
691
+ ("recovery_resilience", *_score_recovery_resilience(events, test_dir, workflow)),
692
+ ]
693
+
694
+ # Build dimension scores dict for weighted computation
695
+ dimension_scores: dict[str, float | None] = {}
696
+ passed: list[str] = []
697
+ failed: list[str] = []
698
+ for dim, score, reason in scored:
699
+ dimension_scores[dim] = score
700
+ if score is None:
701
+ passed.append(_fmt_na(dim, reason))
702
+ else:
703
+ passed.append(_fmt(dim, score, reason))
704
+
705
+ # Add weighted overall score
706
+ weighted = _compute_weighted_score(dimension_scores)
707
+ passed.append(_fmt_weighted(weighted))
708
+
709
+ if not is_control:
710
+ invoked = events.get("skills_invoked", []) or []
711
+ if "comet" not in invoked:
712
+ failed.append("Required skill not invoked: comet")
713
+ else:
714
+ if not any(skill in invoked for skill in _COMET_STAGE_SKILLS):
715
+ failed.append("Required nested Comet stage skill not invoked")
716
+ if not any(skill.startswith("openspec-") for skill in invoked):
717
+ failed.append("Required OpenSpec dependency skill not invoked")
718
+ if not any(skill in invoked for skill in _SUPERPOWERS_DEPENDENCY_SKILLS):
719
+ failed.append("Required Superpowers dependency skill not invoked")
720
+
721
+ # Optional LLM-as-judge overlay: when BENCH_LLM_JUDGE=1, a judge model
722
+ # re-scores the three qualitative dimensions (artifact_quality, spec_drift,
723
+ # main_flow) by reading the actual artifacts. These [RUBRIC-JUDGE] messages
724
+ # supplement (do not replace) the rule-based [RUBRIC] scores so the report
725
+ # can show rule vs judge agreement.
726
+ if os.environ.get("BENCH_LLM_JUDGE") == "1":
727
+ try:
728
+ from scaffold.python.llm_judge import judge_messages
729
+
730
+ judge_results = judge_messages(test_dir)
731
+ passed.extend(judge_results)
732
+ if any(
733
+ result.startswith("[RUBRIC-JUDGE] ") and " status:" not in result
734
+ for result in judge_results
735
+ ):
736
+ passed.append("[RUBRIC-JUDGE] status: enabled_and_successful")
737
+ except Exception as e:
738
+ passed.append(f"[RUBRIC-JUDGE] status: failed - {e}")
739
+
740
+ return passed, failed