@hassangameryt/freeflow 0.7.3 → 0.8.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 (276) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/.cursor-plugin/plugin.json +1 -1
  5. package/NOTICE +14 -0
  6. package/README.md +26 -31
  7. package/capabilities/cognitive-routing/SKILL.md +106 -161
  8. package/capabilities/cognitive-routing/references/both-mode.md +36 -0
  9. package/capabilities/cognitive-routing/references/executor-mode.md +48 -0
  10. package/capabilities/cognitive-routing/references/helper-mode.md +47 -0
  11. package/capabilities/compaction/SKILL.md +49 -0
  12. package/capabilities/compaction/references/summary-format.md +239 -0
  13. package/command-surface.json +4 -0
  14. package/gemini-extension.json +1 -1
  15. package/hooks/shared/runtime-context.mjs +28 -30
  16. package/licenses/Apache-2.0.txt +55 -0
  17. package/package.json +22 -9
  18. package/pi-extension/README.md +41 -0
  19. package/pi-extension/dist/cognitive-routing/assembler.js +393 -0
  20. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/config.js +5 -2
  21. package/pi-extension/dist/cognitive-routing/economics.js +45 -0
  22. package/pi-extension/dist/cognitive-routing/event-schema.js +388 -0
  23. package/pi-extension/dist/{session-sources/events.js → cognitive-routing/event-store.js} +103 -40
  24. package/pi-extension/dist/cognitive-routing/gate.js +241 -0
  25. package/pi-extension/dist/cognitive-routing/handlers.js +899 -0
  26. package/pi-extension/dist/cognitive-routing/handoffs.js +350 -0
  27. package/pi-extension/dist/cognitive-routing/model-control.js +467 -0
  28. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/projection.js +229 -56
  29. package/pi-extension/dist/cognitive-routing/provenance.js +81 -0
  30. package/pi-extension/dist/cognitive-routing/runtime.js +396 -0
  31. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/schemas.js +43 -7
  32. package/pi-extension/dist/cognitive-routing/session.js +221 -0
  33. package/pi-extension/dist/{session-sources → cognitive-routing}/sources.js +99 -85
  34. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/state.js +37 -378
  35. package/pi-extension/dist/cognitive-routing/status.js +80 -0
  36. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/tools.js +12 -12
  37. package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/types.js +5 -11
  38. package/pi-extension/dist/compaction/carry.js +191 -0
  39. package/pi-extension/dist/compaction/config.js +22 -0
  40. package/pi-extension/dist/compaction/controller.js +471 -0
  41. package/pi-extension/dist/compaction/harness.js +77 -0
  42. package/pi-extension/dist/compaction/results.js +158 -0
  43. package/pi-extension/dist/compaction/thresholds.js +35 -0
  44. package/pi-extension/dist/compaction/tool.js +57 -0
  45. package/pi-extension/dist/host/branch.js +13 -0
  46. package/pi-extension/dist/host/canonical.js +12 -0
  47. package/pi-extension/dist/host/catalog.js +77 -0
  48. package/pi-extension/dist/host/config.js +374 -0
  49. package/pi-extension/dist/host/projection-tags.js +60 -0
  50. package/pi-extension/dist/host/prompts.js +82 -0
  51. package/pi-extension/dist/{session-sources → host}/read-only-session.js +112 -1
  52. package/pi-extension/dist/{runtime → host}/request-history.js +121 -39
  53. package/pi-extension/dist/host/runtime-state.js +189 -0
  54. package/pi-extension/dist/{settings/settings-ui.js → host/settings/freeflow-command.js} +620 -410
  55. package/pi-extension/dist/{settings/settings-tui.js → host/settings/settings-view.js} +186 -73
  56. package/pi-extension/dist/host/staging.js +28 -0
  57. package/pi-extension/dist/host/status.js +101 -0
  58. package/pi-extension/dist/index.js +423 -173
  59. package/pi-extension/dist/provider-support/cache/anchor.js +21 -0
  60. package/pi-extension/dist/provider-support/cache/anthropic.js +102 -0
  61. package/pi-extension/dist/provider-support/cache/health.js +73 -0
  62. package/pi-extension/dist/provider-support/cache/index.js +58 -0
  63. package/pi-extension/dist/provider-support/cache/keepalive.js +210 -0
  64. package/pi-extension/dist/provider-support/cache/monitor.js +17 -0
  65. package/pi-extension/dist/provider-support/cache/openai-responses.js +48 -0
  66. package/pi-extension/dist/provider-support/effort.js +13 -0
  67. package/pi-extension/dist/provider-support/index.js +44 -3
  68. package/pi-extension/dist/provider-support/{astra → openai}/adapter.js +46 -29
  69. package/pi-extension/dist/provider-support/{astra → openai}/history.js +10 -8
  70. package/pi-extension/dist/provider-support/{astra → openai}/index.js +8 -4
  71. package/pi-extension/dist/provider-support/{astra → openai}/session-state.js +29 -38
  72. package/pi-extension/dist/provider-support/routes.js +17 -0
  73. package/pi-extension/dist/tool-execution/apply-patch/grammar.js +23 -0
  74. package/pi-extension/dist/tool-execution/apply-patch/match.js +38 -0
  75. package/pi-extension/dist/tool-execution/apply-patch/parser.js +177 -0
  76. package/pi-extension/dist/tool-execution/apply-patch/plan.js +201 -0
  77. package/pi-extension/dist/tool-execution/apply-patch/tool.js +84 -0
  78. package/pi-extension/dist/tool-execution/background.js +238 -0
  79. package/pi-extension/dist/tool-execution/bash-guard.js +23 -0
  80. package/pi-extension/dist/tool-execution/config.js +22 -0
  81. package/pi-extension/dist/tool-execution/edit-messages.js +120 -0
  82. package/pi-extension/dist/tool-execution/file-state.js +138 -0
  83. package/pi-extension/dist/tool-execution/file-tracking.js +143 -0
  84. package/pi-extension/dist/tool-execution/prompt.js +54 -0
  85. package/pi-extension/dist/tool-execution/tools.js +16 -0
  86. package/pi-extension/freeflow/README.md +9 -0
  87. package/plugin.json +1 -1
  88. package/runtime/prompts/cognitive-routing.md +4 -4
  89. package/runtime/prompts/core.md +22 -75
  90. package/runtime/prompts/interaction-contract.md +15 -8
  91. package/runtime/prompts/tool-execution.md +38 -0
  92. package/runtime/prompts/working-method.md +108 -0
  93. package/skills/action-selection/SKILL.md +39 -47
  94. package/skills/action-selection/references/trajectory-stalls.md +2 -0
  95. package/skills/bypass/SKILL.md +2 -2
  96. package/skills/commit-work/SKILL.md +31 -83
  97. package/skills/commit-work/references/git-state-edges.md +1 -1
  98. package/skills/commit-work/references/simple-push.md +2 -0
  99. package/skills/commit-work/references/staging-decisions.md +1 -1
  100. package/skills/decision-gate/SKILL.md +31 -50
  101. package/skills/design-for-depth/SKILL.md +44 -53
  102. package/skills/design-for-depth/references/design-pressure-signals.md +46 -144
  103. package/skills/design-for-depth/references/implementation-decisions.md +1 -1
  104. package/skills/design-for-depth/references/interface-design-loop.md +5 -36
  105. package/skills/design-for-depth/references/module-and-dependency-design.md +2 -32
  106. package/skills/design-for-depth/references/state-and-failure-boundaries.md +2 -13
  107. package/skills/diagnose-failure/SKILL.md +39 -24
  108. package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +2 -0
  109. package/skills/diagnose-failure/references/flaky-and-performance-diagnosis.md +2 -2
  110. package/skills/discuss/SKILL.md +35 -11
  111. package/skills/discuss/references/discussion-continuity.md +7 -27
  112. package/skills/evaluate-skill/SKILL.md +49 -80
  113. package/skills/evaluate-skill/references/evaluation-definition-schema.md +35 -5
  114. package/skills/evaluate-skill/references/evaluation-design.md +14 -14
  115. package/skills/evaluate-skill/references/execution-and-evidence.md +26 -5
  116. package/skills/evaluate-skill/references/review-and-revision.md +3 -1
  117. package/skills/evaluate-skill/scripts/lib/definitions.mjs +49 -8
  118. package/skills/evaluate-skill/scripts/lib/pi.mjs +14 -7
  119. package/skills/evaluate-skill/scripts/lib/review.mjs +196 -0
  120. package/skills/evaluate-skill/scripts/lib/runner.mjs +45 -8
  121. package/skills/evaluate-skill/scripts/lib/sandbox.mjs +2 -0
  122. package/skills/evaluate-skill/scripts/lib/trials.mjs +103 -0
  123. package/skills/evaluate-skill/scripts/lib/view.mjs +67 -1
  124. package/skills/evaluate-skill/scripts/pi-command-tool.mjs +144 -0
  125. package/skills/evaluate-skill/scripts/pi-guard.mjs +30 -13
  126. package/skills/evaluate-skill/scripts/skill-eval.mjs +114 -34
  127. package/skills/execute-work/SKILL.md +41 -9
  128. package/skills/execute-work/references/code-practices.md +2 -0
  129. package/skills/execute-work/references/execute-work-edges.md +11 -1
  130. package/skills/handoff/SKILL.md +1 -1
  131. package/skills/handoff/references/handoff-templates.md +1 -1
  132. package/skills/review-artifact/SKILL.md +42 -41
  133. package/skills/review-artifact/references/adjudicate-artifact-review.md +1 -1
  134. package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +1 -1
  135. package/skills/review-work/SKILL.md +38 -32
  136. package/skills/review-work/references/adjudicate-work-review.md +1 -1
  137. package/skills/review-work/references/independent-work-reviewer-contract.md +1 -1
  138. package/skills/review-work/references/security-risk-lens.md +2 -4
  139. package/skills/setup-freeflow/SKILL.md +3 -1
  140. package/skills/setup-freeflow/references/activation-contract.md +7 -13
  141. package/skills/setup-freeflow/references/host-setup.md +3 -3
  142. package/skills/track-work/SKILL.md +113 -161
  143. package/skills/track-work/references/working-record-format.md +189 -350
  144. package/skills/track-work/scripts/lib/document.mjs +62 -6
  145. package/skills/track-work/scripts/lib/format.mjs +16 -1
  146. package/skills/track-work/scripts/lib/store.mjs +9 -8
  147. package/skills/track-work/scripts/lib/transitions.mjs +79 -4
  148. package/skills/track-work/scripts/working-record.mjs +34 -12
  149. package/skills/verify-work/SKILL.md +29 -20
  150. package/skills/verify-work/references/browser-runtime-evidence.md +1 -5
  151. package/skills/verify-work/references/integration-evidence.md +2 -0
  152. package/skills/verify-work/references/performance-evidence.md +3 -1
  153. package/skills/verify-work/references/test-design.md +3 -1
  154. package/skills/workflow/SKILL.md +65 -21
  155. package/skills/workflow/references/domain-skill-composition.md +5 -3
  156. package/skills/write-docs/SKILL.md +83 -0
  157. package/skills/write-docs/references/documentation-shapes.md +119 -0
  158. package/skills/write-docs/scripts/docs-check.mjs +139 -0
  159. package/skills/write-plan/SKILL.md +40 -40
  160. package/skills/write-plan/references/plan-shapes.md +1 -1
  161. package/skills/write-skill/SKILL.md +107 -147
  162. package/skills/write-skill/references/activation-boundaries.md +2 -0
  163. package/skills/write-skill/references/agent-first-instructions.md +22 -10
  164. package/skills/write-skill/references/progressive-disclosure.md +4 -2
  165. package/skills/write-skill/references/skill-dependency-graphs.md +2 -0
  166. package/skills/write-skill/scripts/lib/similarity.mjs +56 -0
  167. package/skills/write-skill/scripts/skill-author.mjs +18 -2
  168. package/skills/write-spec/SKILL.md +34 -41
  169. package/skills/write-spec/references/artifact-standards.md +1 -1
  170. package/skills/write-spec/references/decision-records.md +2 -0
  171. package/skills/write-spec/references/spec-shapes.md +1 -1
  172. package/capabilities/context-virtualization/SKILL.md +0 -103
  173. package/capabilities/conversation-history/SKILL.md +0 -53
  174. package/hooks/tests/check-host-adapters.test.mjs +0 -82
  175. package/hooks/tests/check-runtime-context-hook.sh +0 -212
  176. package/pi-extension/dist/cognitive-routing-v2/runtime.js +0 -2181
  177. package/pi-extension/dist/context-virtualization/commands.js +0 -89
  178. package/pi-extension/dist/context-virtualization/projector.js +0 -42
  179. package/pi-extension/dist/context-virtualization/runtime.js +0 -378
  180. package/pi-extension/dist/context-virtualization/state.js +0 -57
  181. package/pi-extension/dist/context-virtualization/types.js +0 -10
  182. package/pi-extension/dist/conversation-history/passages.js +0 -66
  183. package/pi-extension/dist/conversation-history/ranking.js +0 -105
  184. package/pi-extension/dist/conversation-history/runtime.js +0 -226
  185. package/pi-extension/dist/conversation-history/search.js +0 -56
  186. package/pi-extension/dist/conversation-history/types.js +0 -1
  187. package/pi-extension/dist/freeflow-context/resolver.js +0 -120
  188. package/pi-extension/dist/freeflow-context/runtime.js +0 -80
  189. package/pi-extension/dist/freeflow-context/source-projector.js +0 -95
  190. package/pi-extension/dist/freeflow-context/tool.js +0 -314
  191. package/pi-extension/dist/freeflow-context/types.js +0 -12
  192. package/pi-extension/dist/freeflow-context/visibility.js +0 -28
  193. package/pi-extension/dist/integrations/mcp-config.js +0 -29
  194. package/pi-extension/dist/runtime/runtime-context.js +0 -754
  195. package/pi-extension/dist/runtime/runtime-identity.js +0 -5
  196. package/pi-extension/dist/session-sources/provenance.js +0 -32
  197. package/pi-extension/dist/ui/text-component.js +0 -57
  198. package/pi-extension/src/cognitive-routing-v2/budget.ts +0 -42
  199. package/pi-extension/src/cognitive-routing-v2/config.ts +0 -173
  200. package/pi-extension/src/cognitive-routing-v2/projection.ts +0 -375
  201. package/pi-extension/src/cognitive-routing-v2/render.ts +0 -277
  202. package/pi-extension/src/cognitive-routing-v2/runtime.ts +0 -2241
  203. package/pi-extension/src/cognitive-routing-v2/schemas.ts +0 -180
  204. package/pi-extension/src/cognitive-routing-v2/state.ts +0 -839
  205. package/pi-extension/src/cognitive-routing-v2/tools.ts +0 -62
  206. package/pi-extension/src/cognitive-routing-v2/types.ts +0 -254
  207. package/pi-extension/src/context-virtualization/commands.ts +0 -111
  208. package/pi-extension/src/context-virtualization/projector.ts +0 -62
  209. package/pi-extension/src/context-virtualization/runtime.ts +0 -428
  210. package/pi-extension/src/context-virtualization/state.ts +0 -79
  211. package/pi-extension/src/context-virtualization/types.ts +0 -92
  212. package/pi-extension/src/conversation-history/passages.ts +0 -81
  213. package/pi-extension/src/conversation-history/ranking.ts +0 -155
  214. package/pi-extension/src/conversation-history/runtime.ts +0 -250
  215. package/pi-extension/src/conversation-history/search.ts +0 -79
  216. package/pi-extension/src/conversation-history/types.ts +0 -31
  217. package/pi-extension/src/freeflow-context/resolver.ts +0 -139
  218. package/pi-extension/src/freeflow-context/runtime.ts +0 -100
  219. package/pi-extension/src/freeflow-context/source-projector.ts +0 -106
  220. package/pi-extension/src/freeflow-context/tool.ts +0 -366
  221. package/pi-extension/src/freeflow-context/types.ts +0 -70
  222. package/pi-extension/src/freeflow-context/visibility.ts +0 -53
  223. package/pi-extension/src/index.ts +0 -390
  224. package/pi-extension/src/integrations/mcp-config.ts +0 -32
  225. package/pi-extension/src/provider-support/astra/adapter.ts +0 -108
  226. package/pi-extension/src/provider-support/astra/history.ts +0 -145
  227. package/pi-extension/src/provider-support/astra/index.ts +0 -12
  228. package/pi-extension/src/provider-support/astra/session-state.ts +0 -113
  229. package/pi-extension/src/provider-support/index.ts +0 -5
  230. package/pi-extension/src/runtime/request-history.ts +0 -243
  231. package/pi-extension/src/runtime/runtime-context.ts +0 -860
  232. package/pi-extension/src/runtime/runtime-identity.ts +0 -8
  233. package/pi-extension/src/session-sources/events.ts +0 -230
  234. package/pi-extension/src/session-sources/provenance.ts +0 -39
  235. package/pi-extension/src/session-sources/read-only-session.ts +0 -170
  236. package/pi-extension/src/session-sources/sources.ts +0 -334
  237. package/pi-extension/src/settings/settings-tui.ts +0 -501
  238. package/pi-extension/src/settings/settings-ui.ts +0 -1652
  239. package/pi-extension/src/ui/text-component.ts +0 -66
  240. package/pi-extension/tests/cache-reuse/history.test.js +0 -117
  241. package/pi-extension/tests/cache-reuse/native.test.js +0 -91
  242. package/pi-extension/tests/cache-reuse/settings.test.js +0 -211
  243. package/pi-extension/tests/cognitive-routing-v2/communication.test.js +0 -577
  244. package/pi-extension/tests/cognitive-routing-v2/compaction-input.test.js +0 -183
  245. package/pi-extension/tests/cognitive-routing-v2/delegation.test.js +0 -557
  246. package/pi-extension/tests/cognitive-routing-v2/native.test.js +0 -474
  247. package/pi-extension/tests/cognitive-routing-v2/performance.test.js +0 -87
  248. package/pi-extension/tests/cognitive-routing-v2/persistence.test.js +0 -300
  249. package/pi-extension/tests/cognitive-routing-v2/projection.test.js +0 -241
  250. package/pi-extension/tests/cognitive-routing-v2/recovery.test.js +0 -1034
  251. package/pi-extension/tests/cognitive-routing-v2/render.test.js +0 -244
  252. package/pi-extension/tests/cognitive-routing-v2/runtime.test.js +0 -423
  253. package/pi-extension/tests/cognitive-routing-v2/stabilization.test.js +0 -521
  254. package/pi-extension/tests/cognitive-routing-v2/state.test.js +0 -586
  255. package/pi-extension/tests/context-virtualization/extension.test.js +0 -775
  256. package/pi-extension/tests/context-virtualization/projector.test.js +0 -110
  257. package/pi-extension/tests/context-virtualization/runtime.test.js +0 -230
  258. package/pi-extension/tests/conversation-history/runtime.test.js +0 -98
  259. package/pi-extension/tests/conversation-history/search.test.js +0 -97
  260. package/pi-extension/tests/fixtures/pi-host.js +0 -4
  261. package/pi-extension/tests/fixtures/routing-native.js +0 -191
  262. package/pi-extension/tests/integration/mode-free-core.test.js +0 -220
  263. package/pi-extension/tests/integration/pi-extension.test.js +0 -1447
  264. package/pi-extension/tests/integration/prompt-architecture.test.js +0 -447
  265. package/pi-extension/tests/integration/unaffected-regressions.test.js +0 -478
  266. package/pi-extension/tests/provider-support/astra-boundaries.test.js +0 -75
  267. package/pi-extension/tests/provider-support/astra.test.js +0 -306
  268. package/pi-extension/tests/provider-support/cli.test.js +0 -92
  269. package/pi-extension/tests/provider-support/native.test.js +0 -183
  270. package/pi-extension/tests/settings/settings-tui.test.js +0 -243
  271. package/pi-extension/tsconfig.json +0 -16
  272. package/runtime/prompts/context-virtualization.md +0 -3
  273. package/runtime/prompts/conversation-history.md +0 -3
  274. package/skills/design-for-depth/references/software-design-philosophy.md +0 -202
  275. /package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/budget.js +0 -0
  276. /package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/render.js +0 -0
