@hassangameryt/freeflow 0.5.0 → 0.6.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 (284) 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/README.md +148 -154
  5. package/capabilities/cognitive-routing/SKILL.md +229 -0
  6. package/capabilities/context-virtualization/SKILL.md +103 -0
  7. package/capabilities/conversation-history/SKILL.md +53 -0
  8. package/command-surface.json +6 -13
  9. package/hooks/freeflow-runtime-context.mjs +35 -91
  10. package/hooks/tests/check-runtime-context-hook.sh +56 -39
  11. package/package.json +24 -16
  12. package/pi-extension/dist/cognitive-routing/commands.js +96 -0
  13. package/pi-extension/dist/cognitive-routing/config.js +236 -0
  14. package/pi-extension/dist/cognitive-routing/controller.js +862 -0
  15. package/pi-extension/dist/cognitive-routing/history.js +439 -0
  16. package/pi-extension/dist/cognitive-routing/host.js +126 -0
  17. package/pi-extension/dist/cognitive-routing/runtime.js +43 -0
  18. package/pi-extension/dist/cognitive-routing/tool.js +211 -0
  19. package/pi-extension/dist/cognitive-routing/types.js +6 -0
  20. package/pi-extension/dist/context-virtualization/commands.js +89 -0
  21. package/pi-extension/dist/context-virtualization/projector.js +42 -0
  22. package/pi-extension/dist/context-virtualization/runtime.js +356 -0
  23. package/pi-extension/dist/context-virtualization/state.js +57 -0
  24. package/pi-extension/dist/context-virtualization/types.js +10 -0
  25. package/pi-extension/dist/conversation-history/passages.js +66 -0
  26. package/pi-extension/dist/conversation-history/ranking.js +105 -0
  27. package/pi-extension/dist/conversation-history/runtime.js +226 -0
  28. package/pi-extension/dist/conversation-history/search.js +56 -0
  29. package/pi-extension/dist/conversation-history/types.js +1 -0
  30. package/pi-extension/dist/freeflow-context/resolver.js +120 -0
  31. package/pi-extension/dist/freeflow-context/runtime.js +80 -0
  32. package/pi-extension/dist/freeflow-context/source-projector.js +95 -0
  33. package/pi-extension/dist/freeflow-context/tool.js +308 -0
  34. package/pi-extension/dist/freeflow-context/types.js +12 -0
  35. package/pi-extension/dist/freeflow-context/visibility.js +28 -0
  36. package/pi-extension/dist/index.js +516 -98
  37. package/pi-extension/dist/runtime/runtime-context.js +318 -271
  38. package/pi-extension/dist/runtime/runtime-identity.js +5 -0
  39. package/pi-extension/dist/settings/settings-tui.js +78 -0
  40. package/pi-extension/dist/settings/settings-ui.js +593 -563
  41. package/pi-extension/dist/ui/text-component.js +57 -0
  42. package/pi-extension/src/cognitive-routing/commands.ts +119 -0
  43. package/pi-extension/src/cognitive-routing/config.ts +307 -0
  44. package/pi-extension/src/cognitive-routing/controller.ts +1118 -0
  45. package/pi-extension/src/cognitive-routing/history.ts +638 -0
  46. package/pi-extension/src/cognitive-routing/host.ts +172 -0
  47. package/pi-extension/src/cognitive-routing/runtime.ts +57 -0
  48. package/pi-extension/src/cognitive-routing/tool.ts +272 -0
  49. package/pi-extension/src/cognitive-routing/types.ts +89 -0
  50. package/pi-extension/src/context-virtualization/commands.ts +111 -0
  51. package/pi-extension/src/context-virtualization/projector.ts +62 -0
  52. package/pi-extension/src/context-virtualization/runtime.ts +406 -0
  53. package/pi-extension/src/context-virtualization/state.ts +79 -0
  54. package/pi-extension/src/context-virtualization/types.ts +92 -0
  55. package/pi-extension/src/conversation-history/passages.ts +81 -0
  56. package/pi-extension/src/conversation-history/ranking.ts +155 -0
  57. package/pi-extension/src/conversation-history/runtime.ts +250 -0
  58. package/pi-extension/src/conversation-history/search.ts +79 -0
  59. package/pi-extension/src/conversation-history/types.ts +31 -0
  60. package/pi-extension/src/freeflow-context/resolver.ts +139 -0
  61. package/pi-extension/src/freeflow-context/runtime.ts +100 -0
  62. package/pi-extension/src/freeflow-context/source-projector.ts +106 -0
  63. package/pi-extension/src/freeflow-context/tool.ts +360 -0
  64. package/pi-extension/src/freeflow-context/types.ts +70 -0
  65. package/pi-extension/src/freeflow-context/visibility.ts +53 -0
  66. package/pi-extension/src/index.ts +553 -101
  67. package/pi-extension/src/runtime/runtime-context.ts +339 -281
  68. package/pi-extension/src/runtime/runtime-identity.ts +8 -0
  69. package/pi-extension/src/settings/settings-tui.ts +93 -0
  70. package/pi-extension/src/settings/settings-ui.ts +700 -613
  71. package/pi-extension/src/ui/text-component.ts +66 -0
  72. package/pi-extension/tests/cognitive-routing/commands.test.js +134 -0
  73. package/pi-extension/tests/cognitive-routing/controller.test.js +1099 -0
  74. package/pi-extension/tests/cognitive-routing/extension-lifecycle.test.js +1071 -0
  75. package/pi-extension/tests/cognitive-routing/history.test.js +274 -0
  76. package/pi-extension/tests/cognitive-routing/host-fixture.js +4 -0
  77. package/pi-extension/tests/cognitive-routing/host-identity.test.js +63 -0
  78. package/pi-extension/tests/cognitive-routing/profile-resolution.test.js +236 -0
  79. package/pi-extension/tests/cognitive-routing/tool.test.js +230 -0
  80. package/pi-extension/tests/context-virtualization/extension.test.js +749 -0
  81. package/pi-extension/tests/context-virtualization/projector.test.js +110 -0
  82. package/pi-extension/tests/context-virtualization/runtime.test.js +216 -0
  83. package/pi-extension/tests/conversation-history/runtime.test.js +98 -0
  84. package/pi-extension/tests/conversation-history/search.test.js +97 -0
  85. package/pi-extension/tests/integration/pi-extension.test.js +927 -2048
  86. package/pi-extension/tests/integration/prompt-architecture.test.js +305 -0
  87. package/runtime/prompts/cognitive-routing.md +9 -0
  88. package/runtime/prompts/context-virtualization.md +3 -0
  89. package/runtime/prompts/conversation-history.md +3 -0
  90. package/runtime/prompts/core.md +13 -0
  91. package/runtime/prompts/interaction-contract.md +7 -0
  92. package/runtime/prompts/skills.md +65 -0
  93. package/skills/action-selection/SKILL.md +91 -0
  94. package/skills/bypass/SKILL.md +3 -2
  95. package/skills/commit-work/SKILL.md +1 -1
  96. package/skills/commit-work/references/staging-decisions.md +1 -1
  97. package/skills/decision-gate/SKILL.md +1 -1
  98. package/skills/design-for-depth/SKILL.md +14 -33
  99. package/skills/design-for-depth/references/design-pressure-signals.md +1 -1
  100. package/skills/design-for-depth/references/interface-design-loop.md +1 -1
  101. package/skills/design-for-depth/references/software-design-philosophy.md +1 -1
  102. package/skills/diagnose-failure/SKILL.md +20 -14
  103. package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +1 -3
  104. package/skills/diagnose-failure/references/{flaky-and-performance.md → flaky-and-performance-diagnosis.md} +1 -1
  105. package/skills/discuss/SKILL.md +34 -22
  106. package/skills/discuss/references/discussion-continuity.md +71 -0
  107. package/skills/evaluate-skill/SKILL.md +5 -5
  108. package/skills/evaluate-skill/references/{definition-schema.md → evaluation-definition-schema.md} +42 -2
  109. package/skills/evaluate-skill/references/execution-and-evidence.md +8 -3
  110. package/skills/evaluate-skill/scripts/lib/definitions.mjs +114 -3
  111. package/skills/evaluate-skill/scripts/lib/grade-interaction.mjs +156 -1
  112. package/skills/evaluate-skill/scripts/lib/grade.mjs +9 -1
  113. package/skills/evaluate-skill/scripts/lib/pi.mjs +147 -32
  114. package/skills/evaluate-skill/scripts/lib/rpc.mjs +4 -4
  115. package/skills/evaluate-skill/scripts/lib/runner.mjs +36 -14
  116. package/skills/evaluate-skill/scripts/lib/sandbox.mjs +92 -0
  117. package/skills/evaluate-skill/scripts/pi-guard.mjs +1 -1
  118. package/skills/evaluate-skill/scripts/pi-observer.mjs +66 -0
  119. package/skills/evaluate-skill/scripts/skill-eval.mjs +6 -5
  120. package/skills/execute-work/SKILL.md +18 -15
  121. package/skills/execute-work/references/code-practices.md +1 -1
  122. package/skills/execute-work/references/execute-work-edges.md +42 -0
  123. package/skills/finish-branch/SKILL.md +2 -2
  124. package/skills/finish-branch/references/integration-options.md +1 -1
  125. package/skills/handoff/SKILL.md +3 -3
  126. package/skills/launch-work/SKILL.md +1 -1
  127. package/skills/launch-work/references/launch-readiness.md +2 -2
  128. package/skills/migration-work/SKILL.md +2 -2
  129. package/skills/migration-work/references/migration-lifecycle.md +1 -1
  130. package/skills/mode-contract/SKILL.md +4 -4
  131. package/skills/release-work/SKILL.md +1 -1
  132. package/skills/release-work/references/release-evidence.md +1 -1
  133. package/skills/review-artifact/SKILL.md +28 -26
  134. package/skills/review-work/SKILL.md +28 -26
  135. package/skills/review-work/references/{reviewer-prompt.md → independent-work-reviewer-contract.md} +1 -1
  136. package/skills/review-work/references/security-risk-lens.md +1 -1
  137. package/skills/setup-freeflow/SKILL.md +3 -1
  138. package/skills/setup-freeflow/references/activation-contract.md +2 -2
  139. package/skills/setup-freeflow/references/host-setup.md +2 -2
  140. package/skills/simplify-code/SKILL.md +1 -1
  141. package/skills/simplify-code/references/simplification-patterns.md +1 -1
  142. package/skills/tdd/SKILL.md +18 -38
  143. package/skills/tdd/references/test-design.md +2 -2
  144. package/skills/track-work/SKILL.md +362 -58
  145. package/skills/track-work/scripts/lib/codec.mjs +570 -0
  146. package/skills/track-work/scripts/lib/commands.mjs +568 -0
  147. package/skills/track-work/scripts/lib/contract.mjs +303 -0
  148. package/skills/track-work/scripts/lib/model.mjs +506 -0
  149. package/skills/track-work/scripts/lib/operations.mjs +965 -0
  150. package/skills/track-work/scripts/lib/record-store.mjs +264 -0
  151. package/skills/track-work/scripts/lib/result.mjs +37 -0
  152. package/skills/track-work/scripts/lib/rewrites.mjs +740 -0
  153. package/skills/track-work/scripts/lib/schema.mjs +277 -0
  154. package/skills/track-work/scripts/lib/source-inventory.mjs +162 -0
  155. package/skills/track-work/scripts/lib/views.mjs +443 -0
  156. package/skills/track-work/scripts/lib/workspace.mjs +134 -0
  157. package/skills/track-work/scripts/working-record.mjs +122 -0
  158. package/skills/verify-work/SKILL.md +14 -2
  159. package/skills/verify-work/references/browser-runtime-evidence.md +1 -1
  160. package/skills/verify-work/references/integration-evidence.md +1 -1
  161. package/skills/verify-work/references/performance-evidence.md +1 -1
  162. package/skills/workflow/SKILL.md +105 -53
  163. package/skills/workflow/references/domain-skill-composition.md +22 -42
  164. package/skills/write-plan/SKILL.md +1 -1
  165. package/skills/write-skill/SKILL.md +3 -2
  166. package/skills/write-skill/references/progressive-disclosure.md +17 -3
  167. package/capabilities/output-router/SKILL.md +0 -206
  168. package/capabilities/output-router/references/safety-policy.md +0 -40
  169. package/capabilities/output-router/references/setup.md +0 -110
  170. package/pi-extension/dist/output-router/host-producer-identification.js +0 -232
  171. package/pi-extension/dist/output-router/native-safety-net.js +0 -216
  172. package/pi-extension/dist/output-router/observed-tool-routing.js +0 -122
  173. package/pi-extension/dist/output-router/renderers.js +0 -1023
  174. package/pi-extension/dist/output-router/router-tools.js +0 -554
  175. package/pi-extension/dist/output-router/schemas.js +0 -383
  176. package/pi-extension/dist/output-router/status.js +0 -744
  177. package/pi-extension/dist/output-router/utils.js +0 -502
  178. package/pi-extension/src/output-router/host-producer-identification.ts +0 -256
  179. package/pi-extension/src/output-router/native-safety-net.ts +0 -248
  180. package/pi-extension/src/output-router/observed-tool-routing.ts +0 -134
  181. package/pi-extension/src/output-router/renderers.ts +0 -1108
  182. package/pi-extension/src/output-router/router-tools.ts +0 -579
  183. package/pi-extension/src/output-router/schemas.ts +0 -387
  184. package/pi-extension/src/output-router/status.ts +0 -791
  185. package/pi-extension/src/output-router/utils.ts +0 -554
  186. package/pi-extension/tests/output-router/observed-producers.test.js +0 -132
  187. package/pi-extension/tests/output-router/search.test.js +0 -722
  188. package/router/dist/benchmarks/benchmark-harness.d.ts +0 -35
  189. package/router/dist/benchmarks/benchmark-harness.js +0 -92
  190. package/router/dist/benchmarks/benchmarks.d.ts +0 -109
  191. package/router/dist/benchmarks/benchmarks.js +0 -979
  192. package/router/dist/benchmarks/codex-qa-benchmarks.d.ts +0 -95
  193. package/router/dist/benchmarks/codex-qa-benchmarks.js +0 -500
  194. package/router/dist/benchmarks/command-benchmarks.d.ts +0 -143
  195. package/router/dist/benchmarks/command-benchmarks.js +0 -698
  196. package/router/dist/benchmarks/context-mode-normalized-benchmarks.d.ts +0 -82
  197. package/router/dist/benchmarks/context-mode-normalized-benchmarks.js +0 -773
  198. package/router/dist/benchmarks/context-mode-real-deep-benchmark.d.ts +0 -132
  199. package/router/dist/benchmarks/context-mode-real-deep-benchmark.js +0 -1380
  200. package/router/dist/benchmarks/context-saving-baseline.d.ts +0 -60
  201. package/router/dist/benchmarks/context-saving-baseline.js +0 -470
  202. package/router/dist/benchmarks/index-benchmarks.d.ts +0 -103
  203. package/router/dist/benchmarks/index-benchmarks.js +0 -862
  204. package/router/dist/benchmarks/storage-policy-benchmarks.d.ts +0 -101
  205. package/router/dist/benchmarks/storage-policy-benchmarks.js +0 -618
  206. package/router/dist/benchmarks/vault-index-benchmarks.d.ts +0 -56
  207. package/router/dist/benchmarks/vault-index-benchmarks.js +0 -322
  208. package/router/dist/config/config.d.ts +0 -103
  209. package/router/dist/config/config.js +0 -632
  210. package/router/dist/config/router-contract.d.ts +0 -10
  211. package/router/dist/config/router-contract.js +0 -54
  212. package/router/dist/config/schema.d.ts +0 -27
  213. package/router/dist/config/schema.js +0 -648
  214. package/router/dist/config/types.d.ts +0 -573
  215. package/router/dist/config/types.js +0 -41
  216. package/router/dist/evidence/bounded-evidence.d.ts +0 -40
  217. package/router/dist/evidence/bounded-evidence.js +0 -323
  218. package/router/dist/evidence/evidence-range-selector.d.ts +0 -24
  219. package/router/dist/evidence/evidence-range-selector.js +0 -232
  220. package/router/dist/evidence/evidence-search.d.ts +0 -27
  221. package/router/dist/evidence/evidence-search.js +0 -490
  222. package/router/dist/evidence/evidence.d.ts +0 -38
  223. package/router/dist/evidence/evidence.js +0 -200
  224. package/router/dist/evidence/failure-contracts.d.ts +0 -37
  225. package/router/dist/evidence/failure-contracts.js +0 -166
  226. package/router/dist/evidence/line-ranges.d.ts +0 -24
  227. package/router/dist/evidence/line-ranges.js +0 -22
  228. package/router/dist/experiments/local-index.d.ts +0 -64
  229. package/router/dist/experiments/local-index.js +0 -581
  230. package/router/dist/index.d.ts +0 -30
  231. package/router/dist/index.js +0 -32
  232. package/router/dist/local/local-traversal.d.ts +0 -18
  233. package/router/dist/local/local-traversal.js +0 -334
  234. package/router/dist/processing/engine.d.ts +0 -132
  235. package/router/dist/processing/engine.js +0 -533
  236. package/router/dist/processing/reducers.d.ts +0 -280
  237. package/router/dist/processing/reducers.js +0 -1673
  238. package/router/dist/processing/renderers.d.ts +0 -31
  239. package/router/dist/processing/renderers.js +0 -195
  240. package/router/dist/processing/scripts.d.ts +0 -91
  241. package/router/dist/processing/scripts.js +0 -386
  242. package/router/dist/repo/repo-traversal.d.ts +0 -18
  243. package/router/dist/repo/repo-traversal.js +0 -245
  244. package/router/dist/routing/observed-reducers.d.ts +0 -41
  245. package/router/dist/routing/observed-reducers.js +0 -661
  246. package/router/dist/routing/observed-routing.d.ts +0 -26
  247. package/router/dist/routing/observed-routing.js +0 -378
  248. package/router/dist/routing/parsers.d.ts +0 -16
  249. package/router/dist/routing/parsers.js +0 -521
  250. package/router/dist/routing/run-filters.d.ts +0 -60
  251. package/router/dist/routing/run-filters.js +0 -238
  252. package/router/dist/routing/run-reducers.d.ts +0 -49
  253. package/router/dist/routing/run-reducers.js +0 -122
  254. package/router/dist/sandbox/adapter-roots.d.ts +0 -46
  255. package/router/dist/sandbox/adapter-roots.js +0 -66
  256. package/router/dist/sandbox/eryx-python-adapter.d.ts +0 -13
  257. package/router/dist/sandbox/eryx-python-adapter.js +0 -868
  258. package/router/dist/sandbox/jq-wasm-adapter.d.ts +0 -9
  259. package/router/dist/sandbox/jq-wasm-adapter.js +0 -429
  260. package/router/dist/sandbox/quickjs-wasi-adapter.d.ts +0 -13
  261. package/router/dist/sandbox/quickjs-wasi-adapter.js +0 -384
  262. package/router/dist/sandbox/script-sandbox.d.ts +0 -134
  263. package/router/dist/sandbox/script-sandbox.js +0 -337
  264. package/router/dist/setup/script-transform-adapters.d.ts +0 -32
  265. package/router/dist/setup/script-transform-adapters.js +0 -278
  266. package/router/dist/tools/batch.d.ts +0 -33
  267. package/router/dist/tools/batch.js +0 -586
  268. package/router/dist/tools/run.d.ts +0 -62
  269. package/router/dist/tools/run.js +0 -1304
  270. package/router/dist/tools/search.d.ts +0 -66
  271. package/router/dist/tools/search.js +0 -1364
  272. package/router/dist/transform/engine.d.ts +0 -168
  273. package/router/dist/transform/engine.js +0 -2072
  274. package/router/dist/vault/vault-index.d.ts +0 -125
  275. package/router/dist/vault/vault-index.js +0 -416
  276. package/router/dist/vault/vault.d.ts +0 -138
  277. package/router/dist/vault/vault.js +0 -630
  278. package/runtime/interaction-contract.md +0 -16
  279. package/skills/discuss/references/checkpoints.md +0 -66
  280. package/skills/execute-work/references/execution-loop.md +0 -77
  281. package/skills/track-work/references/working-record-schema.md +0 -378
  282. package/skills/workflow/references/workflow-loop.md +0 -92
  283. /package/skills/handoff/references/{templates.md → handoff-templates.md} +0 -0
  284. /package/skills/review-artifact/references/{reviewer-prompt.md → independent-artifact-reviewer-contract.md} +0 -0
