@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
@@ -51,6 +51,11 @@ function buildPlanPackageHash(contextGraphPath) {
51
51
  hash: fileHash(file.path),
52
52
  }))));
53
53
  }
54
+ function stageFingerprintProjectIntent(stageDefinition, projectIntent) {
55
+ if (stageDefinition.contractType === "build-file-evidence")
56
+ return null;
57
+ return projectIntent;
58
+ }
54
59
  export function computeStageFingerprint(contextGraphPath, stageDefinition) {
55
60
  const stageInputs = loadBuildStageInputs(contextGraphPath, stageDefinition.id);
56
61
  if (!stageInputs)
@@ -67,6 +72,10 @@ export function computeStageFingerprint(contextGraphPath, stageDefinition) {
67
72
  id: plan.context.buildPlanId,
68
73
  package_hash: buildPlanPackageHash(contextGraphPath),
69
74
  },
75
+ project: {
76
+ id: plan.context.project.id,
77
+ intent: stageFingerprintProjectIntent(stageDefinition, plan.context.projectIntent),
78
+ },
70
79
  source_manifest: {
71
80
  manifest_id: sourceManifest.manifest_id,
72
81
  generated_at: sourceManifest.generated_at,
@@ -104,6 +113,9 @@ export function computeStageFingerprint(contextGraphPath, stageDefinition) {
104
113
  }))
105
114
  .sort((left, right) => `${left.artifact_id}:${left.path}`.localeCompare(`${right.artifact_id}:${right.path}`)),
106
115
  },
116
+ context_checks: stageDefinition.contractType === "build-file-evidence"
117
+ ? []
118
+ : [...plan.contract.context_checks],
107
119
  },
108
120
  };
109
121
  return StageFingerprintSchema.parse(sha256(stableJson(payload)));