@@ -12,31 +12,42 @@ A **group** asks one behavioral question through exactly two variants:
12
12
  - `baseline`: no target skill for a new skill, or one exact immutable previous package for a revision;
13
13
  - `candidate`: one exact new or updated package.
14
14
 
15
- The **subject** performs the declared task under one variant. The **evaluator** isolates subjects and preserves canonical evidence. The **deterministic grader** derives fixed mechanical facts after run persistence. A **suite** runs an ordered set of independent groups.
15
+ The **subject** performs the declared task under one variant. The **evaluator** isolates subjects and preserves canonical evidence. The **deterministic grader** derives fixed mechanical facts after the run is saved. A **suite** runs an ordered set of independent groups.
16
16
 
17
- Evaluate Skill does not author or revise skills, decide semantic quality, claim readiness, or choose publication. [Write Skill](../write-skill/SKILL.md) owns package preservation and revision. The active agent or user judges unresolved meaning. The user decides whether to revise, use, publish, or reject the skill.
17
+ Evaluate Skill does not author or revise skills, decide semantic quality, claim readiness, or choose publication. [Write Skill](../write-skill/SKILL.md) owns package preservation and revision. The active agent or user judges unresolved meaning; the user decides whether to revise, use, publish, or reject the skill.
18
18
 