@@ -1,6 +1,6 @@
1
1
  # Design Pressure Signals
2
2
 
3
- Use this reference when reviewing code, artifacts, or work for shallow modules and complexity spread.
3
+ Read this when evidence suggests caller knowledge or coordination is spreading and the next route must be classified.
4
4
 
5
5
  The goal is not to find every smell. The goal is to notice pressure that changes the next route.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Interface Design Loop
2
2
 
3
- Use this when structural pressure makes the current interface suspect. The goal is to choose an outcome-level module shape, not add detail to the first plausible design.
3
+ Read this before comparing materially different interfaces when structural pressure or an important pre-implementation correctness boundary makes their ownership consequential, especially when evidence cannot choose or authority, canonical state, atomic visibility, replay, cancellation, or post-commit recovery affects correctness. The goal is to choose an outcome-level module shape, not add detail to the first plausible design.
4
4
 
5
5
  ## 1. Frame The Outcome
6
6
 
@@ -1,6 +1,6 @@
1
1
  # Software Design Philosophy
2
2
 
3
- Use this reference when `design-for-depth` needs deeper reasoning than the active skill can carry.
3
+ Read this when structural pressure is supported but the likely-changing decision or missing information-hiding boundary cannot yet be named.
4
4
 
5
5
  This is not a checklist to run every time. Pull the idea that changes the next route.
