@interf/compiler 0.4.1 → 0.5.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 (162) hide show
  1. package/README.md +70 -66
  2. package/builtin-workflows/interf/README.md +6 -6
  3. package/builtin-workflows/interf/compile/stages/shape/SKILL.md +7 -7
  4. package/builtin-workflows/interf/compile/stages/structure/SKILL.md +2 -2
  5. package/builtin-workflows/interf/compile/stages/summarize/SKILL.md +1 -1
  6. package/builtin-workflows/interf/{workspace.schema.json → compiled.schema.json} +5 -5
  7. package/builtin-workflows/interf/improve/SKILL.md +3 -3
  8. package/builtin-workflows/interf/use/query/SKILL.md +2 -2
  9. package/builtin-workflows/interf/workflow.json +42 -31
  10. package/dist/commands/check-draft.d.ts +19 -0
  11. package/dist/commands/check-draft.js +110 -0
  12. package/dist/commands/compile-controller.d.ts +4 -4
  13. package/dist/commands/compile-controller.js +117 -81
  14. package/dist/commands/compile.d.ts +5 -5
  15. package/dist/commands/compile.js +61 -62
  16. package/dist/commands/compiled-flow.d.ts +23 -0
  17. package/dist/commands/compiled-flow.js +112 -0
  18. package/dist/commands/create-workflow-wizard.d.ts +3 -3
  19. package/dist/commands/create-workflow-wizard.js +11 -11
  20. package/dist/commands/create.d.ts +2 -2
  21. package/dist/commands/create.js +50 -57
  22. package/dist/commands/default.js +2 -2
  23. package/dist/commands/executor-flow.d.ts +20 -1
  24. package/dist/commands/executor-flow.js +67 -7
  25. package/dist/commands/init.js +242 -289
  26. package/dist/commands/list.js +14 -10
  27. package/dist/commands/reset.js +6 -6
  28. package/dist/commands/source-config-wizard.d.ts +12 -8
  29. package/dist/commands/source-config-wizard.js +356 -119
  30. package/dist/commands/status.js +49 -26
  31. package/dist/commands/test-flow.d.ts +23 -10
  32. package/dist/commands/test-flow.js +274 -65
  33. package/dist/commands/test.d.ts +7 -1
  34. package/dist/commands/test.js +264 -65
  35. package/dist/commands/verify.js +23 -14
  36. package/dist/index.d.ts +7 -7
  37. package/dist/index.js +4 -4
  38. package/dist/lib/agent-args.js +2 -1
  39. package/dist/lib/agent-constants.js +1 -1
  40. package/dist/lib/agent-render.js +4 -4
  41. package/dist/lib/agent-shells.d.ts +8 -8
  42. package/dist/lib/agent-shells.js +231 -142
  43. package/dist/lib/{workflow-abi.d.ts → builtin-compiled-workflow.d.ts} +37 -46
  44. package/dist/lib/builtin-compiled-workflow.js +153 -0
  45. package/dist/lib/compiled-compile.d.ts +52 -0
  46. package/dist/lib/compiled-compile.js +274 -0
  47. package/dist/lib/compiled-home.d.ts +5 -0
  48. package/dist/lib/compiled-home.js +32 -0
  49. package/dist/lib/compiled-paths.d.ts +39 -0
  50. package/dist/lib/compiled-paths.js +103 -0
  51. package/dist/lib/{workspace-raw.d.ts → compiled-raw.d.ts} +9 -8
  52. package/dist/lib/{workspace-raw.js → compiled-raw.js} +16 -14
  53. package/dist/lib/compiled-reset.d.ts +1 -0
  54. package/dist/lib/compiled-reset.js +44 -0
  55. package/dist/lib/compiled-schema.d.ts +27 -0
  56. package/dist/lib/compiled-schema.js +110 -0
  57. package/dist/lib/config.d.ts +0 -1
  58. package/dist/lib/config.js +0 -1
  59. package/dist/lib/discovery.d.ts +1 -1
  60. package/dist/lib/discovery.js +3 -3
  61. package/dist/lib/interf-bootstrap.d.ts +1 -1
  62. package/dist/lib/interf-bootstrap.js +4 -4
  63. package/dist/lib/interf-detect.d.ts +9 -10
  64. package/dist/lib/interf-detect.js +70 -59
  65. package/dist/lib/interf-scaffold.d.ts +2 -2
  66. package/dist/lib/interf-scaffold.js +90 -57
  67. package/dist/lib/interf-workflow-package.d.ts +3 -3
  68. package/dist/lib/interf-workflow-package.js +30 -30
  69. package/dist/lib/interf.d.ts +5 -5
  70. package/dist/lib/interf.js +4 -4
  71. package/dist/lib/local-workflows.d.ts +4 -4
  72. package/dist/lib/local-workflows.js +35 -70
  73. package/dist/lib/obsidian.d.ts +1 -1
  74. package/dist/lib/parse.js +92 -1
  75. package/dist/lib/project-paths.d.ts +11 -0
  76. package/dist/lib/project-paths.js +32 -0
  77. package/dist/lib/runtime-acceptance.d.ts +7 -1
  78. package/dist/lib/runtime-acceptance.js +194 -59
  79. package/dist/lib/runtime-contracts.d.ts +2 -4
  80. package/dist/lib/runtime-contracts.js +17 -161
  81. package/dist/lib/runtime-inventory.d.ts +7 -0
  82. package/dist/lib/runtime-inventory.js +29 -0
  83. package/dist/lib/runtime-paths.js +5 -5
  84. package/dist/lib/runtime-prompt.js +7 -6
  85. package/dist/lib/runtime-reconcile.d.ts +2 -3
  86. package/dist/lib/runtime-reconcile.js +94 -184
  87. package/dist/lib/runtime-runs.js +25 -119
  88. package/dist/lib/runtime-types.d.ts +10 -19
  89. package/dist/lib/runtime.d.ts +2 -2
  90. package/dist/lib/runtime.js +1 -1
  91. package/dist/lib/schema.d.ts +169 -153
  92. package/dist/lib/schema.js +116 -164
  93. package/dist/lib/source-config.d.ts +24 -20
  94. package/dist/lib/source-config.js +159 -122
  95. package/dist/lib/state-artifacts.d.ts +5 -5
  96. package/dist/lib/state-artifacts.js +8 -8
  97. package/dist/lib/state-health.d.ts +4 -4
  98. package/dist/lib/state-health.js +110 -126
  99. package/dist/lib/state-io.d.ts +8 -8
  100. package/dist/lib/state-io.js +21 -102
  101. package/dist/lib/state-paths.js +5 -5
  102. package/dist/lib/state-view.d.ts +4 -4
  103. package/dist/lib/state-view.js +52 -55
  104. package/dist/lib/state.d.ts +5 -5
  105. package/dist/lib/state.js +4 -4
  106. package/dist/lib/summarize-plan.d.ts +3 -2
  107. package/dist/lib/summarize-plan.js +19 -21
  108. package/dist/lib/test-execution.js +9 -9
  109. package/dist/lib/test-matrices.d.ts +3 -3
  110. package/dist/lib/test-matrices.js +6 -6
  111. package/dist/lib/test-paths.d.ts +4 -4
  112. package/dist/lib/test-paths.js +26 -11
  113. package/dist/lib/test-sandbox.d.ts +1 -1
  114. package/dist/lib/test-sandbox.js +32 -38
  115. package/dist/lib/test-specs.js +1 -1
  116. package/dist/lib/test-targets.d.ts +2 -2
  117. package/dist/lib/test-targets.js +11 -11
  118. package/dist/lib/test-types.d.ts +1 -1
  119. package/dist/lib/test.d.ts +1 -1
  120. package/dist/lib/test.js +1 -1
  121. package/dist/lib/util.d.ts +2 -0
  122. package/dist/lib/util.js +14 -1
  123. package/dist/lib/validate-compiled.d.ts +27 -0
  124. package/dist/lib/validate-compiled.js +238 -0
  125. package/dist/lib/validate-helpers.d.ts +0 -8
  126. package/dist/lib/validate-helpers.js +0 -30
  127. package/dist/lib/validate.d.ts +6 -4
  128. package/dist/lib/validate.js +76 -27
  129. package/dist/lib/workflow-definitions.d.ts +12 -11
  130. package/dist/lib/workflow-definitions.js +45 -55
  131. package/dist/lib/workflow-helpers.d.ts +2 -3
  132. package/dist/lib/workflow-helpers.js +9 -13
  133. package/dist/lib/workflow-improvement.d.ts +3 -3
  134. package/dist/lib/workflow-improvement.js +48 -48
  135. package/dist/lib/workflow-primitives.d.ts +2 -0
  136. package/dist/lib/workflow-primitives.js +5 -0
  137. package/dist/lib/workflow-review-paths.d.ts +3 -3
  138. package/dist/lib/workflow-review-paths.js +11 -11
  139. package/dist/lib/workflow-stage-runner.d.ts +1 -1
  140. package/dist/lib/workflow-stage-runner.js +8 -8
  141. package/dist/lib/workflows.d.ts +9 -9
  142. package/dist/lib/workflows.js +15 -17
  143. package/package.json +13 -12
  144. package/dist/commands/workspace-flow.d.ts +0 -23
  145. package/dist/commands/workspace-flow.js +0 -109
  146. package/dist/lib/registry.d.ts +0 -16
  147. package/dist/lib/registry.js +0 -65
  148. package/dist/lib/validate-workspace.d.ts +0 -121
  149. package/dist/lib/validate-workspace.js +0 -407
  150. package/dist/lib/workflow-abi.js +0 -181
  151. package/dist/lib/workspace-compile.d.ts +0 -54
  152. package/dist/lib/workspace-compile.js +0 -476
  153. package/dist/lib/workspace-home.d.ts +0 -5
  154. package/dist/lib/workspace-home.js +0 -32
  155. package/dist/lib/workspace-layout.d.ts +0 -2
  156. package/dist/lib/workspace-layout.js +0 -60
  157. package/dist/lib/workspace-paths.d.ts +0 -41
  158. package/dist/lib/workspace-paths.js +0 -107
  159. package/dist/lib/workspace-reset.d.ts +0 -1
  160. package/dist/lib/workspace-reset.js +0 -43
  161. package/dist/lib/workspace-schema.d.ts +0 -17
  162. package/dist/lib/workspace-schema.js +0 -74
