@interf/compiler 0.1.12 → 0.2.1

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 (282) hide show
  1. package/README.md +197 -192
  2. package/dist/commands/benchmark.d.ts.map +1 -1
  3. package/dist/commands/benchmark.js +65 -84
  4. package/dist/commands/benchmark.js.map +1 -1
  5. package/dist/commands/compile.d.ts.map +1 -1
  6. package/dist/commands/compile.js +19 -3
  7. package/dist/commands/compile.js.map +1 -1
  8. package/dist/commands/create.d.ts +3 -0
  9. package/dist/commands/create.d.ts.map +1 -1
  10. package/dist/commands/create.js +39 -14
  11. package/dist/commands/create.js.map +1 -1
  12. package/dist/commands/default.d.ts.map +1 -1
  13. package/dist/commands/default.js +2 -0
  14. package/dist/commands/default.js.map +1 -1
  15. package/dist/commands/init.d.ts.map +1 -1
  16. package/dist/commands/init.js +8 -63
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/index.d.ts +11 -29
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +7 -16
  21. package/dist/index.js.map +1 -1
  22. package/dist/lib/agent-args.d.ts +4 -0
  23. package/dist/lib/agent-args.d.ts.map +1 -0
  24. package/dist/lib/agent-args.js +42 -0
  25. package/dist/lib/agent-args.js.map +1 -0
  26. package/dist/lib/agent-constants.d.ts +6 -0
  27. package/dist/lib/agent-constants.d.ts.map +1 -0
  28. package/dist/lib/agent-constants.js +29 -0
  29. package/dist/lib/agent-constants.js.map +1 -0
  30. package/dist/lib/agent-detection.d.ts +8 -0
  31. package/dist/lib/agent-detection.d.ts.map +1 -0
  32. package/dist/lib/agent-detection.js +66 -0
  33. package/dist/lib/agent-detection.js.map +1 -0
  34. package/dist/lib/agent-execution.d.ts +3 -0
  35. package/dist/lib/agent-execution.d.ts.map +1 -0
  36. package/dist/lib/agent-execution.js +207 -0
  37. package/dist/lib/agent-execution.js.map +1 -0
  38. package/dist/lib/agent-logs.d.ts +3 -0
  39. package/dist/lib/agent-logs.d.ts.map +1 -0
  40. package/dist/lib/agent-logs.js +18 -0
  41. package/dist/lib/agent-logs.js.map +1 -0
  42. package/dist/lib/agent-preflight.d.ts +8 -0
  43. package/dist/lib/agent-preflight.d.ts.map +1 -0
  44. package/dist/lib/agent-preflight.js +77 -0
  45. package/dist/lib/agent-preflight.js.map +1 -0
  46. package/dist/lib/agent-render.d.ts +9 -0
  47. package/dist/lib/agent-render.d.ts.map +1 -0
  48. package/dist/lib/agent-render.js +219 -0
  49. package/dist/lib/agent-render.js.map +1 -0
  50. package/dist/lib/agent-status.d.ts +4 -0
  51. package/dist/lib/agent-status.d.ts.map +1 -0
  52. package/dist/lib/agent-status.js +59 -0
  53. package/dist/lib/agent-status.js.map +1 -0
  54. package/dist/lib/agent-types.d.ts +31 -0
  55. package/dist/lib/agent-types.d.ts.map +1 -0
  56. package/dist/lib/agent-types.js +2 -0
  57. package/dist/lib/agent-types.js.map +1 -0
  58. package/dist/lib/agents.d.ts +7 -49
  59. package/dist/lib/agents.d.ts.map +1 -1
  60. package/dist/lib/agents.js +8 -554
  61. package/dist/lib/agents.js.map +1 -1
  62. package/dist/lib/benchmark-execution.d.ts +9 -0
  63. package/dist/lib/benchmark-execution.d.ts.map +1 -0
  64. package/dist/lib/benchmark-execution.js +488 -0
  65. package/dist/lib/benchmark-execution.js.map +1 -0
  66. package/dist/lib/benchmark-paths.d.ts +11 -0
  67. package/dist/lib/benchmark-paths.d.ts.map +1 -0
  68. package/dist/lib/benchmark-paths.js +38 -0
  69. package/dist/lib/benchmark-paths.js.map +1 -0
  70. package/dist/lib/benchmark-specs.d.ts +8 -0
  71. package/dist/lib/benchmark-specs.d.ts.map +1 -0
  72. package/dist/lib/benchmark-specs.js +115 -0
  73. package/dist/lib/benchmark-specs.js.map +1 -0
  74. package/dist/lib/benchmark-targets.d.ts +5 -0
  75. package/dist/lib/benchmark-targets.d.ts.map +1 -0
  76. package/dist/lib/benchmark-targets.js +72 -0
  77. package/dist/lib/benchmark-targets.js.map +1 -0
  78. package/dist/lib/benchmark-types.d.ts +19 -0
  79. package/dist/lib/benchmark-types.d.ts.map +1 -0
  80. package/dist/lib/benchmark-types.js +2 -0
  81. package/dist/lib/benchmark-types.js.map +1 -0
  82. package/dist/lib/benchmark.d.ts +4 -29
  83. package/dist/lib/benchmark.d.ts.map +1 -1
  84. package/dist/lib/benchmark.js +3 -324
  85. package/dist/lib/benchmark.js.map +1 -1
  86. package/dist/lib/bundled-templates.d.ts +5 -0
  87. package/dist/lib/bundled-templates.d.ts.map +1 -0
  88. package/dist/lib/bundled-templates.js +23 -0
  89. package/dist/lib/bundled-templates.js.map +1 -0
  90. package/dist/lib/config.d.ts +1 -0
  91. package/dist/lib/config.d.ts.map +1 -1
  92. package/dist/lib/config.js +2 -0
  93. package/dist/lib/config.js.map +1 -1
  94. package/dist/lib/eval-packs.d.ts +204 -0
  95. package/dist/lib/eval-packs.d.ts.map +1 -0
  96. package/dist/lib/eval-packs.js +177 -0
  97. package/dist/lib/eval-packs.js.map +1 -0
  98. package/dist/lib/execution-profile.d.ts +18 -0
  99. package/dist/lib/execution-profile.d.ts.map +1 -0
  100. package/dist/lib/execution-profile.js +85 -0
  101. package/dist/lib/execution-profile.js.map +1 -0
  102. package/dist/lib/interf-bootstrap.d.ts +4 -0
  103. package/dist/lib/interf-bootstrap.d.ts.map +1 -1
  104. package/dist/lib/interf-bootstrap.js +71 -68
  105. package/dist/lib/interf-bootstrap.js.map +1 -1
  106. package/dist/lib/interf-compile-plan.d.ts +12 -0
  107. package/dist/lib/interf-compile-plan.d.ts.map +1 -0
  108. package/dist/lib/interf-compile-plan.js +143 -0
  109. package/dist/lib/interf-compile-plan.js.map +1 -0
  110. package/dist/lib/interf-detect.d.ts.map +1 -1
  111. package/dist/lib/interf-detect.js +11 -10
  112. package/dist/lib/interf-detect.js.map +1 -1
  113. package/dist/lib/interf-scaffold.d.ts +1 -10
  114. package/dist/lib/interf-scaffold.d.ts.map +1 -1
  115. package/dist/lib/interf-scaffold.js +25 -362
  116. package/dist/lib/interf-scaffold.js.map +1 -1
  117. package/dist/lib/interf-workflow-package.d.ts +4 -0
  118. package/dist/lib/interf-workflow-package.d.ts.map +1 -0
  119. package/dist/lib/interf-workflow-package.js +131 -0
  120. package/dist/lib/interf-workflow-package.js.map +1 -0
  121. package/dist/lib/interf.d.ts +2 -1
  122. package/dist/lib/interf.d.ts.map +1 -1
  123. package/dist/lib/interf.js +2 -1
  124. package/dist/lib/interf.js.map +1 -1
  125. package/dist/lib/local-workflows.d.ts.map +1 -1
  126. package/dist/lib/local-workflows.js +8 -12
  127. package/dist/lib/local-workflows.js.map +1 -1
  128. package/dist/lib/logger.d.ts +4 -0
  129. package/dist/lib/logger.d.ts.map +1 -0
  130. package/dist/lib/logger.js +11 -0
  131. package/dist/lib/logger.js.map +1 -0
  132. package/dist/lib/obsidian.d.ts.map +1 -1
  133. package/dist/lib/obsidian.js +7 -3
  134. package/dist/lib/obsidian.js.map +1 -1
  135. package/dist/lib/parse.d.ts +2 -2
  136. package/dist/lib/parse.d.ts.map +1 -1
  137. package/dist/lib/parse.js +11 -7
  138. package/dist/lib/parse.js.map +1 -1
  139. package/dist/lib/registry.js +3 -3
  140. package/dist/lib/registry.js.map +1 -1
  141. package/dist/lib/runtime-acceptance.d.ts +4 -0
  142. package/dist/lib/runtime-acceptance.d.ts.map +1 -0
  143. package/dist/lib/runtime-acceptance.js +123 -0
  144. package/dist/lib/runtime-acceptance.js.map +1 -0
  145. package/dist/lib/runtime-contracts.d.ts +4 -0
  146. package/dist/lib/runtime-contracts.d.ts.map +1 -0
  147. package/dist/lib/runtime-contracts.js +63 -0
  148. package/dist/lib/runtime-contracts.js.map +1 -0
  149. package/dist/lib/runtime-paths.d.ts +8 -0
  150. package/dist/lib/runtime-paths.d.ts.map +1 -0
  151. package/dist/lib/runtime-paths.js +28 -0
  152. package/dist/lib/runtime-paths.js.map +1 -0
  153. package/dist/lib/runtime-prompt.d.ts +3 -0
  154. package/dist/lib/runtime-prompt.d.ts.map +1 -0
  155. package/dist/lib/runtime-prompt.js +59 -0
  156. package/dist/lib/runtime-prompt.js.map +1 -0
  157. package/dist/lib/runtime-reconcile.d.ts +6 -0
  158. package/dist/lib/runtime-reconcile.d.ts.map +1 -0
  159. package/dist/lib/runtime-reconcile.js +339 -0
  160. package/dist/lib/runtime-reconcile.js.map +1 -0
  161. package/dist/lib/runtime-runs.d.ts +12 -0
  162. package/dist/lib/runtime-runs.d.ts.map +1 -0
  163. package/dist/lib/runtime-runs.js +337 -0
  164. package/dist/lib/runtime-runs.js.map +1 -0
  165. package/dist/lib/runtime-types.d.ts +42 -0
  166. package/dist/lib/runtime-types.d.ts.map +1 -0
  167. package/dist/lib/runtime-types.js +2 -0
  168. package/dist/lib/runtime-types.js.map +1 -0
  169. package/dist/lib/runtime.d.ts +6 -58
  170. package/dist/lib/runtime.d.ts.map +1 -1
  171. package/dist/lib/runtime.js +5 -614
  172. package/dist/lib/runtime.js.map +1 -1
  173. package/dist/lib/schema.d.ts +156 -13
  174. package/dist/lib/schema.d.ts.map +1 -1
  175. package/dist/lib/schema.js +113 -4
  176. package/dist/lib/schema.js.map +1 -1
  177. package/dist/lib/source-config.d.ts +13 -0
  178. package/dist/lib/source-config.d.ts.map +1 -0
  179. package/dist/lib/source-config.js +75 -0
  180. package/dist/lib/source-config.js.map +1 -0
  181. package/dist/lib/state-artifacts.d.ts +15 -0
  182. package/dist/lib/state-artifacts.d.ts.map +1 -0
  183. package/dist/lib/state-artifacts.js +24 -0
  184. package/dist/lib/state-artifacts.js.map +1 -0
  185. package/dist/lib/state-health.d.ts +9 -0
  186. package/dist/lib/state-health.d.ts.map +1 -0
  187. package/dist/lib/state-health.js +330 -0
  188. package/dist/lib/state-health.js.map +1 -0
  189. package/dist/lib/state-io.d.ts +15 -0
  190. package/dist/lib/state-io.d.ts.map +1 -0
  191. package/dist/lib/state-io.js +219 -0
  192. package/dist/lib/state-io.js.map +1 -0
  193. package/dist/lib/state-paths.d.ts +5 -0
  194. package/dist/lib/state-paths.d.ts.map +1 -0
  195. package/dist/lib/state-paths.js +19 -0
  196. package/dist/lib/state-paths.js.map +1 -0
  197. package/dist/lib/state-view.d.ts +7 -0
  198. package/dist/lib/state-view.d.ts.map +1 -0
  199. package/dist/lib/state-view.js +147 -0
  200. package/dist/lib/state-view.js.map +1 -0
  201. package/dist/lib/state.d.ts +6 -46
  202. package/dist/lib/state.d.ts.map +1 -1
  203. package/dist/lib/state.js +5 -632
  204. package/dist/lib/state.js.map +1 -1
  205. package/dist/lib/summarize-plan.d.ts +1 -0
  206. package/dist/lib/summarize-plan.d.ts.map +1 -1
  207. package/dist/lib/summarize-plan.js +10 -0
  208. package/dist/lib/summarize-plan.js.map +1 -1
  209. package/dist/lib/user-config.js +2 -2
  210. package/dist/lib/user-config.js.map +1 -1
  211. package/dist/lib/validate-helpers.d.ts +21 -0
  212. package/dist/lib/validate-helpers.d.ts.map +1 -0
  213. package/dist/lib/validate-helpers.js +72 -0
  214. package/dist/lib/validate-helpers.js.map +1 -0
  215. package/dist/lib/validate-interface.d.ts +2 -0
  216. package/dist/lib/validate-interface.d.ts.map +1 -1
  217. package/dist/lib/validate-interface.js +103 -53
  218. package/dist/lib/validate-interface.js.map +1 -1
  219. package/dist/lib/validate-kb.d.ts +8 -0
  220. package/dist/lib/validate-kb.d.ts.map +1 -1
  221. package/dist/lib/validate-kb.js +53 -24
  222. package/dist/lib/validate-kb.js.map +1 -1
  223. package/dist/lib/validate.d.ts +1 -1
  224. package/dist/lib/validate.d.ts.map +1 -1
  225. package/dist/lib/validate.js +5 -2
  226. package/dist/lib/validate.js.map +1 -1
  227. package/dist/lib/workflow-definitions.d.ts +1 -1
  228. package/dist/lib/workflow-definitions.d.ts.map +1 -1
  229. package/dist/lib/workflow-definitions.js +90 -166
  230. package/dist/lib/workflow-definitions.js.map +1 -1
  231. package/dist/lib/workflow-helpers.d.ts.map +1 -1
  232. package/dist/lib/workflow-helpers.js +6 -3
  233. package/dist/lib/workflow-helpers.js.map +1 -1
  234. package/dist/lib/workflow-stage-runner.d.ts +41 -0
  235. package/dist/lib/workflow-stage-runner.d.ts.map +1 -0
  236. package/dist/lib/workflow-stage-runner.js +106 -0
  237. package/dist/lib/workflow-stage-runner.js.map +1 -0
  238. package/dist/lib/workflow-starter-docs.d.ts +9 -0
  239. package/dist/lib/workflow-starter-docs.d.ts.map +1 -0
  240. package/dist/lib/workflow-starter-docs.js +18 -0
  241. package/dist/lib/workflow-starter-docs.js.map +1 -0
  242. package/dist/lib/workflows-interface-contracts.d.ts +24 -0
  243. package/dist/lib/workflows-interface-contracts.d.ts.map +1 -0
  244. package/dist/lib/workflows-interface-contracts.js +304 -0
  245. package/dist/lib/workflows-interface-contracts.js.map +1 -0
  246. package/dist/lib/workflows-interface.d.ts +3 -10
  247. package/dist/lib/workflows-interface.d.ts.map +1 -1
  248. package/dist/lib/workflows-interface.js +117 -365
  249. package/dist/lib/workflows-interface.js.map +1 -1
  250. package/dist/lib/workflows-kb.d.ts.map +1 -1
  251. package/dist/lib/workflows-kb.js +79 -55
  252. package/dist/lib/workflows-kb.js.map +1 -1
  253. package/dist/lib/workflows.d.ts.map +1 -1
  254. package/dist/lib/workflows.js +1 -1
  255. package/dist/lib/workflows.js.map +1 -1
  256. package/package.json +15 -4
  257. package/skills/interface/analyze/SKILL.md +79 -28
  258. package/skills/interface/compile/SKILL.md +27 -28
  259. package/skills/interface/create/SKILL.md +53 -230
  260. package/skills/interface/create/references/compile-plan-format.md +31 -31
  261. package/skills/interface/create/references/workflows.md +17 -32
  262. package/skills/interface/query/SKILL.md +15 -1
  263. package/skills/interface/retrieve/SKILL.md +32 -65
  264. package/skills/knowledge-base/compile/SKILL.md +59 -83
  265. package/skills/knowledge-base/compile/references/stage-claims.md +1 -1
  266. package/skills/knowledge-base/compile/references/stage-entities.md +2 -2
  267. package/skills/knowledge-base/query/SKILL.md +13 -1
  268. package/skills/knowledge-base/summarize/SKILL.md +54 -24
  269. package/templates/interface/README.md +13 -12
  270. package/templates/interface/interfaces.md +14 -11
  271. package/templates/knowledge-base/README.md +0 -1
  272. package/templates/knowledge-base/registry.md +15 -15
  273. package/templates/workflow-package/README.md +16 -0
  274. package/templates/workflow-package/create/SKILL.md +8 -0
  275. package/templates/workflow-package/interface-query/SKILL.md +29 -0
  276. package/templates/workflow-package/interface-stage/SKILL.md +13 -0
  277. package/templates/workflow-package/knowledge-base-query/SKILL.md +36 -0
  278. package/templates/workflow-package/knowledge-base-stage/SKILL.md +13 -0
  279. package/templates/workflow-starters/interface/interf/README.md +13 -0
  280. package/templates/workflow-starters/interface/interf/create/SKILL.md +15 -0
  281. package/templates/workflow-starters/knowledge-base/interf/README.md +13 -0
  282. package/templates/workflow-starters/knowledge-base/karpathy/README.md +13 -0