6
6
 
@@ -11,17 +11,23 @@ A **diagnostic loop** is a repeatable check or observation that can reproduce, s
11
11
 
12
12
  A requested patch, plausible code path, reviewer theory, or one favorable rerun is not a supported cause.
13
13
 
14
+ Diagnosis inherits the current authority envelope. Selecting this method authorizes neither active evidence generation nor correction.
15
+
16
+ When diagnosis applies, before choosing its loop, read [the Diagnostic Loop Catalog](references/diagnostic-loop-catalog.md). When timing, randomness, environment variance, or resource behavior shapes the failure, also read [Flaky and Performance Diagnosis](references/flaky-and-performance-diagnosis.md) before choosing or running the observation.
17
+
14
18
  ## Follow The Diagnostic Route
15
19
 
16
20
  ```text
17
21
  [Failure without a supported cause]
18
- -> [Establish expected and observed behavior]
19
- -> [Choose the smallest diagnostic loop]
20
- -> [Reproduce or capture the failure]
22
+ -> [Inspect existing evidence; establish expected and observed behavior]
21
23
  -> [State a falsifiable hypothesis]
22
- -> [Run one distinguishing observation]
24
+ -> [Choose the smallest distinguishing observation]
25
+ -> [Authority envelope covers its effects?]
26
+ -> no -> [Propose purpose, expected evidence, and stop condition]
27
+ -> [Ask once and wait]
28
+ -> yes -> [Run the observation]
23
29
  -> [Route from evidence]
24
- -> hypothesis contradicted -> refine or replace it -> observe again
30
+ -> hypothesis contradicted -> refine or replace it -> choose again
25
31
  -> evidence unavailable -> stop with the smallest missing evidence
26
32
  -> cause supported -> return cause and correction boundary to Workflow
27
33
  -> user-owned behavior or source conflict -> Decision Gate
@@ -29,7 +35,7 @@ A requested patch, plausible code path, reviewer theory, or one favorable rerun
29
35
  -> active harm before cause -> propose bounded containment
30
36
  ```