@@ -0,0 +1,81 @@
1
+ import { type AgentExecutor } from "../agents/lib/executors.js";
2
+ import { type ExecutionStageLedger, type RuntimeStageContract, type StageExecutionSession } from "./lib/schema.js";
3
+ import type { AgentJobType } from "./lib/schema.js";
4
+ import type { BuildPlanId, ProjectId, RuntimeContractType, RuntimeExecutorInfo, RuntimeStage } from "../../contracts/lib/schema.js";
5
+ export declare function writeStageExecutionSessionStarted(options: {
6
+ contextGraphPath: string;
7
+ jobType?: AgentJobType;
8
+ project: ProjectId;
9
+ projectIntent?: string | null;
10
+ buildPlanId: BuildPlanId;
11
+ buildRunId?: string | null;
12
+ stageId: RuntimeStage | null;
13
+ stageLabel: string | null;
14
+ contractType: RuntimeContractType | null;
15
+ stageRunId: string;
16
+ attempt?: number;
17
+ executor: RuntimeExecutorInfo | AgentExecutor;
18
+ shellRoot: string | null;
19
+ contractPath: string | null;
20
+ promptPath: string | null;
21
+ eventStreamPath: string | null;
22
+ statusPath: string | null;
23
+ summary: string | null;
24
+ }): StageExecutionSession;
25
+ export declare function writeStageExecutionSessionStartedFromLedger(options: {
26
+ contextGraphPath: string;
27
+ run: ExecutionStageLedger;
28
+ contract: RuntimeStageContract;
29
+ buildRunId?: string | null;
30
+ shellRoot: string | null;
31
+ promptPath: string | null;
32
+ eventStreamPath: string | null;
33
+ statusPath: string | null;
34
+ }): StageExecutionSession;
35
+ /**
36
+ * Project the terminal session state from a finished ExecutionStageLedger. The
37
+ * session is a projection of the ledger, so the ledger→session field mapping
38
+ * (stage, run id, terminal status, summary, error) lives HERE, once, instead of
39
+ * being re-stated by hand at every ledger-terminal write site. A `running`
40
+ * ledger is not terminal and is ignored (no-op) so callers can pass the record
41
+ * unconditionally. Returns null when no session exists for the run (same
42
+ * contract as `writeStageExecutionSessionFinished`).
43
+ */
44
+ export declare function projectSessionFinishedFromLedger(contextGraphPath: string, ledger: ExecutionStageLedger): StageExecutionSession | null;
45
+ export declare function writeStageExecutionSessionFinished(options: {
46
+ contextGraphPath: string;
47
+ stageId: string | null;
48
+ stageRunId: string;
49
+ status: "succeeded" | "failed";
50
+ summary: string;
51
+ error?: string | null;
52
+ }): StageExecutionSession | null;
53
+ export declare function recordStageExecutionSessionValidationAttempt(options: {
54
+ contextGraphPath: string;
55
+ stageId: string;
56
+ stageRunId: string;
57
+ attempt: number;
58
+ status: "succeeded" | "failed";
59
+ summary: string;
60
+ }): StageExecutionSession | null;
61
+ export declare function markStageExecutionSessionsShellPreserved(options: {
62
+ contextGraphPath: string;
63
+ shellRoot: string;
64
+ }): void;
65
+ /**
66
+ * Reconcile sessions after their stage execution shells were pruned. The build
67
+ * pipeline deletes the whole execution-shells root on a successful build under
68
+ * non-"always" retention, but the session records live in a SEPARATE
69
+ * stage-sessions dir and would keep pointing at the deleted shell with
70
+ * `replay_ready: true` — a dangling pointer (F2). For every session whose shell
71
+ * root no longer exists on disk, downgrade it so "session exists" still implies
72
+ * "session is real": `replay_ready` false, preserved-shell manifest path
73
+ * nulled, and a retention reason recorded. Already-downgraded sessions and
74
+ * sessions whose shell still exists are left untouched. Best-effort and
75
+ * idempotent; runs in the build's `finally`, so it must never throw.
76
+ */
77
+ export declare function reconcilePrunedStageExecutionSessions(options: {
78
+ contextGraphPath: string;
79
+ reason?: string;
80
+ }): void;
81
+ export declare function listStageExecutionSessions(contextGraphPath: string): StageExecutionSession[];
@@ -0,0 +1,308 @@
1
+ import { existsSync, readFileSync, readdirSync, } from "node:fs";
2
+ import { isAbsolute, join, relative, } from "node:path";
3
+ import { preservedShellManifestPath, shellWorkspaceManifestPath, } from "../agents/lib/shell-paths.js";
4
+ import { buildRuntimeExecutorInfo, } from "../agents/lib/executors.js";
5
+ import { contextGraphRuntimeStageSessionPath, contextGraphRuntimeStageSessionsRoot, } from "./context-graph-paths.js";
6
+ import { writeJsonAtomic } from "./atomic-fs.js";
7
+ import { ExecutionShellPathsSchema, StageExecutionSessionSchema, } from "./lib/schema.js";
8
+ function contextRelative(contextGraphPath, path) {
9
+ if (!path)
10
+ return null;
11
+ const rel = isAbsolute(path) ? relative(contextGraphPath, path) : path;
12
+ return rel.replaceAll("\\", "/");
13
+ }
14
+ function shellRuntimeFile(contextGraphPath, shellRoot, fileName) {
15
+ if (!shellRoot)
16
+ return null;
17
+ return contextRelative(contextGraphPath, join(shellRoot, "runtime", fileName));
18
+ }
19
+ /**
20
+ * Context-relative path to a shell runtime file ONLY when it exists on disk.
21
+ * Used for artifacts that are written DURING the run (e.g. the agent reasoning
22
+ * transcript), so a session never advertises a dangling path: null at session
23
+ * start (the file does not exist yet, and a non-reasoning run never creates it),
24
+ * the real path once it has been teed. `shellRootRel` is the context-relative
25
+ * shell root (`.` for the no-shell case, which has no runtime dir to reference).
26
+ */
27
+ function runtimeFileIfExists(contextGraphPath, shellRootRel, fileName) {
28
+ if (!shellRootRel || shellRootRel === ".")
29
+ return null;
30
+ const rel = `${shellRootRel.replace(/\/+$/, "")}/runtime/${fileName}`;
31
+ return existsSync(join(contextGraphPath, rel)) ? rel : null;
32
+ }
33
+ function readShellPaths(shellRoot) {
34
+ if (!shellRoot)
35
+ return null;
36
+ const filePath = join(shellRoot, "runtime", "paths.json");
37
+ if (!existsSync(filePath))
38
+ return null;
39
+ try {
40
+ return ExecutionShellPathsSchema.parse(JSON.parse(readFileSync(filePath, "utf8")));
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ // Stage jobs key the session dir off `stage_id`. Non-stage jobs (job_type !==
47
+ // "stage"/"source-inventory") carry a null stage_id, so they bucket under a
48
+ // stable "_job" segment keyed by stage_run_id. Stage layout is unchanged: every
49
+ // current writer passes a real stage id.
50
+ function stageSessionPath(contextGraphPath, stageId, stageRunId) {
51
+ return contextGraphRuntimeStageSessionPath(contextGraphPath, stageId ?? "_job", stageRunId);
52
+ }
53
+ function readSessionAt(path) {
54
+ if (!existsSync(path))
55
+ return null;
56
+ try {
57
+ return StageExecutionSessionSchema.parse(JSON.parse(readFileSync(path, "utf8")));
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
63
+ function readSession(contextGraphPath, stageId, stageRunId) {
64
+ return readSessionAt(stageSessionPath(contextGraphPath, stageId, stageRunId));
65
+ }
66
+ function writeSession(contextGraphPath, session) {
67
+ const parsed = StageExecutionSessionSchema.parse(session);
68
+ writeJsonAtomic(stageSessionPath(contextGraphPath, parsed.stage_id, parsed.stage_run_id), parsed);
69
+ return parsed;
70
+ }
71
+ function nextAttemptForStage(contextGraphPath, stageId) {
72
+ return listStageExecutionSessions(contextGraphPath)
73
+ .filter((session) => session.stage_id === stageId)
74
+ .length + 1;
75
+ }
76
+ export function writeStageExecutionSessionStarted(options) {
77
+ const now = new Date().toISOString();
78
+ const shellRoot = options.shellRoot;
79
+ const paths = readShellPaths(shellRoot);
80
+ const shellRootPath = contextRelative(options.contextGraphPath, shellRoot) ?? ".";
81
+ const workspacePath = shellRoot ? shellWorkspaceManifestPath(shellRoot) : null;
82
+ const preservedPath = shellRoot ? preservedShellManifestPath(shellRoot) : null;
83
+ const executor = "execute" in options.executor
84
+ ? buildRuntimeExecutorInfo(options.executor)
85
+ : options.executor;
86
+ const existing = readSession(options.contextGraphPath, options.stageId, options.stageRunId);
87
+ return writeSession(options.contextGraphPath, {
88
+ kind: "interf-stage-execution-session",
89
+ version: 1,
90
+ job_type: existing?.job_type ?? options.jobType ?? "stage",
91
+ generated_at: existing?.generated_at ?? now,
92
+ updated_at: now,
93
+ project: options.project,
94
+ project_intent: options.projectIntent ?? null,
95
+ context_graph_path: options.contextGraphPath,
96
+ build_plan: options.buildPlanId,
97
+ build_run_id: options.buildRunId ?? null,
98
+ stage_id: options.stageId,
99
+ stage_label: options.stageLabel,
100
+ contract_type: options.contractType,
101
+ stage_run_id: options.stageRunId,
102
+ attempt: existing?.attempt ?? options.attempt ?? nextAttemptForStage(options.contextGraphPath, options.stageId),
103
+ status: existing?.status ?? "running",
104
+ executor,
105
+ shell: {
106
+ root_path: shellRootPath,
107
+ workspace_manifest_path: workspacePath && existsSync(workspacePath)
108
+ ? contextRelative(options.contextGraphPath, workspacePath)
109
+ : null,
110
+ preserved_shell_manifest_path: preservedPath && existsSync(preservedPath)
111
+ ? contextRelative(options.contextGraphPath, preservedPath)
112
+ : null,
113
+ replay_ready: Boolean(shellRoot && existsSync(join(shellRoot, "AGENTS.md"))),
114
+ retention_reason: existing?.shell.retention_reason ?? null,
115
+ },
116
+ logs: {
117
+ prompt_path: contextRelative(options.contextGraphPath, options.promptPath),
118
+ event_stream_path: contextRelative(options.contextGraphPath, options.eventStreamPath),
119
+ status_path: contextRelative(options.contextGraphPath, options.statusPath),
120
+ },
121
+ runtime_files: {
122
+ project_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "project.json"),
123
+ contract_path: contextRelative(options.contextGraphPath, options.contractPath),
124
+ paths_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "paths.json"),
125
+ source_locator_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "source-locator.json"),
126
+ source_manifest_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "source-manifest.json"),
127
+ source_state_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "source-state.json"),
128
+ stage_inputs_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "stage-inputs.json"),
129
+ expected_inputs_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "expected-inputs.json"),
130
+ reviewed_inputs_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "reviewed-inputs.json"),
131
+ previous_attempts_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "previous-attempts.json"),
132
+ retry_feedback_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "retry-feedback.md"),
133
+ last_validation_failure_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "last-validation-failure.txt"),
134
+ verifier_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "check-stage.mjs"),
135
+ stage_evidence_path: shellRuntimeFile(options.contextGraphPath, shellRoot, "stage-evidence.json"),
136
+ reasoning_path: existing?.runtime_files.reasoning_path
137
+ ?? runtimeFileIfExists(options.contextGraphPath, shellRootPath, "agent-reasoning.jsonl"),
138
+ },
139
+ artifacts: {
140
+ reads: paths?.reads ?? [],
141
+ writes: paths?.writes ?? [],
142
+ },
143
+ validation_attempts: existing?.validation_attempts ?? [],
144
+ summary: options.summary,
145
+ error: existing?.error ?? null,
146
+ });
147
+ }
148
+ export function writeStageExecutionSessionStartedFromLedger(options) {
149
+ return writeStageExecutionSessionStarted({
150
+ contextGraphPath: options.contextGraphPath,
151
+ project: options.contract.project.id,
152
+ projectIntent: options.contract.project.intent,
153
+ buildPlanId: options.contract.build_plan.id,
154
+ buildRunId: options.buildRunId ?? null,
155
+ stageId: options.run.stage,
156
+ stageLabel: options.run.stage_label,
157
+ contractType: options.run.contract_type,
158
+ stageRunId: options.run.run_id,
159
+ executor: options.run.executor,
160
+ shellRoot: options.shellRoot,
161
+ contractPath: options.shellRoot
162
+ ? join(options.shellRoot, "runtime", "stage-contract.json")
163
+ : join(options.contextGraphPath, options.run.contract_path),
164
+ promptPath: options.promptPath,
165
+ eventStreamPath: options.eventStreamPath,
166
+ statusPath: options.statusPath,
167
+ summary: options.run.summary,
168
+ });
169
+ }
170
+ /**
171
+ * Project the terminal session state from a finished ExecutionStageLedger. The
172
+ * session is a projection of the ledger, so the ledger→session field mapping
173
+ * (stage, run id, terminal status, summary, error) lives HERE, once, instead of
174
+ * being re-stated by hand at every ledger-terminal write site. A `running`
175
+ * ledger is not terminal and is ignored (no-op) so callers can pass the record
176
+ * unconditionally. Returns null when no session exists for the run (same
177
+ * contract as `writeStageExecutionSessionFinished`).
178
+ */
179
+ export function projectSessionFinishedFromLedger(contextGraphPath, ledger) {
180
+ if (ledger.status === "running")
181
+ return null;
182
+ return writeStageExecutionSessionFinished({
183
+ contextGraphPath,
184
+ stageId: ledger.stage,
185
+ stageRunId: ledger.run_id,
186
+ status: ledger.status,
187
+ summary: ledger.summary,
188
+ error: ledger.error,
189
+ });
190
+ }
191
+ export function writeStageExecutionSessionFinished(options) {
192
+ const current = readSession(options.contextGraphPath, options.stageId, options.stageRunId);
193
+ if (!current)
194
+ return null;
195
+ return writeSession(options.contextGraphPath, {
196
+ ...current,
197
+ updated_at: new Date().toISOString(),
198
+ status: options.status,
199
+ summary: options.summary,
200
+ error: options.error ?? null,
201
+ runtime_files: {
202
+ ...current.runtime_files,
203
+ // The reasoning transcript is teed DURING the run, so resolve it at finish:
204
+ // set the path iff the agent actually emitted reasoning (file exists), else
205
+ // leave null. Keeps "session references a reasoning file" => "the file is real".
206
+ reasoning_path: current.runtime_files.reasoning_path
207
+ ?? runtimeFileIfExists(options.contextGraphPath, current.shell.root_path, "agent-reasoning.jsonl"),
208
+ },
209
+ });
210
+ }
211
+ export function recordStageExecutionSessionValidationAttempt(options) {
212
+ const current = readSession(options.contextGraphPath, options.stageId, options.stageRunId);
213
+ if (!current)
214
+ return null;
215
+ const withoutExisting = current.validation_attempts
216
+ .filter((attempt) => attempt.attempt !== options.attempt);
217
+ return writeSession(options.contextGraphPath, {
218
+ ...current,
219
+ updated_at: new Date().toISOString(),
220
+ validation_attempts: [
221
+ ...withoutExisting,
222
+ {
223
+ attempt: options.attempt,
224
+ recorded_at: new Date().toISOString(),
225
+ status: options.status,
226
+ summary: options.summary,
227
+ },
228
+ ].sort((left, right) => left.attempt - right.attempt),
229
+ });
230
+ }
231
+ export function markStageExecutionSessionsShellPreserved(options) {
232
+ const shellRootPath = contextRelative(options.contextGraphPath, options.shellRoot);
233
+ const preservedPath = preservedShellManifestPath(options.shellRoot);
234
+ const preservedRel = existsSync(preservedPath)
235
+ ? contextRelative(options.contextGraphPath, preservedPath)
236
+ : null;
237
+ for (const session of listStageExecutionSessions(options.contextGraphPath)) {
238
+ if (session.shell.root_path !== shellRootPath)
239
+ continue;
240
+ writeSession(options.contextGraphPath, {
241
+ ...session,
242
+ updated_at: new Date().toISOString(),
243
+ shell: {
244
+ ...session.shell,
245
+ preserved_shell_manifest_path: preservedRel,
246
+ replay_ready: session.shell.replay_ready && existsSync(join(options.shellRoot, "AGENTS.md")),
247
+ },
248
+ });
249
+ }
250
+ }
251
+ /**
252
+ * Reconcile sessions after their stage execution shells were pruned. The build
253
+ * pipeline deletes the whole execution-shells root on a successful build under
254
+ * non-"always" retention, but the session records live in a SEPARATE
255
+ * stage-sessions dir and would keep pointing at the deleted shell with
256
+ * `replay_ready: true` — a dangling pointer (F2). For every session whose shell
257
+ * root no longer exists on disk, downgrade it so "session exists" still implies
258
+ * "session is real": `replay_ready` false, preserved-shell manifest path
259
+ * nulled, and a retention reason recorded. Already-downgraded sessions and
260
+ * sessions whose shell still exists are left untouched. Best-effort and
261
+ * idempotent; runs in the build's `finally`, so it must never throw.
262
+ */
263
+ export function reconcilePrunedStageExecutionSessions(options) {
264
+ const reason = options.reason
265
+ ?? "Stage execution shell pruned after a successful Build (on-failure retention).";
266
+ for (const session of listStageExecutionSessions(options.contextGraphPath)) {
267
+ const shellRootAbsolute = join(options.contextGraphPath, session.shell.root_path);
268
+ if (existsSync(shellRootAbsolute))
269
+ continue;
270
+ if (!session.shell.replay_ready
271
+ && session.shell.preserved_shell_manifest_path === null
272
+ && session.shell.retention_reason !== null) {
273
+ continue;
274
+ }
275
+ writeSession(options.contextGraphPath, {
276
+ ...session,
277
+ updated_at: new Date().toISOString(),
278
+ shell: {
279
+ ...session.shell,
280
+ preserved_shell_manifest_path: null,
281
+ replay_ready: false,
282
+ retention_reason: reason,
283
+ },
284
+ });
285
+ }
286
+ }
287
+ export function listStageExecutionSessions(contextGraphPath) {
288
+ const root = contextGraphRuntimeStageSessionsRoot(contextGraphPath);
289
+ if (!existsSync(root))
290
+ return [];
291
+ const sessions = [];
292
+ for (const stageId of readdirSync(root)) {
293
+ const stageRoot = join(root, stageId);
294
+ if (!existsSync(stageRoot))
295
+ continue;
296
+ for (const stageRunId of readdirSync(stageRoot)) {
297
+ const session = readSessionAt(join(stageRoot, stageRunId, "session.json"));
298
+ if (session)
299
+ sessions.push(session);
300
+ }
301
+ }
302
+ return sessions.sort((left, right) => {
303
+ const byGenerated = Date.parse(left.generated_at) - Date.parse(right.generated_at);
304
+ if (byGenerated !== 0)
305
+ return byGenerated;
306
+ return left.stage_run_id.localeCompare(right.stage_run_id);
307
+ });
308
+ }
@@ -3,11 +3,10 @@ import { warnInterf } from "../../contracts/utils/logger.js";
3
3
  import { readJsonFileUnchecked, readJsonFileWithSchema } from "../../contracts/utils/parse.js";
