@interf/compiler 0.33.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/README.md +122 -226
  2. package/dist/cli/commands/agents.js +1 -32
  3. package/dist/cli/commands/benchmark.d.ts +2 -3
  4. package/dist/cli/commands/benchmark.js +1 -31
  5. package/dist/cli/commands/build-plan.js +26 -50
  6. package/dist/cli/commands/build.d.ts +2 -3
  7. package/dist/cli/commands/build.js +1 -31
  8. package/dist/cli/commands/graphs.js +177 -32
  9. package/dist/cli/commands/mcp.d.ts +1 -0
  10. package/dist/cli/commands/mcp.js +223 -126
  11. package/dist/cli/commands/project.js +10 -36
  12. package/dist/cli/commands/reset.d.ts +2 -3
  13. package/dist/cli/commands/reset.js +1 -22
  14. package/dist/cli/commands/runs.js +86 -33
  15. package/dist/cli/commands/status.js +3 -24
  16. package/dist/cli/commands/traces.js +1 -29
  17. package/dist/cli/commands/wizard.js +17 -29
  18. package/dist/cli/lib/http-client.d.ts +39 -0
  19. package/dist/cli/lib/http-client.js +73 -0
  20. package/dist/packages/build-plans/authoring/brief.d.ts +25 -4
  21. package/dist/packages/build-plans/authoring/build-plan-authoring.d.ts +42 -1
  22. package/dist/packages/build-plans/authoring/build-plan-authoring.js +470 -63
  23. package/dist/packages/build-plans/authoring/build-plan-edit-session.d.ts +9 -0
  24. package/dist/packages/build-plans/authoring/build-plan-edit-session.js +27 -10
  25. package/dist/packages/build-plans/authoring/build-plan-improvement.js +62 -8
  26. package/dist/packages/build-plans/authoring/lib/build-plan-edit-utils.d.ts +1 -0
  27. package/dist/packages/build-plans/package/build-plan-definitions.d.ts +0 -1
  28. package/dist/packages/build-plans/package/build-plan-definitions.js +5 -3
  29. package/dist/packages/build-plans/package/build-plan-stage-runner.d.ts +1 -0
  30. package/dist/packages/build-plans/package/build-plan-stage-runner.js +2 -1
  31. package/dist/packages/build-plans/package/builtin-build-plan.d.ts +2 -2
  32. package/dist/packages/build-plans/package/builtin-build-plan.js +3 -3
  33. package/dist/packages/build-plans/package/context-interface.d.ts +3 -0
  34. package/dist/packages/build-plans/package/context-interface.js +5 -5
  35. package/dist/packages/build-plans/package/interf-build-plan-package.js +22 -22
  36. package/dist/packages/build-plans/package/local-build-plans.d.ts +10 -5
  37. package/dist/packages/build-plans/package/local-build-plans.js +57 -32
  38. package/dist/packages/contracts/index.d.ts +4 -3
  39. package/dist/packages/contracts/index.js +2 -1
  40. package/dist/packages/contracts/lib/context-graph-layer.d.ts +161 -0
  41. package/dist/packages/contracts/lib/context-graph-layer.js +216 -0
  42. package/dist/packages/contracts/lib/project-paths.d.ts +7 -0
  43. package/dist/packages/contracts/lib/project-paths.js +9 -0
  44. package/dist/packages/contracts/lib/project-schema.d.ts +264 -1
  45. package/dist/packages/contracts/lib/project-schema.js +38 -13
  46. package/dist/packages/contracts/lib/schema.d.ts +556 -23
  47. package/dist/packages/contracts/lib/schema.js +279 -18
  48. package/dist/packages/contracts/utils/filesystem.d.ts +1 -0
  49. package/dist/packages/contracts/utils/filesystem.js +29 -1
  50. package/dist/packages/projects/lib/schema.d.ts +6 -8
  51. package/dist/packages/projects/lib/schema.js +3 -1
  52. package/dist/packages/projects/source-config.d.ts +0 -5
  53. package/dist/packages/projects/source-config.js +9 -22
  54. package/dist/packages/runtime/actions/fields.d.ts +4 -0
  55. package/dist/packages/runtime/actions/form-builders.js +79 -31
  56. package/dist/packages/runtime/actions/form-validators.js +9 -3
  57. package/dist/packages/runtime/actions/helpers.js +3 -3
  58. package/dist/packages/runtime/actions/registry.d.ts +1 -1
  59. package/dist/packages/runtime/actions/registry.js +1 -1
  60. package/dist/packages/runtime/actions/requests.d.ts +1 -1
  61. package/dist/packages/runtime/actions/requests.js +12 -6
  62. package/dist/packages/runtime/actions/schemas.d.ts +7 -0
  63. package/dist/packages/runtime/actions/schemas.js +1 -0
  64. package/dist/packages/runtime/agent-handoff.js +8 -7
  65. package/dist/packages/runtime/agents/lib/execution-profile.d.ts +14 -0
  66. package/dist/packages/runtime/agents/lib/execution-profile.js +23 -0
  67. package/dist/packages/runtime/agents/lib/execution.js +14 -8
  68. package/dist/packages/runtime/agents/lib/executors.d.ts +1 -0
  69. package/dist/packages/runtime/agents/lib/executors.js +11 -2
  70. package/dist/packages/runtime/agents/lib/logs.d.ts +10 -0
  71. package/dist/packages/runtime/agents/lib/logs.js +32 -8
  72. package/dist/packages/runtime/agents/lib/preflight.js +4 -1
  73. package/dist/packages/runtime/agents/lib/render.d.ts +18 -0
  74. package/dist/packages/runtime/agents/lib/render.js +44 -18
  75. package/dist/packages/runtime/agents/lib/shell-templates.js +105 -63
  76. package/dist/packages/runtime/agents/lib/shells.d.ts +29 -0
  77. package/dist/packages/runtime/agents/lib/shells.js +158 -32
  78. package/dist/packages/runtime/agents/lib/source-context-scan.d.ts +10 -0
  79. package/dist/packages/runtime/agents/lib/source-context-scan.js +388 -0
  80. package/dist/packages/runtime/agents/lib/status.js +1 -14
  81. package/dist/packages/runtime/agents/lib/string-utils.d.ts +16 -0
  82. package/dist/packages/runtime/agents/lib/string-utils.js +36 -0
  83. package/dist/packages/runtime/agents/lib/types.d.ts +1 -0
  84. package/dist/packages/runtime/agents/providers/codex.js +2 -0
  85. package/dist/packages/runtime/agents/role-executors.js +2 -1
  86. package/dist/packages/runtime/auth/session-store.js +11 -3
  87. package/dist/packages/runtime/benchmark-question-draft.d.ts +3 -0
  88. package/dist/packages/runtime/benchmark-question-draft.js +57 -28
  89. package/dist/packages/runtime/build/artifact-status.d.ts +1 -1
  90. package/dist/packages/runtime/build/artifact-status.js +1 -1
  91. package/dist/packages/runtime/build/build-evidence.d.ts +2 -1
  92. package/dist/packages/runtime/build/build-evidence.js +11 -5
  93. package/dist/packages/runtime/build/build-pipeline.js +89 -5
  94. package/dist/packages/runtime/build/build-stage-plan.js +3 -1
  95. package/dist/packages/runtime/build/build-stage-runner.js +169 -32
  96. package/dist/packages/runtime/build/build-target.d.ts +3 -0
  97. package/dist/packages/runtime/build/build-target.js +25 -1
  98. package/dist/packages/runtime/build/check-evaluator.d.ts +1 -1
  99. package/dist/packages/runtime/build/check-evaluator.js +655 -4
  100. package/dist/packages/runtime/build/context-graph-paths.d.ts +13 -0
  101. package/dist/packages/runtime/build/context-graph-paths.js +27 -0
  102. package/dist/packages/runtime/build/index.d.ts +2 -2
  103. package/dist/packages/runtime/build/index.js +2 -2
  104. package/dist/packages/runtime/build/inspect-map.d.ts +10 -0
  105. package/dist/packages/runtime/build/inspect-map.js +270 -0
  106. package/dist/packages/runtime/build/lib/schema.d.ts +246 -53
  107. package/dist/packages/runtime/build/lib/schema.js +173 -15
  108. package/dist/packages/runtime/build/native-entrypoint.d.ts +2 -0
  109. package/dist/packages/runtime/build/native-entrypoint.js +286 -0
  110. package/dist/packages/runtime/build/runtime-contracts.js +9 -3
  111. package/dist/packages/runtime/build/runtime-log-paths.d.ts +3 -0
  112. package/dist/packages/runtime/build/runtime-log-paths.js +16 -0
  113. package/dist/packages/runtime/build/runtime-prompt.js +6 -4
  114. package/dist/packages/runtime/build/runtime-runs.js +63 -10
  115. package/dist/packages/runtime/build/runtime-types.d.ts +4 -1
  116. package/dist/packages/runtime/build/runtime.d.ts +3 -1
  117. package/dist/packages/runtime/build/runtime.js +3 -1
  118. package/dist/packages/runtime/build/source-files.js +11 -2
  119. package/dist/packages/runtime/build/source-inventory.d.ts +1 -0
  120. package/dist/packages/runtime/build/source-inventory.js +246 -7
  121. package/dist/packages/runtime/build/source-manifest.d.ts +11 -0
  122. package/dist/packages/runtime/build/source-manifest.js +30 -2
  123. package/dist/packages/runtime/build/stage-evidence.js +80 -11
  124. package/dist/packages/runtime/build/stage-manifest.d.ts +45 -0
  125. package/dist/packages/runtime/build/stage-manifest.js +1125 -0
  126. package/dist/packages/runtime/build/stage-reuse.js +12 -0
  127. package/dist/packages/runtime/build/stage-session.d.ts +81 -0
  128. package/dist/packages/runtime/build/stage-session.js +308 -0
  129. package/dist/packages/runtime/build/state-io.js +10 -11
  130. package/dist/packages/runtime/build/state-view.js +1 -1
  131. package/dist/packages/runtime/build/state.d.ts +1 -1
  132. package/dist/packages/runtime/build/state.js +1 -1
  133. package/dist/packages/runtime/build/summary-coverage-index.d.ts +21 -0
  134. package/dist/packages/runtime/build/summary-coverage-index.js +189 -0
  135. package/dist/packages/runtime/build/traces.js +3 -3
  136. package/dist/packages/runtime/build/validate-context-graph.d.ts +1 -1
  137. package/dist/packages/runtime/build/validate-context-graph.js +5 -5
  138. package/dist/packages/runtime/build/validate.d.ts +1 -1
  139. package/dist/packages/runtime/build/validate.js +1 -1
  140. package/dist/packages/runtime/client.d.ts +3 -3
  141. package/dist/packages/runtime/client.js +8 -13
  142. package/dist/packages/runtime/context-checks.js +13 -0
  143. package/dist/packages/runtime/context-graph-scaffold.js +2 -1
  144. package/dist/packages/runtime/context-graph-semantic-graph.d.ts +9 -0
  145. package/dist/packages/runtime/context-graph-semantic-graph.js +416 -0
  146. package/dist/packages/runtime/execution/lib/schema.d.ts +34 -31
  147. package/dist/packages/runtime/index.d.ts +2 -2
  148. package/dist/packages/runtime/index.js +1 -1
  149. package/dist/packages/runtime/native-run-handlers.d.ts +38 -0
  150. package/dist/packages/runtime/native-run-handlers.js +52 -33
  151. package/dist/packages/runtime/plan-artifact-contract.js +1 -1
  152. package/dist/packages/runtime/project-source-state.d.ts +4 -4
  153. package/dist/packages/runtime/project-source-state.js +5 -2
  154. package/dist/packages/runtime/project-store.d.ts +5 -0
  155. package/dist/packages/runtime/project-store.js +30 -3
  156. package/dist/packages/runtime/requested-artifacts.js +1 -1
  157. package/dist/packages/runtime/run-observability.js +9 -4
  158. package/dist/packages/runtime/runtime-action-proposals.js +3 -3
  159. package/dist/packages/runtime/runtime-build-plans.js +47 -3
  160. package/dist/packages/runtime/runtime-build-runs.js +9 -16
  161. package/dist/packages/runtime/runtime-caches.d.ts +26 -0
  162. package/dist/packages/runtime/runtime-caches.js +47 -0
  163. package/dist/packages/runtime/runtime-jobs.js +6 -6
  164. package/dist/packages/runtime/runtime-project-mutations.js +1 -0
  165. package/dist/packages/runtime/runtime-project-reads.d.ts +4 -1
  166. package/dist/packages/runtime/runtime-project-reads.js +229 -36
  167. package/dist/packages/runtime/runtime-proposal-helpers.js +6 -6
  168. package/dist/packages/runtime/runtime-resource-builders.d.ts +4 -2
  169. package/dist/packages/runtime/runtime-resource-builders.js +16 -14
  170. package/dist/packages/runtime/runtime-status.d.ts +14 -0
  171. package/dist/packages/runtime/runtime-status.js +15 -0
  172. package/dist/packages/runtime/runtime-verify-runs.js +6 -5
  173. package/dist/packages/runtime/runtime.d.ts +439 -22
  174. package/dist/packages/runtime/runtime.js +16 -2
  175. package/dist/packages/runtime/schemas/actions.d.ts +24 -0
  176. package/dist/packages/runtime/schemas/agents.d.ts +28 -0
  177. package/dist/packages/runtime/schemas/agents.js +33 -0
  178. package/dist/packages/runtime/schemas/build-plans.d.ts +181 -8
  179. package/dist/packages/runtime/schemas/build-plans.js +36 -2
  180. package/dist/packages/runtime/schemas/context-graphs.d.ts +1522 -0
  181. package/dist/packages/runtime/schemas/context-graphs.js +110 -0
  182. package/dist/packages/runtime/schemas/files.d.ts +7 -347
  183. package/dist/packages/runtime/schemas/files.js +1 -24
  184. package/dist/packages/runtime/schemas/index.d.ts +1 -0
  185. package/dist/packages/runtime/schemas/index.js +1 -0
  186. package/dist/packages/runtime/schemas/jobs.js +4 -0
  187. package/dist/packages/runtime/schemas/projects.d.ts +48 -21
  188. package/dist/packages/runtime/schemas/projects.js +34 -10
  189. package/dist/packages/runtime/schemas/runs.d.ts +1009 -240
  190. package/dist/packages/runtime/schemas/runs.js +17 -0
  191. package/dist/packages/runtime/service/openapi.js +1 -0
  192. package/dist/packages/runtime/service/operations.d.ts +1666 -145
  193. package/dist/packages/runtime/service/operations.js +147 -17
  194. package/dist/packages/runtime/service/routes.d.ts +11 -3
  195. package/dist/packages/runtime/service/routes.js +11 -3
  196. package/dist/packages/runtime/service/server-app-boot.js +2 -2
  197. package/dist/packages/runtime/service/server-helpers.d.ts +11 -0
  198. package/dist/packages/runtime/service/server-helpers.js +19 -0
  199. package/dist/packages/runtime/service/server-routes-action-proposals.js +4 -2
  200. package/dist/packages/runtime/service/server-routes-agents.js +19 -85
  201. package/dist/packages/runtime/service/server-routes-build-plans.js +14 -11
  202. package/dist/packages/runtime/service/server-routes-project-context.js +102 -7
  203. package/dist/packages/runtime/service/server-routes-project-jobs.js +19 -12
  204. package/dist/packages/runtime/service/server-routes-project-runs.js +5 -2
  205. package/dist/packages/runtime/service/server-routes-projects.js +6 -2
  206. package/dist/packages/runtime/service/server-routes-runs.js +11 -4
  207. package/dist/packages/runtime/verify/lib/schema.js +12 -0
  208. package/dist/packages/runtime/verify/test-file-guard.d.ts +2 -0
  209. package/dist/packages/runtime/verify/test-file-guard.js +29 -0
  210. package/dist/packages/runtime/verify/verify-execution.d.ts +7 -0
  211. package/dist/packages/runtime/verify/verify-execution.js +109 -35
  212. package/dist/packages/runtime/verify/verify-paths.d.ts +1 -0
  213. package/dist/packages/runtime/verify/verify-paths.js +4 -0
  214. package/dist/packages/runtime/verify/verify-specs.js +49 -39
  215. package/dist/packages/runtime/wire-schemas.d.ts +1 -1
  216. package/dist/packages/runtime/wire-schemas.js +1 -1
  217. package/package.json +2 -8
  218. package/public-repo/CONTRIBUTING.md +10 -3
  219. package/public-repo/README.md +122 -226
  220. package/public-repo/build-plans/interf-default/README.md +15 -12
  221. package/public-repo/build-plans/interf-default/build/stages/entrypoint/SKILL.md +74 -0
  222. package/public-repo/build-plans/interf-default/build/stages/knowledge/SKILL.md +95 -0
  223. package/public-repo/build-plans/interf-default/build/stages/summarize/SKILL.md +38 -5
  224. package/public-repo/build-plans/interf-default/build-plan.json +27 -23
  225. package/public-repo/build-plans/interf-default/build-plan.schema.json +24 -20
  226. package/public-repo/build-plans/interf-default/use/query/SKILL.md +8 -7
  227. package/public-repo/openapi/local-service.openapi.json +11637 -4213
  228. package/public-repo/skills/interf/SKILL.md +174 -134
  229. package/dist/packages/runtime/build/runtime-paths.d.ts +0 -8
  230. package/dist/packages/runtime/build/runtime-paths.js +0 -26
  231. package/dist/packages/runtime/build/state-paths.d.ts +0 -7
  232. package/dist/packages/runtime/build/state-paths.js +0 -22
  233. package/public-repo/build-plans/interf-default/build/stages/shape/SKILL.md +0 -34
  234. package/public-repo/build-plans/interf-default/build/stages/structure/SKILL.md +0 -28