31
37
 
32
- Diagnosis may recur inside one Track Work slice. A new hypothesis, observation, or owning-skill route does not create a new slice by itself.
38
+ Diagnosis may recur inside one Slice. A new hypothesis, observation, or owning-skill route does not create a new Slice by itself. When durable task memory exists, [Track Work](../track-work/SKILL.md) preserves diagnosis inside the same Current Slice.
33
39
 
34
40
  ## Enter Diagnosis Deliberately
35
41
 
@@ -41,18 +47,18 @@ If fresh direct evidence already establishes one clear local defect and intended
41
47
 
42
48
  ## Establish The Failure And Loop
43
49
 
44
- Before changing behavior:
50
+ Start by inspecting the report, existing code, tests, logs, configuration, and artifacts. Before generating new evidence:
45
51
 
46
- 1. establish expected behavior from accepted intent and source truth;
47
- 2. reproduce or capture the reported failure at its required boundary;
48
- 3. state a falsifiable hypothesis;
49
- 4. change or observe one distinguishing variable at a time;
52
+ 1. establish expected and observed behavior from accepted intent, source truth, and existing evidence;
53
+ 2. state a falsifiable hypothesis and the alternatives the next observation must distinguish;
54
+ 3. choose the smallest diagnostic loop that can disagree with the hypothesis at the required boundary;
55
+ 4. run one covered observation and change one distinguishing variable at a time;
50
56
  5. trace the causal chain from trigger and state to the observed result;
51
57
  6. preserve evidence that contradicts the leading hypothesis.
52
58
 
53
- Prefer the reported path, input, environment, and observer. A nearby failure may suggest a hypothesis but does not prove the reported failure. Reduced-fidelity reproduction is diagnostic evidence only; name what it cannot establish.
59
+ Diagnosis owns the hypothesis and distinguishing question. When several observers or tools can test that same question, or the likely diagnostic loop is broad, use [Action Selection](../action-selection/SKILL.md) to choose and bound one environment interaction. It returns the observation without redefining the hypothesis or cause. Skip it when the diagnostic loop and observer are already exact.
54
60
 
55
- Read [the diagnostic-loop catalog](references/diagnostic-loop-catalog.md) when the best loop is unclear. Read [flaky and performance diagnosis](references/flaky-and-performance.md) when timing, randomness, environment variance, or resources shape the failure.
61
+ Prefer the reported path, input, environment, and observer. A nearby failure may suggest a hypothesis but does not prove the reported failure. Reduced-fidelity reproduction is diagnostic evidence only; name what it cannot establish.
56
62
 
57
63
  Allowed behavior is not a reproduction. A cache hit does not prove a stale-read bug when caching is permitted. A possible race in source does not explain a report until timing, traces, steps, logs, or an existing expectation connect it.
58
64
 
@@ -96,7 +102,7 @@ A requested patch may instead be an authorized learning action. Its result can s
96
102
 
97
103
  ## Return The Supported Result
98
104
 
99
- When evidence supports a cause, return the failure boundary, diagnostic loop, causal explanation, regression signal, and smallest coherent correction to Workflow. Return an authorized implementation correction to [Execute Work](../execute-work/SKILL.md); use [TDD](../tdd/SKILL.md) when the diagnostic loop provides a failing behavior check that should guide it. Use [Simplify Code](../simplify-code/SKILL.md) when the supported cause shows that obsolete, duplicated, or workaround machinery can be removed while preserving accepted behavior. Mess left by unsuccessful attempts is not enough: settle any behavior or contract change through Workflow first, and do not use cleanup in place of correcting the supported failure or while its evidence remains unresolved. The correction may remain in the current Track Work slice while that slice still has one coherent result.
105
+ When evidence supports a cause, return the failure boundary, diagnostic loop, causal explanation, regression signal, and smallest coherent correction to Workflow. The evidence supports the conclusion and route; it does not by itself authorize the correction. Return an authorized implementation correction to [Execute Work](../execute-work/SKILL.md); use [TDD](../tdd/SKILL.md) when the diagnostic loop provides a failing behavior check that should guide it. Use [Simplify Code](../simplify-code/SKILL.md) when the supported cause shows that obsolete, duplicated, or workaround machinery can be removed while preserving accepted behavior. Mess left by unsuccessful attempts is not enough: settle any behavior or contract change through Workflow first, and do not use cleanup in place of correcting the supported failure or while its evidence remains unresolved. The correction may remain in the same Slice while its result stays coherent; Track Work preserves that continuity when a Working Record exists.
100
106
 
101
107
  After correction, use [Verify Work](../verify-work/SKILL.md) to rerun both the minimized regression signal and the original reported path or strongest available observer. If correction fails or exposes related shared-state consequences, re-enter diagnosis before another patch.
102
108
 
@@ -1,6 +1,6 @@
1
1
  # Diagnostic Loop Catalog
2
2
 
3
- Read this when the smallest useful diagnostic loop for a reported failure or current hypothesis is unclear.
3
+ Read this before choosing a diagnostic loop for a reported failure or current hypothesis. Use it to select the smallest observation that can distinguish meaningful alternatives at the required boundary.
4
4
 
5
5
  ## Common Loops
6
6
 
@@ -32,5 +32,3 @@ An observer must sit on the real path and cover the complete operation. A manual
32
32
  - A registered callback allegedly never runs → invoke or observe the registered entrypoint; calling its helper directly proves only helper behavior.
