@hassangameryt/freeflow 0.7.3 → 0.9.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 (426) hide show
  1. package/.agents/plugins/marketplace.json +2 -2
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/.claude-plugin/plugin.json +2 -2
  4. package/.codex-plugin/plugin.json +3 -3
  5. package/.cursor-plugin/plugin.json +1 -1
  6. package/NOTICE +14 -0
  7. package/README.md +101 -159
  8. package/capabilities/cognitive-routing/SKILL.md +47 -210
  9. package/capabilities/cognitive-routing/references/coordinator.md +163 -0
  10. package/capabilities/cognitive-routing/references/worker.md +38 -0
  11. package/capabilities/compaction/SKILL.md +49 -0
  12. package/capabilities/compaction/references/summary-format.md +250 -0
  13. package/capabilities/messaging/SKILL.md +49 -0
  14. package/capabilities/task-memory/SKILL.md +87 -0
  15. package/command-surface.json +8 -52
  16. package/gemini-extension.json +1 -1
  17. package/hooks/claude/hooks.json +13 -3
  18. package/hooks/codex/hooks.json +2 -1
  19. package/hooks/shared/runtime-context.mjs +73 -83
  20. package/licenses/Apache-2.0.txt +55 -0
  21. package/package.json +42 -12
  22. package/pi-extension/README.md +41 -0
  23. package/pi-extension/dist/ask-user/ask.js +108 -0
  24. package/pi-extension/dist/ask-user/form.js +250 -0
  25. package/pi-extension/dist/ask-user/questions.js +66 -0
  26. package/pi-extension/dist/ask-user/tool.js +124 -0
  27. package/pi-extension/dist/cognitive-routing/assembler.js +417 -0
  28. package/pi-extension/dist/cognitive-routing/bootstrap.js +90 -0
  29. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/config.js +8 -6
  30. package/pi-extension/dist/cognitive-routing/economics.js +45 -0
  31. package/pi-extension/dist/cognitive-routing/event-schema.js +388 -0
  32. package/pi-extension/dist/{session-sources/events.js → cognitive-routing/event-store.js} +107 -41
  33. package/pi-extension/dist/cognitive-routing/gate.js +256 -0
  34. package/pi-extension/dist/cognitive-routing/handlers.js +901 -0
  35. package/pi-extension/dist/cognitive-routing/handoffs.js +350 -0
  36. package/pi-extension/dist/cognitive-routing/model-control.js +476 -0
  37. package/pi-extension/dist/cognitive-routing/projection.js +520 -0
  38. package/pi-extension/dist/cognitive-routing/provenance.js +83 -0
  39. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/render.js +15 -15
  40. package/pi-extension/dist/cognitive-routing/runtime.js +398 -0
  41. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/schemas.js +47 -11
  42. package/pi-extension/dist/cognitive-routing/session.js +223 -0
  43. package/pi-extension/dist/{session-sources → cognitive-routing}/sources.js +126 -87
  44. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/state.js +55 -386
  45. package/pi-extension/dist/cognitive-routing/status.js +81 -0
  46. package/pi-extension/dist/cognitive-routing/tools.js +74 -0
  47. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/types.js +14 -11
  48. package/pi-extension/dist/compaction/carry.js +205 -0
  49. package/pi-extension/dist/compaction/config.js +24 -0
  50. package/pi-extension/dist/compaction/controller.js +494 -0
  51. package/pi-extension/dist/compaction/harness.js +93 -0
  52. package/pi-extension/dist/compaction/results.js +159 -0
  53. package/pi-extension/dist/compaction/thresholds.js +35 -0
  54. package/pi-extension/dist/compaction/tool.js +57 -0
  55. package/pi-extension/dist/host/branch.js +13 -0
  56. package/pi-extension/dist/host/canonical.js +12 -0
  57. package/pi-extension/dist/host/catalog.js +62 -0
  58. package/pi-extension/dist/host/config-validation.js +233 -0
  59. package/pi-extension/dist/host/config.js +361 -0
  60. package/pi-extension/dist/host/inbound.js +142 -0
  61. package/pi-extension/dist/host/projection-tags.js +60 -0
  62. package/pi-extension/dist/host/prompts.js +93 -0
  63. package/pi-extension/dist/{session-sources → host}/read-only-session.js +117 -1
  64. package/pi-extension/dist/{runtime → host}/request-history.js +125 -39
  65. package/pi-extension/dist/host/rows.js +25 -0
  66. package/pi-extension/dist/host/runtime-state.js +204 -0
  67. package/pi-extension/dist/host/section-keeper.js +85 -0
  68. package/pi-extension/dist/host/settings/freeflow-command.js +2323 -0
  69. package/pi-extension/dist/{settings/settings-tui.js → host/settings/settings-view.js} +205 -73
  70. package/pi-extension/dist/host/staging.js +28 -0
  71. package/pi-extension/dist/host/status.js +115 -0
  72. package/pi-extension/dist/index.js +1004 -188
  73. package/pi-extension/dist/messaging/config.js +27 -0
  74. package/pi-extension/dist/messaging/messaging.js +398 -0
  75. package/pi-extension/dist/messaging/registry.js +57 -0
  76. package/pi-extension/dist/messaging/render.js +90 -0
  77. package/pi-extension/dist/messaging/tools.js +109 -0
  78. package/pi-extension/dist/messaging/transport.js +101 -0
  79. package/pi-extension/dist/provider-support/cache/anchor.js +21 -0
  80. package/pi-extension/dist/provider-support/cache/anthropic.js +102 -0
  81. package/pi-extension/dist/provider-support/cache/health.js +73 -0
  82. package/pi-extension/dist/provider-support/cache/index.js +58 -0
  83. package/pi-extension/dist/provider-support/cache/keepalive.js +222 -0
  84. package/pi-extension/dist/provider-support/cache/monitor.js +17 -0
  85. package/pi-extension/dist/provider-support/cache/openai-responses.js +48 -0
  86. package/pi-extension/dist/provider-support/effort.js +13 -0
  87. package/pi-extension/dist/provider-support/index.js +44 -3
  88. package/pi-extension/dist/provider-support/{astra → openai}/adapter.js +46 -29
  89. package/pi-extension/dist/provider-support/{astra → openai}/history.js +10 -8
  90. package/pi-extension/dist/provider-support/{astra → openai}/index.js +8 -4
  91. package/pi-extension/dist/provider-support/{astra → openai}/session-state.js +29 -38
  92. package/pi-extension/dist/provider-support/routes.js +17 -0
  93. package/pi-extension/dist/task-memory/config.js +49 -0
  94. package/pi-extension/dist/task-memory/registry.js +119 -0
  95. package/pi-extension/dist/task-memory/render.js +107 -0
  96. package/pi-extension/dist/task-memory/runtime.js +994 -0
  97. package/pi-extension/dist/task-memory/tool.js +233 -0
  98. package/pi-extension/dist/tool-execution/apply-patch/grammar.js +23 -0
  99. package/pi-extension/dist/tool-execution/apply-patch/match.js +38 -0
  100. package/pi-extension/dist/tool-execution/apply-patch/parser.js +177 -0
  101. package/pi-extension/dist/tool-execution/apply-patch/plan.js +201 -0
  102. package/pi-extension/dist/tool-execution/apply-patch/tool.js +84 -0
  103. package/pi-extension/dist/tool-execution/background.js +430 -0
  104. package/pi-extension/dist/tool-execution/bash-guard.js +23 -0
  105. package/pi-extension/dist/tool-execution/config.js +33 -0
  106. package/pi-extension/dist/tool-execution/edit-messages.js +120 -0
  107. package/pi-extension/dist/tool-execution/file-state.js +138 -0
  108. package/pi-extension/dist/tool-execution/file-tracking.js +163 -0
  109. package/pi-extension/dist/tool-execution/guidance-notices.js +124 -0
  110. package/pi-extension/dist/tool-execution/prompt.js +54 -0
  111. package/pi-extension/dist/tool-execution/skill-reads.js +143 -0
  112. package/pi-extension/dist/tool-execution/tools.js +16 -0
  113. package/pi-extension/freeflow/README.md +9 -0
  114. package/runtime/prompts/cognitive-routing.md +4 -4
  115. package/runtime/prompts/core.md +29 -72
  116. package/runtime/prompts/interaction-contract.md +18 -8
  117. package/runtime/prompts/tool-execution.md +25 -0
  118. package/runtime/prompts/working-method.md +25 -0
  119. package/skills/deliver-work/SKILL.md +76 -0
  120. package/skills/deliver-work/references/branch-closeout.md +134 -0
  121. package/skills/deliver-work/references/commit.md +83 -0
  122. package/skills/deliver-work/references/launch.md +94 -0
  123. package/skills/deliver-work/references/release.md +85 -0
  124. package/skills/deliver-work/scripts/commit-state.mjs +139 -0
  125. package/skills/deliver-work/scripts/delivery-state.mjs +107 -0
  126. package/skills/deliver-work/scripts/lib/git-state.mjs +178 -0
  127. package/skills/deliver-work/scripts/push-route.mjs +122 -0
  128. package/skills/deliver-work/scripts/release-preflight.mjs +177 -0
  129. package/skills/discuss-work/SKILL.md +148 -0
  130. package/skills/{discuss → discuss-work}/references/discussion-continuity.md +13 -50
  131. package/skills/discuss-work/references/learning-action.md +36 -0
  132. package/skills/discuss-work/scripts/choices.mjs +101 -0
  133. package/skills/discuss-work/scripts/lib/choices.mjs +159 -0
  134. package/skills/evaluate-behavior/SKILL.md +107 -0
  135. package/skills/evaluate-behavior/references/authoring.md +381 -0
  136. package/skills/evaluate-behavior/references/coding-tasks.md +145 -0
  137. package/skills/evaluate-behavior/references/conversations-pipelines-judges.md +177 -0
  138. package/skills/evaluate-behavior/references/design-and-measurement.md +273 -0
  139. package/skills/evaluate-behavior/references/running-and-evidence.md +245 -0
  140. package/skills/evaluate-behavior/scripts/claude-guard.mjs +76 -0
  141. package/skills/evaluate-behavior/scripts/guard-rules.mjs +309 -0
  142. package/skills/evaluate-behavior/scripts/lib/agreement.mjs +90 -0
  143. package/skills/evaluate-behavior/scripts/lib/arms.mjs +55 -0
  144. package/skills/evaluate-behavior/scripts/lib/budget.mjs +87 -0
  145. package/skills/evaluate-behavior/scripts/lib/build-source.mjs +287 -0
  146. package/skills/evaluate-behavior/scripts/lib/clear.mjs +74 -0
  147. package/skills/evaluate-behavior/scripts/lib/container.mjs +395 -0
  148. package/skills/evaluate-behavior/scripts/lib/decision.mjs +418 -0
  149. package/skills/evaluate-behavior/scripts/lib/definitions.mjs +1072 -0
  150. package/skills/evaluate-behavior/scripts/lib/freeflow.mjs +103 -0
  151. package/skills/evaluate-behavior/scripts/lib/grade-command.mjs +591 -0
  152. package/skills/evaluate-behavior/scripts/lib/grade-comparison.mjs +90 -0
  153. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-interaction.mjs +19 -18
  154. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-support.mjs +32 -5
  155. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-workspace.mjs +28 -12
  156. package/skills/evaluate-behavior/scripts/lib/grade.mjs +101 -0
  157. package/skills/evaluate-behavior/scripts/lib/hooks.mjs +98 -0
  158. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/confinement.mjs +196 -0
  159. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/constraints.mjs +111 -0
  160. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/index.mjs +48 -0
  161. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/isolation.mjs +74 -0
  162. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/launch.mjs +123 -0
  163. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/model-call.mjs +73 -0
  164. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/recorder.mjs +178 -0
  165. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/session.mjs +494 -0
  166. package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/skills.mjs +81 -0
  167. package/skills/evaluate-behavior/scripts/lib/hosts/index.mjs +31 -0
  168. package/skills/evaluate-behavior/scripts/lib/hosts/names.mjs +3 -0
  169. package/skills/evaluate-behavior/scripts/lib/hosts/pi/confinement.mjs +173 -0
  170. package/skills/evaluate-behavior/scripts/lib/hosts/pi/host.mjs +148 -0
  171. package/skills/evaluate-behavior/scripts/lib/hosts/pi/index.mjs +70 -0
  172. package/skills/evaluate-behavior/scripts/lib/hosts/pi/isolation.mjs +81 -0
  173. package/skills/evaluate-behavior/scripts/lib/hosts/pi/model-call.mjs +79 -0
  174. package/skills/evaluate-behavior/scripts/lib/hosts/pi/process.mjs +241 -0
  175. package/skills/{evaluate-skill/scripts/lib → evaluate-behavior/scripts/lib/hosts/pi}/rpc.mjs +144 -26
  176. package/skills/evaluate-behavior/scripts/lib/identity.mjs +82 -0
  177. package/skills/evaluate-behavior/scripts/lib/judge.mjs +688 -0
  178. package/skills/evaluate-behavior/scripts/lib/metrics.mjs +332 -0
  179. package/skills/evaluate-behavior/scripts/lib/model-call.mjs +17 -0
  180. package/skills/evaluate-behavior/scripts/lib/participants.mjs +616 -0
  181. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/process.mjs +22 -0
  182. package/skills/evaluate-behavior/scripts/lib/queue.mjs +54 -0
  183. package/skills/evaluate-behavior/scripts/lib/reference.mjs +343 -0
  184. package/skills/evaluate-behavior/scripts/lib/reuse.mjs +277 -0
  185. package/skills/evaluate-behavior/scripts/lib/review.mjs +933 -0
  186. package/skills/evaluate-behavior/scripts/lib/runner.mjs +732 -0
  187. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/sandbox.mjs +121 -14
  188. package/skills/evaluate-behavior/scripts/lib/scan-shell.mjs +457 -0
  189. package/skills/evaluate-behavior/scripts/lib/scan.mjs +479 -0
  190. package/skills/evaluate-behavior/scripts/lib/seal.mjs +91 -0
  191. package/skills/evaluate-behavior/scripts/lib/shell.mjs +560 -0
  192. package/skills/evaluate-behavior/scripts/lib/source-override.mjs +64 -0
  193. package/skills/evaluate-behavior/scripts/lib/subject-file.mjs +88 -0
  194. package/skills/{evaluate-skill/scripts/lib/pi.mjs → evaluate-behavior/scripts/lib/subject.mjs} +239 -262
  195. package/skills/evaluate-behavior/scripts/lib/task-copy.mjs +124 -0
  196. package/skills/evaluate-behavior/scripts/lib/trials.mjs +524 -0
  197. package/skills/evaluate-behavior/scripts/lib/validity.mjs +68 -0
  198. package/skills/evaluate-behavior/scripts/lib/view-html.mjs +454 -0
  199. package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/view.mjs +218 -11
  200. package/skills/evaluate-behavior/scripts/pi-command-tool.mjs +159 -0
  201. package/skills/evaluate-behavior/scripts/pi-container-route.mjs +23 -0
  202. package/skills/evaluate-behavior/scripts/pi-guard.mjs +77 -0
  203. package/skills/evaluate-behavior/scripts/pi-login-refresh.mjs +31 -0
  204. package/skills/evaluate-behavior/scripts/skill-eval.mjs +586 -0
  205. package/skills/execute-work/SKILL.md +96 -72
  206. package/skills/execute-work/references/code-practices.md +27 -49
  207. package/skills/execute-work/references/design.md +271 -0
  208. package/skills/execute-work/references/diagnose.md +117 -0
  209. package/skills/execute-work/references/migration.md +108 -0
  210. package/skills/execute-work/references/simplify.md +65 -0
  211. package/skills/execute-work/scripts/self-review.mjs +422 -0
  212. package/skills/execute-work/scripts/touch-map.mjs +290 -0
  213. package/skills/review-work/SKILL.md +94 -64
  214. package/skills/review-work/references/adjudication.md +94 -0
  215. package/skills/review-work/references/artifact.md +198 -0
  216. package/skills/review-work/references/evals-and-judges.md +66 -0
  217. package/skills/review-work/references/work.md +177 -0
  218. package/skills/review-work/scripts/check-brief.mjs +128 -0
  219. package/skills/review-work/scripts/review-packet.mjs +233 -0
  220. package/skills/setup-freeflow/SKILL.md +69 -16
  221. package/skills/track-work/SKILL.md +135 -151
  222. package/skills/track-work/references/handoff.md +190 -0
  223. package/skills/track-work/references/projects.md +51 -0
  224. package/skills/track-work/references/working-record-format.md +201 -344
  225. package/skills/track-work/scripts/lib/document.mjs +79 -19
  226. package/skills/track-work/scripts/lib/format.mjs +18 -1
  227. package/skills/track-work/scripts/lib/recover.mjs +254 -0
  228. package/skills/track-work/scripts/lib/registry.mjs +656 -0
  229. package/skills/track-work/scripts/lib/search.mjs +40 -0
  230. package/skills/track-work/scripts/lib/store.mjs +53 -21
  231. package/skills/track-work/scripts/lib/transitions.mjs +79 -4
  232. package/skills/track-work/scripts/lib/views.mjs +50 -1
  233. package/skills/track-work/scripts/working-record.mjs +263 -22
  234. package/skills/verify-work/SKILL.md +64 -47
  235. package/skills/verify-work/references/feature-map.md +120 -0
  236. package/skills/verify-work/references/runtime-evidence.md +203 -0
  237. package/skills/verify-work/references/test-design.md +27 -6
  238. package/skills/verify-work/scripts/test-changes.mjs +246 -0
  239. package/skills/write-docs/SKILL.md +171 -0
  240. package/skills/write-docs/references/documentation-shapes.md +184 -0
  241. package/skills/write-docs/references/spec-and-plan-shapes.md +308 -0
  242. package/skills/write-docs/scripts/artifact-check.mjs +148 -0
  243. package/skills/write-docs/scripts/docs-check.mjs +229 -0
  244. package/skills/write-docs/scripts/plan-lint.mjs +123 -0
  245. package/skills/write-skill/SKILL.md +165 -165
  246. package/skills/write-skill/references/activation-and-wording.md +143 -0
  247. package/skills/write-skill/references/placement-and-dependencies.md +154 -0
  248. package/skills/write-skill/scripts/lib/compare.mjs +701 -0
  249. package/skills/write-skill/scripts/lib/similarity.mjs +56 -0
  250. package/skills/write-skill/scripts/lib/skill-author.mjs +197 -3
  251. package/skills/write-skill/scripts/skill-author.mjs +67 -8
  252. package/capabilities/context-virtualization/SKILL.md +0 -103
  253. package/capabilities/conversation-history/SKILL.md +0 -53
  254. package/hooks/tests/check-host-adapters.test.mjs +0 -82
  255. package/hooks/tests/check-runtime-context-hook.sh +0 -212
  256. package/pi-extension/dist/cognitive-routing-v2/projection.js +0 -330
  257. package/pi-extension/dist/cognitive-routing-v2/runtime.js +0 -2181
  258. package/pi-extension/dist/cognitive-routing-v2/tools.js +0 -60
  259. package/pi-extension/dist/context-virtualization/commands.js +0 -89
  260. package/pi-extension/dist/context-virtualization/projector.js +0 -42
  261. package/pi-extension/dist/context-virtualization/runtime.js +0 -378
  262. package/pi-extension/dist/context-virtualization/state.js +0 -57
  263. package/pi-extension/dist/context-virtualization/types.js +0 -10
  264. package/pi-extension/dist/conversation-history/passages.js +0 -66
  265. package/pi-extension/dist/conversation-history/ranking.js +0 -105
  266. package/pi-extension/dist/conversation-history/runtime.js +0 -226
  267. package/pi-extension/dist/conversation-history/search.js +0 -56
  268. package/pi-extension/dist/conversation-history/types.js +0 -1
  269. package/pi-extension/dist/freeflow-context/resolver.js +0 -120
  270. package/pi-extension/dist/freeflow-context/runtime.js +0 -80
  271. package/pi-extension/dist/freeflow-context/source-projector.js +0 -95
  272. package/pi-extension/dist/freeflow-context/tool.js +0 -314
  273. package/pi-extension/dist/freeflow-context/types.js +0 -12
  274. package/pi-extension/dist/freeflow-context/visibility.js +0 -28
  275. package/pi-extension/dist/integrations/mcp-config.js +0 -29
  276. package/pi-extension/dist/runtime/runtime-context.js +0 -754
  277. package/pi-extension/dist/runtime/runtime-identity.js +0 -5
  278. package/pi-extension/dist/session-sources/provenance.js +0 -32
  279. package/pi-extension/dist/settings/settings-ui.js +0 -1360
  280. package/pi-extension/dist/ui/text-component.js +0 -57
  281. package/pi-extension/src/cognitive-routing-v2/budget.ts +0 -42
  282. package/pi-extension/src/cognitive-routing-v2/config.ts +0 -173
  283. package/pi-extension/src/cognitive-routing-v2/projection.ts +0 -375
  284. package/pi-extension/src/cognitive-routing-v2/render.ts +0 -277
  285. package/pi-extension/src/cognitive-routing-v2/runtime.ts +0 -2241
  286. package/pi-extension/src/cognitive-routing-v2/schemas.ts +0 -180
  287. package/pi-extension/src/cognitive-routing-v2/state.ts +0 -839
  288. package/pi-extension/src/cognitive-routing-v2/tools.ts +0 -62
  289. package/pi-extension/src/cognitive-routing-v2/types.ts +0 -254
  290. package/pi-extension/src/context-virtualization/commands.ts +0 -111
  291. package/pi-extension/src/context-virtualization/projector.ts +0 -62
  292. package/pi-extension/src/context-virtualization/runtime.ts +0 -428
  293. package/pi-extension/src/context-virtualization/state.ts +0 -79
  294. package/pi-extension/src/context-virtualization/types.ts +0 -92
  295. package/pi-extension/src/conversation-history/passages.ts +0 -81
  296. package/pi-extension/src/conversation-history/ranking.ts +0 -155
  297. package/pi-extension/src/conversation-history/runtime.ts +0 -250
  298. package/pi-extension/src/conversation-history/search.ts +0 -79
  299. package/pi-extension/src/conversation-history/types.ts +0 -31
  300. package/pi-extension/src/freeflow-context/resolver.ts +0 -139
  301. package/pi-extension/src/freeflow-context/runtime.ts +0 -100
  302. package/pi-extension/src/freeflow-context/source-projector.ts +0 -106
  303. package/pi-extension/src/freeflow-context/tool.ts +0 -366
  304. package/pi-extension/src/freeflow-context/types.ts +0 -70
  305. package/pi-extension/src/freeflow-context/visibility.ts +0 -53
  306. package/pi-extension/src/index.ts +0 -390
  307. package/pi-extension/src/integrations/mcp-config.ts +0 -32
  308. package/pi-extension/src/provider-support/astra/adapter.ts +0 -108
  309. package/pi-extension/src/provider-support/astra/history.ts +0 -145
  310. package/pi-extension/src/provider-support/astra/index.ts +0 -12
  311. package/pi-extension/src/provider-support/astra/session-state.ts +0 -113
  312. package/pi-extension/src/provider-support/index.ts +0 -5
  313. package/pi-extension/src/runtime/request-history.ts +0 -243
  314. package/pi-extension/src/runtime/runtime-context.ts +0 -860
  315. package/pi-extension/src/runtime/runtime-identity.ts +0 -8
  316. package/pi-extension/src/session-sources/events.ts +0 -230
  317. package/pi-extension/src/session-sources/provenance.ts +0 -39
  318. package/pi-extension/src/session-sources/read-only-session.ts +0 -170
  319. package/pi-extension/src/session-sources/sources.ts +0 -334
  320. package/pi-extension/src/settings/settings-tui.ts +0 -501
  321. package/pi-extension/src/settings/settings-ui.ts +0 -1652
  322. package/pi-extension/src/ui/text-component.ts +0 -66
  323. package/pi-extension/tests/cache-reuse/history.test.js +0 -117
  324. package/pi-extension/tests/cache-reuse/native.test.js +0 -91
  325. package/pi-extension/tests/cache-reuse/settings.test.js +0 -211
  326. package/pi-extension/tests/cognitive-routing-v2/communication.test.js +0 -577
  327. package/pi-extension/tests/cognitive-routing-v2/compaction-input.test.js +0 -183
  328. package/pi-extension/tests/cognitive-routing-v2/delegation.test.js +0 -557
  329. package/pi-extension/tests/cognitive-routing-v2/native.test.js +0 -474
  330. package/pi-extension/tests/cognitive-routing-v2/performance.test.js +0 -87
  331. package/pi-extension/tests/cognitive-routing-v2/persistence.test.js +0 -300
  332. package/pi-extension/tests/cognitive-routing-v2/projection.test.js +0 -241
  333. package/pi-extension/tests/cognitive-routing-v2/recovery.test.js +0 -1034
  334. package/pi-extension/tests/cognitive-routing-v2/render.test.js +0 -244
  335. package/pi-extension/tests/cognitive-routing-v2/runtime.test.js +0 -423
  336. package/pi-extension/tests/cognitive-routing-v2/stabilization.test.js +0 -521
  337. package/pi-extension/tests/cognitive-routing-v2/state.test.js +0 -586
  338. package/pi-extension/tests/context-virtualization/extension.test.js +0 -775
  339. package/pi-extension/tests/context-virtualization/projector.test.js +0 -110
  340. package/pi-extension/tests/context-virtualization/runtime.test.js +0 -230
  341. package/pi-extension/tests/conversation-history/runtime.test.js +0 -98
  342. package/pi-extension/tests/conversation-history/search.test.js +0 -97
  343. package/pi-extension/tests/fixtures/pi-host.js +0 -4
  344. package/pi-extension/tests/fixtures/routing-native.js +0 -191
  345. package/pi-extension/tests/integration/mode-free-core.test.js +0 -220
  346. package/pi-extension/tests/integration/pi-extension.test.js +0 -1447
  347. package/pi-extension/tests/integration/prompt-architecture.test.js +0 -447
  348. package/pi-extension/tests/integration/unaffected-regressions.test.js +0 -478
  349. package/pi-extension/tests/provider-support/astra-boundaries.test.js +0 -75
  350. package/pi-extension/tests/provider-support/astra.test.js +0 -306
  351. package/pi-extension/tests/provider-support/cli.test.js +0 -92
  352. package/pi-extension/tests/provider-support/native.test.js +0 -183
  353. package/pi-extension/tests/settings/settings-tui.test.js +0 -243
  354. package/pi-extension/tsconfig.json +0 -16
  355. package/plugin.json +0 -33
  356. package/runtime/prompts/context-virtualization.md +0 -3
  357. package/runtime/prompts/conversation-history.md +0 -3
  358. package/skills/action-selection/SKILL.md +0 -100
  359. package/skills/action-selection/references/trajectory-stalls.md +0 -71
  360. package/skills/bypass/SKILL.md +0 -153
  361. package/skills/commit-work/SKILL.md +0 -145
  362. package/skills/commit-work/references/git-state-edges.md +0 -94
  363. package/skills/commit-work/references/simple-push.md +0 -92
  364. package/skills/commit-work/references/staging-decisions.md +0 -106
  365. package/skills/decision-gate/SKILL.md +0 -106
  366. package/skills/design-for-depth/SKILL.md +0 -117
  367. package/skills/design-for-depth/references/design-pressure-signals.md +0 -182
  368. package/skills/design-for-depth/references/implementation-decisions.md +0 -76
  369. package/skills/design-for-depth/references/interface-design-loop.md +0 -136
  370. package/skills/design-for-depth/references/module-and-dependency-design.md +0 -147
  371. package/skills/design-for-depth/references/software-design-philosophy.md +0 -202
  372. package/skills/design-for-depth/references/state-and-failure-boundaries.md +0 -136
  373. package/skills/diagnose-failure/SKILL.md +0 -125
  374. package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +0 -48
  375. package/skills/diagnose-failure/references/flaky-and-performance-diagnosis.md +0 -51
  376. package/skills/discuss/SKILL.md +0 -116
  377. package/skills/evaluate-skill/SKILL.md +0 -219
  378. package/skills/evaluate-skill/references/evaluation-definition-schema.md +0 -385
  379. package/skills/evaluate-skill/references/evaluation-design.md +0 -112
  380. package/skills/evaluate-skill/references/execution-and-evidence.md +0 -90
  381. package/skills/evaluate-skill/references/review-and-revision.md +0 -92
  382. package/skills/evaluate-skill/scripts/lib/definitions.mjs +0 -407
  383. package/skills/evaluate-skill/scripts/lib/grade-comparison.mjs +0 -60
  384. package/skills/evaluate-skill/scripts/lib/grade.mjs +0 -64
  385. package/skills/evaluate-skill/scripts/lib/runner.mjs +0 -368
  386. package/skills/evaluate-skill/scripts/pi-guard.mjs +0 -164
  387. package/skills/evaluate-skill/scripts/skill-eval.mjs +0 -102
  388. package/skills/execute-work/references/execute-work-edges.md +0 -68
  389. package/skills/finish-branch/SKILL.md +0 -117
  390. package/skills/finish-branch/references/integration-options.md +0 -80
  391. package/skills/handoff/SKILL.md +0 -82
  392. package/skills/handoff/references/handoff-templates.md +0 -150
  393. package/skills/launch-work/SKILL.md +0 -116
  394. package/skills/launch-work/references/launch-readiness.md +0 -85
  395. package/skills/migration-work/SKILL.md +0 -115
  396. package/skills/migration-work/references/migration-lifecycle.md +0 -82
  397. package/skills/release-work/SKILL.md +0 -118
  398. package/skills/release-work/references/release-evidence.md +0 -78
  399. package/skills/review-artifact/SKILL.md +0 -142
  400. package/skills/review-artifact/references/adjudicate-artifact-review.md +0 -101
  401. package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +0 -159
  402. package/skills/review-work/references/adjudicate-work-review.md +0 -97
  403. package/skills/review-work/references/independent-work-reviewer-contract.md +0 -139
  404. package/skills/review-work/references/security-risk-lens.md +0 -69
  405. package/skills/setup-freeflow/references/activation-contract.md +0 -109
  406. package/skills/setup-freeflow/references/host-setup.md +0 -67
  407. package/skills/simplify-code/SKILL.md +0 -85
  408. package/skills/simplify-code/references/simplification-patterns.md +0 -70
  409. package/skills/verify-work/references/browser-runtime-evidence.md +0 -55
  410. package/skills/verify-work/references/integration-evidence.md +0 -47
  411. package/skills/verify-work/references/performance-evidence.md +0 -57
  412. package/skills/workflow/SKILL.md +0 -127
  413. package/skills/workflow/references/domain-skill-composition.md +0 -43
  414. package/skills/write-plan/SKILL.md +0 -92
  415. package/skills/write-plan/references/plan-shapes.md +0 -156
  416. package/skills/write-skill/references/activation-boundaries.md +0 -104
  417. package/skills/write-skill/references/agent-first-instructions.md +0 -121
  418. package/skills/write-skill/references/progressive-disclosure.md +0 -127
  419. package/skills/write-skill/references/skill-dependency-graphs.md +0 -190
  420. package/skills/write-spec/SKILL.md +0 -92
  421. package/skills/write-spec/references/artifact-standards.md +0 -86
  422. package/skills/write-spec/references/decision-records.md +0 -78
  423. package/skills/write-spec/references/spec-shapes.md +0 -143
  424. /package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/budget.js +0 -0
  425. /package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/evidence.mjs +0 -0
  426. /package/skills/{evaluate-skill → evaluate-behavior}/scripts/pi-observer.mjs +0 -0