4
4
  import { ContextGraphHealthSchema, ContextGraphStateSchema, ContextGraphViewSpecSchema, SourceFilesSchema, SourceManifestSchema, SourceStateSchema, } from "./lib/schema.js";
5
5
  import { emptyExecutionInventory, } from "./runtime-inventory.js";
6
- import { healthPath, sourceManifestPath, sourceFilesPath, sourceStatePath, statePath, viewSpecPath, } from "./state-paths.js";
7
- import { contextGraphExecutionInventoryPath, } from "./context-graph-paths.js";
6
+ import { contextGraphExecutionInventoryPath, contextGraphRuntimeHealthPath, contextGraphRuntimeSourceFilesPath, contextGraphRuntimeSourceManifestPath, contextGraphRuntimeSourceStatePath, contextGraphRuntimeStatePath, contextGraphRuntimeViewSpecPath, } from "./context-graph-paths.js";
8
7
  import { writeJsonAtomic } from "./atomic-fs.js";
9
8
  export function loadState(dirPath) {
10
- const path = statePath(dirPath);
9
+ const path = contextGraphRuntimeStatePath(dirPath);
11
10
  if (!existsSync(path))
12
11
  return null;
13
12
  const raw = readJsonFileUnchecked(path, "runtime state");
@@ -21,28 +20,28 @@ export function loadState(dirPath) {
21
20
  return null;
22
21
  }
23
22
  export function saveState(dirPath, state) {
24
- writeJsonAtomic(statePath(dirPath), state);
23
+ writeJsonAtomic(contextGraphRuntimeStatePath(dirPath), state);
25
24
  }
26
25
  export function loadContextGraphHealth(dirPath) {
27
- const path = healthPath(dirPath);
26
+ const path = contextGraphRuntimeHealthPath(dirPath);
28
27
  if (!existsSync(path))
29
28
  return null;
30
29
  return readJsonFileWithSchema(path, "context-graph health", ContextGraphHealthSchema);
31
30
  }
32
31
  export function saveContextGraphHealth(dirPath, health) {
33
- writeJsonAtomic(healthPath(dirPath), health);
32
+ writeJsonAtomic(contextGraphRuntimeHealthPath(dirPath), health);
34
33
  }
35
34
  export function loadContextGraphViewSpec(dirPath) {
36
- const path = viewSpecPath(dirPath);
35
+ const path = contextGraphRuntimeViewSpecPath(dirPath);
37
36
  if (!existsSync(path))
38
37
  return null;
39
38
  return loadViewSpec(path, ContextGraphViewSpecSchema);
40
39
  }
41
40
  export function saveContextGraphViewSpec(dirPath, viewSpec) {
42
- writeJsonAtomic(viewSpecPath(dirPath), viewSpec);
41
+ writeJsonAtomic(contextGraphRuntimeViewSpecPath(dirPath), viewSpec);
43
42
  }
44
43
  export function loadContextGraphSourceManifest(dirPath) {
45
- const path = sourceManifestPath(dirPath);
44
+ const path = contextGraphRuntimeSourceManifestPath(dirPath);
46
45
  if (!existsSync(path))
47
46
  return null;
48
47
  return readJsonFileWithSchema(path, "context-graph source manifest", SourceManifestSchema);
@@ -64,7 +63,7 @@ export function loadContextGraphSourceFiles(dirPath) {
64
63
  })),