33
33
  - A failure appears only in CI → compare the same input across local and CI configuration before changing timing or adding retries.
34
34
  - Two causes fit one symptom → choose an observation whose outcomes differ between them; another generic failure is not distinguishing evidence.
35
-
36
- If no safe useful loop is possible, identify the smallest missing artifact or access: command, logs, trace, failing input, timestamped screenshot, environment boundary, or permission for isolated temporary instrumentation. Leave the cause unresolved rather than substituting a weaker claim.
@@ -1,6 +1,6 @@
1
1
  # Flaky And Performance Diagnosis
2
2
 
3
- Read this when timing, randomness, environment variance, or resource behavior makes the failure difficult to reproduce or explain.
3
+ Read this before choosing or running a diagnostic observation when timing, randomness, environment variance, or resource behavior shapes the failure.
4
4
 
5
5
  ## Flaky Failures
6
6
 
@@ -7,7 +7,7 @@ description: Use when discussing, exploring, shaping, challenging, or revisiting
7
7
 
8
8
  Build enough shared understanding to choose the next sound action.
9
9
 
10
- Discussion may shape understanding, recommendations, proposed work, and checkpoints. It does not authorize mutation, settle a user-owned choice implicitly, or turn exploratory output into production behavior.
10
+ Discussion may shape understanding, recommendations, proposed work, and checkpoints. It inherits the current authority envelope: selecting Discuss does not authorize active evidence generation, mutation or delivery, settle a user-owned choice implicitly, or turn exploratory output into production behavior.
11
11
 
12
12
  ## Follow The Discussion Route
13
13
 
@@ -20,13 +20,16 @@ Use this as a directed map, not a checklist:
20
20
  -> [Inspect facts / ask / compare meaningful paths]
21
21
  -> [Route from what is now supported]
22
22
  -> enough understanding
23
- -> task-shaped and continuity may matter
24
- -> Track Work decides whether to recommend a Working Record
25
- -> otherwise -> return direction to Workflow
23
+ -> decide continuity
24
+ -> no record -> return direction to Workflow
25
+ -> record needed and mutation covered -> Track Work -> Discuss -> Workflow
26
+ -> record needed but mutation uncovered -> propose exact mutation -> wait
26
27
  -> one user-owned choice or source conflict -> Decision Gate
27
28
  -> evidence needed -> propose a bounded learning action
28
- -> when authorized -> Track Work
29
- -> Execute Work or wait from its result
29
+ -> apply the continuity decision before returning the proposal
30
+ -> Workflow confirms authority and routes
31
+ -> Track Work when needed -> Workflow -> Execute Work or wait
32
+ -> no record needed -> Execute Work or wait
30
33
  -> re-enter Discuss with evidence
31
34
  -> unexplained or repeated failure -> Diagnose Failure
32
35
  -> stable accepted content or strategy -> Write Spec / Write Plan
@@ -56,7 +59,7 @@ Identify only what the next decision needs:
56
59
  - tentative assumptions or viable alternatives;
57
60
  - evidence and uncertainty that could change the route.
58
61
 
59
- When a Working Record exists, orient from its current context and check important claims against live evidence. Read older history only when the present direction or rationale is unclear. Update only what new evidence affects.
62
+ When a Working Record exists, orient from its current context and check important claims against live evidence. Read older history only when the present direction or rationale is unclear. Update only what new evidence affects. When a material record update is needed, use Track Work's replacement summaries and one-owner storage rather than appending discussion prose. Apply the update only when the authority envelope covers its mutation. If the mutation is uncovered, return it to Workflow and wait. After any covered update, return to Discuss—a record update does not start execution or change the owning route.
60
63
 
61
64
  ## Focus The Discussion
62
65
 
@@ -64,6 +67,8 @@ Stay with the highest unresolved question that could change the outcome, boundar
64
67
 
65
68
  Inspect code, tests, docs, policies, artifacts, repository state, supplied material, or current primary sources when they can answer factual questions. Ask the user about intent, priorities, constraints, and tradeoffs that evidence cannot decide.
66
69
 
70
+ When several inspections, searches, or other observers could answer the same factual question, or the likely probe is broad, use [Action Selection](../action-selection/SKILL.md) to choose and bound one environment interaction. Discuss keeps ownership of the question and interpretation; Action Selection returns the observation. Skip it for an obvious focused read.
71
+
67
72
  When materially different paths remain viable:
68
73
 
69
74
  1. compare only the few that matter, including the current path or waiting when real;
@@ -75,6 +80,27 @@ Ask in natural prose, usually about one main topic at a time. Use a menu only fo
75
80
 
76
81
  When architecture, interfaces, ownership, state, failure contracts, or spreading complexity shape the direction, use [Design for Depth](../design-for-depth/SKILL.md) as a lens and retain it while the boundary remains design-bearing.
77
82
 
83
+ ## Preserve Only Useful State
84
+
85
+ Keep discussion legible as:
86
+
87
+ - **Settled:** supported fact or explicit decision.
88
+ - **Tentative:** current hypothesis or provisional direction.
89
+ - **Open:** unresolved and capable of changing the next action.
90
+
91
+ Before routing to Track Work, ask: **Would losing current task state risk later misalignment?** Use a Working Record when:
92
+
93
+ - the task must survive compaction, pause, session navigation, or ownership transfer;
94
+ - decisions, evidence, blockers, authority, or the next action need durable recovery;
95
+ - one outcome is likely to span several implementation, verification, review, or correction iterations;
96
+ - proposed outcomes must remain ordered and visible without becoming authorized work.
97
+
98
+ Keep state in conversation when context is sufficient and the discussion or next action is short and disposable. Use [Write Spec](../write-spec/SKILL.md) for stable accepted content and [Write Plan](../write-plan/SKILL.md) for a stable ordered strategy. Do not create an artifact merely because discussion occurred.
99
+
100
+ Recommend independent review, local commit, user decision, or continuity checkpoints only when they protect dependent work or reduce material risk. Discussion may shape and preserve an approved checkpoint, but does not execute it. Normal verification and silent self-review provide the ordinary self-check; Workflow establishes the slice outcome.
101
+
102
+ Read [Discussion Continuity](references/discussion-continuity.md) when preserving a compact discussion state or re-entry summary, or when carrying a selected checkpoint from discussion.
103
+
78
104
  ## Learn Through Bounded Action
79
105
 
80
106
  When discussion alone cannot answer a material question, propose the smallest useful learning or delivery action:
@@ -88,24 +114,10 @@ Useful checkpoint, if any:
88
114
  Stop, discard, revise, or promote when:
89
115
  ```
90
116
 
91
- A proposal is not authorization. Before execution, confirm that the action is requested or approved. When the action is authorized, use [Track Work](../track-work/SKILL.md) to decide whether durable task memory is needed, then follow its result to [Execute Work](../execute-work/SKILL.md) or wait.
117
+ Classifying an action as Learning, Delivery, or Deepening does not authorize it. Before returning an uncovered proposal to Workflow, apply the continuity decision above and include any required [Track Work](../track-work/SKILL.md) mutation. Once Workflow confirms that the authority envelope covers the action and any record mutation, use Track Work when needed, return to Workflow, then route to [Execute Work](../execute-work/SKILL.md) or wait.
92
118
 
93
119
  Return with the observed result. Treat prototypes, tests, benchmarks, sketches, and working behavior as evidence, not automatic approval of their design or promotion. Preserve what still holds and re-enter only the affected question.
94
120
 
95
- ## Preserve Only Useful State
96
-
97
- Keep discussion legible as:
98
-
99
- - **Settled:** supported fact or explicit decision.
100
- - **Tentative:** current hypothesis or provisional direction.
101
- - **Open:** unresolved and capable of changing the next action.
102
-
103
- Keep this state in conversation while context is sufficient. Use Track Work when evolving context must survive compaction, pause, or another session. Use [Write Spec](../write-spec/SKILL.md) for stable accepted content and [Write Plan](../write-plan/SKILL.md) for a stable ordered strategy. Do not create an artifact merely because discussion occurred.
104
-
105
- Recommend independent review, local commit, user decision, or continuity checkpoints only when they protect dependent work or reduce material risk. Discussion may shape and preserve an approved checkpoint, but does not execute it. Normal verification and silent self-review provide the ordinary self-check; Workflow establishes the slice outcome.
106
-
107
- Read [discussion checkpoints](references/checkpoints.md) when selecting or preserving a compact discussion checkpoint or re-entry state.
108
-
109
121
  ## Return Supported Direction
110
122
 
111
123
  Converge when the next sound action no longer depends on unresolved direction, not when every future question is answered.
@@ -0,0 +1,71 @@
1
+ # Discussion Continuity
2
+
3
+ Read this when preserving a compact discussion state or re-entry summary, or when carrying a selected checkpoint from discussion.
4
+
5
+ A **discussion state summary** records enough shared understanding to continue or choose the next action. It is not a Checkpoint unless Workflow deliberately selects a boundary that dependent work must not cross unresolved.
6
+
7
+ ## Keep It In Chat When Possible
8
+
9
+ Keep the summary in conversation when the current context can safely continue. Use only fields that help:
10
+
11
+ ```text
12
+ Goal or question:
13
+ Current understanding:
14
+ Settled:
15
+ Tentative:
16
+ Open:
17
+ Evidence or alternatives that matter:
18
+ Selected checkpoints, if any:
19
+ Recommended or accepted next action:
20
+ Authority source or approval needed:
21
+ ```
22
+
23
+ Do not turn a summary into a transcript, questionnaire, frozen architecture, automatic Spec, Plan, Working Record, or checkpoint.
24
+
25
+ ## Preserve Selected Checkpoints Separately
26
+
27
+ When discussion proposes a possible checkpoint, record it as proposed rather than selected. Workflow selects it only when its additional boundary materially protects dependent work and its authority is covered.
28
+
29
+ For a selected checkpoint preserve only what later action needs:
30
+
31
+ ```text
32
+ Status: Selected
33
+ Type:
34
+ Purpose:
35
+ Due boundary:
36
+ Condition:
37
+ Selection source:
38
+ Authority scope:
39
+ ```
40
+
41
+ Do not infer authorization from a recommendation. Keep local commit authority separate from push or integration, and keep migration, deprecation, release, and launch separately controlled.
42
+
43
+ When durable task memory is needed, [Track Work](../../track-work/SKILL.md) owns the pending checkpoint and terminal result. The discussion summary remains conversational state rather than duplicate checkpoint history.
44
+
45
+ ## Preserve A Durable Artifact Only When Needed
46
+
47
+ Choose the artifact by the information that must survive:
48
+
49
+ - **Working Record:** evolving task state, selected checkpoints, Slices, Decisions, evidence, History, and next action. Read [Track Work](../../track-work/SKILL.md).
50
+ - **Spec:** stable accepted content needs a durable source. Read [Write Spec](../../write-spec/SKILL.md).
51
+ - **Plan:** a stable ordered strategy and its selected checkpoints need an execution artifact. Read [Write Plan](../../write-plan/SKILL.md).
52
+ - **ADR:** a surprising, hard-to-reverse repository decision needs durable rationale.
53
+ - **Handoff:** one point-in-time continuation package must transfer to another context or owner.
54
+ - **Domain documentation:** stable terminology or domain meaning belongs in an existing glossary or domain source.
55
+
56
+ Do not create an artifact merely because discussion occurred. Prefer an existing repository convention; ask before inventing a destination whose authority, durability, or ownership matters.
57
+
58
+ ## Preserve Re-Entry State
59
+
60
+ When new evidence reopens discussion, preserve only the affected change:
61
+
62
+ ```text
63
+ New evidence:
64
+ Invalidated assumption:
65
+ Still valid:
66
+ Decision, Slice, or artifact affected:
67
+ Question or learning action now needed:
68
+ Authority or user decision needed:
69
+ ```
70
+
71
+ Do not restart from zero or rewrite unaffected decisions, evidence, artifacts, or work.
@@ -65,9 +65,9 @@ If both variants pass, the pressure may be weak or the baseline sufficient. If b
65
65
 
66
66
  ## Declare The Definition
67
67
 
68
- Use the exact [definition schema](references/definition-schema.md) for group, environment, expectation, suite, and selector shapes.
68
+ Use the exact [Evaluation Definition Schema](references/evaluation-definition-schema.md) for group, environment, expectation, suite, and selector shapes.
69
69
 
70
- Declare the prompt or turns, fixture, exact ordered skills and target, working-tree or Git source, UTF-8 context, tools, model and thinking, deterministic expectations, comparison IDs, and review questions. Snapshot every declared subject resource. Ambient installation is not declared composition.
70
+ Declare the prompt or turns, fixture, exact ordered skills and target, working-tree or Git source, runtime host/session mode and ordered extension bundles when needed, literal/inherited environment sources, UTF-8 context, tools, model and thinking, deterministic expectations, comparison IDs, and review questions. Snapshot every declared subject resource. Ambient installation is not declared composition.
71
71
 
72
72
  ## Run And View
73
73
 
@@ -82,7 +82,7 @@ Run from the definition root. Definition targets resolve from the current workin
82
82
 
83
83
  With no selectors, every suite group and both variants are selected. `--group` is invalid for a direct group. Run `--help` before relying on an operation.
84
84
 
85
- Pi is the direct subject process. One-shot descriptions use fresh JSON-mode subjects. Ordered description turns and body groups use one isolated RPC process per variant. Body groups explicitly deliver one target on turn one. `bash`, definition-supplied command execution, and end-to-end execution are unsupported.
85
+ Pi is the direct subject process; a runtime profile may select the compatible `piflow` command as an explicit host variant. One-shot descriptions use fresh JSON-mode subjects. Ordered description turns and body groups use one isolated RPC process per variant. Body groups explicitly deliver one target on turn one. Declared extension bundles may provide non-native custom tools in body groups and context injections; description groups remain limited to no tools or `read`. Native `bash`, `powershell`, `grep`, `find`, and `ls` tools, definition-supplied command execution, and end-to-end execution are unsupported.
86
86
 
87
87
  Read [execution and evidence](references/execution-and-evidence.md) when operating commands, resolving paths, interpreting states, or reasoning about Pi isolation, persistence, views, cancellation, cleanup, and safeguards.
88
88
 
@@ -90,9 +90,9 @@ Read [execution and evidence](references/execution-and-evidence.md) when operati
90
90
 
91
91
  Append deterministic grades only after canonical run evidence exists. A grade is derived evidence and never mutates or invalidates a run.
92
92
 
93
- Supported checks cover exact skill/resource reads, typed paths, changed paths, file/response text, explicit JSON states, valid turn scope, and factual baseline-to-candidate transitions. A failed check remains ordinary behavioral evidence. Missing evidence stays unavailable. Malformed checks or grading failures produce separate `grade-error` evidence. Transitions carry no quality or readiness meaning.
93
+ Supported checks cover exact skill/resource reads, typed paths, changed paths, file/response text, explicit JSON states, tool-call outcomes and argument predicates, system-prompt or provider-context text by selected request and turn, valid turn scope, and factual baseline-to-candidate transitions. A failed check remains ordinary behavioral evidence. Missing evidence stays unavailable. Malformed checks or grading failures produce separate `grade-error` evidence. Transitions carry no quality or readiness meaning.
94
94
 
95
- Prefer generated grade-first views for routine inspection. Use ordinary file tools for raw run, event, transcript, response, stderr, workspace, definition, grade, and group artifacts. A view may remove repeated transport structure; it must not hide evidence required by the question.
95
+ Prefer generated grade-first views for routine inspection. Use ordinary file tools for raw run, event, transcript, response, stderr, workspace, definition, grade, context-observation, and group artifacts. A view may remove repeated transport structure; it must not hide evidence required by the question.
96
96
 
97
97
  Read [review and revision](references/review-and-revision.md) after evidence exists, when surfaces conflict, meaning still needs judgment, or a revision/rerun boundary must be chosen.
98
98
 
@@ -68,6 +68,7 @@ Rules:
68
68
  - `expectations` is an ordered array with unique expectation IDs.
69
69
  - `review_questions` is an ordered string array. Questions are rendered for the reviewer and never sent to the subject.
70
70
  - `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.