@@ -5,12 +5,15 @@ import { stageExecutionWorkspaceLogPaths, writeStageExecutionWorkspaceManifest,
5
5
  import { ExecutionStageLedgerSchema, } from "./lib/schema.js";
6
6
  import { supportsStageEvidenceHarness, writeStageHarnessProjection, } from "./stage-evidence.js";
7
7
  import { getBuildPlanStageDefinition, getBuildPlanStagePosition, getBuildPlanStages, } from "../../build-plans/package/build-plan-definitions.js";
8
- import { archivedStageContractPath, eventLogPath, promptLogPath, runHistoryPath, runPath, stageContractPath, statusLogPath, } from "./runtime-paths.js";
8
+ import { InterfIdPattern, } from "../../contracts/lib/schema.js";
9
+ import { contextGraphRuntimeArchivedStageContractPath, contextGraphExecutionStageLedgerHistoryPath, contextGraphExecutionStageLedgerPath, contextGraphRuntimeStageContractPath, } from "./context-graph-paths.js";
10
+ import { eventLogPath, promptLogPath, statusLogPath, } from "./runtime-log-paths.js";
9
11
  import { warnInterf } from "../../contracts/utils/logger.js";
10
12
  import { appendJsonlAtomic, writeFileAtomic, writeJsonAtomic } from "./atomic-fs.js";
11
- import { loadState, saveState, } from "./state.js";
13
+ import { initContextGraphState, loadState, saveState, } from "./state.js";
14
+ import { projectSessionFinishedFromLedger, writeStageExecutionSessionStartedFromLedger, } from "./stage-session.js";
12
15
  export function loadExecutionStageLedger(dirPath) {
13
- const path = runPath(dirPath);
16
+ const path = contextGraphExecutionStageLedgerPath(dirPath);
14
17
  if (!existsSync(path))
15
18
  return null;
16
19
  try {
@@ -27,16 +30,16 @@ export function loadExecutionStageLedger(dirPath) {
27
30
  }
28
31
  }
29
32
  export function saveExecutionStageLedger(dirPath, run) {
30
- writeJsonAtomic(runPath(dirPath), run);
33
+ writeJsonAtomic(contextGraphExecutionStageLedgerPath(dirPath), run);
31
34
  }
32
35
  export function writeStageContract(dirPath, contract) {
33
- mkdirSync(dirname(stageContractPath(dirPath)), { recursive: true });
34
- const path = stageContractPath(dirPath);
36
+ mkdirSync(dirname(contextGraphRuntimeStageContractPath(dirPath)), { recursive: true });
37
+ const path = contextGraphRuntimeStageContractPath(dirPath);
35
38
  writeJsonAtomic(path, contract);
36
39
  return path;
37
40
  }
38
41
  function writeArchivedStageContract(dirPath, runId, contract) {
39
- const path = archivedStageContractPath(dirPath, runId);
42
+ const path = contextGraphRuntimeArchivedStageContractPath(dirPath, runId);
40
43
  writeJsonAtomic(path, contract);
41
44
  return path;
42
45
  }
@@ -51,10 +54,28 @@ export async function runExecutorStage(options) {
51
54
  }
52
55
  const prompt = options.buildPrompt(startedRun.activeContractPath);
53
56
  writeExecutionStageLedgerPrompt(startedRun.logPaths.promptLogPath, prompt);
57
+ writeStageExecutionSessionStartedFromLedger({
58
+ contextGraphPath: options.contextGraphPath,
59
+ run: startedRun.run,
60
+ contract: startedRun.contract,
61
+ buildRunId: options.buildRunId ?? null,
62
+ shellRoot: options.executionPath ?? null,
63
+ promptPath: startedRun.logPaths.promptLogPath,
64
+ eventStreamPath: startedRun.logPaths.eventLogPath,
65
+ statusPath: startedRun.logPaths.statusLogPath,
66
+ });
54
67
  const executionPath = options.executionPath ?? options.contextGraphPath;
68
+ // Reasoning lands in the shell's runtime/ dir so it sits beside the other
69
+ // inspectable runtime files, is referenced by the session's reasoning_path,
70
+ // and is preserved when the shell is frozen. Without a shell there is nowhere
71
+ // durable to keep it, so reasoning capture is skipped (null).
72
+ const reasoningLogPath = options.executionPath
73
+ ? join(options.executionPath, "runtime", "agent-reasoning.jsonl")
74
+ : null;
55
75
  const code = await options.executor.execute(executionPath, prompt, {
56
76
  eventLogPath: startedRun.logPaths.eventLogPath,
57
77
  statusLogPath: startedRun.logPaths.statusLogPath,
78
+ reasoningLogPath,
58
79
  completionCheck: options.completionCheck,
59
80
  onStatus: options.onStatus,
60
81
  });
@@ -99,6 +120,27 @@ function updateContextGraphStageTerminalState(dirPath, run, options) {
99
120
  },
100
121
  });