65
64
  });
66
65
  }
67
- const path = sourceFilesPath(dirPath);
66
+ const path = contextGraphRuntimeSourceFilesPath(dirPath);
68
67
  if (!existsSync(path))
69
68
  return null;
70
69
  return readJsonFileWithSchema(path, "context-graph source files", SourceFilesSchema);
@@ -88,7 +87,7 @@ export function loadContextGraphSourceState(dirPath) {
88
87
  })),
89
88
  });
90
89
  }
91
- const path = sourceStatePath(dirPath);
90
+ const path = contextGraphRuntimeSourceStatePath(dirPath);
92
91
  if (!existsSync(path))
93
92
  return null;
94
93
  return readJsonFileWithSchema(path, "context-graph source state", SourceStateSchema);
@@ -113,7 +113,7 @@ function buildDefaultContextGraphViewSpec(dirPath, contextGraphName, generatedAt
113
113
  { id: "status", type: "status", title: "Build Status", path: ".interf/runtime/health.json" },
114
114
  { id: "cards", type: "cards", title: "Key Metrics", path: ".interf/runtime/health.json" },
115
115
  ...(outputDocumentPaths.length > 0
116
- ? [{ id: "outputs", type: "documents", title: "Output Artifacts", paths: outputDocumentPaths }]
116
+ ? [{ id: "outputs", type: "documents", title: "Requested outputs", paths: outputDocumentPaths }]
117
117
  : []),
118
118
  { id: "build-plan", type: "documents", title: "Build Plan Docs", paths: ["build-plan/README.md", ...buildPlan.stages.map((stage) => `build-plan/build/stages/${stage.skillDir}`)] },
119
119
  ],
