@hassangameryt/freeflow 0.4.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 (285) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -1
  3. package/.codex-plugin/plugin.json +2 -1
  4. package/README.md +150 -155
  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 +17 -13
  9. package/hooks/freeflow-runtime-context.mjs +393 -159
  10. package/hooks/hooks.json +26 -1
  11. package/hooks/tests/check-runtime-context-hook.sh +223 -54
  12. package/package.json +25 -16
  13. package/pi-extension/dist/cognitive-routing/commands.js +96 -0
  14. package/pi-extension/dist/cognitive-routing/config.js +236 -0
  15. package/pi-extension/dist/cognitive-routing/controller.js +862 -0
  16. package/pi-extension/dist/cognitive-routing/history.js +439 -0
  17. package/pi-extension/dist/cognitive-routing/host.js +126 -0
  18. package/pi-extension/dist/cognitive-routing/runtime.js +43 -0
  19. package/pi-extension/dist/cognitive-routing/tool.js +211 -0
  20. package/pi-extension/dist/cognitive-routing/types.js +6 -0
  21. package/pi-extension/dist/context-virtualization/commands.js +89 -0
  22. package/pi-extension/dist/context-virtualization/projector.js +42 -0
  23. package/pi-extension/dist/context-virtualization/runtime.js +356 -0
  24. package/pi-extension/dist/context-virtualization/state.js +57 -0
  25. package/pi-extension/dist/context-virtualization/types.js +10 -0
  26. package/pi-extension/dist/conversation-history/passages.js +66 -0
  27. package/pi-extension/dist/conversation-history/ranking.js +105 -0
  28. package/pi-extension/dist/conversation-history/runtime.js +226 -0
  29. package/pi-extension/dist/conversation-history/search.js +56 -0
  30. package/pi-extension/dist/conversation-history/types.js +1 -0
  31. package/pi-extension/dist/freeflow-context/resolver.js +120 -0
  32. package/pi-extension/dist/freeflow-context/runtime.js +80 -0
  33. package/pi-extension/dist/freeflow-context/source-projector.js +95 -0
  34. package/pi-extension/dist/freeflow-context/tool.js +308 -0
  35. package/pi-extension/dist/freeflow-context/types.js +12 -0
  36. package/pi-extension/dist/freeflow-context/visibility.js +28 -0
  37. package/pi-extension/dist/index.js +516 -98
  38. package/pi-extension/dist/runtime/runtime-context.js +318 -271
  39. package/pi-extension/dist/runtime/runtime-identity.js +5 -0
  40. package/pi-extension/dist/settings/settings-tui.js +78 -0
  41. package/pi-extension/dist/settings/settings-ui.js +593 -563
  42. package/pi-extension/dist/ui/text-component.js +57 -0
  43. package/pi-extension/src/cognitive-routing/commands.ts +119 -0
  44. package/pi-extension/src/cognitive-routing/config.ts +307 -0
  45. package/pi-extension/src/cognitive-routing/controller.ts +1118 -0
  46. package/pi-extension/src/cognitive-routing/history.ts +638 -0
  47. package/pi-extension/src/cognitive-routing/host.ts +172 -0
  48. package/pi-extension/src/cognitive-routing/runtime.ts +57 -0
  49. package/pi-extension/src/cognitive-routing/tool.ts +272 -0
  50. package/pi-extension/src/cognitive-routing/types.ts +89 -0
  51. package/pi-extension/src/context-virtualization/commands.ts +111 -0
  52. package/pi-extension/src/context-virtualization/projector.ts +62 -0
  53. package/pi-extension/src/context-virtualization/runtime.ts +406 -0
  54. package/pi-extension/src/context-virtualization/state.ts +79 -0
  55. package/pi-extension/src/context-virtualization/types.ts +92 -0
  56. package/pi-extension/src/conversation-history/passages.ts +81 -0
  57. package/pi-extension/src/conversation-history/ranking.ts +155 -0
  58. package/pi-extension/src/conversation-history/runtime.ts +250 -0
  59. package/pi-extension/src/conversation-history/search.ts +79 -0
  60. package/pi-extension/src/conversation-history/types.ts +31 -0
  61. package/pi-extension/src/freeflow-context/resolver.ts +139 -0
  62. package/pi-extension/src/freeflow-context/runtime.ts +100 -0
  63. package/pi-extension/src/freeflow-context/source-projector.ts +106 -0
  64. package/pi-extension/src/freeflow-context/tool.ts +360 -0
  65. package/pi-extension/src/freeflow-context/types.ts +70 -0
  66. package/pi-extension/src/freeflow-context/visibility.ts +53 -0
  67. package/pi-extension/src/index.ts +553 -101
  68. package/pi-extension/src/runtime/runtime-context.ts +339 -281
  69. package/pi-extension/src/runtime/runtime-identity.ts +8 -0
  70. package/pi-extension/src/settings/settings-tui.ts +93 -0
  71. package/pi-extension/src/settings/settings-ui.ts +700 -613
  72. package/pi-extension/src/ui/text-component.ts +66 -0
  73. package/pi-extension/tests/cognitive-routing/commands.test.js +134 -0
  74. package/pi-extension/tests/cognitive-routing/controller.test.js +1099 -0
  75. package/pi-extension/tests/cognitive-routing/extension-lifecycle.test.js +1071 -0
  76. package/pi-extension/tests/cognitive-routing/history.test.js +274 -0
  77. package/pi-extension/tests/cognitive-routing/host-fixture.js +4 -0
  78. package/pi-extension/tests/cognitive-routing/host-identity.test.js +63 -0
  79. package/pi-extension/tests/cognitive-routing/profile-resolution.test.js +236 -0
  80. package/pi-extension/tests/cognitive-routing/tool.test.js +230 -0
  81. package/pi-extension/tests/context-virtualization/extension.test.js +749 -0
  82. package/pi-extension/tests/context-virtualization/projector.test.js +110 -0
  83. package/pi-extension/tests/context-virtualization/runtime.test.js +216 -0
  84. package/pi-extension/tests/conversation-history/runtime.test.js +98 -0
  85. package/pi-extension/tests/conversation-history/search.test.js +97 -0
  86. package/pi-extension/tests/integration/pi-extension.test.js +928 -2047
  87. package/pi-extension/tests/integration/prompt-architecture.test.js +305 -0
  88. package/runtime/prompts/cognitive-routing.md +9 -0
  89. package/runtime/prompts/context-virtualization.md +3 -0
  90. package/runtime/prompts/conversation-history.md +3 -0
  91. package/runtime/prompts/core.md +13 -0
  92. package/runtime/prompts/interaction-contract.md +7 -0
  93. package/runtime/prompts/skills.md +65 -0
  94. package/skills/action-selection/SKILL.md +91 -0
  95. package/skills/bypass/SKILL.md +3 -2
  96. package/skills/commit-work/SKILL.md +1 -1
  97. package/skills/commit-work/references/staging-decisions.md +1 -1
  98. package/skills/decision-gate/SKILL.md +1 -1
  99. package/skills/design-for-depth/SKILL.md +14 -33
  100. package/skills/design-for-depth/references/design-pressure-signals.md +1 -1
  101. package/skills/design-for-depth/references/interface-design-loop.md +1 -1
  102. package/skills/design-for-depth/references/software-design-philosophy.md +1 -1
  103. package/skills/diagnose-failure/SKILL.md +20 -14
  104. package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +1 -3
  105. package/skills/diagnose-failure/references/{flaky-and-performance.md → flaky-and-performance-diagnosis.md} +1 -1
  106. package/skills/discuss/SKILL.md +34 -22
  107. package/skills/discuss/references/discussion-continuity.md +71 -0
  108. package/skills/evaluate-skill/SKILL.md +5 -5
  109. package/skills/evaluate-skill/references/{definition-schema.md → evaluation-definition-schema.md} +42 -2
  110. package/skills/evaluate-skill/references/execution-and-evidence.md +8 -3
  111. package/skills/evaluate-skill/scripts/lib/definitions.mjs +114 -3
  112. package/skills/evaluate-skill/scripts/lib/grade-interaction.mjs +156 -1
  113. package/skills/evaluate-skill/scripts/lib/grade.mjs +9 -1
  114. package/skills/evaluate-skill/scripts/lib/pi.mjs +147 -32
  115. package/skills/evaluate-skill/scripts/lib/rpc.mjs +4 -4
  116. package/skills/evaluate-skill/scripts/lib/runner.mjs +36 -14
  117. package/skills/evaluate-skill/scripts/lib/sandbox.mjs +92 -0
  118. package/skills/evaluate-skill/scripts/pi-guard.mjs +1 -1
  119. package/skills/evaluate-skill/scripts/pi-observer.mjs +66 -0
  120. package/skills/evaluate-skill/scripts/skill-eval.mjs +6 -5
  121. package/skills/execute-work/SKILL.md +18 -15
  122. package/skills/execute-work/references/code-practices.md +1 -1
  123. package/skills/execute-work/references/execute-work-edges.md +42 -0
  124. package/skills/finish-branch/SKILL.md +2 -2
  125. package/skills/finish-branch/references/integration-options.md +1 -1
  126. package/skills/handoff/SKILL.md +3 -3
  127. package/skills/launch-work/SKILL.md +1 -1
  128. package/skills/launch-work/references/launch-readiness.md +2 -2
  129. package/skills/migration-work/SKILL.md +2 -2
  130. package/skills/migration-work/references/migration-lifecycle.md +1 -1
  131. package/skills/mode-contract/SKILL.md +32 -10
  132. package/skills/release-work/SKILL.md +1 -1
  133. package/skills/release-work/references/release-evidence.md +1 -1
  134. package/skills/review-artifact/SKILL.md +28 -26
  135. package/skills/review-work/SKILL.md +28 -26
  136. package/skills/review-work/references/{reviewer-prompt.md → independent-work-reviewer-contract.md} +1 -1
  137. package/skills/review-work/references/security-risk-lens.md +1 -1
  138. package/skills/setup-freeflow/SKILL.md +6 -10
  139. package/skills/setup-freeflow/references/activation-contract.md +5 -10
  140. package/skills/setup-freeflow/references/host-setup.md +3 -7
  141. package/skills/simplify-code/SKILL.md +1 -1
  142. package/skills/simplify-code/references/simplification-patterns.md +1 -1
  143. package/skills/tdd/SKILL.md +18 -38
  144. package/skills/tdd/references/test-design.md +2 -2
  145. package/skills/track-work/SKILL.md +362 -58
  146. package/skills/track-work/scripts/lib/codec.mjs +570 -0
  147. package/skills/track-work/scripts/lib/commands.mjs +568 -0
  148. package/skills/track-work/scripts/lib/contract.mjs +303 -0
  149. package/skills/track-work/scripts/lib/model.mjs +506 -0
  150. package/skills/track-work/scripts/lib/operations.mjs +965 -0
  151. package/skills/track-work/scripts/lib/record-store.mjs +264 -0
  152. package/skills/track-work/scripts/lib/result.mjs +37 -0
  153. package/skills/track-work/scripts/lib/rewrites.mjs +740 -0
  154. package/skills/track-work/scripts/lib/schema.mjs +277 -0
  155. package/skills/track-work/scripts/lib/source-inventory.mjs +162 -0
  156. package/skills/track-work/scripts/lib/views.mjs +443 -0
  157. package/skills/track-work/scripts/lib/workspace.mjs +134 -0
  158. package/skills/track-work/scripts/working-record.mjs +122 -0
  159. package/skills/verify-work/SKILL.md +14 -2
  160. package/skills/verify-work/references/browser-runtime-evidence.md +1 -1
  161. package/skills/verify-work/references/integration-evidence.md +1 -1
  162. package/skills/verify-work/references/performance-evidence.md +1 -1
  163. package/skills/workflow/SKILL.md +105 -53
  164. package/skills/workflow/references/domain-skill-composition.md +22 -42
  165. package/skills/write-plan/SKILL.md +1 -1
  166. package/skills/write-skill/SKILL.md +3 -2
  167. package/skills/write-skill/references/progressive-disclosure.md +17 -3
  168. package/pi-extension/dist/output-router/host-producer-identification.js +0 -232
  169. package/pi-extension/dist/output-router/native-safety-net.js +0 -216
  170. package/pi-extension/dist/output-router/observed-tool-routing.js +0 -122
  171. package/pi-extension/dist/output-router/renderers.js +0 -1023
  172. package/pi-extension/dist/output-router/router-tools.js +0 -554
  173. package/pi-extension/dist/output-router/schemas.js +0 -383
  174. package/pi-extension/dist/output-router/status.js +0 -744
  175. package/pi-extension/dist/output-router/utils.js +0 -502
  176. package/pi-extension/src/output-router/host-producer-identification.ts +0 -256
  177. package/pi-extension/src/output-router/native-safety-net.ts +0 -248
  178. package/pi-extension/src/output-router/observed-tool-routing.ts +0 -134
  179. package/pi-extension/src/output-router/renderers.ts +0 -1108
  180. package/pi-extension/src/output-router/router-tools.ts +0 -579
  181. package/pi-extension/src/output-router/schemas.ts +0 -387
  182. package/pi-extension/src/output-router/status.ts +0 -791
  183. package/pi-extension/src/output-router/utils.ts +0 -554
  184. package/pi-extension/tests/output-router/observed-producers.test.js +0 -132
  185. package/pi-extension/tests/output-router/search.test.js +0 -722
  186. package/router/dist/benchmarks/benchmark-harness.d.ts +0 -35
  187. package/router/dist/benchmarks/benchmark-harness.js +0 -92
  188. package/router/dist/benchmarks/benchmarks.d.ts +0 -109
  189. package/router/dist/benchmarks/benchmarks.js +0 -979
  190. package/router/dist/benchmarks/codex-qa-benchmarks.d.ts +0 -95
  191. package/router/dist/benchmarks/codex-qa-benchmarks.js +0 -500
  192. package/router/dist/benchmarks/command-benchmarks.d.ts +0 -143
  193. package/router/dist/benchmarks/command-benchmarks.js +0 -698
  194. package/router/dist/benchmarks/context-mode-normalized-benchmarks.d.ts +0 -82
  195. package/router/dist/benchmarks/context-mode-normalized-benchmarks.js +0 -773
  196. package/router/dist/benchmarks/context-mode-real-deep-benchmark.d.ts +0 -132
  197. package/router/dist/benchmarks/context-mode-real-deep-benchmark.js +0 -1380
  198. package/router/dist/benchmarks/context-saving-baseline.d.ts +0 -60
  199. package/router/dist/benchmarks/context-saving-baseline.js +0 -470
  200. package/router/dist/benchmarks/index-benchmarks.d.ts +0 -103
  201. package/router/dist/benchmarks/index-benchmarks.js +0 -862
  202. package/router/dist/benchmarks/storage-policy-benchmarks.d.ts +0 -101
  203. package/router/dist/benchmarks/storage-policy-benchmarks.js +0 -618
  204. package/router/dist/benchmarks/vault-index-benchmarks.d.ts +0 -56
  205. package/router/dist/benchmarks/vault-index-benchmarks.js +0 -322
  206. package/router/dist/config/config.d.ts +0 -103
  207. package/router/dist/config/config.js +0 -632
  208. package/router/dist/config/router-contract.d.ts +0 -10
  209. package/router/dist/config/router-contract.js +0 -54
  210. package/router/dist/config/schema.d.ts +0 -27
  211. package/router/dist/config/schema.js +0 -648
  212. package/router/dist/config/types.d.ts +0 -573
  213. package/router/dist/config/types.js +0 -41
  214. package/router/dist/evidence/bounded-evidence.d.ts +0 -40
  215. package/router/dist/evidence/bounded-evidence.js +0 -323
  216. package/router/dist/evidence/evidence-range-selector.d.ts +0 -24
  217. package/router/dist/evidence/evidence-range-selector.js +0 -232
  218. package/router/dist/evidence/evidence-search.d.ts +0 -27
  219. package/router/dist/evidence/evidence-search.js +0 -490
  220. package/router/dist/evidence/evidence.d.ts +0 -38
  221. package/router/dist/evidence/evidence.js +0 -200
  222. package/router/dist/evidence/failure-contracts.d.ts +0 -37
  223. package/router/dist/evidence/failure-contracts.js +0 -166
  224. package/router/dist/evidence/line-ranges.d.ts +0 -24
  225. package/router/dist/evidence/line-ranges.js +0 -22
  226. package/router/dist/experiments/local-index.d.ts +0 -64
  227. package/router/dist/experiments/local-index.js +0 -581
  228. package/router/dist/index.d.ts +0 -30
  229. package/router/dist/index.js +0 -32
  230. package/router/dist/local/local-traversal.d.ts +0 -18
  231. package/router/dist/local/local-traversal.js +0 -334
  232. package/router/dist/processing/engine.d.ts +0 -132
  233. package/router/dist/processing/engine.js +0 -533
  234. package/router/dist/processing/reducers.d.ts +0 -280
  235. package/router/dist/processing/reducers.js +0 -1673
  236. package/router/dist/processing/renderers.d.ts +0 -31
  237. package/router/dist/processing/renderers.js +0 -195
  238. package/router/dist/processing/scripts.d.ts +0 -91
  239. package/router/dist/processing/scripts.js +0 -386
  240. package/router/dist/repo/repo-traversal.d.ts +0 -18
  241. package/router/dist/repo/repo-traversal.js +0 -245
  242. package/router/dist/routing/observed-reducers.d.ts +0 -41
  243. package/router/dist/routing/observed-reducers.js +0 -661
  244. package/router/dist/routing/observed-routing.d.ts +0 -26
  245. package/router/dist/routing/observed-routing.js +0 -378
  246. package/router/dist/routing/parsers.d.ts +0 -16
  247. package/router/dist/routing/parsers.js +0 -521
  248. package/router/dist/routing/run-filters.d.ts +0 -60
  249. package/router/dist/routing/run-filters.js +0 -238
  250. package/router/dist/routing/run-reducers.d.ts +0 -49
  251. package/router/dist/routing/run-reducers.js +0 -122
  252. package/router/dist/sandbox/adapter-roots.d.ts +0 -46
  253. package/router/dist/sandbox/adapter-roots.js +0 -66
  254. package/router/dist/sandbox/eryx-python-adapter.d.ts +0 -13
  255. package/router/dist/sandbox/eryx-python-adapter.js +0 -868
  256. package/router/dist/sandbox/jq-wasm-adapter.d.ts +0 -9
  257. package/router/dist/sandbox/jq-wasm-adapter.js +0 -429
  258. package/router/dist/sandbox/quickjs-wasi-adapter.d.ts +0 -13
  259. package/router/dist/sandbox/quickjs-wasi-adapter.js +0 -384
  260. package/router/dist/sandbox/script-sandbox.d.ts +0 -134
  261. package/router/dist/sandbox/script-sandbox.js +0 -337
  262. package/router/dist/setup/script-transform-adapters.d.ts +0 -32
  263. package/router/dist/setup/script-transform-adapters.js +0 -278
  264. package/router/dist/tools/batch.d.ts +0 -33
  265. package/router/dist/tools/batch.js +0 -586
  266. package/router/dist/tools/run.d.ts +0 -62
  267. package/router/dist/tools/run.js +0 -1304
  268. package/router/dist/tools/search.d.ts +0 -66
  269. package/router/dist/tools/search.js +0 -1364
  270. package/router/dist/transform/engine.d.ts +0 -168
  271. package/router/dist/transform/engine.js +0 -2072
  272. package/router/dist/vault/vault-index.d.ts +0 -125
  273. package/router/dist/vault/vault-index.js +0 -416
  274. package/router/dist/vault/vault.d.ts +0 -138
  275. package/router/dist/vault/vault.js +0 -630
  276. package/runtime/interaction-contract.md +0 -16
  277. package/skills/discuss/references/checkpoints.md +0 -66
  278. package/skills/execute-work/references/execution-loop.md +0 -77
  279. package/skills/output-router/SKILL.md +0 -206
  280. package/skills/output-router/references/safety-policy.md +0 -40
  281. package/skills/setup-freeflow/references/output-router-setup.md +0 -110
  282. package/skills/track-work/references/working-record-schema.md +0 -378
  283. package/skills/workflow/references/workflow-loop.md +0 -92
  284. /package/skills/handoff/references/{templates.md → handoff-templates.md} +0 -0
  285. /package/skills/review-artifact/references/{reviewer-prompt.md → independent-artifact-reviewer-contract.md} +0 -0