101
122
  }
123
+ function updateContextGraphStageStartedState(dirPath, run) {
124
+ const state = loadState(dirPath) ?? initContextGraphState();
125
+ const currentStage = state.stages?.[run.stage] ?? {};
126
+ saveState(dirPath, {
127
+ ...state,
128
+ stages: {
129
+ ...(state.stages ?? {}),
130
+ [run.stage]: {
131
+ ...currentStage,
132
+ contract_type: run.contract_type,
133
+ status: "running",
134
+ started_at: run.started_at,
135
+ finished_at: null,
136
+ counts: { ...run.counts },
137
+ artifacts: [...run.output_artifacts],
138
+ summary: run.summary,
139
+ run_id: run.run_id,
140
+ },
141
+ },
142
+ });
143
+ }
102
144
  export function markExecutionStageLedgerFailedAfterValidation(dirPath, summary) {
103
145
  const current = loadExecutionStageLedger(dirPath);
104
146
  if (!current)
@@ -119,7 +161,8 @@ export function markExecutionStageLedgerFailedAfterValidation(dirPath, summary)
119
161
  summary,
120
162
  finishedAt,
121
163
  });
122
- appendJsonlAtomic(runHistoryPath(dirPath), next);
164
+ projectSessionFinishedFromLedger(dirPath, next);
165
+ appendJsonlAtomic(contextGraphExecutionStageLedgerHistoryPath(dirPath), next);
123
166
  return next;