19
- Inline examples teach the subject and are part of the candidate intervention. They are not independent evaluation evidence. Keep deterministic criteria and review questions outside natural subject prompts.
19
+ The **Rules** below are binding; if one cannot be met, stop and say why. Everything else is **judgment**: follow its stated goal, and adapt when a different choice serves that goal better.
20
20
 
21
- ## Route From Existing Evidence First
21
+ ## Rules
22
+
23
+ - Never mutate canonical evidence or erase an unfavorable result. Preserve partial and infrastructure evidence without converting unavailable behavior into pass or fail.
24
+ - Never fabricate behavioral evidence. Missing evidence stays unavailable.
25
+ - Compare a revision only against an exact immutable baseline. If none exists, return to Write Skill to preserve the current package; never create a baseline by editing the package being evaluated.
26
+ - Keep deterministic criteria and review questions out of subject prompts and declared subject context.
27
+ - Declare every subject resource. Ambient installation or context is not declared composition.
28
+ - Claim only what the evidence class observed; one class never proves another.
29
+ - Never edit the skill from Evaluate Skill. Return one measured revision target to Write Skill.
30
+ - After a behavioral change, rerun the complete fixed group with both variants. Never reuse an earlier run as the fresh counterpart or rerun only the preferred variant.
31
+ - Advisory review and semantic judgment never enter canonical run or grade state, and neither establishes readiness.
32
+ - Never invoke archived evaluators.
33
+
34
+ ## Start From Existing Evidence
35
+
36
+ Goal: answer the question with the least new evidence that can answer it.
22
37
 
23
38
  Before proposing a run or revision:
24
39
 
25
- - inspect adequate saved evidence;
40
+ - inspect adequate saved evidence, through views and raw artifact reads when a complete result already answers the question;
26
41
  - reuse an existing group unchanged when it still preserves the question, pressure, variants, and fixed criteria;
27
- - use saved views and raw artifact reads when a complete result already answers the question;
28
- - preserve partial infrastructure evidence without converting unavailable behavior into pass or fail;
29
- - do not mutate canonical evidence or erase an unfavorable result.
30
-
31
- For a draft-only request, use Write Skill. Do not fabricate behavioral evidence.
42
+ - for a draft-only request, use Write Skill instead.
32
43
 