@@ -0,0 +1,305 @@
1
+ import assert from "node:assert/strict";
2
+ import { cp, mkdir, mkdtemp, rm, symlink, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ import { tmpdir } from "node:os";
6
+ import test from "node:test";
7
+
8
+ import freeflowExtension from "../../dist/index.js";
9
+ import { PIFLOW_HOST } from "../cognitive-routing/host-fixture.js";
10
+
11
+ function context(cwd) {
12
+ return {
13
+ cwd,
14
+ sessionManager: {
15
+ getEntries: () => [],
16
+ getBranch: () => [],
17
+ buildContextEntries: () => [],
18
+ },
19
+ ui: {
20
+ setStatus() {},
21
+ notify() {},
22
+ },
23
+ };
24
+ }
25
+
26
+ function loadExtension(extension = freeflowExtension, host = PIFLOW_HOST) {
27
+ const handlers = new Map();
28
+ const tools = [];
29
+ let activeToolNames;
30
+ const pi = {
31
+ host,
32
+ registerTool(tool) {
33
+ const index = tools.findIndex((existing) => existing.name === tool.name);
34
+ if (index >= 0) tools[index] = tool;
35
+ else tools.push(tool);
36
+ },
37
+ registerCommand() {},
38
+ registerShortcut() {},
39
+ on(event, handler) {
40
+ handlers.set(event, handler);
41
+ },
42
+ getAllTools() {
43
+ return tools.map((tool) => ({ name: tool.name, sourceInfo: { source: "extension" } }));
44
+ },
45
+ getActiveTools() {
46
+ return activeToolNames ?? tools.map((tool) => tool.name);
47
+ },
48
+ setActiveTools(names) {
49
+ activeToolNames = [...names];
50
+ },
51
+ };
52
+ extension(pi);
53
+ return { handlers, activeToolNames: () => activeToolNames ?? tools.map((tool) => tool.name) };
54
+ }
55
+
56
+ async function configuredRepo(config) {
57
+ const cwd = await mkdtemp(join(tmpdir(), "freeflow-prompt-architecture-"));
58
+ await mkdir(join(cwd, ".freeflow"));
59
+ await writeFile(join(cwd, ".freeflow/config.json"), JSON.stringify(config, null, 2), "utf8");
60
+ return cwd;
61
+ }
62
+
63
+ function lastRuntimeState(messages) {
64
+ return messages.findLast((message) => message.customType === "freeflow-runtime-state");
65
+ }
66
+
67
+ test("composes conditional prompt fragments, discoverable capabilities, and runtime state", async () => {
68
+ const cwd = await configuredRepo({
69
+ defaultMode: "workflow",
70
+ contextVirtualization: true,
71
+ conversationHistory: true,
72
+ });
73
+ try {
74
+ const { handlers, activeToolNames } = loadExtension();
75
+ const ctx = context(cwd);
76
+ await handlers.get("session_start")({ type: "session_start" }, ctx);
77
+
78
+ const before = await handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, ctx);
79
+ assert.equal(before.message, undefined);
80
+ const prompt = before.systemPrompt;
81
+ const order = [
82
+ "# Freeflow Stable Guidance",
83
+ "# Freeflow Interaction Contract",
84
+ "## Shared Terms",
85
+ "## Three Nested Loops",
86
+ "## Workflow Cue",
87
+ "## Action Selection Cue",
88
+ "## Supported Exit",
89
+ "## Context Virtualization Cue",
90
+ "## Conversation History Cue",
91
+ ].map((marker) => prompt.indexOf(marker));
92
+ assert.ok(order.every((index) => index >= 0));
93
+ assert.match(
94
+ prompt,
95
+ /\*\*Slice:\*\* one coherent outcome that can be executed and checked as a unit.*Track Work gives it durable identity/s,
96
+ );
97
+ assert.match(
98
+ prompt,
99
+ /After context loss.*current user direction, bounded task memory, and live evidence.*read Track Work before any record operation.*`resume` view and current schema before mutation.*Workflow is unread.*read it before consequential work or owner selection/s,
100
+ );
101
+ assert.deepEqual(
102
+ order,
103
+ [...order].sort((a, b) => a - b),
104
+ );
105
+ assert.doesNotMatch(prompt, /# Workflow\n/);
106
+ assert.doesNotMatch(prompt, /# Cognitive Routing\n/);
107
+ assert.doesNotMatch(prompt, /# Conversation History\n/);
108
+
109
+ const providerContext = await handlers.get("context")({ messages: [] }, ctx);
110
+ const runtimeState = lastRuntimeState(providerContext.messages);
111
+ assert.ok(runtimeState);
112
+ assert.match(runtimeState.content, /Skills: active/);
113
+ assert.match(runtimeState.content, /Context Virtualization: active/);
114
+ assert.match(runtimeState.content, /Conversation History: active/);
115
+ assert.match(runtimeState.content, /Cognitive Routing: inactive/);
116
+
117
+ const resources = await handlers.get("resources_discover")({ cwd }, ctx);
118
+ assert.ok(resources.skillPaths.some((path) => path.endsWith("/skills/action-selection/SKILL.md")));
119
+ assert.ok(resources.skillPaths.some((path) => path.endsWith("/capabilities/context-virtualization/SKILL.md")));
120
+ assert.ok(resources.skillPaths.some((path) => path.endsWith("/capabilities/conversation-history/SKILL.md")));
121
+ assert.ok(!resources.skillPaths.some((path) => path.endsWith("/capabilities/cognitive-routing/SKILL.md")));
122
+ assert.ok(activeToolNames().includes("freeflow_context"));
123
+ } finally {
124
+ await rm(cwd, { recursive: true, force: true });
125
+ }
126
+ });
127
+
128
+ test("provider context reuses the before-agent surface until the next provider turn", async () => {
129
+ const cwd = await configuredRepo({ defaultMode: "workflow", contextVirtualization: true });
130
+ try {
131
+ const { handlers } = loadExtension();
132
+ const ctx = context(cwd);
133
+ await handlers.get("session_start")({ type: "session_start" }, ctx);
134
+
135
+ const before = await handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, ctx);
136
+ assert.match(before.systemPrompt, /## Context Virtualization Cue/);
137
+
138
+ await writeFile(
139
+ join(cwd, ".freeflow/config.json"),
140
+ JSON.stringify({ defaultMode: "workflow", skills: { enabled: false }, contextVirtualization: true }),
141
+ "utf8",
142
+ );
143
+ const sameTurn = await handlers.get("context")({ messages: [] }, ctx);
144
+ assert.match(lastRuntimeState(sameTurn.messages).content, /Skills: active/);
145
+ assert.match(lastRuntimeState(sameTurn.messages).content, /Context Virtualization: active/);
146
+
147
+ const next = await handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, ctx);
148
+ assert.doesNotMatch(next.systemPrompt, /## Shared Terms/);
149
+ assert.doesNotMatch(next.systemPrompt, /## Context Virtualization Cue/);
150
+ } finally {
151
+ await rm(cwd, { recursive: true, force: true });
152
+ }
153
+ });
154
+
155
+ test("Skills is the parent gate for capability prompt, discovery, and tools", async () => {
156
+ const cwd = await configuredRepo({
157
+ defaultMode: "workflow",
158
+ skills: { enabled: false },
159
+ contextVirtualization: true,
160
+ conversationHistory: true,
161
+ });
162
+ try {
163
+ const { handlers, activeToolNames } = loadExtension();
164
+ const ctx = context(cwd);
165
+ await handlers.get("session_start")({ type: "session_start" }, ctx);
166
+
167
+ const before = await handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, ctx);
168
+ assert.match(before.systemPrompt, /# Freeflow Stable Guidance/);
169
+ assert.match(before.systemPrompt, /## Mode/);
170
+ assert.match(before.systemPrompt, /# Freeflow Interaction Contract/);
171
+ assert.doesNotMatch(before.systemPrompt, /## Shared Terms/);
172
+ assert.doesNotMatch(before.systemPrompt, /## Three Nested Loops/);
173
+ assert.doesNotMatch(before.systemPrompt, /## Context Virtualization Cue/);
174
+ assert.doesNotMatch(before.systemPrompt, /## Conversation History Cue/);
175
+
176
+ const providerContext = await handlers.get("context")({ messages: [] }, ctx);
177
+ const runtimeState = lastRuntimeState(providerContext.messages);
178
+ assert.match(runtimeState.content, /Skills: inactive/);
179
+ assert.match(runtimeState.content, /Context Virtualization: inactive/);
180
+ assert.match(runtimeState.content, /Conversation History: inactive/);
181
+
182
+ const resources = await handlers.get("resources_discover")({ cwd }, ctx);
183
+ assert.deepEqual(resources.skillPaths, []);
184
+ assert.ok(!activeToolNames().includes("freeflow_context"));
185
+ } finally {
186
+ await rm(cwd, { recursive: true, force: true });
187
+ }
188
+ });
189
+
190
+ test("missing optional prompt fragments preserve runtime context loading", async () => {
191
+ const root = await mkdtemp(join(tmpdir(), "freeflow-prompt-fragment-failure-"));
192
+ try {
193
+ await cp(join(process.cwd(), "pi-extension", "dist"), join(root, "pi-extension", "dist"), { recursive: true });
194
+ await cp(join(process.cwd(), "runtime", "prompts"), join(root, "runtime", "prompts"), { recursive: true });
195
+ await rm(join(root, "runtime", "prompts", "cognitive-routing.md"));
196
+
197
+ const runtime = await import(
198
+ `${pathToFileURL(join(root, "pi-extension", "dist", "runtime", "runtime-context.js")).href}?missing-prompt=${Date.now()}`
199
+ );
200
+ const state = {
201
+ configured: true,
202
+ enabled: true,
203
+ interactionContract: { effective: true },
204
+ skills: { effective: true },
205
+ cognitiveRouting: { effective: true },
206
+ contextVirtualization: { effective: false },
207
+ conversationHistory: { effective: false },
208
+ };
209
+
210
+ const loaded = await runtime.getRuntimeContext(state);
211
+ assert.equal(loaded.cognitiveRoutingPrompt, null);
212
+ assert.match(
213
+ runtime.runtimeContext(loaded, { ...state, cognitiveRouting: { effective: false } }),
214
+ /# Freeflow Stable Guidance/,
215
+ );
216
+ assert.doesNotMatch(
217
+ runtime.runtimeContext(loaded, { ...state, cognitiveRouting: { effective: false } }),
218
+ /## Cognitive Routing Cue/,
219
+ );
220
+ } finally {
221
+ await rm(root, { recursive: true, force: true });
222
+ }
223
+ });
224
+
225
+ test("missing child prompt removes that capability from every model-facing surface", async () => {
226
+ const root = await mkdtemp(join(tmpdir(), "freeflow-child-prompt-failure-"));
227
+ const cwd = await configuredRepo({ defaultMode: "workflow", contextVirtualization: true });
228
+ try {
229
+ await cp(join(process.cwd(), "pi-extension", "dist"), join(root, "pi-extension", "dist"), { recursive: true });
230
+ await cp(join(process.cwd(), "runtime", "prompts"), join(root, "runtime", "prompts"), { recursive: true });
231
+ await symlink(join(process.cwd(), "node_modules"), join(root, "node_modules"), "dir");
232
+ await rm(join(root, "runtime", "prompts", "context-virtualization.md"));
233
+
234
+ const extension = (
235
+ await import(`${pathToFileURL(join(root, "pi-extension", "dist", "index.js")).href}?missing-child=${Date.now()}`)
236
+ ).default;
237
+ const { handlers, activeToolNames } = loadExtension(extension);
238
+ const ctx = context(cwd);
239
+ await handlers.get("session_start")({ type: "session_start" }, ctx);
240
+
241
+ const before = await handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, ctx);
242
+ assert.doesNotMatch(before.systemPrompt, /## Context Virtualization Cue/);
243
+ const resources = await handlers.get("resources_discover")({ cwd }, ctx);
244
+ assert.ok(!resources.skillPaths.some((path) => path.endsWith("/capabilities/context-virtualization/SKILL.md")));
245
+ assert.ok(!activeToolNames().includes("freeflow_context"));
246
+ const providerContext = await handlers.get("context")({ messages: [] }, ctx);
247
+ assert.match(providerContext.messages.at(-1).content, /Context Virtualization: unavailable/);
248
+ } finally {
249
+ await rm(cwd, { recursive: true, force: true });
250
+ await rm(root, { recursive: true, force: true });
251
+ }
252
+ });
253
+
254
+ test("missing core prompt preserves the host prompt and marks Freeflow unavailable", async () => {
255
+ const root = await mkdtemp(join(tmpdir(), "freeflow-core-prompt-failure-"));
256
+ const cwd = await configuredRepo({ defaultMode: "workflow" });
257
+ try {
258
+ await cp(join(process.cwd(), "pi-extension", "dist"), join(root, "pi-extension", "dist"), { recursive: true });
259
+ await cp(join(process.cwd(), "runtime", "prompts"), join(root, "runtime", "prompts"), { recursive: true });
260
+ await symlink(join(process.cwd(), "node_modules"), join(root, "node_modules"), "dir");
261
+ await rm(join(root, "runtime", "prompts", "core.md"));
262
+
263
+ const extension = (
264
+ await import(`${pathToFileURL(join(root, "pi-extension", "dist", "index.js")).href}?missing-core=${Date.now()}`)
265
+ ).default;
266
+ const { handlers } = loadExtension(extension);
267
+ const ctx = context(cwd);
268
+ await handlers.get("session_start")({ type: "session_start" }, ctx);
269
+
270
+ const before = await handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, ctx);
271
+ assert.equal(before.systemPrompt, "base prompt");
272
+ const resources = await handlers.get("resources_discover")({ cwd }, ctx);
273
+ assert.deepEqual(resources.skillPaths, []);
274
+ const providerContext = await handlers.get("context")({ messages: [] }, ctx);
275
+ assert.match(providerContext.messages.at(-1).content, /Interaction Contract: unavailable/);
276
+ assert.match(providerContext.messages.at(-1).content, /Skills: unavailable/);
277
+ assert.match(providerContext.messages.at(-1).content, /Active mode: `inactive`/);
278
+ } finally {
279
+ await rm(cwd, { recursive: true, force: true });
280
+ await rm(root, { recursive: true, force: true });
281
+ }
282
+ });
283
+
284
+ test("Runtime State remains present while Freeflow is disabled and prompt surfaces disappear", async () => {
285
+ const cwd = await configuredRepo({ enabled: false, skills: { enabled: true } });
286
+ try {
287
+ const { handlers } = loadExtension();
288
+ const ctx = context(cwd);
289
+ const before = await handlers.get("before_agent_start")({ systemPrompt: "base prompt" }, ctx);
290
+ assert.equal(before.systemPrompt, "base prompt");
291
+ assert.equal(before.message, undefined);
292
+
293
+ const providerContext = await handlers.get("context")({ messages: [] }, ctx);
294
+ const runtimeState = lastRuntimeState(providerContext.messages);
295
+ assert.ok(runtimeState);
296
+ assert.match(runtimeState.content, /Active mode: `inactive`/);
297
+ assert.match(runtimeState.content, /Skills: inactive/);
298
+ assert.match(runtimeState.content, /Interaction Contract: inactive/);
299
+
300
+ const resources = await handlers.get("resources_discover")({ cwd }, ctx);
301
+ assert.deepEqual(resources.skillPaths, []);
302
+ } finally {
303
+ await rm(cwd, { recursive: true, force: true });
304
+ }
305
+ });
@@ -0,0 +1,9 @@
1
+ ## Cognitive Routing Cue
2
+
3
+ Cognitive Routing changes compute only and governs compute placement across Freeflow methods. Use the latest Runtime State `Control` and `Profile`.
4
+
5
+ When Cognitive Routing is active and its skill has not been read in the current context, read it before applying another Freeflow skill or taking task Act.
6
+
7
+ Under manual control, use the held profile for the ordinary unsplit Workflow and do not request a switch. Under automatic control, every authorized execution-bearing bounded activity is Reasoning-led. Without an `OPEN` delegation, Standard transfers the activity before task Act. Reasoning opens one execution boundary, makes the governing judgment and bounded contract explicit, delegates execution to Standard, then resumes the current owner to assess returned evidence and self-review a supported result. Standard takes task Act only inside delegation; direct Reasoning task Act remains gated.
8
+
9
+ Use the discoverable Cognitive Routing skill before opening, acting within, delegating, returning, closing, reopening, recovering, yielding, or switching an automatic execution boundary. A profile change never widens authority or changes the current owner.
@@ -0,0 +1,3 @@
1
+ ## Context Virtualization Cue
2
+
3
+ After broad or noisy tool evidence has been safely narrowed, exhausted, or crossed a meaningful activity boundary, use Context Virtualization to keep necessary evidence active and archive residue. Do not archive governing context or exact evidence still needed by current work.
@@ -0,0 +1,3 @@
1
+ ## Conversation History Cue
2
+
3
+ When the next decision requires exact prior conversation evidence absent from active context, use Conversation History instead of reconstructing it from memory. Current user direction, live source truth, and present runtime state remain authoritative over historical evidence.
@@ -0,0 +1,13 @@
1
+ # Freeflow Stable Guidance
2
+
3
+ Freeflow is a workflow layer for one active coding agent. These instructions establish the minimum language and first cues needed before deeper methods are discovered. They do not override user instructions, repository policy, host safety, or tool permissions, and they do not create authority.
4
+
5
+ Use the latest extension-generated Freeflow Runtime State. Earlier mode, capability, control, and profile state is history. Apply only Freeflow blocks, skills, and tools exposed for the current provider request.
6
+
7
+ ## Mode
8
+
9
+ - `conversation`: answer, discuss, critique, and inspect existing evidence without mutating or deliberately exercising target behavior. Ask the user to change mode before active evidence generation or mutation.
10
+ - `workflow`: use the adaptive Workflow for consequential or mutating work.
11
+ - `strict-workflow`: use the same Workflow with stronger decision, evidence, verification, and checkpoint pressure at high-risk or hard-to-reverse boundaries.
12
+
13
+ The user chooses mode. Task type, skill selection, direct skill calls, usefulness, or new evidence does not change it or widen authority.
@@ -0,0 +1,7 @@
1
+ # Freeflow Interaction Contract
2
+
3
+ Work as a collaborative senior engineer. Read the whole user turn before responding. Treat the user’s goals and choices as theirs, and judge factual and technical claims from evidence: agree when supported, disagree when warranted, state uncertainty plainly, and revise when evidence changes.
4
+
5
+ Treat questions, criticism, examples, hypotheses, and tentative ideas as discussion. When a turn mixes a direct question with a request or approval to act, answer first and wait for clear authorization. Proceed in the same response only when the user explicitly asks you to answer and then act without waiting.
6
+
7
+ With a clear action request, recommend brief discussion only when user input could materially change the outcome, scope, tradeoffs, approach, or acceptance. Otherwise stay within the request and current mode, choose reversible local details, and proceed. Ask before going beyond the request.
@@ -0,0 +1,65 @@
1
+ ## Shared Terms
2
+
3
+ - **Authority envelope:** the requested outcome, permitted effects, evidence boundary, and stop condition established by valid current authority.
4
+ - **Owner:** the one activity or skill responsible for the current bounded activity. Methods, tools, reviewers, and domain guidance do not take ownership automatically.
5
+ - **Bounded activity:** one coherent unit of discussion, preservation, work, evidence, or judgment that can be assessed as one result.
6
+ - **Slice:** one coherent outcome that can be executed and checked as a unit. It may span several bounded activities and methods. Track Work gives it durable identity when task memory is needed.
7
+ - **Evidence boundary:** the strongest claim the current observer can directly support.
8
+ - **Self-review:** after initial evidence supports a bounded result, the producing agent silently checks it once for alignment, suitability, and unnecessary complexity before accepting or reusing it. Self-review is not independent review.
9
+ - **Independent review:** separately selected judgment from a context that did not produce the reviewed state. It reports without editing and does not authorize correction.
10
+ - **Checkpoint:** a deliberately selected decision, review, preservation, or delivery boundary that must be resolved before dependent work continues. A pause or bounded activity ending is not automatically a checkpoint.
11
+ - **Re-entry:** return only to the narrowest owner whose responsibility changed, preserving valid work, decisions, and evidence.
12
+ - **Supported Exit:** an evidence-supported answer, wait, pause, handoff, deferment, stop, controlled boundary, or completion.
13
+
14
+ ## Three Nested Loops
15
+
16
+ One user-facing **Interaction Lifecycle** runs from Entry to Supported Exit:
17
+
18
+ ```text
19
+ [Entry]
20
+ -> [Feedback Loop when needed]
21
+ -> [Supported Exit]
22
+ ```
23
+
24
+ A later user turn or route-changing evidence begins another lifecycle.
25
+
26
+ For each bounded activity, the **Feedback Loop** is:
27
+
28
+ ```text
29
+ Orient
30
+ -> choose one owner
31
+ -> use the owner
32
+ -> gather or produce evidence
33
+ -> determine what the result proves
34
+ -> self-review the supported result
35
+ -> continue, correct, re-enter, ask, defer, stop, or exit
36
+ ```
37
+
38
+ When the owner must touch the environment, the **Environment Interaction Loop** is:
39
+
40
+ ```text
41
+ Need evidence or a covered effect
42
+ -> select and bound one action
43
+ -> choose the tool
44
+ -> execute once
45
+ -> observe
46
+ -> identify what changed
47
+ -> reconcile observation residency when available
48
+ -> return to the owner
49
+ ```
50
+
51
+ The Environment Interaction Loop may run zero or more times inside one Feedback Loop. It never changes the owner or authority by itself.
52
+
53
+ ## Workflow Cue
54
+
55
+ Workflow owns authority, one active owner, evidence-driven re-entry, and Supported Exit. A direct request covers only its bounded outcome and entailed effects and checks. Before uncovered active evidence, mutation, delivery, or another separately controlled action, state the purpose, action, expected result, and stop condition; ask once and wait. Mode, skills, memory, reviews, and new evidence do not grant authority.
56
+
57
+ After context loss, rebuild the decision surface from current user direction, bounded task memory, and live evidence. If a Working Record exists, read Track Work before any record operation; use its `resume` view and current schema before mutation, even when another skill owns the surrounding work. If Workflow is unread, read it before consequential work or owner selection. Summaries and records preserve context but do not prove live state or create authority.
58
+
59
+ ## Action Selection Cue
60
+
61
+ Before an uncertain, broad, or repeated environment interaction, use Action Selection to choose and bound one useful action. Return its observation and state change to the current owner. An obvious mechanical and directly verifiable action takes the fast path without manufactured alternatives.
62
+
63
+ ## Supported Exit
64
+
65
+ Reach a Supported Exit only when fresh evidence supports the accepted outcome, required self-review and selected checkpoints are resolved, task memory and required artifacts are accurate, and no material contradiction, source conflict, or user-owned decision remains hidden. Report the outcome, evidence, limits, and current route.
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: "action-selection"
3
+ description: "Use when selecting, bounding, or learning from an environment interaction, especially when several tool actions are plausible, expected output may be broad, or recent interactions have not materially changed the current understanding."
4
+ ---
5
+
6
+ # Action Selection
7
+
8
+ Control one environment interaction inside the active Workflow owner. Select and bound one action, learn from its actual result, and return the changed evidence to that owner.
9
+
10
+ Action Selection does not choose the task owner, widen authority, decide accepted behavior, or replace implementation, diagnosis, verification, review, or other specialized methods.
11
+
12
+ ## Run The Environment Interaction Loop
13
+
14
+ ```text
15
+ Need evidence or a covered effect
16
+ -> choose the fast path or branch path
17
+ -> select and bound one action
18
+ -> execute once
19
+ -> observe the actual result
20
+ -> identify what changed
21
+ -> return to the owning activity
22
+ ```
23
+
24
+ ### Use The Fast Path
25
+
26
+ When current evidence supports one known, mechanical, covered, and directly verifiable action, use the direct tool and execute it.
27
+
28
+ Do not generate alternatives before a focused read, accepted edit, exact check, formatting step, or other obvious continuation.
29
+
30
+ ### Use The Branch Path
31
+
32
+ When several actions are plausible, the likely action is broad, or recent interactions have not changed the current understanding:
33
+
34
+ 1. name the question or outcome the next interaction must resolve;
35
+ 2. check whether active evidence already resolves it;
36
+ 3. consider only the few materially different actions;
37
+ 4. choose the action most likely to change the current decision with proportionate interaction, observation, side-effect, and recovery cost;
38
+ 5. execute one action and decide again from reality.
39
+
40
+ Keep the comparison internal unless it exposes a user-owned decision. Do not produce candidate tables, simulate a long future trajectory, or plan several environment steps before the first result arrives.
41
+
42
+ ## Prefer Decision-Bearing Actions
43
+
44
+ Among actions already covered by the current route and authority, prefer one that:
45
+
46
+ - bears directly on the current question or accepted outcome;
47
+ - distinguishes the leading alternatives;
48
+ - uses the narrowest sufficient observer or effect;
49
+ - avoids repeating unchanged evidence or an eliminated path;
50
+ - produces a clear next branch whether the result supports or contradicts the current hypothesis;
51
+ - keeps output, side effects, reversibility, and recovery cost proportionate.
52
+
53
+ Do not calculate a numeric score. Use these properties to reject low-value branches and select one useful interaction.
54
+
55
+ ## Shape The Tool Action
56
+
57
+ Match the tool and scope to the evidence or effect required:
58
+
59
+ - use a focused source operation when the file, symbol, range, or artifact is known;
60
+ - use semantic or structural navigation when ownership or relationships are the question;
61
+ - use bounded text search when structural evidence is unavailable or the target is literal or dynamic;
62
+ - use a targeted test or runtime observer when behavior is the question;
63
+ - use a direct mutation tool only after the owning activity has selected the exact effect;
64
+ - use broad search when the relevant source is genuinely unknown, then narrow from its result instead of restarting breadth.
65
+
66
+ Bound the directory, symbol, pattern, range, test target, time window, result count, or requested fields when the tool supports it.
67
+
68
+ Tool sophistication is not evidence quality. Choose the simplest available tool that can establish the required boundary.
69
+
70
+ ## Update From The Observation
71
+
72
+ After execution, identify:
73
+
74
+ - what fact, hypothesis, path, or task state changed;
75
+ - what became stronger, weaker, eliminated, contradicted, or still unresolved;
76
+ - whether the result answered the current question;
77
+ - what single next action, if any, is now supported.
78
+
79
+ If the observation did not change the decision or distinguish alternatives, do not repeat it through synonyms, nearby files, or another tool returning equivalent evidence. Reframe the question, choose a different kind of observer, or stop with the missing evidence.
80
+
81
+ Repeat the loop only while the same owning activity and question remain valid and each observation changes the decision surface.
82
+
83
+ ## Return To The Owner
84
+
85
+ Return the observation and its state change to the activity that requested it.
86
+
87
+ Return to Workflow when the result changes authority, scope, ownership, accepted direction, evidence boundary, or stop conditions. Return repeated unexplained failure to diagnosis rather than selecting another speculative action.
88
+
89
+ Stop when one next action is sufficiently supported, no covered interaction can reduce the important uncertainty, or another activity now owns the problem.
90
+
91
+ The objective is not fewer tool calls at any cost. It is fewer low-value interactions while preserving supported outcomes.
@@ -40,7 +40,7 @@ A generic or scoped bypass does not remove:
40
40
  - the user's authority over product behavior, scope, public interfaces, compatibility, permissions, security, privacy, billing, data loss, migrations, deployment, or another hard-to-reverse outcome;
41
41
  - a conflict with code, tests, docs, policies, requirements, accepted behavior, or another source of truth;
42
42
  - host safety, sandbox, permission, or approval controls;
43
- - proportionate verification and supported self-review before a factual or completion claim;
43
+ - proportionate verification and required self-review for every bounded activity before its result is accepted, reused, or claimed complete;
44
44
  - an accepted Spec, Plan, selected checkpoint, required artifact review, selected independent review, or other accepted completion boundary;
45
45
  - a stop condition or evidence that invalidates the current route.
46
46
 
@@ -73,7 +73,8 @@ When the bypass is valid:
73
73
  1. skip only the selected optional pressure;
74
74
  2. perform only the separately authorized bounded action;
75
75
  3. gather the same proportionate evidence the outcome requires;
76
- 4. report what was skipped, the result, and whether the bypass is spent or still task-scoped.
76
+ 4. silently self-review the supported result before accepting, reusing, or reporting it;
77
+ 5. report what was skipped, the result, and whether the bypass is spent or still task-scoped.
77
78
 
78
79
  When a boundary remains:
79
80
 
@@ -15,7 +15,7 @@ A planned checkpoint remains conditional on live state. Do not force it when its
15
15
 
16
16
  A commit does not select or trigger independent review. Complete only review selected by Workflow, an approved Plan, or repository policy. Commit Work does not adjudicate findings or authorize corrections or follow-up review. Fresh verification is required for the claim the commit represents.
17
17
 
18
- Read [staging decisions](references/staging-decisions.md) when changes are mixed, generated files or durable docs appear, existing staged state is unclear, or broad commit/push language conflicts with diff evidence.
18
+ Read [staging decisions](references/staging-decisions.md) when changes or staged state are mixed, generated files or durable docs appear, existing staged ownership is unclear, broad commit/push language conflicts with diff evidence, or producing a narrow checkpoint may touch user-owned work.
19
19
 
20
20
  ## Route Check
21
21
 
@@ -1,6 +1,6 @@
1
1
  # Staging Decisions
2
2
 
3
- Use this when staged state is mixed, generated files or durable docs appear, broad commit/push language conflicts with the diff, or producing a narrow checkpoint may touch user-owned work.
3
+ Read this when changes or staged state are mixed, generated files or durable docs appear, existing staged ownership is unclear, broad commit/push language conflicts with diff evidence, or producing a narrow checkpoint may touch user-owned work.
4
4
 
5
5
  ## Evidence First
6
6
 
@@ -7,7 +7,7 @@ description: Use when proceeding would silently choose for the user, conflict wi
7
7
 
8
8
  Stop before making a decision that belongs to the user or quietly changing the agreed path.
9
9
 
10
- The [Interaction Contract](../../runtime/interaction-contract.md) governs whether the user is asking, proposing, reasoning, or authorizing action. Decision Gate begins only after one blocking choice or conflict is clear. When the problem or alternatives still need broader exploration, read [Discuss](../discuss/SKILL.md) instead.
10
+ The [Interaction Contract](../../runtime/prompts/interaction-contract.md) governs whether the user is asking, proposing, reasoning, or authorizing action. Decision Gate begins only after one blocking choice or conflict is clear. When the problem or alternatives still need broader exploration, read [Discuss](../discuss/SKILL.md) instead.
11
11
 
12
12
  ## Stop Here
13
13
 
@@ -15,7 +15,7 @@ Use this as a compositional lens, not a mandatory phase or permission to refacto
15
15
 
16
16
  ## Compose The Lens Early
17
17
 
18
- Read this during design-bearing discussion before core boundaries settle. Use it while writing a Spec or Plan when ownership, interfaces, state, or failure behavior shapes the contract. Keep it available during execution, TDD, and review when the work must preserve those decisions or exposes new coordination.
18
+ Use this lens during design-bearing discussion before core boundaries settle. Use it while writing a Spec or Plan when ownership, interfaces, state, or failure behavior shapes the contract. Keep it available during execution, TDD, and review when the work must preserve those decisions or exposes new coordination.
19
19
 
20
20
  Feedback may also route here after [Diagnose Failure](../diagnose-failure/SKILL.md) establishes structural ownership, interface, state, or failure-unit pressure. Ordinary bugs, failed tests, or finding count do not prove bad design.
21
21
 
@@ -23,20 +23,16 @@ Do not force this lens onto a local change whose interface remains sound. Do not
23
23
 
24
24
  ## Start With Outcome And Failure
25
25
 
26
- Before choosing classes, services, states, or adapters, ask:
26
+ Before choosing classes, services, states, or adapters, establish:
27
27
 
28
- - What complete outcome should the caller request?
29
- - Which decisions genuinely belong to the caller?
30
- - Which ordering, policy, storage, retry, cleanup, or provider details can the module own?
31
- - What counts as complete and visible success?
32
- - If it fails, who observes it, what state or evidence is written, and what must never happen?
33
- - Does failure stop, fail closed, fail open, degrade, retry, escalate, or require recovery?
34
- - What is safe to restart, and what evidence establishes recovery?
35
- - Which likely-changing decision should remain local?
28
+ - the complete outcome callers need and the decisions they genuinely own;
29
+ - the coordination or likely-changing policy the module can hide;
30
+ - visible success and the **failure unit**—the smallest outcome treated as one success, failure, and recovery boundary;
31
+ - failure observers, state or evidence written, forbidden partial outcomes, response policy (stop, fail closed/open, degrade, retry, or escalate), safe restart, recovery, and required proof.
36
32
 
37
- The answers form the **failure contract**: failure modes, observers, written state, forbidden outcomes, retry or degradation behavior, recovery, and proof. The **failure unit** is the smallest outcome treated as one success, failure, and recovery boundary. Failure behavior is part of the interface even when its mechanism remains private.
33
+ These form the **failure contract**. Failure behavior is part of the interface even when its mechanism remains private.
38
34
 
39
- When these answers change product behavior, public interfaces, compatibility, permissions, security, privacy, billing, data loss, migration direction, or another user-owned outcome, use [Decision Gate](../decision-gate/SKILL.md). This lens surfaces the decision; it does not make it silently.
35
+ When the boundary changes product behavior, public interfaces, compatibility, permissions, security, privacy, billing, data loss, migration direction, or another user-owned outcome, use [Decision Gate](../decision-gate/SKILL.md). This lens surfaces the decision; it does not make it silently.
40
36
 
41
37
  ## Hide Coordination
42
38
 
@@ -51,38 +47,23 @@ Before exposing a flag, state, path, filename, ordering rule, retry, timing beha
51
47
 
52
48
  Keep caller-owned outcomes and decisions public. Keep internal sequencing, storage, cleanup, provider mechanics, integrity publication, and optimization private unless correct use requires caller control.
53
49
 
54
- Read [software design philosophy](references/software-design-philosophy.md) when the reason a design is shallow or coordination-heavy is unclear.
50
+ Read [software design philosophy](references/software-design-philosophy.md) when structural pressure is supported but the likely-changing decision or missing information-hiding boundary cannot yet be named.
55
51
 
56
52
  ## Recognize Structural Pressure
57
53
 
58
- Structural pressure exists when evidence shows that:
54
+ Structural pressure appears when caller knowledge, duplicated policy, lifecycle choreography, test-only exposure, or unowned failure behavior spreads across a boundary, or a bounded outcome requires an unplanned subsystem because no current seam owns it.
59
55
 
60
- - each correction adds caller knowledge, public states, flags, retries, or recovery rules;
61
- - one policy or behavior requires unrelated edits across callers;
62
- - callers or tests duplicate lifecycle choreography;
63
- - tests need many owned internals or production hooks created only for testing;
64
- - a bounded outcome requires an unplanned subsystem because no current seam can own it;
65
- - correctness depends on coordinated steps that no module owns.
66
-
67
- These signals justify design attention, not automatic refactoring. Read [design pressure signals](references/design-pressure-signals.md) when code, artifacts, tests, or reviews show complexity spreading.
56
+ Read [design pressure signals](references/design-pressure-signals.md) when that evidence may change the next route. The reference owns the detailed classifier and examples; the signals justify design attention, not automatic refactoring.
68
57
 
69
58
  Diagnose repeated or unexplained failure before redesigning. Direct design work is appropriate when structural pressure is already observable or an important boundary must be chosen before implementation.
70
59
 
71
60
  ## Shape The Interface
72
61
 
73
- When pressure changes the next action:
74
-
75
- 1. Name the complete outcome and settled behavior.
76
- 2. Choose the success and failure unit.
77
- 3. Inventory what callers, tests, reviewers, and future agents must know.
78
- 4. Keep caller-owned decisions public and move internal protocol behind the module.
79
- 5. Separate required trust and safety from speculative efficiency, scale, or portability.
80
- 6. For a structural or hard-to-reverse choice, compare materially different ownership or seam placements—not cosmetic variants.
81
- 7. Prefer the design with less caller knowledge, better locality, safer failure behavior, easier correct use, and proportionate evidence cost.
62
+ Before comparing materially different interfaces, read [the interface design loop](references/interface-design-loop.md) when structural pressure or an important pre-implementation correctness boundary makes ownership consequential, especially when authority, canonical state, atomic visibility, replay, cancellation, or post-commit recovery affects correctness.
82
63
 
83
- Read [the interface design loop](references/interface-design-loop.md) when materially different interfaces must be compared, evidence cannot yet choose one, or authority, canonical state, atomic visibility, replay, cancellation, or post-commit recovery affects correctness.
64
+ The reference owns the complete comparison method. Prefer the interface that removes caller knowledge, localizes likely change, makes correct use easy, preserves honest failure and recovery, and costs proportionate evidence.
84
65
 
85
- Do not force multiple designs for an obvious local choice. If source inspection cannot distinguish viable designs, propose one bounded learning slice with a question, competing designs, evidence, cost boundary, and discard-or-promote condition.
66
+ Do not force multiple designs for an obvious local choice. When evidence cannot distinguish viable seams, use the reference's bounded learning route rather than quietly implementing the whole subsystem.
86
67
 
87
68
  ## Tests And Evidence
88
69