124
167
  }
125
168
  export function markExecutionStageLedgerSucceededAfterValidation(dirPath, summary) {
@@ -142,7 +185,8 @@ export function markExecutionStageLedgerSucceededAfterValidation(dirPath, summar
142
185
  summary,
143
186
  finishedAt,
144
187
  });
145
- appendJsonlAtomic(runHistoryPath(dirPath), next);
188
+ projectSessionFinishedFromLedger(dirPath, next);
189
+ appendJsonlAtomic(contextGraphExecutionStageLedgerHistoryPath(dirPath), next);
146
190
  return next;
147
191
  }
148
192
  function startExecutionStageLedger(options) {
@@ -151,6 +195,10 @@ function startExecutionStageLedger(options) {
151
195
  const buildPlanStages = getBuildPlanStages(options.buildPlan, options.buildPlanSourcePath);
152
196
  const stagePosition = getBuildPlanStagePosition(options.buildPlan, options.stage, options.buildPlanSourcePath);
153
197
  const stageDefinition = getBuildPlanStageDefinition(options.buildPlan, options.stage, options.buildPlanSourcePath);
198
+ const project = options.contract.project ?? {
199
+ id: InterfIdPattern.test(options.contextGraphName) ? options.contextGraphName : "project",
200
+ intent: null,
201
+ };
154
202
  const contract = {
155
203
  kind: "interf-stage-contract",
156
204
  version: 1,
@@ -158,6 +206,7 @@ function startExecutionStageLedger(options) {
158
206
  run_id: runId,
159
207
  target_type: "context-graph",
160
208
  target_name: options.contextGraphName,
209
+ project,
161
210
  build_plan: {
162
211
  id: options.buildPlan,
163
212
  stage_index: stagePosition?.stageIndex ?? null,
@@ -171,6 +220,7 @@ function startExecutionStageLedger(options) {
171
220
  instructions: options.contract.instructions,
172
221
  counts: options.contract.counts,
173
222
  artifacts: options.contract.artifacts,
223
+ context_checks: options.contract.context_checks,
174
224
  policies: options.contract.policies,
175
225
  };
176
226
  const activeContractPath = writeStageContract(options.contextGraphPath, contract);
@@ -214,6 +264,7 @@ function startExecutionStageLedger(options) {
214
264
  error: null,
215
265
  };
216
266
  const startedRun = beginExecutionStageLedger(options.contextGraphPath, run);
267
+ updateContextGraphStageStartedState(options.contextGraphPath, startedRun);
217
268
  if (options.executionPath) {
218
269
  writeStageExecutionWorkspaceManifest({
219
270
  contextGraphPath: options.contextGraphPath,
@@ -243,9 +294,10 @@ function finalizeExecutionStageLedger(dirPath, code) {
243
294
  if (!current)
244
295
  return null;
245
296
  const finishedAt = new Date().toISOString();
297
+ const status = code === 0 ? "succeeded" : "failed";
246
298
  const next = {
247
299
  ...current,
248
- status: code === 0 ? "succeeded" : "failed",
300
+ status,
249
301
  updated_at: finishedAt,
250
302
  finished_at: finishedAt,
251
303
  exit_code: code,
@@ -255,6 +307,7 @@ function finalizeExecutionStageLedger(dirPath, code) {
255
307
  : `${current.stage_label} failed with exit code ${code}.`,
256
308
  };
257
309
  saveExecutionStageLedger(dirPath, next);
310
+ projectSessionFinishedFromLedger(dirPath, next);
258
311
  return next;
259
312
  }
260
313
  function writeExecutionStageLedgerPrompt(path, prompt) {
@@ -1,5 +1,5 @@
1
1
  import { type AgentExecutor } from "../agents/lib/executors.js";
2
- import { type ExecutionStageLedger, type RuntimeStageContract, type RuntimeStageInstructions } from "./lib/schema.js";
2
+ import { type ExecutionStageLedger, type RuntimeProjectContext, type RuntimeStageContract, type RuntimeStageInstructions } from "./lib/schema.js";
3
3
  import type { Check, BuildPlanId, RuntimeContractType, RuntimeStage } from "../../contracts/lib/schema.js";
4
4
  export type ExecutionStageLedgerStatus = "running" | "succeeded" | "failed";
5
5
  export type RuntimeStageContractDraft = Omit<RuntimeStageContract, "kind" | "version" | "generated_at" | "run_id" | "target_type" | "target_name" | "build_plan" | "stage" | "stage_label" | "contract_type" | "executor">;
@@ -10,6 +10,7 @@ export interface RuntimeStageExecutionOptions {
10
10
  contextGraphName: string;
11
11
  buildPlan: BuildPlanId;
12
12
  buildPlanSourcePath?: string;
13
+ buildRunId?: string | null;
13
14
  stage: RuntimeStage;
14
15
  stageLabel: string;
15
16
  contractType: RuntimeContractType;
@@ -21,6 +22,7 @@ export interface RuntimeStageExecutionOptions {
21
22
  }
22
23
  export interface RuntimeStageContractOptions {
23
24
  contextGraphName: string;
25
+ project: RuntimeProjectContext;
24
26
  stageId: string;
25
27
  stageLabel: string;
26
28
  counts?: Record<string, number>;
@@ -32,6 +34,7 @@ export interface RuntimeStageContractOptions {
32
34
  path: string;
33
35
  checks: Check[];
34
36
  }>;
37
+ contextChecks?: RuntimeStageContract["context_checks"];
35
38
  buildPlanNotes?: string[];
36
39
  localSkillDocs?: string[];
37
40
  instructions: RuntimeStageInstructions;
@@ -1,6 +1,8 @@
1
1
  export type { ExecutionStageLedgerPatch, ExecutionStageLedgerStatus, RuntimeStageContractDraft, RuntimeStageExecutionOptions, RuntimeStageContractOptions, } from "./runtime-types.js";
2
- export { archivedStageContractPath, eventLogPath, logsDirPath, promptLogPath, runHistoryPath, runPath, stageContractPath, statusLogPath, } from "./runtime-paths.js";
2
+ export { contextGraphRuntimeArchivedStageContractPath as archivedStageContractPath, contextGraphRuntimeLogsRoot as logsDirPath, contextGraphExecutionStageLedgerHistoryPath as runHistoryPath, contextGraphExecutionStageLedgerPath as runPath, contextGraphRuntimeStageContractPath as stageContractPath, } from "./context-graph-paths.js";
3
+ export { eventLogPath, promptLogPath, statusLogPath, } from "./runtime-log-paths.js";
3
4
  export { buildStagePrompt } from "./runtime-prompt.js";
4
5
  export { buildRuntimeStageContract, } from "./runtime-contracts.js";
5
6
  export { reconcileStageEvidence, supportsStageEvidenceHarness, writeStageHarnessProjection, } from "./stage-evidence.js";
7
+ export { listStageExecutionSessions, markStageExecutionSessionsShellPreserved, recordStageExecutionSessionValidationAttempt, writeStageExecutionSessionFinished, writeStageExecutionSessionStarted, writeStageExecutionSessionStartedFromLedger, } from "./stage-session.js";
6
8
  export { beginExecutionStageLedger, loadExecutionStageLedger, markExecutionStageLedgerFailedAfterValidation, markExecutionStageLedgerSucceededAfterValidation, runExecutorStage, saveExecutionStageLedger, updateExecutionStageLedger, writeStageContract, } from "./runtime-runs.js";
@@ -1,5 +1,7 @@
1
- export { archivedStageContractPath, eventLogPath, logsDirPath, promptLogPath, runHistoryPath, runPath, stageContractPath, statusLogPath, } from "./runtime-paths.js";
1
+ export { contextGraphRuntimeArchivedStageContractPath as archivedStageContractPath, contextGraphRuntimeLogsRoot as logsDirPath, contextGraphExecutionStageLedgerHistoryPath as runHistoryPath, contextGraphExecutionStageLedgerPath as runPath, contextGraphRuntimeStageContractPath as stageContractPath, } from "./context-graph-paths.js";
2
+ export { eventLogPath, promptLogPath, statusLogPath, } from "./runtime-log-paths.js";
2
3
  export { buildStagePrompt } from "./runtime-prompt.js";
3
4
  export { buildRuntimeStageContract, } from "./runtime-contracts.js";
4
5
  export { reconcileStageEvidence, supportsStageEvidenceHarness, writeStageHarnessProjection, } from "./stage-evidence.js";
6
+ export { listStageExecutionSessions, markStageExecutionSessionsShellPreserved, recordStageExecutionSessionValidationAttempt, writeStageExecutionSessionFinished, writeStageExecutionSessionStarted, writeStageExecutionSessionStartedFromLedger, } from "./stage-session.js";
5
7
  export { beginExecutionStageLedger, loadExecutionStageLedger, markExecutionStageLedgerFailedAfterValidation, markExecutionStageLedgerSucceededAfterValidation, runExecutorStage, saveExecutionStageLedger, updateExecutionStageLedger, writeStageContract, } from "./runtime-runs.js";
@@ -14,7 +14,16 @@ function shortHash(value, length = 16) {
14
14
  .digest("hex")
15
15
  .slice(0, length);
16
16
  }
17
- function normalizeRelativePath(path) {
17
+ /**
18
+ * Canonicalize ONLY the path separators (`\` -> `/`) so a file's stable hash id
19
+ * is identical on Windows and POSIX. This is deliberately NOT the canonical
20
+ * `normalizeLayerPath` (`contracts/lib/context-graph-layer.ts`): it must NOT
21
+ * strip a leading `./` or a trailing slash, because the resulting string is
22
+ * stored as `SourceFile.path` and fed verbatim into the file-id hash. Touching
23
+ * the leading/trailing characters here would change every existing source-file
24
+ * id. Separators-only is the intended, stable difference.
25
+ */
26
+ function normalizeSeparatorsForFileId(path) {
18
27
  return path.replaceAll("\\", "/");
19
28
  }
20
29
  /**
@@ -40,7 +49,7 @@ function buildSource(sourcePath) {
40
49
  };
41
50
  }
42
51
  function buildSourceFile(source, sourcePath, relativePath) {
43
- const normalizedPath = normalizeRelativePath(relativePath);
52
+ const normalizedPath = normalizeSeparatorsForFileId(relativePath);
44
53
  const absolutePath = resolve(sourcePath, relativePath);
45
54
  return {
46
55
  id: `file-${shortHash(`${source.id}\0${normalizedPath}`)}`,
@@ -15,6 +15,7 @@ export declare function runSourceInventory(options: {
15
15
  executor: AgentExecutor;
16
16
  contextGraphPath: string;
17
17
  project: string;
18
+ projectIntent?: string | null;
18
19
  sourceLocator: string;
19
20
  buildPlanId: string;
20
21
  stageIds: string[];
@@ -3,9 +3,14 @@ import { join, relative } from "node:path";
3
3
  import { SourceManifestSchema, } from "../../contracts/lib/schema.js";
4
4
  import { buildRuntimeExecutorInfo } from "../agents/lib/executors.js";
5
5
  import { shellEventLogPath, shellPromptLogPath, shellStatusLogPath, } from "../agents/lib/shell-paths.js";
6
+ import { renderClaudeBootstrap, } from "../agents/lib/shell-templates.js";
7
+ import { freezePreservedShell, writeIfChanged, writeNativeSkillCopies, } from "../agents/lib/shell-fs.js";
8
+ import { writeStageExecutionWorkspaceManifest, } from "../agents/lib/shell-workspace.js";
6
9
  import { contextGraphRuntimeSourceManifestPath, stageExecutionShellsRoot, } from "./context-graph-paths.js";
7
- import { loadContextGraphSourceManifest, writeBuildSourceRuntimeFromManifest, } from "./source-manifest.js";
10
+ import { dropFilesystemArtifacts, loadContextGraphSourceManifest, writeBuildSourceRuntimeFromManifest, } from "./source-manifest.js";
11
+ import { writeSourceStageManifest, } from "./stage-manifest.js";
8
12
  import { createRunEventId, createRunEventTimestamp, } from "../execution/events.js";
13
+ import { markStageExecutionSessionsShellPreserved, recordStageExecutionSessionValidationAttempt, writeStageExecutionSessionFinished, writeStageExecutionSessionStarted, } from "./stage-session.js";
9
14
  function sourceInventoryShellRoot(contextGraphPath, attempt) {
10
15
  return join(stageExecutionShellsRoot(contextGraphPath), `source-inventory-${Date.now().toString(36)}-${attempt}`);
11
16
  }
@@ -54,10 +59,13 @@ function sourceInventoryPrompt(options) {
54
59
  "You are the Interf Source inventory agent.",
55
60
  "Interf does not read or copy the user's Source files. You own Source access through your normal tools.",
56
61
  `Project: ${options.project}`,
62
+ ...(options.projectIntent ? [`Project intent: ${options.projectIntent}`] : []),
57
63
  `Source locator: ${options.sourceLocator}`,
58
64
  "Read `runtime/source-locator.json` first.",
59
65
  "List every Source file you can access. Use paths relative to the Source locator.",
60
- "For PDFs, decks, sheets, and other multi-unit files, record page/slide/sheet units when you can.",
66
+ "Use canonical file kinds only: pdf, document, spreadsheet, presentation, image, text, other. Markdown, txt, and plain-text files must use kind `text`.",
67
+ "For plain text or markdown files, use an inspectable unit like `{ \"kind\": \"file\", \"index\": 1, \"label\": \"whole file\" }` when useful.",
68
+ "For PDFs, decks, sheets, and other multi-unit files, record page/slide/sheet/table/image/section units when you can.",
61
69
  "Do not copy Source files into this shell.",
62
70
  "Write exactly one JSON file at runtime/source-manifest.json.",
63
71
  "The JSON must match this shape, with real values replacing the example:",
@@ -67,10 +75,116 @@ function sourceInventoryPrompt(options) {
67
75
  "Emit DONE: source inventory complete after runtime/source-manifest.json is written.",
68
76
  ].join("\n");
69
77
  }
78
+ function renderSourceInventoryAgents(options) {
79
+ return [
80
+ `# ${options.project} — Source Inventory Execution Shell`,
81
+ "",
82
+ "This is an isolated Interf execution shell for Source inventory.",
83
+ "It is a replayable stage workspace: prompts, logs, contract, input locator, and output manifest live here.",
84
+ "",
85
+ "## Start Here",
86
+ "",
87
+ "1. Read `runtime/stage-contract.json` now.",
88
+ "2. Read `runtime/source-locator.json` now.",
89
+ "3. Use the local native `interf-stage` skill now.",
90
+ "4. Write exactly one output: `runtime/source-manifest.json`.",
91
+ "",
92
+ "## Boundaries",
93
+ "",
94
+ `- Build Plan: \`${options.buildPlanId}\`.`,
95
+ "- Stage: `source-inventory`.",
96
+ "- Do not copy Source files into this shell.",
97
+ "- Source files remain read-only and external to Interf.",
98
+ "- Record every accessible Source file, inspectable units, and human-readable evidence.",
99
+ "",
100
+ "## Goal",
101
+ "",
102
+ "- produce a Source Manifest that future stages can use deterministically",
103
+ "- preserve Source file paths relative to the Source locator",
104
+ "- stop once `runtime/source-manifest.json` is valid",
105
+ "",
106
+ ].join("\n");
107
+ }
108
+ function renderSourceInventorySkill() {
109
+ return [
110
+ "---",
111
+ "name: interf-stage",
112
+ "description: >",
113
+ " Native local execution skill for the Interf Source inventory stage.",
114
+ " Use it only inside an automated Source inventory execution shell.",
115
+ "---",
116
+ "",
117
+ "# Interf Source Inventory",
118
+ "",
119
+ "Read `runtime/stage-contract.json` and `runtime/source-locator.json` first.",
120
+ "Inspect the Source through your own tools. Do not copy Source files into the shell.",
121
+ "Write `runtime/source-manifest.json` with every accessible Source file, Source-relative path, inspectable units, and evidence.",
122
+ "Emit DONE only after the manifest exists and matches the contract.",
123
+ "",
124
+ ].join("\n");
125
+ }
126
+ function writeSourceInventoryShellSurface(options) {
127
+ const agents = renderSourceInventoryAgents({
128
+ project: options.project,
129
+ buildPlanId: options.buildPlanId,
130
+ });
131
+ writeIfChanged(join(options.shellRoot, "AGENTS.md"), `${agents.trimEnd()}\n`);
132
+ writeIfChanged(join(options.shellRoot, "CLAUDE.md"), renderClaudeBootstrap(agents));
133
+ writeNativeSkillCopies(options.shellRoot, "interf-stage", renderSourceInventorySkill());
134
+ }
70
135
  function readShellManifest(shellRoot) {
71
136
  const manifestPath = join(shellRoot, "runtime", "source-manifest.json");
72
137
  const raw = JSON.parse(readFileSync(manifestPath, "utf8"));
73
- return SourceManifestSchema.parse(raw);
138
+ return SourceManifestSchema.parse(normalizeSourceManifestCandidate(raw));
139
+ }
140
+ function normalizeSourceManifestCandidate(value) {
141
+ if (!value || typeof value !== "object" || !Array.isArray(value.files)) {
142
+ return value;
143
+ }
144
+ return {
145
+ ...value,
146
+ files: (value.files).map((file) => {
147
+ if (!file || typeof file !== "object")
148
+ return file;
149
+ const candidate = file;
150
+ return {
151
+ ...candidate,
152
+ kind: normalizeSourceFileKind(candidate.kind, candidate.path),
153
+ };
154
+ }),
155
+ };
156
+ }
157
+ function normalizeSourceFileKind(kind, path) {
158
+ const raw = typeof kind === "string" ? kind.trim().toLowerCase() : "";
159
+ const normalized = raw.replaceAll("_", "-").replace(/\s+/g, "-");
160
+ if (["pdf", "document", "spreadsheet", "presentation", "image", "text", "other"].includes(normalized)) {
161
+ return normalized;
162
+ }
163
+ if (["markdown", "md", "txt", "plain-text", "text-file", "source-text"].includes(normalized))
164
+ return "text";
165
+ if (["doc", "docx", "word"].includes(normalized))
166
+ return "document";
167
+ if (["sheet", "sheets", "table", "csv", "tsv", "xls", "xlsx"].includes(normalized))
168
+ return "spreadsheet";
169
+ if (["deck", "slide", "slides", "ppt", "pptx"].includes(normalized))
170
+ return "presentation";
171
+ if (["jpg", "jpeg", "png", "gif", "webp", "svg"].includes(normalized))
172
+ return "image";
173
+ if (typeof path === "string") {
174
+ if (/\.(md|markdown|txt|text)$/i.test(path))
175
+ return "text";
176
+ if (/\.(doc|docx|rtf|odt)$/i.test(path))
177
+ return "document";
178
+ if (/\.(csv|tsv|xls|xlsx)$/i.test(path))
179
+ return "spreadsheet";
180
+ if (/\.(ppt|pptx|odp)$/i.test(path))
181
+ return "presentation";
182
+ if (/\.(jpe?g|png|gif|webp|svg)$/i.test(path))
183
+ return "image";
184
+ if (/\.pdf$/i.test(path))
185
+ return "pdf";
186
+ }
187
+ return kind === undefined ? undefined : "other";
74
188
  }
75
189
  function contextGraphRelativePath(contextGraphPath, filePath) {
76
190
  return relative(contextGraphPath, filePath).replaceAll("\\", "/");
@@ -154,11 +268,18 @@ export async function runSourceInventory(options) {
154
268
  sourceManifest: existing,
155
269
  runId: options.runId ?? existing.run_id,
156
270
  });
271
+ const existingContent = dropFilesystemArtifacts(existing);
272
+ writeSourceStageManifest({
273
+ contextGraphPath: options.contextGraphPath,
274
+ buildPlanId: options.buildPlanId,
275
+ sourceManifest: existingContent,
276
+ runId: options.runId ?? existingContent.run_id,
277
+ });
157
278
  return {
158
279
  ok: true,
159
280
  code: 0,
160
- summary: `Source Manifest already exists with ${existing.source_total} file(s).`,
161
- manifest: existing,
281
+ summary: `Source Manifest already exists with ${existingContent.source_total} file(s).`,
282
+ manifest: existingContent,
162
283
  };
163
284
  }
164
285
  const maxAttempts = Math.max(1, Math.min(5, Math.trunc(options.maxAttempts ?? 2)));
@@ -168,11 +289,17 @@ export async function runSourceInventory(options) {
168
289
  const inventoryRunId = `${options.runId ?? "source-inventory"}-source-inventory-${attempt}`;
169
290
  mkdirSync(join(shellRoot, "runtime"), { recursive: true });
170
291
  mkdirSync(join(shellRoot, "logs"), { recursive: true });
292
+ writeSourceInventoryShellSurface({
293
+ shellRoot,
294
+ project: options.project,
295
+ buildPlanId: options.buildPlanId,
296
+ });
171
297
  writeFileSync(join(shellRoot, "runtime", "source-locator.json"), `${JSON.stringify({
172
298
  kind: "interf-source-locator",
173
299
  version: 1,
174
300
  generated_at: new Date().toISOString(),
175
301
  project: options.project,
302
+ project_intent: options.projectIntent ?? null,
176
303
  source: {
177
304
  kind: "local-folder",
178
305
  locator: options.sourceLocator,
@@ -185,6 +312,7 @@ export async function runSourceInventory(options) {
185
312
  generated_at: new Date().toISOString(),
186
313
  run_id: options.runId ?? null,
187
314
  project: options.project,
315
+ project_intent: options.projectIntent ?? null,
188
316
  source: {
189
317
  kind: "local-folder",
190
318
  locator: options.sourceLocator,
@@ -200,8 +328,17 @@ export async function runSourceInventory(options) {
200
328
  "manifest paths are relative to the Source locator",
201
329
  ],
202
330
  }, null, 2)}\n`);
331
+ writeFileSync(join(shellRoot, "runtime", "paths.json"), `${JSON.stringify({
332
+ kind: "interf-execution-shell",
333
+ version: 1,
334
+ build_plan: options.buildPlanId,
335
+ stage: "source-inventory",
336
+ reads: [],
337
+ writes: [],
338
+ }, null, 2)}\n`);
203
339
  const prompt = sourceInventoryPrompt({
204
340
  project: options.project,
341
+ projectIntent: options.projectIntent ?? null,
205
342
  sourceLocator: options.sourceLocator,
206
343
  runId: options.runId ?? null,
207
344
  executor: options.executor,
@@ -216,14 +353,74 @@ export async function runSourceInventory(options) {
216
353
  writeFileSync(shellPromptLogPath(shellRoot, inventoryRunId), prompt);
217
354
  writeFileSync(shellEventLogPath(shellRoot, inventoryRunId), "");
218
355
  writeFileSync(shellStatusLogPath(shellRoot, inventoryRunId), "");
356
+ writeStageExecutionWorkspaceManifest({
357
+ contextGraphPath: options.contextGraphPath,
358
+ shellRoot,
359
+ buildPlanId: options.buildPlanId,
360
+ stage: {
361
+ id: "source-inventory",
362
+ label: "Source Inventory",
363
+ contractType: "source-inventory",
364
+ },
365
+ logPaths: {
366
+ promptLogPath: shellPromptLogPath(shellRoot, inventoryRunId),
367
+ eventLogPath: shellEventLogPath(shellRoot, inventoryRunId),
368
+ statusLogPath: shellStatusLogPath(shellRoot, inventoryRunId),
369
+ },
370
+ });
371
+ writeStageExecutionSessionStarted({
372
+ contextGraphPath: options.contextGraphPath,
373
+ jobType: "source-inventory",
374
+ project: options.project,
375
+ projectIntent: options.projectIntent ?? null,
376
+ buildPlanId: options.buildPlanId,
377
+ buildRunId: options.runId ?? null,
378
+ stageId: "source-inventory",
379
+ stageLabel: "Source Inventory",
380
+ contractType: "source-inventory",
381
+ stageRunId: inventoryRunId,
382
+ attempt,
383
+ executor: options.executor,
384
+ shellRoot,
385
+ contractPath: join(shellRoot, "runtime", "stage-contract.json"),
386
+ promptPath: shellPromptLogPath(shellRoot, inventoryRunId),
387
+ eventStreamPath: shellEventLogPath(shellRoot, inventoryRunId),
388
+ statusPath: shellStatusLogPath(shellRoot, inventoryRunId),
389
+ summary: "Collecting Source Manifest.",
390
+ });
219
391
  await emitInventoryEvent(options.events, options.runId ?? undefined, "stage.started", undefined, logs);
220
392
  const code = await options.executor.execute(shellRoot, prompt, {
221
393
  eventLogPath: shellEventLogPath(shellRoot, inventoryRunId),
222
394
  statusLogPath: shellStatusLogPath(shellRoot, inventoryRunId),
395
+ // Tee reasoning to the shell's runtime/ dir, the same convention the
396
+ // shared stage path uses (runtime-runs.ts). The session reader resolves
397
+ // reasoning_path to this file only when it exists, so a scan that emits
398
+ // no reasoning leaves it null. This makes the source-inventory session as
399
+ // legible as every other agent job (policy rule 6) without re-routing it
400
+ // through the shared stage path.
401
+ reasoningLogPath: join(shellRoot, "runtime", "agent-reasoning.jsonl"),
223
402
  completionCheck: () => existsSync(join(shellRoot, "runtime", "source-manifest.json")),
224
403
  });
225
404
  if (code !== 0) {
226
405
  feedback = `source inventory executor exited with code ${code}`;
406
+ recordStageExecutionSessionValidationAttempt({
407
+ contextGraphPath: options.contextGraphPath,
408
+ stageId: "source-inventory",
409
+ stageRunId: inventoryRunId,
410
+ attempt,
411
+ status: "failed",
412
+ summary: feedback,
413
+ });
414
+ writeStageExecutionSessionFinished({
415
+ contextGraphPath: options.contextGraphPath,
416
+ stageId: "source-inventory",
417
+ stageRunId: inventoryRunId,
418
+ status: "failed",
419
+ summary: feedback,
420
+ error: feedback,
421
+ });
422
+ freezePreservedShell(shellRoot, "stage-execution");
423
+ markStageExecutionSessionsShellPreserved({ contextGraphPath: options.contextGraphPath, shellRoot });
227
424
  continue;
228
425
  }
229
426
  try {
@@ -234,10 +431,10 @@ export async function runSourceInventory(options) {
234
431
  executor: options.executor,
235
432
  attempt,
236
433
  });
237
- const written = SourceManifestSchema.parse({
434
+ const written = dropFilesystemArtifacts(SourceManifestSchema.parse({
238
435
  ...manifest,
239
436
  run_id: options.runId ?? manifest.run_id,
240
- });
437
+ }));
241
438
  writeBuildSourceRuntimeFromManifest({
242
439
  contextGraphPath: options.contextGraphPath,
243
440
  buildPlanId: options.buildPlanId,
@@ -247,7 +444,31 @@ export async function runSourceInventory(options) {
247
444
  sourceManifest: written,
248
445
  runId: options.runId ?? null,
249
446
  });
447
+ writeSourceStageManifest({
448
+ contextGraphPath: options.contextGraphPath,
449
+ buildPlanId: options.buildPlanId,
450
+ sourceManifest: written,
451
+ runId: options.runId ?? null,
452
+ });
250
453
  await emitInventoryEvent(options.events, options.runId ?? undefined, "stage.passed", `Source Manifest captured ${written.source_total} file(s).`);
454
+ recordStageExecutionSessionValidationAttempt({
455
+ contextGraphPath: options.contextGraphPath,
456
+ stageId: "source-inventory",
457
+ stageRunId: inventoryRunId,
458
+ attempt,
459
+ status: "succeeded",
460
+ summary: `Source Manifest captured ${written.source_total} file(s).`,
461
+ });
462
+ writeStageExecutionSessionFinished({
463
+ contextGraphPath: options.contextGraphPath,
464
+ stageId: "source-inventory",
465
+ stageRunId: inventoryRunId,
466
+ status: "succeeded",
467
+ summary: `Source Manifest captured ${written.source_total} file(s).`,
468
+ error: null,
469
+ });
470
+ freezePreservedShell(shellRoot, "stage-execution");
471
+ markStageExecutionSessionsShellPreserved({ contextGraphPath: options.contextGraphPath, shellRoot });
251
472
  return {
252
473
  ok: true,
253
474
  code: 0,
@@ -258,6 +479,24 @@ export async function runSourceInventory(options) {
258
479
  }
259
480
  catch (error) {
260
481
  feedback = error instanceof Error ? error.message : String(error);
482
+ recordStageExecutionSessionValidationAttempt({
483
+ contextGraphPath: options.contextGraphPath,
484
+ stageId: "source-inventory",
485
+ stageRunId: inventoryRunId,
486
+ attempt,
487
+ status: "failed",
488
+ summary: feedback,
489
+ });
490
+ writeStageExecutionSessionFinished({
491
+ contextGraphPath: options.contextGraphPath,
492
+ stageId: "source-inventory",
493
+ stageRunId: inventoryRunId,
494
+ status: "failed",
495
+ summary: feedback,
496
+ error: feedback,
497
+ });
498
+ freezePreservedShell(shellRoot, "stage-execution");
499
+ markStageExecutionSessionsShellPreserved({ contextGraphPath: options.contextGraphPath, shellRoot });
261
500
  }
262
501
  }
263
502
  await emitInventoryEvent(options.events, options.runId ?? undefined, "stage.failed", feedback ?? "Source inventory failed.");
@@ -7,6 +7,17 @@ export declare function materializeStageSourceSlice(options: {
7
7
  stageInputs: StageInputs;
8
8
  }): StageInputs;
9
9
  export declare function buildShellSourceState(sourceState: SourceState, stageInputs: StageInputs): SourceState;
10
+ /**
11
+ * Drop OS-generated filesystem junk (`.DS_Store`, AppleDouble forks, `Thumbs.db`,
12
+ * etc.) from the Source Manifest before it is materialized into runtime coverage
13
+ * inputs. These are not Source content, so they must never become required
14
+ * `expected` inputs — otherwise a Source folder shows "not ready" purely because
15
+ * Finder/Explorer left a sidecar behind. Matched by filename only (provable),
16
+ * never by an agent's `not-relevant` label, so a genuinely skipped content file
17
+ * still counts toward readiness. `source_total` is recomputed to stay equal to
18
+ * the filtered file count.
19
+ */
20
+ export declare function dropFilesystemArtifacts(manifest: SourceManifest): SourceManifest;
10
21
  export declare function sourceManifestToSourceFiles(manifest: SourceManifest): SourceFiles;
11
22
  export declare function sourceManifestToSourceState(manifest: SourceManifest): SourceState;
12
23
  /**