@@ -1,15 +1,15 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { countFilesRecursive } from "./filesystem.js";
4
- import { readInterfConfig, refreshWorkspaceBootstrapGuidance, resolveInterfaceKnowledgeBasePath, resolveKnowledgeBaseSourcePath, syncClaudeBootstrap, } from "./interf.js";
4
+ import { readInterfConfig, refreshWorkspaceBootstrapGuidance, resolveInterfaceKnowledgeBasePath, resolveKnowledgeBaseSourcePath, syncClaudeBootstrap, writeInterfaceCompilePlanTemplate, } from "./interf.js";
5
5
  import { loadState, computeInterfaceHealth, refreshInterfaceArtifacts, } from "./state.js";
6
- import { buildStagePrompt, markRuntimeRunFailedAfterValidation, markRuntimeRunSucceededAfterValidation, runtimeRunStdoutContains, runExecutorStage, validateStageContractAcceptance, } from "./runtime.js";
7
- import { formatInterfaceWorkflowStageStep, getInterfaceWorkflow, getWorkflowStagePolicyNotes, resolveInterfaceWorkflowFromConfig, } from "./workflow-definitions.js";
8
- import { validateInterfaceRetrieve, validateInterfacePlan, } from "./validate.js";
9
- import { reportLine, reportBlankLine, reportValidationFailure, buildLocalSkillContractExtension, buildLocalSkillContractExtensionRelativeTo, mergeLocalSkillContractExtensions, emptyLocalSkillContractExtension, buildStageInstructions, bundledSkillForContractType, resolveStageAcceptance, validateStageOutcome, workflowCreateDirectory, workflowQueryDirectory, workflowCompileStageDirectory, } from "./workflow-helpers.js";
10
- // ---------------------------------------------------------------------------
11
- // Interface-specific helpers
12
- // ---------------------------------------------------------------------------
6
+ import { buildStagePrompt, markRuntimeRunFailedAfterValidation, markRuntimeRunSucceededAfterValidation, runExecutorStage, validateStageContractAcceptance, } from "./runtime.js";
7
+ import { reconcileInterfaceAnalyzeRun, reconcileInterfaceCompileRun, reconcileInterfaceRetrieveRun, } from "./runtime-reconcile.js";
8
+ import { formatInterfaceWorkflowStageStep, getInterfaceWorkflow, resolveInterfaceWorkflowFromConfig, } from "./workflow-definitions.js";
9
+ import { validateInterfaceRetrieve, } from "./validate.js";
10
+ import { reportLine, reportBlankLine, buildLocalSkillContractExtension, buildLocalSkillContractExtensionRelativeTo, emptyLocalSkillContractExtension, mergeLocalSkillContractExtensions, buildStageInstructions, bundledSkillForContractType, workflowCreateDirectory, workflowCompileStageDirectory, } from "./workflow-helpers.js";
11
+ import { buildInterfaceAnalyzeContract, buildInterfaceCompileContract, buildInterfaceCreateContract, buildInterfaceRetrieveContract, isRetrieveStageComplete, validateInterfacePlanForUseCase, } from "./workflows-interface-contracts.js";
12
+ import { executeValidatedStage, findStageByContractType, } from "./workflow-stage-runner.js";
13
13
  export function resolveInterfaceContext(knowledgeBasePath) {
14
14
  const config = readInterfConfig(knowledgeBasePath);
15
15
  const workflowId = resolveInterfaceWorkflowFromConfig(config);
@@ -24,284 +24,36 @@ export function resolveInterfaceContext(knowledgeBasePath) {
24
24
  export function interfaceExecutionStages(workflowId, interfacePath) {
25
25
  return getInterfaceWorkflow(workflowId, { workspacePath: interfacePath }).stages;
26
26
  }
27
- export function isRetrieveStageComplete(dirPath) {
28
- const validation = validateInterfaceRetrieve(dirPath);
29
- return validation.required && validation.ok;
30
- }
31
- // ---------------------------------------------------------------------------
32
- // Interface contract builders
33
- // ---------------------------------------------------------------------------
34
- function buildInterfaceCreateContract(options) {
35
- const connectedKnowledgeBasePath = resolveInterfaceKnowledgeBasePath(options.knowledgeBasePath);
36
- const workflowSourcePath = connectedKnowledgeBasePath
37
- ? resolveKnowledgeBaseSourcePath(connectedKnowledgeBasePath)
38
- : undefined;
39
- const workflow = getInterfaceWorkflow(options.workflow, {
40
- sourcePath: workflowSourcePath,
41
- workspacePath: options.knowledgeBasePath,
42
- });
43
- const localSkills = mergeLocalSkillContractExtensions([
27
+ function buildInterfaceCreateInstructions(interfacePath, connectedKnowledgeBasePath) {
28
+ return buildStageInstructions("interface/create", mergeLocalSkillContractExtensions([
44
29
  connectedKnowledgeBasePath
45
- ? buildLocalSkillContractExtensionRelativeTo(connectedKnowledgeBasePath, options.knowledgeBasePath, [workflowQueryDirectory()], "Use the connected knowledge-base workflow docs as higher-level knowledge-base guidance only if they materially improve the interface scaffold.")
30
+ ? buildLocalSkillContractExtensionRelativeTo(connectedKnowledgeBasePath, interfacePath, [], "Use the connected knowledge-base workflow README as high-level guidance only if it materially improves the interface scaffold.")
46
31
  : emptyLocalSkillContractExtension(),
47
- buildLocalSkillContractExtension(options.knowledgeBasePath, [workflowCreateDirectory()], "Use the interface workflow's local create docs as scaffolding heuristics only if they materially improve the interface setup."),
48
- ]);
49
- return {
50
- instructions: options.instructions,
51
- counts: {
52
- workflow_selected: 1,
53
- local_skill_docs: localSkills.count,
54
- },
55
- artifacts: {
56
- reads: [
57
- "AGENTS.md",
58
- "home.md",
59
- "../../AGENTS.md",
60
- "../../interf.json",
61
- "../../home.md",
62
- "../../knowledge/",
63
- "../../summaries/",
64
- ...localSkills.reads,
65
- ],
66
- writes: [
67
- "interf.json",
68
- "compile-plan.md",
69
- "AGENTS.md",
70
- "CLAUDE.md",
71
- ],
72
- verifies: [
73
- "interf verify interface-plan --json",
74
- ],
75
- },
76
- policies: {
77
- execution_mode: "deterministic",
78
- status_prefixes: ["STATUS:", "DONE:", "BLOCKED:", "ERROR:"],
79
- notes: [
80
- `Interface name: ${options.name}.`,
81
- `Selected workflow: ${workflow.id} (${workflow.label}).`,
82
- `Workflow stages: ${workflow.stages.map((stage) => `${stage.label} [${stage.id}]`).join(" -> ")}.`,
83
- `Use case: ${options.useCase}.`,
84
- `Connected knowledge-base: ${options.knowledgeBaseName} at ${connectedKnowledgeBasePath ?? "unknown"}.`,
85
- "The scaffold already exists with home.md, AGENTS.md, CLAUDE.md, interf.json, and the .interf runtime artifacts.",
86
- "Read the current local AGENTS.md and home.md first. They are the interface workspace bootstrap you are updating.",
87
- "Then consult ../../AGENTS.md and ../../home.md for parent knowledge-base navigation and evidence structure.",
88
- "This interface lives inside the parent knowledgeBase. Do not assume it will be opened as a standalone Obsidian vault.",
89
- "Do not recreate the vault or ask follow-up questions.",
90
- "Use the selected workflow as the starting point, then adapt it to the knowledge-base data and the use case.",
91
- "Edit the existing compile-plan.md scaffold in place. Preserve the stage headings and required subsection labels from the starter plan; refine the bullets and narrative instead of replacing the structure.",
92
- "Preserve the existing AGENTS.md scaffold sections, especially the manual access checklist, raw-source gate, and navigation/router guidance. Update only the interface-specific description and lines that must reflect the use case.",
93
- "Do not replace AGENTS.md with a shorter template.",
94
- "Analyze the knowledge-base and update only the interface definition files in this vault: interf.json, compile-plan.md, and AGENTS.md. CLAUDE.md is a generated mirror of AGENTS.md and will be rewritten by the harness.",
95
- ...localSkills.notes,
96
- ],
97
- },
98
- };
99
- }
100
- export function buildInterfaceRetrieveContract(interfacePath, workflowId, summaryCount, instructions, stageId = "retrieve", stageSkillDir = "retrieve") {
101
- const connectedKnowledgeBasePath = resolveInterfaceKnowledgeBasePath(interfacePath);
102
- const sourcePath = connectedKnowledgeBasePath ? resolveKnowledgeBaseSourcePath(connectedKnowledgeBasePath) : undefined;
103
- const acceptance = resolveStageAcceptance("interface", workflowId, stageId, sourcePath, interfacePath);
104
- const localSkills = mergeLocalSkillContractExtensions([
105
- connectedKnowledgeBasePath
106
- ? buildLocalSkillContractExtensionRelativeTo(connectedKnowledgeBasePath, interfacePath, [workflowQueryDirectory()], "Use the connected knowledge-base workflow docs as higher-level knowledge-base guidance before applying interface-local retrieve rules.")
107
- : emptyLocalSkillContractExtension(),
108
- buildLocalSkillContractExtension(interfacePath, [workflowCompileStageDirectory(stageSkillDir)], "Use interface-local docs to refine filters, expansion heuristics, ranking, and ontology hints."),
109
- ]);
110
- return {
111
- instructions,
112
- counts: {
113
- knowledge_base_summary_total: summaryCount,
114
- local_skill_docs: localSkills.count,
115
- },
116
- ...(acceptance ? { acceptance } : {}),
117
- artifacts: {
118
- reads: [
119
- "AGENTS.md",
120
- "home.md",
121
- "../../AGENTS.md",
122
- "../../home.md",
123
- "interf.json",
124
- "compile-plan.md",
125
- "../../.interf/source-access.json",
126
- "../../summaries/",
127
- ".interf/state.json",
128
- ...localSkills.reads,
129
- ],
130
- writes: [
131
- ".interf/relevant.json",
132
- ".interf/coverage.json",
133
- ".interf/state.json",
134
- ".interf/health.json",
135
- ],
136
- verifies: [
137
- "interf verify retrieve --json",
138
- ],
139
- },
140
- policies: {
141
- execution_mode: "deterministic",
142
- status_prefixes: ["STATUS:", "DONE:", "BLOCKED:", "ERROR:"],
143
- notes: [
144
- "Read local `AGENTS.md` first, then consult parent knowledge-base `../../AGENTS.md` and `../../home.md` before considering raw-source fallback.",
145
- "Access hierarchy for this stage is: local interface artifacts -> parent knowledge-base artifacts -> raw source files only when needed.",
146
- "Treat the interface runtime in compile-plan.md as an initial hypothesis, not a final truth.",
147
- "Scan ALL knowledge-base summaries frontmatter before making any selection.",
148
- "Review abstracts for the candidate set, expand through linked summaries when needed, and stop only when the retrieved set is coverage-complete for this interface.",
149
- "Selection quality is judged by the proof of reviewed, retrieved, and excluded files, not by superficial brevity.",
150
- "If you need raw-file fallback, inspect `../../.interf/source-access.json` first and verify one suggested path is readable. These are canonical absolute source-file paths shared by the parent knowledge base. If they are not reachable, continue from knowledge-base summaries and report that raw fallback was unavailable.",
151
- ...getWorkflowStagePolicyNotes("interface", workflowId, stageId, sourcePath, interfacePath),
152
- ...localSkills.notes,
153
- ],
154
- evidence_weighting: {
155
- required_fields: ["source_kind", "evidence_tier", "truth_mode", "state"],
156
- preserve_tiers: true,
157
- },
158
- working_set: {
159
- target_context_fraction: 0.15,
160
- strategy: "Frontmatter scan first, then abstract review, then linked expansion only where coverage proof requires it.",
161
- },
162
- },
163
- };
164
- }
165
- export function buildInterfaceAnalyzeContract(interfacePath, workflowId, analyzeCount, instructions, stageId = "analyze", stageSkillDir = "analyze") {
166
- const connectedKnowledgeBasePath = resolveInterfaceKnowledgeBasePath(interfacePath);
167
- const sourcePath = connectedKnowledgeBasePath ? resolveKnowledgeBaseSourcePath(connectedKnowledgeBasePath) : undefined;
168
- const acceptance = resolveStageAcceptance("interface", workflowId, stageId, sourcePath, interfacePath);
169
- const localSkills = mergeLocalSkillContractExtensions([
170
- connectedKnowledgeBasePath
171
- ? buildLocalSkillContractExtensionRelativeTo(connectedKnowledgeBasePath, interfacePath, [workflowQueryDirectory()], "Use the connected knowledge-base workflow docs as higher-level knowledge-base guidance before applying interface-local analyze rules.")
172
- : emptyLocalSkillContractExtension(),
173
- buildLocalSkillContractExtension(interfacePath, [workflowCompileStageDirectory(stageSkillDir)], "Use interface-local docs to refine the interface ontology, extraction schema, and evidence grouping."),
174
- ]);
175
- return {
176
- instructions,
177
- counts: {
178
- relevant_total: analyzeCount,
179
- local_skill_docs: localSkills.count,
180
- },
181
- ...(acceptance ? { acceptance } : {}),
182
- artifacts: {
183
- reads: [
184
- "AGENTS.md",
185
- "home.md",
186
- "../../AGENTS.md",
187
- "../../home.md",
188
- "interf.json",
189
- "compile-plan.md",
190
- ".interf/relevant.json",
191
- "../../.interf/source-access.json",
192
- "../../summaries/",
193
- ".interf/state.json",
194
- ...localSkills.reads,
195
- ],
196
- writes: [
197
- ".interf/analysis.json",
198
- ".interf/state.json",
199
- ".interf/health.json",
200
- ],
201
- verifies: [],
202
- },
203
- policies: {
204
- execution_mode: "deterministic",
205
- status_prefixes: ["STATUS:", "DONE:", "BLOCKED:", "ERROR:"],
206
- notes: [
207
- "Read local `AGENTS.md` first, then consult parent knowledge-base `../../AGENTS.md` and `../../home.md` before considering raw-source fallback.",
208
- "Access hierarchy for this stage is: local interface artifacts -> parent knowledge-base artifacts -> raw source files only when needed.",
209
- "This is the deep extraction pass over the relevant set selected by retrieve.",
210
- "Refine the interface runtime from evidence when the knowledge base clearly demands it.",
211
- "Keep extraction local to the interface ontology and output goals.",
212
- "If you need raw-file fallback, inspect `../../.interf/source-access.json` first and verify one suggested path is readable. These are canonical absolute source-file paths shared by the parent knowledge base. If they are not reachable, continue from knowledge-base summaries and report that raw fallback was unavailable.",
213
- ...getWorkflowStagePolicyNotes("interface", workflowId, stageId, sourcePath, interfacePath),
214
- ...localSkills.notes,
215
- ],
216
- evidence_weighting: {
217
- required_fields: ["source_kind", "evidence_tier", "truth_mode", "state"],
218
- preserve_tiers: true,
219
- },
220
- working_set: {
221
- target_context_fraction: 0.3,
222
- strategy: "Batch relevant summaries into bounded sets, derive local entities/claims, then merge before writing analysis artifacts.",
223
- },
224
- },
225
- };
32
+ buildLocalSkillContractExtension(interfacePath, [workflowCreateDirectory()], "Use the interface workflow's local create docs as scaffolding heuristics only if they materially improve the interface setup."),
33
+ ]));
226
34
  }
227
- export function buildInterfaceCompileContract(interfacePath, workflowId, relevantCount, instructions, stageId = "compile", stageSkillDir = "compile") {
228
- const connectedKnowledgeBasePath = resolveInterfaceKnowledgeBasePath(interfacePath);
229
- const sourcePath = connectedKnowledgeBasePath ? resolveKnowledgeBaseSourcePath(connectedKnowledgeBasePath) : undefined;
230
- const acceptance = resolveStageAcceptance("interface", workflowId, stageId, sourcePath, interfacePath);
231
- const localSkills = mergeLocalSkillContractExtensions([
35
+ function buildInterfaceStageInstructions(contractType, interfacePath, connectedKnowledgeBasePath, stageSkillDir, parentPurpose, localPurpose) {
36
+ return buildStageInstructions(bundledSkillForContractType(contractType), mergeLocalSkillContractExtensions([
232
37
  connectedKnowledgeBasePath
233
- ? buildLocalSkillContractExtensionRelativeTo(connectedKnowledgeBasePath, interfacePath, [workflowQueryDirectory()], "Use the connected knowledge-base workflow docs as higher-level knowledge-base guidance before applying interface-local compile rules.")
38
+ ? buildLocalSkillContractExtensionRelativeTo(connectedKnowledgeBasePath, interfacePath, [], parentPurpose)
234
39
  : emptyLocalSkillContractExtension(),
235
- buildLocalSkillContractExtension(interfacePath, [workflowCompileStageDirectory(stageSkillDir)], "Use interface-local docs to refine the output inventory, navigation, canvases, and final interface shape."),
236
- ]);
237
- return {
238
- instructions,
239
- counts: {
240
- relevant_total: relevantCount,
241
- local_skill_docs: localSkills.count,
242
- },
243
- ...(acceptance ? { acceptance } : {}),
244
- artifacts: {
245
- reads: [
246
- "AGENTS.md",
247
- "home.md",
248
- "../../AGENTS.md",
249
- "../../home.md",
250
- "interf.json",
251
- "compile-plan.md",
252
- ".interf/analysis.json",
253
- ".interf/relevant.json",
254
- "../../.interf/source-access.json",
255
- "../../summaries/",
256
- ...localSkills.reads,
257
- ],
258
- writes: [
259
- "knowledge/",
260
- "briefs/",
261
- "summaries/",
262
- "home.md",
263
- ".interf/state.json",
264
- ".interf/health.json",
265
- ],
266
- verifies: [],
267
- },
268
- policies: {
269
- execution_mode: "deterministic",
270
- status_prefixes: ["STATUS:", "DONE:", "BLOCKED:", "ERROR:"],
271
- notes: [
272
- "Read local `AGENTS.md` first, then consult parent knowledge-base `../../AGENTS.md` and `../../home.md` before considering raw-source fallback.",
273
- "Access hierarchy for this stage is: local interface artifacts -> parent knowledge-base artifacts -> raw source files only when needed.",
274
- "The interface is a local context shell for agents. Build it so an agent can navigate AGENTS.md -> home.md -> local knowledge/briefs/summaries -> knowledge-base summaries -> raw only when needed.",
275
- "When local outputs cite knowledge-base evidence, point to the parent knowledge-base summary path `../../summaries/...`, not the interface-local `summaries/` folder.",
276
- "Prefer durable local notes and indexes over monolithic summaries.",
277
- "Delete stale analysis handoff artifacts once durable outputs and state have been written.",
278
- "If you need raw-file fallback, inspect `../../.interf/source-access.json` first and verify one suggested path is readable. These are canonical absolute source-file paths shared by the parent knowledge base. If they are not reachable, continue from knowledge-base summaries and report that raw fallback was unavailable.",
279
- ...getWorkflowStagePolicyNotes("interface", workflowId, stageId, sourcePath, interfacePath),
280
- ...localSkills.notes,
281
- ],
282
- evidence_weighting: {
283
- required_fields: ["source_kind", "evidence_tier", "truth_mode", "state"],
284
- preserve_tiers: true,
285
- },
286
- working_set: {
287
- target_context_fraction: 0.25,
288
- strategy: "Use analysis artifacts as the compile ledger, then write entities, claims, briefs, and navigation in separate local passes.",
289
- },
290
- },
291
- };
40
+ buildLocalSkillContractExtension(interfacePath, [workflowCompileStageDirectory(stageSkillDir)], localPurpose),
41
+ ]));
292
42
  }
293
43
  // ---------------------------------------------------------------------------
294
44
  // Interface orchestration functions
295
45
  // ---------------------------------------------------------------------------
296
46
  export async function planInterface(options) {
297
47
  const connectedKnowledgeBasePath = resolveInterfaceKnowledgeBasePath(options.knowledgeBasePath);
48
+ writeInterfaceCompilePlanTemplate(options.knowledgeBasePath, {
49
+ workflowId: options.workflow,
50
+ sourcePath: connectedKnowledgeBasePath ? resolveKnowledgeBaseSourcePath(connectedKnowledgeBasePath) : undefined,
51
+ interfaceName: options.name,
52
+ useCase: options.useCase.trim(),
53
+ targetQuestions: options.targetQuestions,
54
+ });
298
55
  const interfaceWorkflow = resolveInterfaceWorkflowFromConfig(readInterfConfig(options.knowledgeBasePath));
299
- const instructions = buildStageInstructions("interface/create", mergeLocalSkillContractExtensions([
300
- connectedKnowledgeBasePath
301
- ? buildLocalSkillContractExtensionRelativeTo(connectedKnowledgeBasePath, options.knowledgeBasePath, [workflowQueryDirectory()], "Use the connected knowledge-base workflow docs as higher-level guidance only if they materially improve the interface scaffold.")
302
- : emptyLocalSkillContractExtension(),
303
- buildLocalSkillContractExtension(options.knowledgeBasePath, [workflowCreateDirectory()], "Use the interface workflow's local create docs as scaffolding heuristics only if they materially improve the interface setup."),
304
- ]));
56
+ const instructions = buildInterfaceCreateInstructions(options.knowledgeBasePath, connectedKnowledgeBasePath);
305
57
  const code = await runExecutorStage({
306
58
  executor: options.executor,
307
59
  knowledgeBasePath: options.knowledgeBasePath,
@@ -319,19 +71,22 @@ export async function planInterface(options) {
319
71
  useCase: options.useCase,
320
72
  knowledgeBaseName: options.knowledgeBaseName,
321
73
  knowledgeBasePath: options.knowledgeBasePath,
74
+ targetQuestions: options.targetQuestions,
322
75
  instructions,
323
76
  }),
324
77
  buildPrompt: (contractPath) => buildStagePrompt(instructions, contractPath, [
325
- "Emit exactly one startup line: STATUS: loaded interface creation contract.",
326
- "Emit STATUS: analyzed knowledge-base when the scaffold inputs and knowledge-base evidence have been reviewed.",
327
- "Emit STATUS: wrote compile plan after interf.json and compile-plan.md are updated and AGENTS.md still preserves the scaffold router/checklist.",
328
- "Emit DONE: interface create complete when the scaffold is ready for `interf compile`.",
78
+ "Emit exactly one startup line, verbatim and on its own line: STATUS: loaded interface creation contract.",
79
+ "After the scaffold inputs and knowledge-base evidence have been reviewed, emit this canonical line verbatim and on its own line: STATUS: analyzed knowledge-base.",
80
+ "Do not inspect raw source files or run chart extraction in this stage. Encode future raw/chart work in compile-plan.md instead.",
81
+ "After compile-plan.md is updated and the scaffold still validates, emit this canonical line verbatim and on its own line: STATUS: wrote compile plan. interf.json and AGENTS.md may remain unchanged when the scaffold is already correct.",
82
+ "When the scaffold is ready for `interf compile`, stop. You may emit `DONE: interface create complete.` as a final progress line, but the CLI validates completion from the scaffold files instead of trusting that line.",
83
+ "You may emit additional STATUS lines, but the three canonical STATUS lines above are mandatory and must not be paraphrased.",
329
84
  ]),
85
+ completionCheck: () => validateInterfacePlanForUseCase(options.knowledgeBasePath, options.useCase).ok,
330
86
  });
331
87
  syncClaudeBootstrap(options.knowledgeBasePath);
332
- const validation = validateInterfacePlan(options.knowledgeBasePath);
333
- const emittedDone = runtimeRunStdoutContains(options.knowledgeBasePath, "DONE: interface create complete");
334
- if (validation.ok && (code === 0 || emittedDone)) {
88
+ const validation = validateInterfacePlanForUseCase(options.knowledgeBasePath, options.useCase);
89
+ if (validation.ok) {
335
90
  if (code !== 0) {
336
91
  markRuntimeRunSucceededAfterValidation(options.knowledgeBasePath, "create-interface completed successfully.");
337
92
  }
@@ -355,63 +110,56 @@ export async function runInterfaceRetrieve(options) {
355
110
  const sourcePath = options.sourcePath ?? context.sourcePath ?? resolveKnowledgeBaseSourcePath(resolveInterfaceKnowledgeBasePath(options.knowledgeBasePath) ?? options.knowledgeBasePath);
356
111
  const workflowId = context.workflowId;
357
112
  const connectedKnowledgeBasePath = context.connectedKnowledgeBasePath;
358
- const stageDefinition = options.stageDefinition ?? interfaceExecutionStages(workflowId, options.knowledgeBasePath).find((stage) => stage.contractType === "interface-retrieval");
113
+ const stageDefinition = options.stageDefinition ?? findStageByContractType(interfaceExecutionStages(workflowId, options.knowledgeBasePath), "interface-retrieval");
359
114
  const stageStatusLabel = stageDefinition.label.toLowerCase();
360
115
  const knowledgeBaseSummaryTotal = connectedKnowledgeBasePath ? countFilesRecursive(join(connectedKnowledgeBasePath, "summaries")) : 0;
361
116
  if (options.reportStep !== false) {
362
117
  reportLine(options.reporter, formatInterfaceWorkflowStageStep(workflowId, stageDefinition.id, { sourcePath }));
363
118
  }
364
- const instructions = buildStageInstructions(bundledSkillForContractType(stageDefinition.contractType), mergeLocalSkillContractExtensions([
365
- connectedKnowledgeBasePath
366
- ? buildLocalSkillContractExtensionRelativeTo(connectedKnowledgeBasePath, options.knowledgeBasePath, [workflowQueryDirectory()], "Use the connected knowledge-base workflow docs as higher-level knowledge-base guidance before applying interface-local retrieve rules.")
367
- : emptyLocalSkillContractExtension(),
368
- buildLocalSkillContractExtension(options.knowledgeBasePath, [workflowCompileStageDirectory(stageDefinition.skillDir)], "Use interface-local docs to refine filters, expansion heuristics, ranking, and ontology hints."),
369
- ]));
370
- const code = await runExecutorStage({
119
+ const instructions = buildInterfaceStageInstructions(stageDefinition.contractType, options.knowledgeBasePath, connectedKnowledgeBasePath, stageDefinition.skillDir, "Use the connected knowledge-base workflow README as high-level knowledge-base context before applying interface-local retrieve rules.", "Use interface-local docs to refine filters, expansion heuristics, ranking, and ontology hints.");
120
+ const stageResult = await executeValidatedStage({
371
121
  executor: options.executor,
372
- knowledgeBasePath: options.knowledgeBasePath,
122
+ workspacePath: options.knowledgeBasePath,
373
123
  targetType: "interface",
374
- knowledgeBaseName: context.knowledgeBaseName,
124
+ targetName: context.knowledgeBaseName,
375
125
  workflow: workflowId,
376
126
  workflowSourcePath: sourcePath,
377
- stage: stageDefinition.id,
378
- stageLabel: stageDefinition.label,
379
- contractType: stageDefinition.contractType,
127
+ stageDefinition,
128
+ instructions,
380
129
  summary: `Preparing ${stageDefinition.label.toLowerCase()} across ${knowledgeBaseSummaryTotal} knowledge-base summaries.`,
381
130
  contract: buildInterfaceRetrieveContract(options.knowledgeBasePath, workflowId, knowledgeBaseSummaryTotal, instructions, stageDefinition.id, stageDefinition.skillDir),
382
- buildPrompt: (contractPath) => buildStagePrompt(instructions, contractPath, [
131
+ statusLines: [
383
132
  `Emit exactly one startup line: STATUS: loaded ${stageStatusLabel} plan ${knowledgeBaseSummaryTotal} summary files.`,
384
133
  `Emit STATUS: scanned X/${knowledgeBaseSummaryTotal} after each scan batch or every 250 files, whichever comes first.`,
385
134
  "Emit STATUS: reviewed A abstracts, P expansion passes after the candidate-review phase is complete.",
386
135
  "Emit STATUS: selected R relevant, J rejected, D delta after filters are applied and the retrieved set is finalized.",
387
- `Emit DONE: ${stageStatusLabel} complete when \`.interf/relevant.json\`, \`.interf/coverage.json\`, and \`.interf/state.json\` are updated.`,
388
- ]),
136
+ "If the retrieved set is final, write `.interf/relevant.json` and `.interf/coverage.json` immediately, then emit the DONE line and stop.",
137
+ `Emit DONE: ${stageStatusLabel} complete when \`.interf/relevant.json\` and \`.interf/coverage.json\` are updated.`,
138
+ ],
139
+ reporter: options.reporter,
389
140
  completionCheck: () => isRetrieveStageComplete(options.knowledgeBasePath) &&
390
141
  validateStageContractAcceptance(options.knowledgeBasePath).ok,
142
+ reconcile: () => reconcileInterfaceRetrieveRun(options.knowledgeBasePath),
143
+ refreshArtifacts: () => refreshInterfaceArtifacts(options.knowledgeBasePath, { ensureViewSpec: true }),
144
+ validate: () => validateInterfaceRetrieve(options.knowledgeBasePath),
391
145
  });
392
- if (code !== 0) {
146
+ if (!stageResult.ok) {
393
147
  return {
394
148
  ok: false,
395
- code,
149
+ code: stageResult.code,
396
150
  knowledgeBaseSummaryTotal,
397
151
  relevantCount: 0,
398
152
  deltaCount: 0,
399
153
  analyzeCount: 0,
400
154
  };
401
155
  }
402
- refreshInterfaceArtifacts(options.knowledgeBasePath, { ensureViewSpec: true });
403
- const validation = validateStageOutcome(options.knowledgeBasePath, validateInterfaceRetrieve(options.knowledgeBasePath));
404
- if (!validation.ok) {
405
- reportValidationFailure(options.reporter, validation.summary);
406
- markRuntimeRunFailedAfterValidation(options.knowledgeBasePath, validation.summary);
407
- }
408
156
  const queryState = loadState(options.knowledgeBasePath);
409
157
  const relevantCount = queryState?.relevant_count ?? 0;
410
158
  const deltaCount = queryState?.delta_count ?? relevantCount;
411
159
  const analyzeCount = deltaCount > 0 ? deltaCount : relevantCount;
412
160
  return {
413
- ok: validation.ok,
414
- code: validation.ok ? 0 : 1,
161
+ ok: true,
162
+ code: 0,
415
163
  knowledgeBaseSummaryTotal,
416
164
  relevantCount,
417
165
  deltaCount,
@@ -424,7 +172,7 @@ export async function runInterfaceAnalyze(options) {
424
172
  const workflowId = resolveInterfaceWorkflowFromConfig(interfaceConfig);
425
173
  const connectedKnowledgeBasePath = resolveInterfaceKnowledgeBasePath(options.knowledgeBasePath);
426
174
  const sourcePath = options.sourcePath ?? (connectedKnowledgeBasePath ? resolveKnowledgeBaseSourcePath(connectedKnowledgeBasePath) : options.knowledgeBasePath);
427
- const stageDefinition = options.stageDefinition ?? interfaceExecutionStages(workflowId, options.knowledgeBasePath).find((stage) => stage.contractType === "interface-analysis");
175
+ const stageDefinition = options.stageDefinition ?? findStageByContractType(interfaceExecutionStages(workflowId, options.knowledgeBasePath), "interface-analysis");
428
176
  const stageStatusLabel = stageDefinition.label.toLowerCase();
429
177
  const queryState = loadState(options.knowledgeBasePath);
430
178
  const relevantCount = queryState?.relevant_count ?? 0;
@@ -434,50 +182,44 @@ export async function runInterfaceAnalyze(options) {
434
182
  reportBlankLine(options.reporter);
435
183
  reportLine(options.reporter, `${formatInterfaceWorkflowStageStep(workflowId, stageDefinition.id, { sourcePath })}${analyzeCount > 0 ? ` (${analyzeCount} files)` : ""}`);
436
184
  }
437
- const instructions = buildStageInstructions(bundledSkillForContractType(stageDefinition.contractType), mergeLocalSkillContractExtensions([
438
- connectedKnowledgeBasePath
439
- ? buildLocalSkillContractExtensionRelativeTo(connectedKnowledgeBasePath, options.knowledgeBasePath, [workflowQueryDirectory()], "Use the connected knowledge-base workflow docs as higher-level knowledge-base guidance before applying interface-local analyze rules.")
440
- : emptyLocalSkillContractExtension(),
441
- buildLocalSkillContractExtension(options.knowledgeBasePath, [workflowCompileStageDirectory(stageDefinition.skillDir)], "Use interface-local docs to refine the interface ontology, extraction schema, and evidence grouping."),
442
- ]));
443
- const code = await runExecutorStage({
185
+ const instructions = buildInterfaceStageInstructions(stageDefinition.contractType, options.knowledgeBasePath, connectedKnowledgeBasePath, stageDefinition.skillDir, "Use the connected knowledge-base workflow README as high-level knowledge-base context before applying interface-local analyze rules.", "Use interface-local docs to refine the interface ontology, extraction schema, and evidence grouping.");
186
+ const stageResult = await executeValidatedStage({
444
187
  executor: options.executor,
445
- knowledgeBasePath: options.knowledgeBasePath,
188
+ workspacePath: options.knowledgeBasePath,
446
189
  targetType: "interface",
447
- knowledgeBaseName,
190
+ targetName: knowledgeBaseName,
448
191
  workflow: workflowId,
449
192
  workflowSourcePath: sourcePath,
450
- stage: stageDefinition.id,
451
- stageLabel: stageDefinition.label,
452
- contractType: stageDefinition.contractType,
193
+ stageDefinition,
194
+ instructions,
453
195
  summary: `Preparing ${stageDefinition.label.toLowerCase()} for ${analyzeCount} interface summaries.`,
454
196
  contract: buildInterfaceAnalyzeContract(options.knowledgeBasePath, workflowId, analyzeCount, instructions, stageDefinition.id, stageDefinition.skillDir),
455
- buildPrompt: (contractPath) => buildStagePrompt(instructions, contractPath, [
197
+ statusLines: [
456
198
  `Emit exactly one startup line: STATUS: loaded ${stageStatusLabel} plan ${analyzeCount} files.`,
199
+ "Emit STATUS: inspecting <current subtask> before each new raw page group, market batch, chart family, or extraction method.",
200
+ "During long-running raw/PDF/chart extraction, do not stay silent for more than about one minute. Emit another STATUS: inspecting <current subtask> line before continuing.",
457
201
  `Emit STATUS: analyzed X/${analyzeCount} after each batch or every 25 files, whichever comes first.`,
202
+ `If the target ledger is narrower than the file count, still emit visible STATUS lines as each target batch is classified. Do not wait for the final analyzed X/${analyzeCount} milestone before reporting progress.`,
458
203
  `Emit STATUS: wrote ${stageStatusLabel} outputs after \`.interf/analysis.json\` is updated.`,
459
- `Emit DONE: ${stageStatusLabel} complete when state reflects the finished extraction pass.`,
460
- ]),
204
+ `Emit DONE: ${stageStatusLabel} complete when \`.interf/analysis.json\` reflects the finished extraction pass.`,
205
+ ],
206
+ reporter: options.reporter,
461
207
  completionCheck: () => {
462
208
  const state = loadState(options.knowledgeBasePath);
463
209
  return Boolean(state?.analyze_complete &&
464
210
  existsSync(join(options.knowledgeBasePath, ".interf", "analysis.json")) &&
465
211
  validateStageContractAcceptance(options.knowledgeBasePath).ok);
466
212
  },
213
+ reconcile: () => reconcileInterfaceAnalyzeRun(options.knowledgeBasePath),
214
+ refreshArtifacts: () => refreshInterfaceArtifacts(options.knowledgeBasePath, { ensureViewSpec: true }),
215
+ validate: () => ({
216
+ ok: true,
217
+ summary: "Interface analyze verified.",
218
+ }),
467
219
  });
468
- if (code === 0) {
469
- refreshInterfaceArtifacts(options.knowledgeBasePath, { ensureViewSpec: true });
470
- }
471
- const acceptance = code === 0
472
- ? validateStageContractAcceptance(options.knowledgeBasePath)
473
- : { ok: false, summary: "Stage execution failed before acceptance validation." };
474
- if (code === 0 && !acceptance.ok) {
475
- reportValidationFailure(options.reporter, acceptance.summary);
476
- markRuntimeRunFailedAfterValidation(options.knowledgeBasePath, acceptance.summary);
477
- }
478
220
  return {
479
- ok: code === 0 && acceptance.ok,
480
- code: code === 0 && acceptance.ok ? 0 : 1,
221
+ ok: stageResult.ok,
222
+ code: stageResult.code,
481
223
  relevantCount,
482
224
  deltaCount,
483
225
  analyzeCount,
@@ -489,54 +231,64 @@ export async function runInterfaceCompileStage(options) {
489
231
  const workflowId = resolveInterfaceWorkflowFromConfig(interfaceConfig);
490
232
  const connectedKnowledgeBasePath = resolveInterfaceKnowledgeBasePath(options.knowledgeBasePath);
491
233
  const sourcePath = options.sourcePath ?? (connectedKnowledgeBasePath ? resolveKnowledgeBaseSourcePath(connectedKnowledgeBasePath) : options.knowledgeBasePath);
492
- const stageDefinition = options.stageDefinition ?? interfaceExecutionStages(workflowId, options.knowledgeBasePath).find((stage) => stage.contractType === "interface-output");
234
+ const stageDefinition = options.stageDefinition ?? findStageByContractType(interfaceExecutionStages(workflowId, options.knowledgeBasePath), "interface-output");
493
235
  const stageStatusLabel = stageDefinition.label.toLowerCase();
494
236
  const relevantCount = loadState(options.knowledgeBasePath)?.relevant_count ?? 0;
495
237
  if (options.reportStep !== false) {
496
238
  reportBlankLine(options.reporter);
497
239
  reportLine(options.reporter, formatInterfaceWorkflowStageStep(workflowId, stageDefinition.id, { sourcePath }));
498
240
  }
499
- const instructions = buildStageInstructions(bundledSkillForContractType(stageDefinition.contractType), mergeLocalSkillContractExtensions([
500
- connectedKnowledgeBasePath
501
- ? buildLocalSkillContractExtensionRelativeTo(connectedKnowledgeBasePath, options.knowledgeBasePath, [workflowQueryDirectory()], "Use the connected knowledge-base workflow docs as higher-level knowledge-base guidance before applying interface-local compile rules.")
502
- : emptyLocalSkillContractExtension(),
503
- buildLocalSkillContractExtension(options.knowledgeBasePath, [workflowCompileStageDirectory(stageDefinition.skillDir)], "Use interface-local docs to refine the output inventory, navigation, canvases, and final interface shape."),
504
- ]));
505
- const code = await runExecutorStage({
241
+ const instructions = buildInterfaceStageInstructions(stageDefinition.contractType, options.knowledgeBasePath, connectedKnowledgeBasePath, stageDefinition.skillDir, "Use the connected knowledge-base workflow README as high-level knowledge-base context before applying interface-local compile rules.", "Use interface-local docs to refine the output inventory, navigation, canvases, and final interface shape.");
242
+ const stageResult = await executeValidatedStage({
506
243
  executor: options.executor,
507
- knowledgeBasePath: options.knowledgeBasePath,
244
+ workspacePath: options.knowledgeBasePath,
508
245
  targetType: "interface",
509
- knowledgeBaseName,
246
+ targetName: knowledgeBaseName,
510
247
  workflow: workflowId,
511
248
  workflowSourcePath: sourcePath,
512
- stage: stageDefinition.id,
513
- stageLabel: stageDefinition.label,
514
- contractType: stageDefinition.contractType,
249
+ stageDefinition,
250
+ instructions,
515
251
  summary: `Preparing ${stageDefinition.label.toLowerCase()} from ${relevantCount} relevant files.`,
516
252
  contract: buildInterfaceCompileContract(options.knowledgeBasePath, workflowId, relevantCount, instructions, stageDefinition.id, stageDefinition.skillDir),
517
- buildPrompt: (contractPath) => buildStagePrompt(instructions, contractPath, [
253
+ statusLines: [
518
254
  `Emit exactly one startup line: STATUS: loaded ${stageStatusLabel} plan ${relevantCount} relevant files.`,
519
255
  "Emit STATUS: wrote entities X after the entity pass completes.",
520
256
  "Emit STATUS: wrote claims Y after the claim pass completes.",
521
257
  `Emit STATUS: wrote ${stageStatusLabel} outputs after local notes and home.md are updated.`,
522
- `Emit DONE: ${stageStatusLabel} complete when state is updated and temporary analysis artifacts are cleaned up.`,
523
- ]),
524
- completionCheck: () => computeInterfaceHealth(options.knowledgeBasePath).status === "compiled" &&
525
- validateStageContractAcceptance(options.knowledgeBasePath).ok,
258
+ `Emit DONE: ${stageStatusLabel} complete when the required outputs are on disk and temporary analysis artifacts are cleaned up.`,
259
+ ],
260
+ reporter: options.reporter,
261
+ completionCheck: () => {
262
+ const state = loadState(options.knowledgeBasePath);
263
+ const health = computeInterfaceHealth(options.knowledgeBasePath);
264
+ return Boolean(state?.compile_complete &&
265
+ typeof state.last_compile === "string" &&
266
+ health.checks.home_present &&
267
+ health.checks.outputs_present &&
268
+ !health.checks.analysis_pending &&
269
+ validateStageContractAcceptance(options.knowledgeBasePath).ok);
270
+ },
271
+ reconcile: () => reconcileInterfaceCompileRun(options.knowledgeBasePath),
272
+ refreshArtifacts: () => refreshInterfaceArtifacts(options.knowledgeBasePath, { ensureViewSpec: true }),
273
+ validate: () => {
274
+ const state = loadState(options.knowledgeBasePath);
275
+ const health = computeInterfaceHealth(options.knowledgeBasePath);
276
+ const ok = Boolean(state?.compile_complete &&
277
+ typeof state.last_compile === "string" &&
278
+ health.checks.home_present &&
279
+ health.checks.outputs_present &&
280
+ !health.checks.analysis_pending);
281
+ return {
282
+ ok,
283
+ summary: ok
284
+ ? "Interface compile verified."
285
+ : `Interface compile failed — health is ${health.status}/${health.stage}.`,
286
+ };
287
+ },
526
288
  });
527
- if (code === 0) {
528
- refreshInterfaceArtifacts(options.knowledgeBasePath, { ensureViewSpec: true });
529
- }
530
- const acceptance = code === 0
531
- ? validateStageContractAcceptance(options.knowledgeBasePath)
532
- : { ok: false, summary: "Stage execution failed before acceptance validation." };
533
- if (code === 0 && !acceptance.ok) {
534
- reportValidationFailure(options.reporter, acceptance.summary);
535
- markRuntimeRunFailedAfterValidation(options.knowledgeBasePath, acceptance.summary);
536
- }
537
289
  return {
538
- ok: code === 0 && acceptance.ok,
539
- code: code === 0 && acceptance.ok ? 0 : 1,
290
+ ok: stageResult.ok,
291
+ code: stageResult.code,
540
292
  relevantCount,
541
293
  };
542
294
  }