33
- A revision comparison requires an exact immutable baseline identity. If none exists, return to Write Skill to preserve the complete current package before revision. Evaluate Skill consumes baseline and candidate identities; it does not create a baseline by editing the package it is evaluating.
44
+ Do not rerun merely to demonstrate process.
34
45
 
35
46
  ## Name One Behavioral Question
36
47
 
37
- Name the exact claim and observing mechanism before choosing the group shape.
48
+ Goal: one question, observed at the boundary where the claim lives.
38
49
 
39
- Evidence classes include:
50
+ Name the exact claim and observing mechanism before choosing the group shape. Evidence classes include:
40
51
 
41
52
  - **Description activation:** did a natural prompt cause the exact target to be read, and when?
42
53
  - **First-read body behavior:** did explicit body delivery guide the subject using only guaranteed context?
@@ -44,9 +55,7 @@ Evidence classes include:
44
55
  - **Dependency composition:** did exact ordered skills, resources, and context work together?
45
56
  - **Retained use:** did guidance remain useful on later declared turns without redelivery?
46
57
  - **Artifact outcome:** did files, structured state, events, and responses match fixed criteria?
47
- - **Cross-host behavior:** did the same behavioral question hold on every named host?
48
-
49
- One evidence class does not prove another.
58
+ - **Cross-host behavior:** did the same behavioral question hold on every named host? The evaluator currently runs only native Pi hosts.
50
59
 
51
60
  ```text
52
61
  successful read
@@ -65,10 +74,14 @@ correct behavior
65
74
  ≠ proof that the target caused it
66
75
  ```
67
76
 
77
+ Test a skill's Rules and its judgment differently. A Rule needs pressure to break it; it passes only if it holds. Judgment needs a case where following the default literally is the worse choice; it passes on outcome, so a candidate that only obeys cannot pass.
78
+
68
79
  Read [Evaluation Design](references/evaluation-design.md) before choosing or materially changing the question, evidence class, group shape, pressure, or baseline/candidate boundary.
69
80
 
70
81
  ## Design The Smallest Valid Comparison
71
82
 
83
+ Goal: the only difference between variants is the target, and the pressure is strong enough to show it.
84
+
72
85
  Before subject output exists:
73
86
 
74
87
  1. fix one behavioral question;
@@ -78,80 +91,51 @@ Before subject output exists:
78
91
  5. keep prompt or turns, fixture, tools, model, thinking, other skills, context, runtime, and criteria fixed except for the target difference;
79
92
  6. run one group or an ordered suite serially;
80
93
  7. inspect canonical evidence and deterministic facts before judging meaning;
81
- 8. classify the failed boundary before proposing revision;
82
- 9. return one measured revision target to Write Skill;
83
- 10. rerun the complete fixed group with both variants after a behavioral change.
84
-
85
- For a new skill:
86
-
87
- ```text
88
- baseline: no target skill
89
- candidate: exact candidate package
90
- ```
91
-
92
- For a revision:
93
-
94
- ```text
95
- baseline: exact previous package
96
- candidate: exact revised package
97
- ```
94
+ 8. classify the failed boundary before proposing revision.
98
95
 
99
- For a description-only revision, keep body, references, scripts, and other resources byte-identical.
96
+ For a new skill, the baseline has no target skill. For a revision, the baseline is the exact previous package. For a description-only revision, keep body, references, scripts, and other resources byte-identical.
100
97
 
101
98
  If both variants pass, the pressure may be weak or the baseline already sufficient. If both fail, distinguish skill, fixture, dependency, environment, host, isolation, and criterion failures before revising instructions.
102
99
 
103
- ## Declare The Complete Environment
100
+ Inline examples in the skill teach the subject and are part of the candidate intervention; they are not independent evaluation evidence.
104
101
 
105
- Use the exact [Evaluation Definition Schema](references/evaluation-definition-schema.md) when authoring or checking group and suite JSON.
102
+ ## Declare The Complete Environment
106
103
 
107
- Declare:
104
+ Use the exact [Evaluation Definition Schema](references/evaluation-definition-schema.md) when authoring or checking group and suite JSON. Declare:
108
105
 
109
106
  - prompt or ordered turns;
110
107
  - fixture;
111
108
  - exact ordered skill packages and target index;
112
109
  - working-tree or Git source identity;
113
110
  - context resources;
114
- - tools;
111
+ - tools and any declared commands;
115
112
  - model and thinking;
116
- - runtime host and extension bundles when needed;
113
+ - runtime host, prompt mode, and extension bundles when needed;
117
114
  - literal and inherited environment sources;
118
115
  - deterministic expectations and comparison IDs;
119
116
  - review questions.
120
117
 
121
- Snapshot every declared subject resource. Ambient installation is not declared composition.
122
-
123
- Criteria and review questions remain outside the subject prompt.
124
-
125
118
  ## Run And Preserve Canonical Evidence
126
119
 
127
120
  Before operating the evaluator, resolving paths, interpreting states, or reasoning about host execution, read [Execution and Evidence](references/execution-and-evidence.md).
128
121
 
129
- Use the canonical [skill evaluator](scripts/skill-eval.mjs):
122
+ Use the canonical [skill evaluator](scripts/skill-eval.mjs) from the definition root:
130
123
 
131
124
  ```text
132
- node <evaluate-skill-directory>/scripts/skill-eval.mjs run <suite-or-group-path> [--group <id-or-position>] [--variant baseline|candidate]
125
+ node <evaluate-skill-directory>/scripts/skill-eval.mjs run <suite-or-group-path> [--group <id-or-position>] [--variant baseline|candidate] [--trials <n>] [--max-cost <total>]
133
126
  node <evaluate-skill-directory>/scripts/skill-eval.mjs view <result-id-or-directory> [--group <id-or-position>] [--variant baseline|candidate]
127
+ node <evaluate-skill-directory>/scripts/skill-eval.mjs review <result-id-or-directory> --model <provider/model> [--group <id-or-position>] [--thinking <level>]
134
128
  ```
135
129
 
136
- Run from the definition root.
130
+ One run per variant cannot separate a behavioral difference from sampling noise. Use `--trials <n>` before claiming a difference; each trial is an independent complete result, and the aggregate only counts their deterministic grades. Use `--max-cost` when trials or suites could spend more than intended.
137
131
 
138
132
  With no selectors, run or view every suite group and both variants. Selectors narrow execution or viewing scope; they do not modify definitions.
139
133
 
140
- Canonical results live under:
141
-
142
- ```text
143
- <definition-root>/.skill-eval/runs/<result-id>
144
- ```
145
-
146
- A view is a projection of saved evidence, not its canonical source. Use ordinary file tools when exact run, event, transcript, response, stderr, workspace, definition, grade, context-observation, or group artifacts matter.
147
-
148
- Do not invoke archived evaluators.
134
+ Canonical results live under `<definition-root>/.skill-eval/runs/<result-id>`. A view is a projection of saved evidence, not its canonical source; use ordinary file tools when the exact run, event, transcript, response, stderr, workspace, definition, grade, context-observation, or group artifact matters.
149
135
 
150
136
  ## Derive Facts Without Inventing Meaning
151
137
 
152
- Append deterministic grades only after canonical run evidence exists.
153
-
154
- Deterministic checks may establish exact facts such as:
138
+ Deterministic grades are appended only after canonical run evidence exists. They can establish exact facts such as:
155
139
 
156
140
  - skill or resource reads;
157
141
  - file and path state;
@@ -162,25 +146,15 @@ Deterministic checks may establish exact facts such as:
162
146
  - context text at a selected surface, request, and turn;
163
147
  - factual baseline-to-candidate transitions.
164
148
 
165
- A failed check remains ordinary behavioral evidence. It does not turn a valid subject run into infrastructure failure.
166
-
167
- Missing evidence remains unavailable.
168
-
169
- Malformed expectations or grading failures produce separate `grade-error` evidence and do not rewrite canonical run evidence.
149
+ A failed check remains ordinary behavioral evidence; it does not turn a valid subject run into infrastructure failure. Malformed expectations or grading failures produce separate `grade-error` evidence and do not rewrite run evidence.
170
150
 