71
72
 
72
73
  ## Description Group Example
73
74
 
@@ -203,10 +204,45 @@ A body group explicitly delivers each target on turn one and observes first-read
203
204
  }
204
205
  ```
205
206
 
206
- Body groups allow no tools or path-guarded `read`, `write`, and `edit`. A no-target baseline uses `skills: []` and `target: null`; the candidate must always identify a target.
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.
207
208
 
208
209
  The examples are complete definition shapes. Replace fixture, resource, model, and Git-ref values with paths and identities that exist under your definition root.
209
210
 
211
+ ## Runtime Profile
212
+
213
+ A runtime profile is shared by both baseline and candidate variants. It changes the host environment, not the skill target:
214
+
215
+ ```json
216
+ {
217
+ "runtime": {
218
+ "host": "pi",
219
+ "session": false,
220
+ "extensions": [
221
+ {
222
+ "entry": "extensions/probe.mjs",
223
+ "resources": ["extensions"]
224
+ }
225
+ ],
226
+ "environment": {
227
+ "literal": {
228
+ "PROBE_MODE": "injection-test"
229
+ },
230
+ "inherit": []
231
+ }
232
+ }
233
+ }
234
+ ```
235
+
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.
237
+
238
+ `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
+
240
+ Extensions are trusted executable inputs, not OS-sandboxed code. The evaluator proves declared identity and post-run immutability, but extension code retains its host permissions.
241
+
242
+ When a group declares `context-text` expectations, the evaluator loads its base isolation guard first, then declared bundles, then a non-mutating final observer. The observer records two per-turn surfaces: the chained `before_agent_start` system prompt and each provider-neutral `context` message projection. `context-text` expectations select `surface: "system-prompt"` or `surface: "provider-context"` and may select `request: "first"`, `"last"`, or a positive request number. Groups without context assertions do not create context-observation artifacts.
243
+
244
+ A custom tool name is allowed in `group.tools` only when the runtime declares an extension bundle. The evaluator remains extension-neutral: it does not interpret feature names or configuration schemas. Put feature configuration in the ordinary group fixture or runtime environment, and test combinations as separate suite groups.
245
+
210
246
  ## Variant Environment
211
247
 
212
248
  Each environment has exactly:
@@ -216,7 +252,7 @@ Each environment has exactly:
216
252
  "source": { "kind": "git", "ref": "v1.2.3" },
217
253
  "skills": ["skills/target", "skills/support"],
218
254
  "target": 0,
219
- "context": ["runtime/interaction-contract.md"]
255
+ "context": ["runtime/prompts/interaction-contract.md"]
220
256
  }