@@ -0,0 +1,586 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { realpath } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { createInterface } from "node:readline/promises";
6
+
7
+ import { extensionLabel } from "./lib/build-source.mjs";
8
+ import { clearRun } from "./lib/clear.mjs";
9
+ import { loadDefinition, selectDefinition } from "./lib/definitions.mjs";
10
+ import "./lib/metrics.mjs";
11
+ import { createBudget } from "./lib/budget.mjs";
12
+ import { createLimiter, setCpuJobs } from "./lib/queue.mjs";
13
+ import { checkSelection } from "./lib/reference.mjs";
14
+ import { applySourceOverrides, parseSourceOverrides } from "./lib/source-override.mjs";
15
+ import { createRunReuse, resultsDirectory, runEvaluation } from "./lib/runner.mjs";
16
+ import { armSealing } from "./lib/seal.mjs";
17
+ import { calibrateJudges, reviewResult, reviewRubric } from "./lib/review.mjs";
18
+ import { runTrials } from "./lib/trials.mjs";
19
+ import { renderResult } from "./lib/view.mjs";
20
+ import { writeHtml } from "./lib/view-html.mjs";
21
+
22
+ const OPTIONS = {
23
+ run: [
24
+ "--group",
25
+ "--variant",
26
+ "--trials",
27
+ "--max-cost",
28
+ "--yes",
29
+ "--dry-run",
30
+ "--skip-reference-check",
31
+ "--jobs",
32
+ "--cpu-jobs",
33
+ "--results",
34
+ "--reuse",
35
+ "--pilot",
36
+ "--source",
37
+ ],
38
+ "check-tasks": ["--group"],
39
+ clear: ["--group", "--variant", "--flag", "--all", "--reason", "--results"],
40
+ view: ["--group", "--variant", "--html", "--results"],
41
+ review: [
42
+ "--results",
43
+ "--group",
44
+ "--model",
45
+ "--thinking",
46
+ "--configuration",
47
+ "--swap",
48
+ "--swap-sample",
49
+ "--limit",
50
+ "--rubric",
51
+ "--calibrate",
52
+ ],
53
+ };
54
+ const argv = process.argv.slice(2);
55
+ const [command] = argv;
56
+
57
+ function printUsage() {
58
+ process.stdout.write(
59
+ `Usage:
60
+ skill-eval run <suite-or-group-path> [options]
61
+ skill-eval view <result-id-or-directory> [options]
62
+ skill-eval review <result-id-or-directory> --model <provider/model> [options]
63
+ skill-eval check-tasks <suite-or-group-path> [--group <id-or-position>]
64
+ skill-eval review <result-or-aggregate-id> --rubric [options]
65
+ skill-eval review <result-or-aggregate-id> --calibrate <labels.json>
66
+ skill-eval clear <result-id-or-directory> [--group <id>] [--variant <arm>] (--flag <id>... | --all) --reason <text>
67
+
68
+ Commands:
69
+ run Execute selected evaluation groups
70
+ view Render selected stored evidence or a trial aggregate
71
+ review Record an advisory, arm-blind model answer to each group's review questions
72
+ check-tasks Check that each group's reference_solution passes its workspace and command checks, which must fail before it,
73
+ and list what each task's copy lacks against its original setting (Git history, ignored files, tools,
74
+ network); no model
75
+ clear Record that a person read a run's transcript-scan flags and they do not taint it (with --reason), then
76
+ rebuild the aggregates that list the run; until then a flagged run is held out of every count and decision
77
+
78
+ Selectors:
79
+ --group <id-or-position>
80
+ --variant <baseline|candidate> (run, view) or any other arm the selected groups declare
81
+
82
+ Run options:
83
+ --trials <n> Run n independent complete invocations and record an aggregate
84
+ (a suite's decision always aggregates; its trials schedule sets n)
85
+ --max-cost <total> Stop starting subjects once host-reported cost reaches the total
86
+ --yes Start without asking (the plan is printed either way; scripts never ask)
87
+ --dry-run Allow uncommitted inputs; the result is marked as a dry run and supports no claim
88
+ --skip-reference-check Run even when a declared reference_solution fails check-tasks (the result records it)
89
+ --jobs <n> Run up to n subjects at once across groups, arms and trials (default 1)
90
+ --cpu-jobs <n> Run up to n local CPU tasks at once, such as hidden test commands (default 2)
91
+ --reuse Count matching complete canonical runs from the results index as trials instead of
92
+ running them again (each once per run, listed as reused), and index this run's own
93
+ --pilot <n> Run the first n groups once first; stop with a report on any failed or invalid run,
94
+ check error, or comparison no arm passed; otherwise continue (the pilot counts as a trial)
95
+ --source <arm>=<sha> For this run only, use the commit for every Git source ref the arm declares (its subject,
96
+ Freeflow and source-built extensions); recorded, never written to the definition (repeatable)
97
+
98
+ Result location (run, view, review):
99
+ --results <dir> Store and find results under <dir> instead of <cwd>/.skill-eval/runs
100
+
101
+ Review options:
102
+ --model <provider/model> Required reviewer model
103
+ --thinking <level> Optional reviewer thinking level
104
+ --configuration <file> A schema 2 configuration file for the reviewer: its model, host extensions and settings
105
+ --swap Review again with the run labels in reverse order, and record agreement
106
+ --swap-sample <fraction> Swap only on a random sample of the groups (the fraction, rounded up), recorded
107
+ --rubric Judge each run alone, blind to its arm, against its group's rubric; the group's
108
+ judges, or --model, answer; judged evidence is stored beside each run; an
109
+ aggregate judges every trial
110
+ --calibrate <labels.json> Score judges against hand labels ({ "<run path>": { "<dimension>": answer } })
111
+ and record each judge configuration's calibration in the target's judged evidence
112
+ --limit <name>=<chars> Show the reviewer more or less: response, argument, file or materials (repeatable;
113
+ defaults 8000, 300, 20000, 60000). Anything cut is recorded as a contract gap.
114
+
115
+ Paths:
116
+ Definition paths resolve from the current working directory.
117
+ Suite group references resolve relative to the suite file.
118
+ Results are stored under <cwd>/.skill-eval/runs/<result-id>, or under --results.
119
+ view accepts a stored result or aggregate ID or an explicit directory.
120
+
121
+ Selection:
122
+ No selectors choose every suite group and every arm.
123
+ --group is invalid for a direct group definition or result.
124
+
125
+ Current run support:
126
+ Description and explicit-body groups with prompt or ordered turns
127
+ Working-tree or Git-backed ordered skills/context; optional fresh fixture copies
128
+ Description tools: read; body tools: read, write, edit, run_command for declared commands, or declared extension tools
129
+ Runtime profiles: Pi hosts, isolated or host system prompt, ordered immutable extension bundles, environment overrides
130
+ Deterministic reads, paths, changed paths, text, JSON, tool calls, context observations, and factual comparisons
131
+ Ordered suites run serially (or --jobs subjects at once) and continue after isolated variant, group, or
132
+ post-processing failures
133
+ Grade-first views show compact criterion details, usage, and result-relative artifact paths
134
+ `,
135
+ );
136
+ }
137
+
138
+ function fail(message, exitCode = 2) {
139
+ process.stderr.write(`${message}\n`);
140
+ process.exitCode = exitCode;
141
+ }
142
+
143
+ function parseOperation(values) {
144
+ const [target, ...options] = values;
145
+ if (!target) throw new Error(`skill-eval ${command} requires a target`);
146
+ const allowed = OPTIONS[command];
147
+ const parsed = {
148
+ group: null,
149
+ variant: null,
150
+ trials: null,
151
+ maxCost: null,
152
+ model: null,
153
+ thinking: null,
154
+ configuration: null,
155
+ swapSample: null,
156
+ calibrate: null,
157
+ html: null,
158
+ reason: null,
159
+ jobs: null,
160
+ cpuJobs: null,
161
+ results: null,
162
+ pilot: null,
163
+ };
164
+ let swap = false;
165
+ let rubric = false;
166
+ const limits = {};
167
+ let yes = false;
168
+ let dryRun = false;
169
+ let reuse = false;
170
+ let skipReferenceCheck = false;
171
+ let all = false;
172
+ const sourceValues = [];
173
+ const flags = [];
174
+ const keys = {
175
+ "--jobs": "jobs",
176
+ "--cpu-jobs": "cpuJobs",
177
+ "--results": "results",
178
+ "--pilot": "pilot",
179
+ "--group": "group",
180
+ "--variant": "variant",
181
+ "--trials": "trials",
182
+ "--max-cost": "maxCost",
183
+ "--model": "model",
184
+ "--configuration": "configuration",
185
+ "--thinking": "thinking",
186
+ "--swap-sample": "swapSample",
187
+ "--calibrate": "calibrate",
188
+ "--html": "html",
189
+ "--reason": "reason",
190
+ };
191
+ for (let index = 0; index < options.length; index += 1) {
192
+ const option = options[index];
193
+ const value = options[index + 1];
194
+ if (!allowed.includes(option)) throw new Error(`Unknown option: ${option}`);
195
+ if (option === "--swap") {
196
+ swap = true;
197
+ continue;
198
+ }
199
+ if (option === "--rubric") {
200
+ rubric = true;
201
+ continue;
202
+ }
203
+ if (option === "--all") {
204
+ all = true;
205
+ continue;
206
+ }
207
+ if (option === "--flag") {
208
+ if (!value || value.startsWith("--")) throw new Error("--flag requires a flag ID, such as network-1");
209
+ flags.push(value);
210
+ index += 1;
211
+ continue;
212
+ }
213
+ if (option === "--source") {
214
+ if (!value || value.startsWith("--")) throw new Error("--source requires <arm>=<commit SHA>");
215
+ sourceValues.push(value);
216
+ index += 1;
217
+ continue;
218
+ }
219
+ if (option === "--limit") {
220
+ const [, name, chars] = /^([a-z]+)=(\d+)$/.exec(value ?? "") ?? [];
221
+ if (!name) throw new Error("--limit requires <name>=<chars>, such as file=40000");
222
+ if (Object.hasOwn(limits, name)) throw new Error(`--limit ${name} may be supplied only once`);
223
+ limits[name] = Number(chars);
224
+ index += 1;
225
+ continue;
226
+ }
227
+ if (option === "--yes") {
228
+ yes = true;
229
+ continue;
230
+ }
231
+ if (option === "--dry-run") {
232
+ dryRun = true;
233
+ continue;
234
+ }
235
+ if (option === "--reuse") {
236
+ reuse = true;
237
+ continue;
238
+ }
239
+ if (option === "--skip-reference-check") {
240
+ skipReferenceCheck = true;
241
+ continue;
242
+ }
243
+ if (!value || value.startsWith("--")) throw new Error(`${option} requires a value`);
244
+ const key = keys[option];
245
+ if (parsed[key] !== null) throw new Error(`${option} may be supplied only once`);
246
+ parsed[key] = value;
247
+ index += 1;
248
+ }
249
+ // Null when omitted: one trial, unless the suite's decision schedules its own.
250
+ let trials = null;
251
+ if (parsed.trials !== null) {
252
+ trials = Number(parsed.trials);
253
+ if (!/^\d+$/.test(parsed.trials) || trials < 1) throw new Error("--trials must be a positive integer");
254
+ }
255
+ let maxCost = null;
256
+ if (parsed.maxCost !== null) {
257
+ maxCost = Number(parsed.maxCost);
258
+ if (!Number.isFinite(maxCost) || maxCost <= 0) throw new Error("--max-cost must be a positive number");
259
+ }
260
+ const positive = (name, value, fallback) => {
261
+ if (value === null) return fallback;
262
+ if (!/^\d+$/.test(value) || Number(value) < 1) throw new Error(`${name} must be a positive integer`);
263
+ return Number(value);
264
+ };
265
+ const jobs = positive("--jobs", parsed.jobs, 1);
266
+ const cpuJobs = positive("--cpu-jobs", parsed.cpuJobs, null);
267
+ const pilot = positive("--pilot", parsed.pilot, null);
268
+ const swapSample = parsed.swapSample === null ? null : Number(parsed.swapSample);
269
+ if (swapSample !== null && !(swapSample > 0 && swapSample <= 1)) {
270
+ throw new Error("--swap-sample must be a fraction greater than 0 and at most 1");
271
+ }
272
+ if ([rubric, parsed.calibrate !== null, swap || swapSample !== null].filter(Boolean).length > 1) {
273
+ throw new Error("--rubric, --calibrate and swapping are separate review modes; use one");
274
+ }
275
+ // A rubric's judges may be declared by its group, and calibration starts no judge.
276
+ const needsModel = command === "review" && !rubric && parsed.calibrate === null;
277
+ if (needsModel && parsed.model === null && parsed.configuration === null) {
278
+ throw new Error("skill-eval review requires --model or --configuration");
279
+ }
280
+ if (command === "clear") {
281
+ if (all === flags.length > 0) throw new Error("skill-eval clear needs either --flag <id> (repeatable) or --all");
282
+ if (parsed.reason === null) throw new Error("skill-eval clear needs --reason, the person's reason for clearing");
283
+ }
284
+ return {
285
+ target,
286
+ clear: { flags: all ? "all" : flags, reason: parsed.reason },
287
+ selectors: { group: parsed.group, variant: parsed.variant },
288
+ trials,
289
+ maxCost,
290
+ model: parsed.model,
291
+ thinking: parsed.thinking,
292
+ configuration: parsed.configuration,
293
+ html: parsed.html,
294
+ swap,
295
+ swapSample,
296
+ rubric,
297
+ calibrate: parsed.calibrate,
298
+ limits,
299
+ yes,
300
+ dryRun,
301
+ jobs,
302
+ cpuJobs,
303
+ pilot,
304
+ reuse,
305
+ results: parsed.results,
306
+ skipReferenceCheck,
307
+ sources: parseSourceOverrides(sourceValues),
308
+ };
309
+ }
310
+
311
+ async function withCancellation(run) {
312
+ const controller = new AbortController();
313
+ const abort = () => controller.abort();
314
+ process.once("SIGINT", abort);
315
+ process.once("SIGTERM", abort);
316
+ try {
317
+ return await run(controller.signal);
318
+ } finally {
319
+ process.removeListener("SIGINT", abort);
320
+ process.removeListener("SIGTERM", abort);
321
+ }
322
+ }
323
+
324
+ function printResult(result) {
325
+ process.stdout.write(`Result: ${result.id}\nPath: ${result.path}\nState: ${result.state}\n`);
326
+ }
327
+
328
+ /**
329
+ * What a run will start, from the definition alone: subjects, the models they use, and any Freeflow builds.
330
+ * Printed before anything starts; an interactive terminal is asked to confirm unless --yes was given.
331
+ * Returns null when not confirmed, else the selected suite's decision rule (null when it declares none).
332
+ */
333
+ async function planRun(operation, root) {
334
+ // Resolved the way the runner resolves it, so the plan loads exactly what will run.
335
+ const definitionPath = await realpath(path.resolve(root, operation.target));
336
+ const definition = await loadDefinition(definitionPath, { root });
337
+ const selection = selectDefinition(definition, operation.selectors);
338
+ // Refused here, before the plan, exactly as the runner would refuse it.
339
+ applySourceOverrides(selection, operation.sources);
340
+ const decision = definition.kind === "suite" ? (definition.decision ?? null) : null;
341
+ const schedule = decision?.trials ?? null;
342
+ if (schedule !== null && operation.trials !== null && operation.trials !== schedule.initial) {
343
+ throw new Error(
344
+ `the suite's decision schedules ${schedule.initial} initial trials; omit --trials or set it to ${schedule.initial}`,
345
+ );
346
+ }
347
+ const trials = schedule?.initial ?? operation.trials ?? 1;
348
+ let arms = 0;
349
+ let unsealed = 0;
350
+ const models = new Set();
351
+ const freeflow = new Set();
352
+ const extensions = new Set();
353
+ for (const { group, variants } of selection.groups) {
354
+ for (const [arm, state] of Object.entries(variants)) {
355
+ if (state !== "selected") continue;
356
+ arms += 1;
357
+ if (armSealing(group, arm).network === "host") unsealed += 1;
358
+ const model = group.variants[arm].model;
359
+ models.add(model ? `${model.model}${model.thinking ? ` (${model.thinking})` : ""}` : "host default");
360
+ if (group.variants[arm].freeflow) freeflow.add(group.variants[arm].freeflow.source.ref);
361
+ for (const extension of group.variants[arm].hostExtensions ?? []) {
362
+ extensions.add(extensionLabel(extension));
363
+ }
364
+ }
365
+ }
366
+ const groups = selection.groups.length;
367
+ let counts = `${groups} group${groups === 1 ? "" : "s"}, ${arms} arm${arms === 1 ? "" : "s"}, ${trials} trial${trials === 1 ? "" : "s"}`;
368
+ let subjects = `${arms * trials}`;
369
+ if (schedule !== null && schedule.max > schedule.initial) {
370
+ // Adaptive rounds add trials only to undecided cases, so the count is a range up to every case at max.
371
+ counts += `, adaptive up to ${schedule.max} per case`;
372
+ subjects += ` to ${arms * schedule.max}`;
373
+ }
374
+ let line = `Plan: ${subjects} subjects (${counts}); models: ${[...models].join(", ")}`;
375
+ if (freeflow.size > 0) line += `; Freeflow builds: ${[...freeflow].join(", ")}`;
376
+ if (extensions.size > 0) line += `; extensions: ${[...extensions].join(", ")}`;
377
+ if (operation.jobs > 1) line += `; ${operation.jobs} subjects at once`;
378
+ if (operation.pilot !== null) line += `; pilot of the first ${Math.min(operation.pilot, groups)} groups`;
379
+ if (operation.reuse) line += "; reusing matching runs";
380
+ // Said before anything starts: code the subject writes will run on this machine, with its network and files.
381
+ if (unsealed > 0) {
382
+ line += `; unsealed: ${unsealed} arm${unsealed === 1 ? " runs" : "s run"} declared commands or graders on the host`;
383
+ }
384
+ const overridden = Object.entries(operation.sources ?? {});
385
+ if (overridden.length > 0) line += `; sources: ${overridden.map(([arm, commit]) => `${arm}=${commit}`).join(", ")}`;
386
+ if (operation.dryRun) line += "; dry run";
387
+ process.stdout.write(`${line}\n`);
388
+ if (operation.yes || !process.stdin.isTTY || !process.stdout.isTTY) return { decision };
389
+ const readline = createInterface({ input: process.stdin, output: process.stdout });
390
+ const answer = await readline.question("Start? [y/N] ");
391
+ readline.close();
392
+ return /^y(es)?$/i.test(answer.trim()) ? { decision } : null;
393
+ }
394
+
395
+ async function run(operation) {
396
+ const root = process.cwd();
397
+ const plan = await planRun(operation, root);
398
+ if (plan === null) {
399
+ process.stdout.write("Not started.\n");
400
+ process.exitCode = 1;
401
+ return;
402
+ }
403
+ if (operation.cpuJobs !== null) setCpuJobs(operation.cpuJobs);
404
+ await withCancellation(async (signal) => {
405
+ const common = {
406
+ root,
407
+ signal,
408
+ dryRun: operation.dryRun,
409
+ jobs: operation.jobs,
410
+ results: operation.results,
411
+ skipReferenceCheck: operation.skipReferenceCheck,
412
+ sources: operation.sources,
413
+ };
414
+ // A suite's decision is reached over an aggregate, so it always runs as trials, even a single one; so does a
415
+ // pilot, which then counts as the first part of that one trial instead of being paid for twice.
416
+ if (plan.decision === null && (operation.trials ?? 1) === 1 && operation.pilot === null) {
417
+ const shared = {
418
+ ...common,
419
+ budget: createBudget(operation.maxCost),
420
+ subjects: createLimiter(operation.jobs),
421
+ reuse: createRunReuse(resultsDirectory(root, operation.results), operation.reuse),
422
+ };
423
+ const result = await runEvaluation(operation.target, operation.selectors, shared);
424
+ printResult(result);
425
+ if (result.state !== "complete") process.exitCode = 1;
426
+ return;
427
+ }
428
+ const aggregate = await runTrials(operation.target, operation.selectors, {
429
+ ...common,
430
+ trials: operation.trials,
431
+ maxCost: operation.maxCost,
432
+ onTrial: printResult,
433
+ reuse: operation.reuse,
434
+ pilot: operation.pilot,
435
+ });
436
+ if (aggregate.state === "pilot-stopped") {
437
+ reportPilot(aggregate.pilot.id, aggregate.pilot.problems);
438
+ return;
439
+ }
440
+ if (aggregate.aggregate.pilot) reportPilot(aggregate.aggregate.pilot.id, []);
441
+ process.stdout.write(`Aggregate: ${aggregate.id}\nPath: ${aggregate.path}\nState: ${aggregate.state}\n`);
442
+ if (aggregate.state !== "complete") process.exitCode = 1;
443
+ });
444
+ }
445
+
446
+ /** Prints a pilot's outcome; false (and a failing exit) when its problems stop the run. */
447
+ function reportPilot(id, problems) {
448
+ if (problems.length === 0) {
449
+ process.stdout.write(`Pilot: ${id} passed\n`);
450
+ return true;
451
+ }
452
+ process.stdout.write(`Pilot: ${id} stopped the run\n${problems.map((problem) => ` - ${problem}\n`).join("")}`);
453
+ process.exitCode = 1;
454
+ return false;
455
+ }
456
+
457
+ /** Checks each selected group's reference_solution against its graders. Runs no subject; exits 1 if any is unsolvable. */
458
+ async function checkTasks(operation) {
459
+ const root = process.cwd();
460
+ const definitionPath = await realpath(path.resolve(root, operation.target));
461
+ const selection = selectDefinition(await loadDefinition(definitionPath, { root }), operation.selectors);
462
+ const results = await checkSelection(selection, { root });
463
+ for (const [index, result] of results.entries()) {
464
+ // Each group is named with its file, so a suite with many groups shows which one to fix.
465
+ const file = path.relative(root, selection.groups[index].group.files[0]);
466
+ process.stdout.write(`${result.id} (${file}): ${result.state}${result.reason ? ` (${result.reason})` : ""}\n`);
467
+ for (const arm of result.arms ?? []) process.stdout.write(` ${arm.arm}: ${arm.state}\n`);
468
+ // What the task's copy lacks against its original setting; reported for the author to judge, never refused.
469
+ for (const gap of result.copy?.gaps ?? []) process.stdout.write(` copy lacks: ${gap}\n`);
470
+ for (const [arm, tools] of Object.entries(result.copy?.tools ?? {})) {
471
+ process.stdout.write(` ${arm} tools: ${tools.join(", ") || "none"}; network: ${result.copy.network[arm]}\n`);
472
+ }
473
+ }
474
+ if (results.some((result) => result.state === "unsolvable" || result.state === "already-solved")) {
475
+ process.exitCode = 1;
476
+ }
477
+ }
478
+
479
+ async function review(operation) {
480
+ if (operation.calibrate !== null) return calibrate(operation);
481
+ if (operation.rubric) return judge(operation);
482
+ const outcome = await withCancellation((signal) =>
483
+ reviewResult(operation.target, operation.selectors, {
484
+ root: process.cwd(),
485
+ results: operation.results,
486
+ signal,
487
+ model: operation.model,
488
+ thinking: operation.thinking,
489
+ configuration: operation.configuration,
490
+ swap: operation.swap,
491
+ swapSample: operation.swapSample,
492
+ limits: operation.limits,
493
+ }),
494
+ );
495
+ for (const group of outcome.groups) {
496
+ process.stdout.write(`Review ${group.id}: ${group.state}${group.artifact ? ` (${group.artifact})` : ""}\n`);
497
+ }
498
+ if (outcome.groups.some((group) => group.state === "review-error")) process.exitCode = 1;
499
+ }
500
+
501
+ function printAggregate(aggregate) {
502
+ if (aggregate === null) return;
503
+ process.stdout.write(`Aggregate: rebuilt; claim: ${aggregate.claim ?? "none"}\n`);
504
+ }
505
+
506
+ async function judge(operation) {
507
+ const outcome = await withCancellation((signal) =>
508
+ reviewRubric(operation.target, operation.selectors, {
509
+ root: process.cwd(),
510
+ results: operation.results,
511
+ signal,
512
+ model: operation.model,
513
+ thinking: operation.thinking,
514
+ configuration: operation.configuration,
515
+ limits: operation.limits,
516
+ }),
517
+ );
518
+ for (const entry of outcome.groups) {
519
+ const where = entry.artifact ? ` (${entry.artifact})` : entry.reason ? ` (${entry.reason})` : "";
520
+ process.stdout.write(`Judged ${entry.id}${entry.arm ? ` ${entry.arm}` : ""}: ${entry.state}${where}\n`);
521
+ }
522
+ printAggregate(outcome.aggregate);
523
+ if (outcome.groups.some((entry) => entry.state === "judge-error")) process.exitCode = 1;
524
+ }
525
+
526
+ async function calibrate(operation) {
527
+ const outcome = await calibrateJudges(operation.target, operation.calibrate, {
528
+ root: process.cwd(),
529
+ results: operation.results,
530
+ });
531
+ const number = (value) => (value === null ? "-" : value.toFixed(2));
532
+ for (const calibration of outcome.calibrations) {
533
+ const name = `${calibration.model}${calibration.thinking ? ` (${calibration.thinking})` : ""}`;
534
+ const dimensions = Object.entries(calibration.dimensions).map(
535
+ ([id, { items, agreement, kappa }]) =>
536
+ `${id}: agreement=${number(agreement)} kappa=${number(kappa)} over ${items}`,
537
+ );
538
+ process.stdout.write(`Calibration ${name} [${calibration.configuration}]: ${dimensions.join("; ")}\n`);
539
+ }
540
+ process.stdout.write(`Judged grades updated: ${outcome.updated}\n`);
541
+ printAggregate(outcome.aggregate);
542
+ }
543
+
544
+ if (!command || command === "--help" || command === "-h") {
545
+ printUsage();
546
+ } else if (Object.hasOwn(OPTIONS, command)) {
547
+ try {
548
+ const operation = parseOperation(argv.slice(1));
549
+ if (command === "view" && operation.html !== null) {
550
+ const written = await writeHtml(operation.target, operation.html, {
551
+ root: process.cwd(),
552
+ results: operation.results,
553
+ selectors: operation.selectors,
554
+ });
555
+ process.stdout.write(`Wrote ${written}\n`);
556
+ } else if (command === "view") {
557
+ process.stdout.write(
558
+ await renderResult(operation.target, operation.selectors, { root: process.cwd(), results: operation.results }),
559
+ );
560
+ } else if (command === "review") {
561
+ await review(operation);
562
+ } else if (command === "check-tasks") {
563
+ await checkTasks(operation);
564
+ } else if (command === "clear") {
565
+ const outcome = await clearRun(operation.target, {
566
+ group: operation.selectors.group,
567
+ variant: operation.selectors.variant,
568
+ flags: operation.clear.flags,
569
+ reason: operation.clear.reason,
570
+ root: process.cwd(),
571
+ results: operation.results,
572
+ });
573
+ process.stdout.write(
574
+ `Cleared ${outcome.result} ${outcome.group} ${outcome.arm}: ${outcome.cleared.join(", ") || "nothing new"}\n` +
575
+ `Still held by: ${outcome.remaining.join(", ") || "nothing"}\n` +
576
+ `Aggregates rebuilt: ${outcome.rebuilt.join(", ") || "none"}\n`,
577
+ );
578
+ } else {
579
+ await run(operation);
580
+ }
581
+ } catch (error) {
582
+ fail(error instanceof Error ? error.message : String(error), 1);
583
+ }
584
+ } else {
585
+ fail(`Unknown command: ${command}`);
586
+ }