171
151
  A transition such as `fail-to-pass` is a factual comparison. It does not mean bad-to-good, not-ready-to-ready, or rejected-to-promotable.
172
152
 
173
153
  ## Review Meaning After Evidence Exists
174
154
 
175
- After canonical evidence and deterministic grades exist, read [Review and Revision](references/review-and-revision.md) when:
155
+ After canonical evidence and deterministic grades exist, read [Review and Revision](references/review-and-revision.md) when evidence conflicts, semantic meaning remains unresolved, the failed boundary must be classified, a revision target must be selected, or rerun scope is uncertain.
176
156
 
177
- - evidence conflicts;
178
- - semantic meaning remains unresolved;
179
- - the failed boundary must be classified;
180
- - a revision target must be selected;
181
- - rerun scope is uncertain.
182
-
183
- The evaluator does not launch an automatic semantic grader.
157
+ The evaluator never grades meaning automatically. `review` records an optional advisory answer to each review question from a separate model that sees the two runs unlabeled, in `semantic-grade.json`.
184
158
 
185
159
  The active agent or user may judge reasoning quality, authority preservation, architectural fitness, recommendation quality, or semantic completeness. Keep that judgment, cited evidence, uncertainty, and limits outside canonical run and grade state.
186
160
 
@@ -190,12 +164,9 @@ When evidence supports a candidate change:
190
164
 
191
165
  1. identify the exact failed boundary;
192
166
  2. preserve the canonical result path and relevant evidence;
193
- 3. state one measured revision target;
194
- 4. keep unrelated instructions and criteria stable;
195
- 5. return revision to Write Skill;
196
- 6. rerun the complete fixed group with both variants after the change.
197
-
198
- Do not edit the skill from Evaluate Skill.
167
+ 3. state one measured revision target, keeping unrelated instructions and criteria stable;
168
+ 4. return revision to Write Skill;
169
+ 5. rerun the complete fixed group with both variants after the change.
199
170
 
200
171
  If the evaluation definition or criterion is wrong, preserve the old result and state that it no longer answers the revised question. Do not reinterpret it as evidence for the new question.
201
172
 
@@ -214,6 +185,4 @@ Report:
214
185
  - what it does not prove;
215
186
  - any supported failed boundary or revision target.
216
187
 
217
- Stop rather than overclaim when required activation, first-read, composition, retained-use, isolation, artifact, or host evidence is unavailable.
218
-
219
- The active agent or user judges unresolved behavior. The user decides whether to revise, use, publish, or reject the skill.
188
+ Stop rather than overclaim when required activation, first-read, composition, retained-use, isolation, artifact, or host evidence is unavailable. The user decides whether to revise, use, publish, or reject the skill.
@@ -2,6 +2,8 @@
2
2
 
3
3
  Read this when authoring or checking schema-version-1 group and suite JSON.
4
4
 
5
+ This reference is a contract: the shapes and constraints below are binding as written. Structural violations are rejected before any subject runs; a malformed expectation surfaces afterward as `grade-error` evidence.
6
+
5
7
  This file owns user-authored definition shapes. Read [execution and evidence](execution-and-evidence.md) for commands, path resolution, run states, persistence, views, isolation, and safeguards.
6
8
 
7
9
  ## Definition Root
@@ -62,13 +64,14 @@ Rules:
62
64
  - `input` contains exactly one of:
63
65
  - `prompt`: one non-empty string;
64
66
  - `turns`: a non-empty ordered array of non-empty strings. Repeated natural turns are allowed.
65
- - `fixture` is `null` or one contained relative directory/file path.
67
+ - `fixture` is `null` or one contained relative directory path. The directory's contents become the workspace.
66
68
  - `tools` is an ordered array with no duplicates.
67
69
  - `variants` contains exactly `baseline` and `candidate`.
68
70
  - `expectations` is an ordered array with unique expectation IDs.
69
71
  - `review_questions` is an ordered string array. Questions are rendered for the reviewer and never sent to the subject.
70
72
  - `model` is optional. `model.model` names the provider/model; optional `model.thinking` selects its thinking level. The CLI has no model override.
71
- - `runtime` is optional. When omitted, the group runs under a plain `pi` host with no declared extensions. When present, it declares the host, ordered extension bundles, and string environment overrides.
73
+ - `runtime` is optional. When omitted, the group runs under a plain `pi` host with the isolated prompt and no declared extensions. When present, it declares the host, prompt mode, ordered extension bundles, and string environment overrides.
74
+ - `commands` is optional and only for body groups that list the `run_command` tool. See [Declared Commands](#declared-commands).
72
75
 
73
76
  ## Description Group Example
74
77
 
@@ -204,7 +207,7 @@ A body group explicitly delivers each target on turn one and observes first-read
204
207
  }
205
208
  ```
206
209
 
207
- Description groups allow no tools or only built-in `read`. Body groups allow built-in `read`, `write`, and `edit`, plus custom tools declared by a runtime extension bundle. Native `bash`, `powershell`, `grep`, `find`, and `ls` tools are unsupported. A no-target baseline or runtime-only group may use `skills: []` and `target: null`; a candidate that declares skills must identify its target.
210
+ Description groups allow no tools or only built-in `read`. Body groups allow built-in `read`, `write`, and `edit`, the evaluator's `run_command` tool for declared commands, plus custom tools declared by a runtime extension bundle. Native `bash`, `powershell`, `grep`, `find`, and `ls` tools are unsupported. A no-target baseline or runtime-only group may use `skills: []` and `target: null`; a candidate that declares skills must identify its target.
208
211
 
209
212
  The examples are complete definition shapes. Replace fixture, resource, model, and Git-ref values with paths and identities that exist under your definition root.
210
213
 
@@ -233,7 +236,12 @@ A runtime profile is shared by both baseline and candidate variants. It changes
233
236
  }
234
237
  ```
235
238
 
236
- `host` is `pi` or `piflow`; the evaluator maps it to the corresponding installed host command and records the selected host. `session` controls whether the variant receives an isolated persistent session directory; it defaults to `false` in omitted runtime profiles. A runtime may declare zero or more bundles. Each bundle has an entry file and one or more directory resources copied under their original relative paths, so sibling imports and multi-tree extensions remain intact. Bundle bytes are snapshotted once and copied identically to both variants.
239
+ `host` is `pi`; the evaluator maps it to the installed Pi command and records the selected host. Optional `prompt` is `isolated` (default) or `host`:
240
+
241
+ - `isolated` replaces the host's system prompt with a minimal evaluator-owned prompt. Use it to isolate the target skill.
242
+ - `host` keeps the host's own system prompt and whatever declared extensions compose onto it, appending declared context. Use it when evidence must reflect the production prompt, for example by declaring the Freeflow Pi extension bundle with a fixture containing `.freeflow/config.json`.
243
+
244
+ Both modes enforce the same tool and path guards. `session` controls whether the variant receives an isolated persistent session directory; it defaults to `false` in omitted runtime profiles. A runtime may declare zero or more bundles. Each bundle has an entry file and one or more directory resources copied under their original relative paths, so sibling imports and multi-tree extensions remain intact. Bundle bytes are snapshotted once and copied identically to both variants.
237
245
 
238
246
  `environment.literal` contains non-secret string configuration and is recorded in run evidence. `environment.inherit` names parent-process variables whose values are passed to the child but never persisted; other parent variables are not passed. Missing inherited variables invalidate the variant. The evaluator supplies only a small host-runtime baseline such as `PATH` and `HOME`. Launch-control and loader keys are rejected from inherited values, literal and inherited names must not overlap, and secret-like literal keys are rejected.
239
247
 
@@ -355,7 +363,29 @@ Two expectations may share one comparison ID only when they have opposite varian
355
363
 
356
364
  Definition loading validates common structure and unique IDs. Kind-specific expectation validation occurs during deterministic grading after run persistence. A malformed expectation therefore becomes separate `grade-error` evidence rather than changing the subject run. Use the documented shapes to avoid spending a subject run on an invalid check.