@@ -1,5 +1,5 @@
1
1
  export type { RuntimeStatus, BuildStage, ContextGraphState, ContextGraphHealth, ViewSection, ViewCard, ContextGraphViewSpec, SourceFiles, SourceState, StageInputs, } from "./lib/schema.js";
2
- export { statePath, healthPath, viewSpecPath, sourceFilesPath, sourceStatePath, } from "./state-paths.js";
2
+ export { contextGraphRuntimeStatePath as statePath, contextGraphRuntimeHealthPath as healthPath, contextGraphRuntimeViewSpecPath as viewSpecPath, contextGraphRuntimeSourceFilesPath as sourceFilesPath, contextGraphRuntimeSourceStatePath as sourceStatePath, } from "./context-graph-paths.js";
3
3
  export { loadState, saveState, loadContextGraphHealth, saveContextGraphHealth, loadContextGraphViewSpec, loadContextGraphSourceFiles, loadContextGraphSourceState, saveContextGraphViewSpec, initContextGraphState, } from "./state-io.js";
4
4
  export { refreshContextGraphArtifacts, } from "./state-artifacts.js";
5
5
  export { computeContextGraphHealth, resolveContextGraphStatus, resolveBuildStage, } from "./state-health.js";
@@ -1,4 +1,4 @@
1
- export { statePath, healthPath, viewSpecPath, sourceFilesPath, sourceStatePath, } from "./state-paths.js";
1
+ export { contextGraphRuntimeStatePath as statePath, contextGraphRuntimeHealthPath as healthPath, contextGraphRuntimeViewSpecPath as viewSpecPath, contextGraphRuntimeSourceFilesPath as sourceFilesPath, contextGraphRuntimeSourceStatePath as sourceStatePath, } from "./context-graph-paths.js";
2
2
  export { loadState, saveState, loadContextGraphHealth, saveContextGraphHealth, loadContextGraphViewSpec, loadContextGraphSourceFiles, loadContextGraphSourceState, saveContextGraphViewSpec, initContextGraphState, } from "./state-io.js";