221
257
  ```
222
258
 
@@ -255,6 +291,10 @@ Without `turn`, response checks use the final response and workspace checks use
255
291
  | `file-text` | workspace `path`, string `value`, optional body `turn` | `contains`, `not-contains`, `equals` |
256
292
  | `json` | workspace `path`, optional body `turn`, conditional `pointer` and `value` | `available`, `missing`, `valid`, `malformed`, `field-present`, `field-absent`, `field-equals` |
257
293
  | `response-text` | string `value`, optional body `turn` | `contains`, `not-contains`, `equals` |
294
+ | `tool-call` | string `tool`, optional body `turn`, optional `argumentContains`/`argumentNotContains` arrays | `called`, `succeeded`, `failed`, `not-called` |
295
+ | `context-text` | string `value`, optional `surface` (`system-prompt` or `provider-context`), optional `request`, optional body `turn` | `contains`, `not-contains`, `equals` |
296
+
297
+ For `tool-call` with `expect: "not-called"`, omitted argument filters require zero calls to the named tool. Supplied filters scope the absence check to calls matching those argument predicates.
258
298
 
259
299
  ### Resource paths
260
300
 
@@ -33,7 +33,9 @@ With no selectors, `run` or `view` selects every suite group and both variants.
33
33
 
34
34
  ## Current Execution Boundary
35
35
 
36
- `run` executes description and body groups. `end-to-end` is a reserved definition type and is rejected before subject execution. Description groups allow no tools or `read`; body groups allow no tools or path-guarded `read`, `write`, and `edit`. `bash` and definition-supplied commands are unsupported.
36
+ `run` executes description and body groups. `end-to-end` is a reserved definition type and is 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.
37
+
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.
37
39
 
38
40
  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.
39
41
 
@@ -43,9 +45,12 @@ A body target is matched to the exact snapshotted `SKILL.md` and explicitly deli
43
45
 
44
46
  For each selected variant:
45
47
 
46
- - snapshot exact declared skills and context;
48
+ - snapshot exact declared skills, context, and the shared runtime bundle resources;
49
+ - copy the shared runtime bundles identically into the variant and verify their fingerprints before and after execution;
47
50
  - snapshot the group fixture once from the definition-root working tree—never from a variant Git source—then create an independent writable copy;
48
51
  - preserve skill order and target index;
52
+ - preserve runtime host, session mode, and extension order;
53
+ - preserve runtime bundle and provider-context observation evidence when requested;
49
54
  - replace ambient instructions with evaluator-owned declared context;
50
55
  - keep criteria and review questions outside the subject prompt;
51
56
  - allow reads only from workspace and declared immutable resources;
@@ -76,7 +81,7 @@ Views can render a complete result, all baseline or candidate variants, one grou
76
81
 
77
82
  Path cells escape literal backslashes before tab, carriage return, and newline. Variant views exclude expectation-owned errors from the other variant while retaining comparison, group, and system errors.
78
83
 
79
- Use ordinary file tools for raw `run.json`, events, transcript, final response, stderr, workspace, definition, grade, and group artifacts. Views remove transport noise; they do not replace canonical evidence.
84
+ Use ordinary file tools for raw `run.json`, events, transcript, final response, stderr, workspace, definition, grade, context observations, and group artifacts. Views remove transport noise; they do not replace canonical evidence. Tool-call grades distinguish attempted, succeeded, failed, and not-called outcomes.
80
85
 
81
86
  ## Safeguards And Limits
82
87
 
@@ -4,6 +4,20 @@ import path from "node:path";
4
4
  const ID = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
5
5
  const EVALUATION_TYPES = new Set(["description", "body", "end-to-end"]);
6
6
  const VARIANTS = ["baseline", "candidate"];
7
+ const EVALUATION_HOSTS = new Set(["pi", "piflow"]);
8
+ const RESERVED_ENVIRONMENT_KEYS = new Set([
9
+ "PATH",
10
+ "HOME",
11
+ "PWD",
12
+ "OLDPWD",
13
+ "SHELL",
14
+ "BASH_ENV",
15
+ "NODE_OPTIONS",
16
+ "NODE_PATH",
17
+ "PI_PACKAGE_DIR",
18
+ "PIFLOW_CODING_AGENT_DIR",
19
+ "PIFLOW_CODING_AGENT_SESSION_DIR",
20
+ ]);
7
21
 
8
22
  export class DefinitionError extends Error {
9
23
  constructor(code, message, definitionPath = null) {
@@ -129,6 +143,102 @@ function validateEnvironment(value, label, definitionPath) {
129
143
  }
130
144
  }
131
145
 
146
+ function validateRuntime(value, definitionPath) {
147
+ const runtime = requireExactKeys(
148
+ value,
149
+ ["host", "extensions", "environment", "session"],
150
+ [],
151
+ "group.runtime",
152
+ definitionPath,
153
+ );
154
+ if (!EVALUATION_HOSTS.has(runtime.host)) {
155
+ fail("invalid-definition", "group.runtime.host must be pi or piflow", definitionPath);
156
+ }
157
+ if (!Array.isArray(runtime.extensions)) {
158
+ fail("invalid-definition", "group.runtime.extensions must be an array", definitionPath);
159
+ }
160
+ const bundleIds = new Set();
161
+ for (const [index, entry] of runtime.extensions.entries()) {
162
+ const bundle = requireExactKeys(
163
+ entry,
164
+ ["entry", "resources"],
165
+ [],
166
+ `group.runtime.extensions[${index}]`,
167
+ definitionPath,
168
+ );
169
+ requireSafeRelativePath(bundle.entry, `group.runtime.extensions[${index}].entry`, definitionPath);
170
+ const resources = requireStringArray(
171
+ bundle.resources,
172
+ `group.runtime.extensions[${index}].resources`,
173
+ definitionPath,
174
+ { paths: true, unique: true },
175
+ );
176
+ if (resources.length === 0) {
177
+ fail("invalid-definition", `group.runtime.extensions[${index}].resources must not be empty`, definitionPath);
178
+ }
179
+ const bundleId = `${bundle.entry}\u0000${resources.join("\u0000")}`;
180
+ if (bundleIds.has(bundleId)) {
181
+ fail("invalid-definition", "group.runtime.extensions contains duplicate bundles", definitionPath);
182
+ }
183
+ bundleIds.add(bundleId);
184
+ }
185
+ if (typeof runtime.session !== "boolean") {
186
+ fail("invalid-definition", "group.runtime.session must be a boolean", definitionPath);
187
+ }
188
+ const environment = requireExactKeys(
189
+ runtime.environment,
190
+ ["literal", "inherit"],
191
+ [],
192
+ "group.runtime.environment",
193
+ definitionPath,
194
+ );
195
+ const literal = requireObject(environment.literal, "group.runtime.environment.literal", definitionPath);
196
+ const inherited = requireStringArray(environment.inherit, "group.runtime.environment.inherit", definitionPath, {
197
+ unique: true,
198
+ });
199
+ const literalKeys = new Set(Object.keys(literal).map((key) => key.toUpperCase()));
200
+ for (const [key, value] of Object.entries(literal)) {
201
+ const normalizedKey = key.toUpperCase();
202
+ if (
203
+ !/^[A-Za-z_][A-Za-z0-9_]*$/.test(key) ||
204
+ isBlockedEnvironmentKey(normalizedKey) ||
205
+ /TOKEN|SECRET|PASSWORD|API[_-]?KEY|PRIVATE[_-]?KEY|CREDENTIAL/i.test(key)
206
+ ) {
207
+ fail(
208
+ "invalid-definition",
209
+ `group.runtime.environment.literal contains a reserved or secret-like key: ${key}`,
210
+ definitionPath,
211
+ );
212
+ }
213
+ if (typeof value !== "string") {
214
+ fail("invalid-definition", `group.runtime.environment.literal.${key} must be a string`, definitionPath);
215
+ }
216
+ }
217
+ for (const key of inherited) {
218
+ const normalizedKey = key.toUpperCase();
219
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key) || isBlockedEnvironmentKey(normalizedKey)) {
220
+ fail("invalid-definition", `group.runtime.environment.inherit contains an invalid key: ${key}`, definitionPath);
221
+ }
222
+ if (literalKeys.has(normalizedKey)) {
223
+ fail(
224
+ "invalid-definition",
225
+ `group.runtime.environment key is declared as both literal and inherited: ${key}`,
226
+ definitionPath,
227
+ );
228
+ }
229
+ }
230
+ }
231
+
232
+ function isBlockedEnvironmentKey(normalizedKey) {
233
+ return (
234
+ RESERVED_ENVIRONMENT_KEYS.has(normalizedKey) ||
235
+ normalizedKey.startsWith("SKILL_EVAL_") ||
236
+ normalizedKey.startsWith("PI_") ||
237
+ normalizedKey.startsWith("LD_") ||
238
+ normalizedKey.startsWith("DYLD_")
239
+ );
240
+ }
241
+
132
242
  function validateExpectations(value, definitionPath) {
133
243
  if (!Array.isArray(value)) fail("invalid-definition", "group.expectations must be an array", definitionPath);
134
244
  const ids = new Set();
@@ -164,7 +274,7 @@ function validateGroup(value, definitionPath) {
164
274
  "expectations",
165
275
  "review_questions",
166
276
  ],
167
- ["model"],
277
+ ["model", "runtime"],
168
278
  "group",
169
279
  definitionPath,
170
280
  );
@@ -177,12 +287,13 @@ function validateGroup(value, definitionPath) {
177
287
  validateInput(group.input, definitionPath);
178
288
  if (group.fixture !== null) requireSafeRelativePath(group.fixture, "group.fixture", definitionPath);
179
289
  requireStringArray(group.tools, "group.tools", definitionPath, { unique: true });
290
+ if (Object.hasOwn(group, "runtime")) validateRuntime(group.runtime, definitionPath);
180
291
  const variants = requireExactKeys(group.variants, VARIANTS, [], "group.variants", definitionPath);
181
292
  for (const variant of VARIANTS) validateEnvironment(variants[variant], `group.variants.${variant}`, definitionPath);
182
- if (variants.candidate.target === null) {
293
+ if (variants.candidate.target === null && variants.candidate.skills.length > 0) {
183
294
  fail(
184
295
  "invalid-definition",
185
- "group.variants.candidate.target must identify the candidate target skill",
296
+ "group.variants.candidate.target must identify the candidate target skill when candidate skills are declared",
186
297
  definitionPath,
187
298
  );
188
299
  }