357
365
 
358
- Definition-supplied commands and tests are unsupported.
366
+ Definition-supplied commands run only through the subject's `run_command` tool. Grading never runs commands.
367
+
368
+ ## Declared Commands
369
+
370
+ A body group that must let the subject run tests or other programs lists the `run_command` tool and declares each allowed command:
371
+
372
+ ```json
373
+ {
374
+ "tools": ["read", "edit", "run_command"],
375
+ "commands": [
376
+ { "id": "unit-tests", "argv": ["node", "--test"], "timeout_ms": 120000 },
377
+ { "id": "lint", "argv": ["npm", "run", "lint"] }
378
+ ]
379
+ }
380
+ ```
381
+
382
+ - `run_command` and `commands` require each other and are valid only in body groups.
383
+ - Each command has a unique `id` (group-ID syntax), a non-empty `argv`, and optional integer `timeout_ms` from 1 to 600000 (default 120000).
384
+ - The subject chooses only a declared `id`; it cannot change `argv`. The argv runs without a shell, in the workspace, without evaluator control variables.
385
+ - Output is capped per stream and marked when truncated. A nonzero exit or timeout is an ordinary tool result, not a tool error.
386
+ - Grade calls with `tool-call` expectations, for example `tool: "run_command"` with `argumentContains: ["unit-tests"]`.
387
+
388
+ Commands are trusted author input with the evaluator's host permissions, like extension bundles; the subject only selects among them.
359
389
 
360
390
  ## Suite
361
391
 
@@ -2,16 +2,7 @@
2
2
 
3
3
  Read this before choosing or materially changing the behavioral question, evidence class, group shape, pressure, or baseline/candidate boundary.
4
4
 
5
- ## Keep Roles Distinct
6
-
7
- - **Subject:** performs the declared task under one variant.
8
- - **Evaluator:** isolates subjects and preserves canonical evidence.
9
- - **Deterministic grader:** derives fixed mechanical facts after run persistence.
10
- - **Reviewer:** the active agent or user judges unresolved meaning.
11
- - **Author:** uses Write Skill to revise one measured pressure point.
12
- - **User:** decides whether to revise, use, publish, or reject the skill.
13
-
14
- The evaluator does not revise the skill, launch an automatic semantic grader, or own readiness, promotion, or production status.
5
+ This reference is judgment: adapt it to the question being answered. Its binding statements restate [Evaluate Skill](../SKILL.md) Rules or the definition schema.
15
6
 
16
7
  ## Map Claims To Evidence
17
8
 
@@ -60,6 +51,8 @@ For a new skill, baseline has no target.
60
51
 
61
52
  For a revision, baseline names an exact immutable previous package. If no exact baseline exists, return to Write Skill before revision.
62
53
 
54
+ To learn whether a skill's body, not just its description, changes behavior, add a separate group whose baseline is a neutral package: the same name and description with a placeholder body. A candidate that matches the neutral baseline gains nothing from its body under that pressure.
55
+
63
56
  For a description-only revision, body and resources remain byte-identical.
64
57
 
65
58
  Freeze prompts or turns, fixture, tools, model, thinking, other skills, context, runtime, and criteria across variants.
@@ -101,12 +94,19 @@ A useful group:
101
94
  - distinguishes baseline from candidate behavior;
102
95
  - remains realistic enough that passing behavior is useful.
103
96
 
104
- If both variants pass, the pressure may be weak or the baseline sufficient.
97
+ Choose the pressure by the kind of instruction under test:
98
+
99
+ - **A Rule:** make breaking it the easy or rewarded path, such as urgency, a user request that conflicts with it, or a shortcut that saves work. The candidate passes only if the Rule holds.
100
+ - **Judgment:** include at least one case where following the default literally is the worse choice, next to a case where the default is right. The candidate passes on the outcome in both, so a variant that only obeys the default cannot pass.
101
+
102
+ ## Grade By Requirement And Respect Variance
103
+
104
+ Grade each requirement a group checks, not only pass or fail. Label each as derivable from the request and code, dependent on a clarification, or imposed by the evaluator (an exact name or message only the checker knows); a failure on an evaluator-imposed requirement says little about the skill.
105
105
 
106
- If both fail, classify skill, fixture, dependency, environment, host, isolation, or criterion before editing.
106
+ One run per cell cannot separate a difference of one or two items from run-to-run variance. Repeat the cell, or report such a difference as unresolved.
107
107
 
108
- ## Reuse Existing Evidence
108
+ Freeze the candidate before a batch runs. Items used to develop a revision are not evidence for it: judge it on held-out items, and stop iterating on the items it was tuned against.
109
109
 
110
- When saved canonical evidence already answers the fixed question, inspect it through views and raw artifacts. Do not rerun merely to demonstrate process.
110
+ ## Keep Separate Conclusions Separate
111
111
 
112
112
  An explicitly delivered body may support first-read behavior while a natural prompt still fails activation. Preserve both conclusions; one does not repair the other.
@@ -1,14 +1,17 @@
1
1
  # Execution And Evidence
2
2
 
3
- Read this when operating `run|view`, resolving paths, interpreting states, or reasoning about Pi execution, isolation, persistence, cancellation, and safeguards.
3
+ Read this when operating `run|view|review`, resolving paths, interpreting states, or reasoning about Pi execution, isolation, persistence, cancellation, and safeguards.
4
+
5
+ This reference is a contract: it states how the evaluator behaves. Rely on that behavior as written; its binding requirements on you restate [Evaluate Skill](../SKILL.md) Rules.
4
6
 
5
7
  ## Command And Path Contract
6
8
 
7
9
  Run commands from the repository or fixture root that owns the definitions:
8
10
 
9
11
  ```text
10
- node <evaluate-skill-directory>/scripts/skill-eval.mjs run <suite-or-group-path> [--group <id-or-position>] [--variant baseline|candidate]
12
+ node <evaluate-skill-directory>/scripts/skill-eval.mjs run <suite-or-group-path> [--group <id-or-position>] [--variant baseline|candidate] [--trials <n>] [--max-cost <total>]
11
13
  node <evaluate-skill-directory>/scripts/skill-eval.mjs view <result-id-or-directory> [--group <id-or-position>] [--variant baseline|candidate]
14
+ node <evaluate-skill-directory>/scripts/skill-eval.mjs review <result-id-or-directory> --model <provider/model> [--group <id-or-position>] [--thinking <level>]
12
15
  ```
13
16
 
14
17
  - The current working directory is the definition root and result root.
@@ -33,9 +36,9 @@ With no selectors, `run` or `view` selects every suite group and both variants.
33
36
 
34
37
  ## Current Execution Boundary
35
38
 
36
- `run` executes description and body groups. Unsupported group types are rejected before subject execution. Description groups allow no tools or `read`; body groups allow no tools or path-guarded `read`, `write`, and `edit`, plus non-native custom tools supplied by a declared runtime extension bundle. Native `bash`, `powershell`, `grep`, `find`, and `ls` tools and definition-supplied commands are unsupported.
39
+ `run` executes description and body groups. Unsupported group types are rejected before subject execution. Description groups allow no tools or `read`; body groups allow no tools or path-guarded `read`, `write`, and `edit`, the evaluator's `run_command` tool for declared commands, plus non-native custom tools supplied by a declared runtime extension bundle. Native `bash`, `powershell`, `grep`, `find`, and `ls` tools are unsupported.
37
40
 