3
3
  export { refreshContextGraphArtifacts, } from "./state-artifacts.js";
4
4
  export { computeContextGraphHealth, resolveContextGraphStatus, resolveBuildStage, } from "./state-health.js";
@@ -0,0 +1,21 @@
1
+ /** Stable delimiters around the managed coverage block in `home.md`. */
2
+ export declare const HOME_COVERAGE_BLOCK_BEGIN = "<!-- interf:coverage-index:begin -->";
3
+ export declare const HOME_COVERAGE_BLOCK_END = "<!-- interf:coverage-index:end -->";
4
+ export interface SummaryCoverageIndexResult {
5
+ /** Number of summary notes the home coverage block wikilinks. */
6
+ summaries: number;
7
+ /** The file the navigation links were written into. */
8
+ indexPath: string;
9
+ }
10
+ /**
11
+ * Ensure `home.md` wikilinks every summary the build produced, via a managed,
12
+ * deterministic coverage block. Call this at build finalization, AFTER the stage
13
+ * agents have produced summaries, BEFORE the connectivity check runs. Guarantees
14
+ * every summary note has an inbound graph edge from the entrypoint spine
15
+ * regardless of agent behavior.
16
+ *
17
+ * Returns the count of linked summaries, or `null` when there is nothing to index
18
+ * (no `summaries/` layer). Never throws into the build: assembly is already
19
+ * complete; this is the connectivity floor laid on top.
20
+ */
21
+ export declare function ensureSummaryCoverageIndex(contextGraphPath: string): SummaryCoverageIndexResult | null;