@@ -1,12 +1,13 @@
1
1
  import { existsSync, readFileSync, statSync, writeFileSync, } from "node:fs";
2
2
  import { join, relative } from "node:path";
3
- import { countFilesRecursive, listFilesRecursive } from "./filesystem.js";
4
- import { parseJsonFrontmatter, readJsonFileUnchecked } from "./parse.js";
3
+ import { listFilesRecursive } from "./filesystem.js";
4
+ import { compiledZoneAbsolutePath, findCompiledSchemaZone, readCompiledSchemaFile, } from "./compiled-schema.js";
5
+ import { parseJsonFrontmatter } from "./parse.js";
5
6
  import { loadRuntimeRun } from "./runtime.js";
6
- import { initWorkspaceState, loadState, refreshWorkspaceArtifacts, saveState, } from "./state.js";
7
- import { validateWorkspace, validateWorkspaceCompile, validateWorkspaceStructure, validateWorkspaceSummarize, } from "./validate.js";
8
- import { workspaceHomeIsShaped } from "./workspace-home.js";
9
- import { workspaceRuntimeRoot } from "./workspace-paths.js";
7
+ import { initCompiledState, loadState, refreshCompiledArtifacts, saveState, } from "./state.js";
8
+ import { compiledInventoryFromEntries } from "./runtime-inventory.js";
9
+ import { compiledRuntimeRoot } from "./compiled-paths.js";
10
+ import { extractSynthAbstract, isOutputMarkdownFile } from "./validate.js";
10
11
  function readActiveRunStartedAtMs(dirPath) {
11
12
  const run = loadRuntimeRun(dirPath);
12
13
  if (!run)
@@ -14,22 +15,18 @@ function readActiveRunStartedAtMs(dirPath) {
14
15
  const startedAtMs = Date.parse(run.started_at);
15
16
  return Number.isFinite(startedAtMs) ? startedAtMs : null;
16
17
  }
17
- function pathUpdatedSince(dirPath, relativePath, sinceMs) {
18
- const absolutePath = join(dirPath, relativePath);
18
+ function anyPathUpdatedSince(absolutePath, sinceMs) {
19
19
  if (!existsSync(absolutePath))
20
20
  return false;
21
21
  try {
22
- return statSync(absolutePath).mtimeMs >= sinceMs;
22
+ const stat = statSync(absolutePath);
23
+ if (stat.isFile())
24
+ return stat.mtimeMs >= sinceMs;
23
25
  }
24
26
  catch {
25
27
  return false;
26
28
  }
27
- }
28
- function anyFileUpdatedSince(dirPath, relativeDir, sinceMs) {
29
- const absoluteDir = join(dirPath, relativeDir);
30
- if (!existsSync(absoluteDir))
31
- return false;
32
- for (const filePath of listFilesRecursive(absoluteDir)) {
29
+ for (const filePath of listFilesRecursive(absolutePath)) {
33
30
  try {
34
31
  if (statSync(filePath).mtimeMs >= sinceMs)
35
32
  return true;
@@ -40,207 +37,120 @@ function anyFileUpdatedSince(dirPath, relativeDir, sinceMs) {
40
37
  }
41
38
  return false;
42
39
  }
43
- function readSummaryAbstract(content) {
40
+ function zoneArtifactCount(dirPath, zonePath, kind) {
41
+ const absolutePath = compiledZoneAbsolutePath(dirPath, { path: zonePath });
42
+ if (!existsSync(absolutePath))
43
+ return 0;
44
+ if (kind === "file")
45
+ return 1;
46
+ return listFilesRecursive(absolutePath).length;
47
+ }
48
+ function summaryAbstract(content) {
44
49
  const parsed = parseJsonFrontmatter(content);
45
50
  if (!parsed)
46
51
  return null;
47
- const frontmatterAbstract = typeof parsed.frontmatter.abstract === "string"
48
- ? parsed.frontmatter.abstract.trim()
49
- : "";
50
- if (frontmatterAbstract.length > 0)
51
- return frontmatterAbstract;
52
- const match = parsed.body.match(/^## Abstract\s+([\s\S]*?)(?:\n## |\n# |$)/m);
53
- const bodyAbstract = match?.[1]?.trim() ?? "";
54
- return bodyAbstract.length > 0 ? bodyAbstract : null;
55
- }
56
- function isWorkspaceInventoryEntry(entry) {
57
- return entry !== null;
52
+ return extractSynthAbstract(parsed.frontmatter, parsed.body);
58
53
  }
59
- function buildWorkspaceInventoryEntries(dirPath) {
60
- const summariesDir = join(dirPath, "summaries");
61
- if (!existsSync(summariesDir))
54
+ function buildStageInventoryEntries(dirPath, stage) {
55
+ const schema = readCompiledSchemaFile(join(dirPath, ".interf", "workflow"));
56
+ if (!schema)
62
57
  return [];
63
- return listFilesRecursive(summariesDir, (filePath) => filePath.endsWith(".md"))
58
+ const inputZone = stage.reads
59
+ .map((zoneId) => findCompiledSchemaZone(schema, zoneId))
60
+ .find((zone) => zone && zone.kind !== "runtime");
61
+ const outputZone = stage.writes
62
+ .map((zoneId) => findCompiledSchemaZone(schema, zoneId))
63
+ .find((zone) => zone && zone.kind !== "runtime");
64
+ if (!inputZone || !outputZone)
65
+ return [];
66
+ const outputRoot = compiledZoneAbsolutePath(dirPath, outputZone);
67
+ if (!existsSync(outputRoot))
68
+ return [];
69
+ return listFilesRecursive(outputRoot, isOutputMarkdownFile)
64
70
  .map((filePath) => {
65
- const relativeSummaryPath = relative(dirPath, filePath);
66
71
  const content = readFileSync(filePath, "utf8");
67
72
  const parsed = parseJsonFrontmatter(content);
68
73
  if (!parsed)
69
74
  return null;
70
- const source = typeof parsed.frontmatter.source === "string"
75
+ const inputPath = typeof parsed.frontmatter.source === "string"
71
76
  ? parsed.frontmatter.source.trim()
72
- : typeof parsed.frontmatter.source_file === "string"
73
- ? parsed.frontmatter.source_file.trim()
74
- : typeof parsed.frontmatter.raw === "string"
75
- ? parsed.frontmatter.raw.trim()
76
- : "";
77
- if (source.length === 0)
77
+ : "";
78
+ if (inputPath.length === 0)
78
79
  return null;
79
- const abstract = readSummaryAbstract(content);
80
+ const abstract = summaryAbstract(content);
80
81
  return {
81
- source,
82
- summary: relativeSummaryPath,
83
- source_kind: typeof parsed.frontmatter.source_kind === "string"
84
- ? parsed.frontmatter.source_kind
85
- : "unknown",
86
- evidence_tier: typeof parsed.frontmatter.evidence_tier === "string"
87
- ? parsed.frontmatter.evidence_tier
88
- : "primary",
89
- truth_mode: typeof parsed.frontmatter.truth_mode === "string"
90
- ? parsed.frontmatter.truth_mode
91
- : "reported-data",
82
+ input_zone: inputZone.id,
83
+ input_path: inputPath,
84
+ output_zone: outputZone.id,
85
+ output_path: relative(dirPath, filePath).replaceAll("\\", "/"),
92
86
  state: typeof parsed.frontmatter.state === "string"
93
87
  ? parsed.frontmatter.state
94
- : "summarized",
95
- status: "summarized",
96
- ...(abstract ? { abstract } : {}),
97
- frontmatter_scanned: true,
98
- abstract_read: Boolean(abstract),
88
+ : "complete",
89
+ metadata: {
90
+ source_kind: typeof parsed.frontmatter.source_kind === "string"
91
+ ? parsed.frontmatter.source_kind
92
+ : "unknown",
93
+ evidence_tier: typeof parsed.frontmatter.evidence_tier === "string"
94
+ ? parsed.frontmatter.evidence_tier
95
+ : "primary",
96
+ truth_mode: typeof parsed.frontmatter.truth_mode === "string"
97
+ ? parsed.frontmatter.truth_mode
98
+ : "reported-data",
99
+ abstract,
100
+ frontmatter_scanned: true,
101
+ abstract_read: Boolean(abstract),
102
+ },
99
103
  };
100
104
  })
101
- .filter(isWorkspaceInventoryEntry)
102
- .sort((left, right) => left.source.localeCompare(right.source));
103
- }
104
- function writeWorkspaceInventory(dirPath, entries) {
105
- writeFileSync(join(workspaceRuntimeRoot(dirPath), "inventory.json"), JSON.stringify({
106
- entries,
107
- total: entries.length,
108
- }, null, 2) + "\n");
105
+ .filter((entry) => entry !== null)
106
+ .sort((left, right) => left.input_path.localeCompare(right.input_path));
109
107
  }
110
- export function reconcileWorkspaceSummarizeRun(dirPath, expectedSummaryTotal) {
111
- const startedAtMs = readActiveRunStartedAtMs(dirPath);
112
- if (startedAtMs === null)
113
- return false;
114
- const plan = readJsonFileUnchecked(join(workspaceRuntimeRoot(dirPath), "summarize-targets.json"), "summarize plan");
115
- if (!plan || plan.targetCount === 0)
116
- return false;
117
- if (!plan.targets.every((target) => pathUpdatedSince(dirPath, target.output, startedAtMs))) {
118
- return false;
119
- }
120
- const summaryValidation = validateWorkspace(dirPath);
121
- const summaryCount = countFilesRecursive(join(dirPath, "summaries"));
122
- if (summaryCount < expectedSummaryTotal ||
123
- !summaryValidation.summary_frontmatter_valid ||
124
- !summaryValidation.abstracts_valid) {
125
- return false;
126
- }
127
- const inventoryEntries = buildWorkspaceInventoryEntries(dirPath);
128
- if (inventoryEntries.length < expectedSummaryTotal)
129
- return false;
130
- writeWorkspaceInventory(dirPath, inventoryEntries);
131
- const currentState = {
132
- ...initWorkspaceState(),
133
- ...(loadState(dirPath) ?? {}),
134
- };
135
- const nextState = {
136
- ...currentState,
137
- pending: [],
138
- summarized: inventoryEntries.length,
139
- structured: 0,
140
- shaped: 0,
141
- compiled: 0,
142
- last_summarize: new Date().toISOString(),
143
- last_structure: null,
144
- last_shape: null,
145
- last_compile: null,
146
- inventory_complete: true,
147
- abstracts_read: Math.max(currentState.abstracts_read ?? 0, inventoryEntries.length),
148
- full_reads: 0,
149
- entity_count: 0,
150
- claim_count: 0,
151
- };
152
- saveState(dirPath, nextState);
153
- refreshWorkspaceArtifacts(dirPath, { ensureViewSpec: true });
154
- return validateWorkspaceSummarize(dirPath).ok;
108
+ function writeStageInventory(dirPath, stageId, entries) {
109
+ writeFileSync(join(compiledRuntimeRoot(dirPath), "inventory.json"), JSON.stringify(compiledInventoryFromEntries(entries, stageId), null, 2) + "\n");
155
110
  }
156
- export function reconcileWorkspaceStructureRun(dirPath) {
157
- const startedAtMs = readActiveRunStartedAtMs(dirPath);
158
- if (startedAtMs === null)
159
- return false;
160
- if (!(anyFileUpdatedSince(dirPath, "knowledge/entities", startedAtMs) ||
161
- anyFileUpdatedSince(dirPath, "knowledge/claims", startedAtMs) ||
162
- anyFileUpdatedSince(dirPath, "knowledge/indexes", startedAtMs))) {
163
- return false;
164
- }
165
- const summaryCount = countFilesRecursive(join(dirPath, "summaries"));
166
- const inventoryEntries = buildWorkspaceInventoryEntries(dirPath);
167
- if (summaryCount > 0 && inventoryEntries.length < summaryCount) {
168
- return false;
169
- }
170
- if (inventoryEntries.length > 0) {
171
- writeWorkspaceInventory(dirPath, inventoryEntries);
172
- }
173
- const validation = validateWorkspaceStructure(dirPath);
174
- if (!validation.required || !validation.checks.outputs_present)
175
- return false;
176
- const currentState = {
177
- ...initWorkspaceState(),
178
- ...(loadState(dirPath) ?? {}),
179
- };
180
- const entityCount = countFilesRecursive(join(dirPath, "knowledge", "entities"));
181
- const claimCount = countFilesRecursive(join(dirPath, "knowledge", "claims"));
182
- const nextState = {
183
- ...currentState,
184
- summarized: summaryCount,
185
- structured: summaryCount,
186
- shaped: 0,
187
- compiled: 0,
188
- inventory_complete: true,
189
- abstracts_read: Math.max(currentState.abstracts_read ?? 0, validation.counts.abstracts_read),
190
- full_reads: Math.max(currentState.full_reads ?? 0, summaryCount),
191
- entity_count: entityCount,
192
- claim_count: claimCount,
193
- last_structure: new Date().toISOString(),
194
- last_shape: null,
195
- last_compile: null,
196
- };
197
- saveState(dirPath, nextState);
198
- refreshWorkspaceArtifacts(dirPath, { ensureViewSpec: true });
199
- return validateWorkspaceStructure(dirPath).ok;
111
+ function activeRunCounts(dirPath) {
112
+ return { ...(loadRuntimeRun(dirPath)?.counts ?? {}) };
200
113
  }
201
- export function reconcileWorkspaceShapeRun(dirPath) {
114
+ export function reconcileCompiledStageRun(dirPath, stage) {
202
115
  const startedAtMs = readActiveRunStartedAtMs(dirPath);
203
116
  if (startedAtMs === null)
204
117
  return false;
205
- if (!pathUpdatedSince(dirPath, "home.md", startedAtMs)) {
118
+ const schema = readCompiledSchemaFile(join(dirPath, ".interf", "workflow"));
119
+ if (!schema)
206
120
  return false;
207
- }
208
- if (!workspaceHomeIsShaped(dirPath)) {
121
+ const writeZones = stage.writes
122
+ .map((zoneId) => findCompiledSchemaZone(schema, zoneId))
123
+ .filter((zone) => zone !== null);
124
+ if (writeZones.length === 0)
209
125
  return false;
210
- }
211
- const summaryCount = countFilesRecursive(join(dirPath, "summaries"));
212
- const inventoryEntries = buildWorkspaceInventoryEntries(dirPath);
213
- if (summaryCount > 0 && inventoryEntries.length < summaryCount) {
126
+ if (!writeZones.some((zone) => anyPathUpdatedSince(compiledZoneAbsolutePath(dirPath, zone), startedAtMs))) {
214
127
  return false;
215
128
  }
129
+ const inventoryEntries = buildStageInventoryEntries(dirPath, stage);
216
130
  if (inventoryEntries.length > 0) {
217
- writeWorkspaceInventory(dirPath, inventoryEntries);
131
+ writeStageInventory(dirPath, stage.id, inventoryEntries);
218
132
  }
219
- const structureValidation = validateWorkspaceStructure(dirPath);
220
- if (!structureValidation.ok)
221
- return false;
222
133
  const currentState = {
223
- ...initWorkspaceState(),
134
+ ...initCompiledState(),
224
135
  ...(loadState(dirPath) ?? {}),
136
+ stages: {
137
+ ...(loadState(dirPath)?.stages ?? {}),
138
+ },
225
139
  };
226
- const entityCount = countFilesRecursive(join(dirPath, "knowledge", "entities"));
227
- const claimCount = countFilesRecursive(join(dirPath, "knowledge", "claims"));
228
140
  const now = new Date().toISOString();
229
- const nextState = {
230
- ...currentState,
231
- summarized: summaryCount,
232
- structured: summaryCount,
233
- shaped: summaryCount,
234
- compiled: summaryCount,
235
- inventory_complete: true,
236
- abstracts_read: Math.max(currentState.abstracts_read ?? 0, summaryCount),
237
- full_reads: Math.max(currentState.full_reads ?? 0, summaryCount),
238
- entity_count: entityCount,
239
- claim_count: claimCount,
240
- last_shape: now,
241
- last_compile: now,
141
+ currentState.stages[stage.id] = {
142
+ contract_type: stage.contractType,
143
+ status: "succeeded",
144
+ started_at: loadRuntimeRun(dirPath)?.started_at ?? now,
145
+ finished_at: now,
146
+ counts: activeRunCounts(dirPath),
147
+ zone_counts: Object.fromEntries(writeZones.map((zone) => [zone.id, zoneArtifactCount(dirPath, zone.path, zone.kind)])),
148
+ artifacts: writeZones.map((zone) => zone.kind === "file" ? zone.path : `${zone.path}/`),
149
+ summary: loadRuntimeRun(dirPath)?.summary ?? null,
150
+ run_id: loadRuntimeRun(dirPath)?.run_id ?? null,
242
151
  };
243
- saveState(dirPath, nextState);
244
- refreshWorkspaceArtifacts(dirPath, { ensureViewSpec: true });
245
- return validateWorkspaceCompile(dirPath).ok;
152
+ currentState.last_compile = now;
153
+ saveState(dirPath, currentState);
154
+ refreshCompiledArtifacts(dirPath, { ensureViewSpec: true });
155
+ return true;
246
156
  }
@@ -16,7 +16,8 @@ export function loadRuntimeRun(dirPath) {
16
16
  const parsed = RuntimeRunSchema.safeParse(raw);
17
17
  if (parsed.success)
18
18
  return parsed.data;
19
- return normalizeRuntimeRunRecord(raw);
19
+ warnInterf(`Warning: failed to validate runtime run at ${path}: ${parsed.error.issues.map((issue) => issue.message).join("; ")}`);
20
+ return null;
20
21
  }
21
22
  catch (error) {
22
23
  warnInterf(`Warning: failed to read runtime run at ${path}: ${error instanceof Error ? error.message : String(error)}`);
@@ -36,34 +37,34 @@ export function writeStageContract(dirPath, contract) {
36
37
  export async function runExecutorStage(options) {
37
38
  const run = startRuntimeRun(options);
38
39
  const prompt = options.buildPrompt(run.contract_path);
39
- writeRuntimeRunPrompt(options.workspacePath, run.run_id, prompt);
40
- const executionPath = options.executionPath ?? options.workspacePath;
40
+ writeRuntimeRunPrompt(options.compiledPath, run.run_id, prompt);
41
+ const executionPath = options.executionPath ?? options.compiledPath;
41
42
  const code = await options.executor.execute(executionPath, prompt, {
42
- eventLogPath: eventLogPath(options.workspacePath, run.run_id),
43
- statusLogPath: statusLogPath(options.workspacePath, run.run_id),
43
+ eventLogPath: eventLogPath(options.compiledPath, run.run_id),
44
+ statusLogPath: statusLogPath(options.compiledPath, run.run_id),
44
45
  completionCheck: options.completionCheck,
45
46
  });
46
- finalizeRuntimeRun(options.workspacePath, code);
47
+ finalizeRuntimeRun(options.compiledPath, code);
47
48
  return code;
48
49
  }
49
50
  export async function runExecutorSummarizeStage(options) {
50
51
  const run = startRuntimeRun(options);
51
52
  const prompt = options.buildPrompt(run.contract_path);
52
53
  let lastReported = 0;
53
- writeRuntimeRunPrompt(options.workspacePath, run.run_id, prompt);
54
- const executionPath = options.executionPath ?? options.workspacePath;
54
+ writeRuntimeRunPrompt(options.compiledPath, run.run_id, prompt);
55
+ const executionPath = options.executionPath ?? options.compiledPath;
55
56
  const progressPromise = options.executor.execute(executionPath, prompt, {
56
- eventLogPath: eventLogPath(options.workspacePath, run.run_id),
57
- statusLogPath: statusLogPath(options.workspacePath, run.run_id),
57
+ eventLogPath: eventLogPath(options.compiledPath, run.run_id),
58
+ statusLogPath: statusLogPath(options.compiledPath, run.run_id),
58
59
  completionCheck: options.completionCheck,
59
60
  });
60
61
  const timer = setInterval(() => {
61
- const currentSummaryCount = countFilesRecursive(join(options.workspacePath, "summaries"));
62
+ const currentSummaryCount = countFilesRecursive(join(options.compiledPath, "summaries"));
62
63
  const completed = Math.max(0, Math.min(options.targetCount, currentSummaryCount - options.startingSummaryCount));
63
64
  if (completed <= lastReported)
64
65
  return;
65
66
  lastReported = completed;
66
- updateRuntimeRun(options.workspacePath, {
67
+ updateRuntimeRun(options.compiledPath, {
67
68
  counts: {
68
69
  ...run.counts,
69
70
  completed_summaries: completed,
@@ -75,7 +76,7 @@ export async function runExecutorSummarizeStage(options) {
75
76
  }, 10000);
76
77
  try {
77
78
  const code = await progressPromise;
78
- finalizeRuntimeRun(options.workspacePath, code);
79
+ finalizeRuntimeRun(options.compiledPath, code);
79
80
  return code;
80
81
  }
81
82
  finally {
@@ -145,8 +146,8 @@ function startRuntimeRun(options) {
145
146
  version: 1,
146
147
  generated_at: generatedAt,
147
148
  run_id: runId,
148
- target_type: "workspace",
149
- target_name: options.workspaceName,
149
+ target_type: "compiled",
150
+ target_name: options.compiledName,
150
151
  workflow: {
151
152
  id: options.workflow,
152
153
  stage_index: stagePosition?.stageIndex ?? null,
@@ -163,13 +164,13 @@ function startRuntimeRun(options) {
163
164
  artifacts: options.contract.artifacts,
164
165
  policies: options.contract.policies,
165
166
  };
166
- const contractPath = writeStageContract(options.workspacePath, contract);
167
+ const contractPath = writeStageContract(options.compiledPath, contract);
167
168
  const run = {
168
169
  kind: "interf-run",
169
170
  version: 1,
170
171
  run_id: runId,
171
- target_type: "workspace",
172
- target_name: options.workspaceName,
172
+ target_type: "compiled",
173
+ target_name: options.compiledName,
173
174
  workflow: options.workflow,
174
175
  stage: options.stage,
175
176
  stage_label: stageDefinition?.label ?? options.stageLabel,
@@ -179,20 +180,20 @@ function startRuntimeRun(options) {
179
180
  started_at: generatedAt,
180
181
  updated_at: generatedAt,
181
182
  finished_at: null,
182
- contract_path: relative(options.workspacePath, contractPath),
183
- ...(options.executionPath ? { execution_path: relative(options.workspacePath, options.executionPath) } : {}),
183
+ contract_path: relative(options.compiledPath, contractPath),
184
+ ...(options.executionPath ? { execution_path: relative(options.compiledPath, options.executionPath) } : {}),
184
185
  counts: { ...contract.counts },
185
186
  output_artifacts: [...contract.artifacts.writes],
186
187
  logs: {
187
- prompt_path: relative(options.workspacePath, promptLogPath(options.workspacePath, runId)),
188
- event_stream_path: relative(options.workspacePath, eventLogPath(options.workspacePath, runId)),
189
- status_path: relative(options.workspacePath, statusLogPath(options.workspacePath, runId)),
188
+ prompt_path: relative(options.compiledPath, promptLogPath(options.compiledPath, runId)),
189
+ event_stream_path: relative(options.compiledPath, eventLogPath(options.compiledPath, runId)),
190
+ status_path: relative(options.compiledPath, statusLogPath(options.compiledPath, runId)),
190
191
  },
191
192
  summary: options.summary,
192
193
  exit_code: null,
193
194
  error: null,
194
195
  };
195
- return beginRuntimeRun(options.workspacePath, run);
196
+ return beginRuntimeRun(options.compiledPath, run);
196
197
  }
197
198
  function finalizeRuntimeRun(dirPath, code) {
198
199
  const current = loadRuntimeRun(dirPath);
@@ -221,101 +222,6 @@ function writeRuntimeRunPrompt(dirPath, runId, prompt) {
221
222
  function createRunId() {
222
223
  return `run_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
223
224
  }
224
- function normalizeRuntimeRunRecord(raw) {
225
- if (!raw || typeof raw !== "object")
226
- return null;
227
- const record = raw;
228
- const executor = record.executor;
229
- if (record.kind !== "interf-run" ||
230
- typeof record.version !== "number" ||
231
- typeof record.run_id !== "string" ||
232
- typeof record.target_name !== "string" ||
233
- typeof record.workflow !== "string" ||
234
- typeof record.stage !== "string" ||
235
- !executor ||
236
- typeof executor !== "object" ||
237
- typeof record.started_at !== "string" ||
238
- typeof record.updated_at !== "string" ||
239
- typeof record.contract_path !== "string" ||
240
- typeof record.summary !== "string") {
241
- return null;
242
- }
243
- const normalizedTargetType = inferRuntimeTargetType(record.target_type);
244
- if (!normalizedTargetType)
245
- return null;
246
- const executorRecord = executor;
247
- const normalized = {
248
- kind: "interf-run",
249
- version: record.version,
250
- run_id: record.run_id,
251
- target_type: normalizedTargetType,
252
- target_name: record.target_name,
253
- workflow: record.workflow,
254
- stage: record.stage,
255
- stage_label: typeof record.stage_label === "string" ? record.stage_label : record.stage,
256
- contract_type: typeof record.contract_type === "string"
257
- ? inferRuntimeContractType(record.contract_type, record.stage)
258
- : inferRuntimeContractType(record.target_type, record.stage),
259
- status: normalizeRuntimeRunStatus(record),
260
- executor: {
261
- kind: executorRecord.kind,
262
- name: executorRecord.name,
263
- display_name: executorRecord.display_name,
264
- command: typeof executorRecord.command === "string" ? executorRecord.command : null,
265
- model: typeof executorRecord.model === "string" ? executorRecord.model : null,
266
- effort: typeof executorRecord.effort === "string" ? executorRecord.effort : null,
267
- profile: typeof executorRecord.profile === "string" ? executorRecord.profile : null,
268
- timeout_ms: typeof executorRecord.timeout_ms === "number" ? executorRecord.timeout_ms : null,
269
- },
270
- started_at: record.started_at,
271
- updated_at: record.updated_at,
272
- finished_at: typeof record.finished_at === "string" ? record.finished_at : null,
273
- contract_path: record.contract_path,
274
- execution_path: typeof record.execution_path === "string" ? record.execution_path : undefined,
275
- counts: record.counts && typeof record.counts === "object" ? record.counts : {},
276
- output_artifacts: Array.isArray(record.output_artifacts) ? record.output_artifacts : [],
277
- logs: record.logs && typeof record.logs === "object" ? record.logs : undefined,
278
- summary: record.summary,
279
- exit_code: typeof record.exit_code === "number" ? record.exit_code : null,
280
- error: typeof record.error === "string" ? record.error : null,
281
- };
282
- const parsed = RuntimeRunSchema.safeParse(normalized);
283
- return parsed.success ? parsed.data : null;
284
- }
285
- function normalizeRuntimeRunStatus(record) {
286
- const status = record.status;
287
- if (status === "running" || status === "succeeded" || status === "failed")
288
- return status;
289
- if (typeof record.exit_code === "number")
290
- return record.exit_code === 0 ? "succeeded" : "failed";
291
- if (typeof record.error === "string" && record.error.length > 0)
292
- return "failed";
293
- return "running";
294
- }
295
- function inferRuntimeTargetType(targetType) {
296
- if (targetType === "workspace") {
297
- return "workspace";
298
- }
299
- return null;
300
- }
301
- function inferRuntimeContractType(contractType, stage) {
302
- if (contractType === "workspace-file-evidence") {
303
- return "workspace-file-evidence";
304
- }
305
- if (contractType === "workspace-knowledge-structure") {
306
- return "workspace-knowledge-structure";
307
- }
308
- if (contractType === "workspace-query-shape") {
309
- return "workspace-query-shape";
310
- }
311
- if (stage === "structure" || stage === "compile") {
312
- return "workspace-knowledge-structure";
313
- }
314
- if (stage === "shape") {
315
- return "workspace-query-shape";
316
- }
317
- return "workspace-file-evidence";
318
- }
319
225
  function replaceOrAppendRunHistoryEntry(dirPath, run) {
320
226
  const historyPath = runHistoryPath(dirPath);
321
227
  if (!existsSync(historyPath)) {
@@ -4,9 +4,9 @@ export type RuntimeRunStatus = "running" | "succeeded" | "failed";
4
4
  export type RuntimeStageContractDraft = Omit<RuntimeStageContract, "kind" | "version" | "generated_at" | "run_id" | "target_type" | "target_name" | "workflow" | "stage" | "stage_label" | "contract_type" | "executor">;
5
5
  export interface RuntimeStageExecutionOptions {
6
6
  executor: WorkflowExecutor;
7
- workspacePath: string;
7
+ compiledPath: string;
8
8
  executionPath?: string;
9
- workspaceName: string;
9
+ compiledName: string;
10
10
  workflow: WorkflowId;
11
11
  workflowSourcePath?: string;
12
12
  stage: RuntimeStage;
@@ -26,27 +26,18 @@ export interface RuntimeStageAcceptanceValidation {
26
26
  summary: string;
27
27
  failures: string[];
28
28
  }
29
- export interface WorkspaceSummarizeContractOptions {
30
- workspaceName: string;
31
- targetCount: number;
32
- expectedSummaryTotal: number;
33
- sourcePath: string;
34
- planPath: string;
35
- workflowNotes?: string[];
36
- localSkillDocs?: string[];
37
- instructions: RuntimeStageInstructions;
38
- acceptance?: RuntimeStageAcceptance;
39
- }
40
- export interface WorkspaceKnowledgeContractOptions {
41
- workspaceName: string;
42
- summaryCount: number;
29
+ export interface RuntimeStageContractOptions {
30
+ compiledName: string;
31
+ stageId: string;
32
+ stageLabel: string;
33
+ counts?: Record<string, number>;
34
+ extraReadArtifacts?: string[];
35
+ stageReadArtifacts: string[];
36
+ stageWriteArtifacts: string[];
43
37
  workflowNotes?: string[];
44
38
  localSkillDocs?: string[];
45
39
  instructions: RuntimeStageInstructions;
46
40
  acceptance?: RuntimeStageAcceptance;
47
41
  }
48
- export interface WorkspaceShapeContractOptions extends WorkspaceKnowledgeContractOptions {
49
- shapeInputPath: string;
50
- }
51
42
  export interface RuntimeRunPatch extends Partial<Pick<RuntimeRun, "counts" | "summary" | "status" | "error" | "exit_code" | "finished_at">> {
52
43
  }
@@ -1,6 +1,6 @@
1
- export type { RuntimeRunPatch, RuntimeRunStatus, RuntimeStageAcceptanceValidation, RuntimeStageContractDraft, RuntimeStageExecutionOptions, RuntimeSummarizeExecutionOptions, WorkspaceSummarizeContractOptions, } from "./runtime-types.js";
1
+ export type { RuntimeRunPatch, RuntimeRunStatus, RuntimeStageAcceptanceValidation, RuntimeStageContractDraft, RuntimeStageExecutionOptions, RuntimeSummarizeExecutionOptions, RuntimeStageContractOptions, } from "./runtime-types.js";
2
2
  export { eventLogPath, logsDirPath, promptLogPath, runHistoryPath, runPath, stageContractPath, statusLogPath, } from "./runtime-paths.js";
3
3
  export { validateStageContractAcceptance } from "./runtime-acceptance.js";
4
4
  export { buildStagePrompt } from "./runtime-prompt.js";
5
- export { buildWorkspaceSummarizeContract, buildWorkspaceStructureContract, buildWorkspaceShapeContract, } from "./runtime-contracts.js";
5
+ export { buildRuntimeStageContract, } from "./runtime-contracts.js";
6
6
  export { beginRuntimeRun, loadRuntimeRun, markRuntimeRunFailedAfterValidation, markRuntimeRunSucceededAfterValidation, runExecutorStage, runExecutorSummarizeStage, saveRuntimeRun, updateRuntimeRun, writeStageContract, } from "./runtime-runs.js";
@@ -1,5 +1,5 @@
1
1
  export { eventLogPath, logsDirPath, promptLogPath, runHistoryPath, runPath, stageContractPath, statusLogPath, } from "./runtime-paths.js";
2
2
  export { validateStageContractAcceptance } from "./runtime-acceptance.js";
3
3
  export { buildStagePrompt } from "./runtime-prompt.js";
4
- export { buildWorkspaceSummarizeContract, buildWorkspaceStructureContract, buildWorkspaceShapeContract, } from "./runtime-contracts.js";
4
+ export { buildRuntimeStageContract, } from "./runtime-contracts.js";
5
5
  export { beginRuntimeRun, loadRuntimeRun, markRuntimeRunFailedAfterValidation, markRuntimeRunSucceededAfterValidation, runExecutorStage, runExecutorSummarizeStage, saveRuntimeRun, updateRuntimeRun, writeStageContract, } from "./runtime-runs.js";