38
- A runtime profile selects the installed `pi` or `piflow` host, whether the variant uses an isolated persistent session directory, zero or more ordered extension bundles, and declarative environment sources. Literal values are non-secret configuration; only explicitly inherited parent variables are passed to the child without being persisted, alongside a small host-runtime baseline. Missing inherited variables invalidate the variant. Launch-control and loader keys are rejected from inherited values, and literal and inherited names must not overlap. For body runs, delivery remains `unavailable` until target setup succeeds; `natural-prompt` or `explicit-skill-command` records a prompt attempt. When a group declares context assertions, the evaluator launches the base guard first, declared extensions second, and a final non-mutating observer last. The observer records both the effective `before_agent_start` system prompt and each provider-neutral `context` message projection; it does not replace or sanitize extension injections after the base guard has established evaluator-owned isolation.
41
+ A runtime profile selects the installed native Pi host, the `isolated` or `host` prompt mode, whether the variant uses an isolated persistent session directory, zero or more ordered extension bundles, and declarative environment sources. Literal values are non-secret configuration; only explicitly inherited parent variables are passed to the child without being persisted, alongside a small host-runtime baseline. Missing inherited variables invalidate the variant. Launch-control and loader keys are rejected from inherited values, and literal and inherited names must not overlap. For body runs, delivery remains `unavailable` until target setup succeeds; `natural-prompt` or `explicit-skill-command` records a prompt attempt. The evaluator launches the base guard first, its command tool when the group declares commands, declared extensions next, and, when a group declares context assertions, a final non-mutating observer last. The observer records both the effective `before_agent_start` system prompt and each provider-neutral `context` message projection; it does not replace or sanitize extension injections after the base guard has established evaluator-owned isolation.
39
42
 
40
43
  Use fresh JSON-mode execution for one-shot descriptions. Use one persistent RPC process per selected variant for ordered description turns and all body groups. RPC correlates responses, waits for `agent_settled`, disables automatic retry and compaction, preserves directly observed partial-turn evidence, and cleans the process tree.
41
44
 
@@ -85,6 +88,24 @@ Use ordinary file tools for raw `run.json`, events, transcript, final response,
85
88
 
86
89
  ## Safeguards And Limits
87
90
 
88
- Normal completion follows settlement. Path guards, no-progress detection, cancellation, process-tree cleanup, and very high emergency ceilings stop runaway or unsafe infrastructure. Do not impose ordinary guessed turn, token, spend, output, or short time caps.
91
+ Normal completion follows settlement. Path guards, no-progress detection, cancellation, process-tree cleanup, and very high emergency ceilings stop runaway or unsafe infrastructure. Subjects run until they settle, with no turn, token, output, or short time cap, because a guessed cap cuts off the behavior the evaluation is trying to observe.
92
+
93
+ `--max-cost <total>` is an explicit spend ceiling, not a subject cap. After each subject finishes, its host-reported `usage.cost.total` is added to the invocation's spend; once spend reaches the ceiling, no further subject starts and queued variants become `cancelled`. The subject already running completes, so spend can exceed the ceiling by one subject. The summary records `budget` with the ceiling, spend, and whether it was exhausted. A host that reports no cost never exhausts the ceiling.
94
+
95
+ ## Trials
96
+
97
+ `--trials <n>` runs the selection as `n` independent complete invocations. Each trial is an ordinary result with its own ID. A separate aggregate under `.skill-eval/runs/<aggregate-id>/aggregate.json` lists the trials and, per group, counts pass, fail, and unavailable for every deterministic check and comparison, plus comparison transitions. `--max-cost` is shared across trials, and exhaustion stops starting further trials. `view <aggregate-id>` renders the counts; view an individual trial for its evidence.
98
+
99
+ ## Advisory Review
100
+
101
+ `review` answers each group's `review_questions` with a separate reviewer model:
102
+
103
+ - only groups with review questions and two complete runs are reviewed;
104
+ - the reviewer sees the task turns, each run's responses, tool calls, and changed paths as Run A and Run B in random order, and never sees variant names or deterministic grades;
105
+ - it runs without tools, skills, extensions, context files, or session, with only the base process environment;
106
+ - `groups/<id>/semantic-grade.json` records the label mapping, prompt hash, answers mapped back to variants, and errors; `groups/<id>/review/` keeps the prompt, events, final response, and stderr;
107
+ - malformed or incomplete reviewer output becomes `review-error` with the raw response preserved.
108
+
109
+ A review is advisory. It never changes run or deterministic grade evidence, and rerunning it replaces only the previous advisory review.
89
110
 
90
111
  When an unsupported operation changes the question, reject it or run a clearly separate direct comparison with explicit limits. Never invoke archived evaluators as a fallback.
@@ -2,6 +2,8 @@
2
2
 
3
3
  Read this after canonical evidence and deterministic grades exist, when evidence conflicts, meaning remains unresolved, the failed boundary must be classified, or revision and rerun scope must be chosen.
4
4
 
5
+ This reference is judgment: adapt it to the evidence in hand. Its rerun and no-edit requirements restate [Evaluate Skill](../SKILL.md) Rules.
6
+
5
7
  ## Use The Strongest Evidence
6
8
 
7
9
  Prefer, in order:
@@ -76,7 +78,7 @@ After a measured skill revision or resolved infrastructure cause:
76
78
  - do not use partial evidence as a comparable full result;
77
79
  - do not rerun merely to erase failure.
78
80
 
79
- For variance, use independent complete invocations rather than repeated preferred variants.
81
+ For variance, use `--trials` to run independent complete invocations rather than repeated preferred variants.
80
82
 
81
83
  ## Report
82
84
 
@@ -2,9 +2,12 @@ import { readFile, realpath } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
 
4
4
  const ID = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
5
- const EVALUATION_TYPES = new Set(["description", "body", "end-to-end"]);
5
+ const EVALUATION_TYPES = new Set(["description", "body"]);
6
6
  const VARIANTS = ["baseline", "candidate"];
7
- const EVALUATION_HOSTS = new Set(["pi", "piflow"]);
7
+ const EVALUATION_HOSTS = new Set(["pi"]);
8
+ const PROMPT_MODES = new Set(["isolated", "host"]);
9
+ export const COMMAND_TOOL = "run_command";
10
+ const MAX_COMMAND_TIMEOUT_MS = 10 * 60 * 1000;
8
11
  const RESERVED_ENVIRONMENT_KEYS = new Set([
9
12
  "PATH",
10
13
  "HOME",
@@ -15,8 +18,6 @@ const RESERVED_ENVIRONMENT_KEYS = new Set([
15
18
  "NODE_OPTIONS",
16
19
  "NODE_PATH",
17
20
  "PI_PACKAGE_DIR",
18
- "PIFLOW_CODING_AGENT_DIR",
19
- "PIFLOW_CODING_AGENT_SESSION_DIR",
20
21
  ]);
21
22
 
22
23
  export class DefinitionError extends Error {
@@ -147,12 +148,15 @@ function validateRuntime(value, definitionPath) {
147
148
  const runtime = requireExactKeys(
148
149
  value,
149
150
  ["host", "extensions", "environment", "session"],
150
- [],
151
+ ["prompt"],
151
152
  "group.runtime",
152
153
  definitionPath,
153
154
  );
154
155
  if (!EVALUATION_HOSTS.has(runtime.host)) {
155
- fail("invalid-definition", "group.runtime.host must be pi or piflow", definitionPath);
156
+ fail("invalid-definition", "group.runtime.host must be pi", definitionPath);
157
+ }
158
+ if (Object.hasOwn(runtime, "prompt") && !PROMPT_MODES.has(runtime.prompt)) {
159
+ fail("invalid-definition", "group.runtime.prompt must be isolated or host", definitionPath);
156
160
  }
157
161
  if (!Array.isArray(runtime.extensions)) {
158
162
  fail("invalid-definition", "group.runtime.extensions must be an array", definitionPath);
@@ -253,6 +257,42 @@ function validateExpectations(value, definitionPath) {
253
257
  }
254
258
  }
255
259
 
260
+ // Declared commands are fixed by the definition author; the subject may only choose which one runs.
261
+ function validateCommands(group, definitionPath) {
262
+ const toolDeclared = group.tools.includes(COMMAND_TOOL);
263
+ if (!Object.hasOwn(group, "commands")) {
264
+ if (toolDeclared) fail("invalid-definition", `${COMMAND_TOOL} requires declared group.commands`, definitionPath);
265
+ return;
266
+ }
267
+ if (!toolDeclared) fail("invalid-definition", `group.commands requires the ${COMMAND_TOOL} tool`, definitionPath);
268
+ if (group.type !== "body")
269
+ fail("invalid-definition", "group.commands are supported only by body groups", definitionPath);
270
+ if (!Array.isArray(group.commands) || group.commands.length === 0) {
271
+ fail("invalid-definition", "group.commands must be a non-empty array", definitionPath);
272
+ }
273
+ const ids = new Set();
274
+ for (const [index, entry] of group.commands.entries()) {
275
+ const label = `group.commands[${index}]`;
276
+ const command = requireExactKeys(entry, ["id", "argv"], ["timeout_ms"], label, definitionPath);
277
+ requireId(command.id, `${label}.id`, definitionPath);
278
+ if (ids.has(command.id))
279
+ fail("invalid-definition", `group.commands contains duplicate ID ${command.id}`, definitionPath);
280
+ ids.add(command.id);
281
+ const argv = requireStringArray(command.argv, `${label}.argv`, definitionPath);
282
+ if (argv.length === 0) fail("invalid-definition", `${label}.argv must not be empty`, definitionPath);
283
+ if (
284
+ Object.hasOwn(command, "timeout_ms") &&
285
+ (!Number.isInteger(command.timeout_ms) || command.timeout_ms < 1 || command.timeout_ms > MAX_COMMAND_TIMEOUT_MS)
286
+ ) {
287
+ fail(
288
+ "invalid-definition",
289
+ `${label}.timeout_ms must be an integer from 1 to ${MAX_COMMAND_TIMEOUT_MS}`,
290
+ definitionPath,
291
+ );
292
+ }
293
+ }
294
+ }
295
+
256
296
  function validateModel(value, definitionPath) {
257
297
  const model = requireExactKeys(value, ["model"], ["thinking"], "group.model", definitionPath);
258
298
  requireString(model.model, "group.model.model", definitionPath);
@@ -274,7 +314,7 @@ function validateGroup(value, definitionPath) {
274
314
  "expectations",
275
315
  "review_questions",
276
316
  ],
277
- ["model", "runtime"],
317
+ ["model", "runtime", "commands"],
278
318
  "group",
279
319
  definitionPath,
280
320
  );
@@ -282,11 +322,12 @@ function validateGroup(value, definitionPath) {
282
322
  if (group.kind !== "group") fail("invalid-definition", "group.kind must be group", definitionPath);
283
323
  requireId(group.id, "group.id", definitionPath);
284
324
  if (!EVALUATION_TYPES.has(group.type)) {
285
- fail("invalid-definition", "group.type must be description, body, or end-to-end", definitionPath);
325
+ fail("invalid-definition", "group.type must be description or body", definitionPath);
286
326
  }
287
327
  validateInput(group.input, definitionPath);
288
328
  if (group.fixture !== null) requireSafeRelativePath(group.fixture, "group.fixture", definitionPath);
289
329
  requireStringArray(group.tools, "group.tools", definitionPath, { unique: true });
330
+ validateCommands(group, definitionPath);
290
331
  if (Object.hasOwn(group, "runtime")) validateRuntime(group.runtime, definitionPath);
291
332
  const variants = requireExactKeys(group.variants, VARIANTS, [], "group.variants", definitionPath);
292
333
  for (const variant of VARIANTS) validateEnvironment(variants[variant], `group.variants.${variant}`, definitionPath);
@@ -30,8 +30,9 @@ import {
30
30
  } from "./sandbox.mjs";
31
31
 
32
32
  const guardExtension = fileURLToPath(new URL("../pi-guard.mjs", import.meta.url));
33
+ const commandToolExtension = fileURLToPath(new URL("../pi-command-tool.mjs", import.meta.url));
33
34
  const observerExtension = fileURLToPath(new URL("../pi-observer.mjs", import.meta.url));
34
- const HOST_COMMANDS = { pi: "pi", piflow: "piflow" };
35
+ const HOST_COMMANDS = { pi: "pi" };
35
36
  const BASE_PROCESS_ENVIRONMENT_KEYS = [
36
37
  "PATH",
37
38
  "HOME",
@@ -43,8 +44,6 @@ const BASE_PROCESS_ENVIRONMENT_KEYS = [
43
44
  "XDG_CONFIG_HOME",
44
45
  "XDG_DATA_HOME",
45
46
  "XDG_CACHE_HOME",
46
- "PIFLOW_CODING_AGENT_DIR",
47
- "PIFLOW_CODING_AGENT_SESSION_DIR",
48
47
  "PI_PACKAGE_DIR",
49
48
  "PI_OFFLINE",
50
49
  ];
@@ -150,6 +149,7 @@ function subjectRun({ group, variant }, subject, observation) {
150
149
  completedAt: new Date().toISOString(),
151
150
  workspace: subject.workspace,
152
151
  tools: [...group.tools],
152
+ commands: group.commands ?? [],
153
153
  model: {
154
154
  declared: group.model ?? null,
155
155
  observed: observation.model,
@@ -329,9 +329,7 @@ function createProcessEnvironment({
329
329
  contextObservationPath,
330
330
  requiresContextObservation,
331
331
  }) {
332
- const processEnvironment = Object.fromEntries(
333
- BASE_PROCESS_ENVIRONMENT_KEYS.flatMap((key) => (process.env[key] === undefined ? [] : [[key, process.env[key]]])),
334
- );
332
+ const processEnvironment = baseProcessEnvironment();
335
333
  Object.assign(processEnvironment, {
336
334
  PWD: workspace,
337
335
  ...runtime.environment.literal,
@@ -342,7 +340,9 @@ function createProcessEnvironment({
342
340
  SKILL_EVAL_ALLOWED_TOOLS: JSON.stringify(group.tools),
343
341
  SKILL_EVAL_CONTEXT_MANIFEST: contextManifestPath ?? "",
344
342
  SKILL_EVAL_HOST: runtime.host,
343
+ SKILL_EVAL_PROMPT_MODE: runtime.prompt,
345
344
  });
345
+ if (group.commands !== undefined) processEnvironment.SKILL_EVAL_COMMANDS = JSON.stringify(group.commands);
346
346
  for (const key of runtime.environment.inherit) {
347
347
  if (process.env[key] === undefined) {
348
348
  throw new VariantSetupError(`inherited runtime environment variable is unavailable: ${key}`);
@@ -353,6 +353,12 @@ function createProcessEnvironment({
353
353
  return processEnvironment;
354
354
  }
355
355
 
356
+ export function baseProcessEnvironment() {
357
+ return Object.fromEntries(
358
+ BASE_PROCESS_ENVIRONMENT_KEYS.flatMap((key) => (process.env[key] === undefined ? [] : [[key, process.env[key]]])),
359
+ );
360
+ }
361
+
356
362
  async function readContextObservations(file, required) {
357
363
  const contents = await readFile(file, "utf8").catch((error) => {
358
364
  if (error?.code === "ENOENT") {
@@ -426,6 +432,7 @@ function piArguments(group, environment, runtime, mode, observeContext, sessionD
426
432
  if (runtime.session) args.push("--session-dir", sessionDirectory);
427
433
  else args.push("--no-session");
428
434
  args.push("--no-extensions", "--extension", guardExtension);
435
+ if (group.commands !== undefined) args.push("--extension", commandToolExtension);
429
436
  for (const bundle of runtime.extensions) args.push("--extension", bundle.entry);
430
437
  if (observeContext) args.push("--extension", observerExtension);
431
438
  args.push("--no-skills", "--no-prompt-templates", "--no-themes", "--no-context-files", "--no-approve");
@@ -438,7 +445,7 @@ function piArguments(group, environment, runtime, mode, observeContext, sessionD
438
445
  return args;
439
446
  }
440
447
 
441
- async function runPiProcess({ command, args, cwd, eventsFile, stderrFile, signal, environment }) {
448
+ export async function runPiProcess({ command, args, cwd, eventsFile, stderrFile, signal, environment }) {
442
449
  const child = spawn(command, args, {
443
450
  cwd,
444
451
  detached: process.platform !== "win32",