@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.
- package/README.md +122 -226
- package/dist/cli/commands/agents.js +1 -32
- package/dist/cli/commands/benchmark.d.ts +2 -3
- package/dist/cli/commands/benchmark.js +1 -31
- package/dist/cli/commands/build-plan.js +26 -50
- package/dist/cli/commands/build.d.ts +2 -3
- package/dist/cli/commands/build.js +1 -31
- package/dist/cli/commands/graphs.js +177 -32
- package/dist/cli/commands/mcp.d.ts +1 -0
- package/dist/cli/commands/mcp.js +223 -126
- package/dist/cli/commands/project.js +10 -36
- package/dist/cli/commands/reset.d.ts +2 -3
- package/dist/cli/commands/reset.js +1 -22
- package/dist/cli/commands/runs.js +86 -33
- package/dist/cli/commands/status.js +3 -24
- package/dist/cli/commands/traces.js +1 -29
- package/dist/cli/commands/wizard.js +17 -29
- package/dist/cli/lib/http-client.d.ts +39 -0
- package/dist/cli/lib/http-client.js +73 -0
- package/dist/packages/build-plans/authoring/brief.d.ts +25 -4
- package/dist/packages/build-plans/authoring/build-plan-authoring.d.ts +42 -1
- package/dist/packages/build-plans/authoring/build-plan-authoring.js +470 -63
- package/dist/packages/build-plans/authoring/build-plan-edit-session.d.ts +9 -0
- package/dist/packages/build-plans/authoring/build-plan-edit-session.js +27 -10
- package/dist/packages/build-plans/authoring/build-plan-improvement.js +62 -8
- package/dist/packages/build-plans/authoring/lib/build-plan-edit-utils.d.ts +1 -0
- package/dist/packages/build-plans/package/build-plan-definitions.d.ts +0 -1
- package/dist/packages/build-plans/package/build-plan-definitions.js +5 -3
- package/dist/packages/build-plans/package/build-plan-stage-runner.d.ts +1 -0
- package/dist/packages/build-plans/package/build-plan-stage-runner.js +2 -1
- package/dist/packages/build-plans/package/builtin-build-plan.d.ts +2 -2
- package/dist/packages/build-plans/package/builtin-build-plan.js +3 -3
- package/dist/packages/build-plans/package/context-interface.d.ts +3 -0
- package/dist/packages/build-plans/package/context-interface.js +5 -5
- package/dist/packages/build-plans/package/interf-build-plan-package.js +22 -22
- package/dist/packages/build-plans/package/local-build-plans.d.ts +10 -5
- package/dist/packages/build-plans/package/local-build-plans.js +57 -32
- package/dist/packages/contracts/index.d.ts +4 -3
- package/dist/packages/contracts/index.js +2 -1
- package/dist/packages/contracts/lib/context-graph-layer.d.ts +161 -0
- package/dist/packages/contracts/lib/context-graph-layer.js +216 -0
- package/dist/packages/contracts/lib/project-paths.d.ts +7 -0
- package/dist/packages/contracts/lib/project-paths.js +9 -0
- package/dist/packages/contracts/lib/project-schema.d.ts +264 -1
- package/dist/packages/contracts/lib/project-schema.js +38 -13
- package/dist/packages/contracts/lib/schema.d.ts +556 -23
- package/dist/packages/contracts/lib/schema.js +279 -18
- package/dist/packages/contracts/utils/filesystem.d.ts +1 -0
- package/dist/packages/contracts/utils/filesystem.js +29 -1
- package/dist/packages/projects/lib/schema.d.ts +6 -8
- package/dist/packages/projects/lib/schema.js +3 -1
- package/dist/packages/projects/source-config.d.ts +0 -5
- package/dist/packages/projects/source-config.js +9 -22
- package/dist/packages/runtime/actions/fields.d.ts +4 -0
- package/dist/packages/runtime/actions/form-builders.js +79 -31
- package/dist/packages/runtime/actions/form-validators.js +9 -3
- package/dist/packages/runtime/actions/helpers.js +3 -3
- package/dist/packages/runtime/actions/registry.d.ts +1 -1
- package/dist/packages/runtime/actions/registry.js +1 -1
- package/dist/packages/runtime/actions/requests.d.ts +1 -1
- package/dist/packages/runtime/actions/requests.js +12 -6
- package/dist/packages/runtime/actions/schemas.d.ts +7 -0
- package/dist/packages/runtime/actions/schemas.js +1 -0
- package/dist/packages/runtime/agent-handoff.js +8 -7
- package/dist/packages/runtime/agents/lib/execution-profile.d.ts +14 -0
- package/dist/packages/runtime/agents/lib/execution-profile.js +23 -0
- package/dist/packages/runtime/agents/lib/execution.js +14 -8
- package/dist/packages/runtime/agents/lib/executors.d.ts +1 -0
- package/dist/packages/runtime/agents/lib/executors.js +11 -2
- package/dist/packages/runtime/agents/lib/logs.d.ts +10 -0
- package/dist/packages/runtime/agents/lib/logs.js +32 -8
- package/dist/packages/runtime/agents/lib/preflight.js +4 -1
- package/dist/packages/runtime/agents/lib/render.d.ts +18 -0
- package/dist/packages/runtime/agents/lib/render.js +44 -18
- package/dist/packages/runtime/agents/lib/shell-templates.js +105 -63
- package/dist/packages/runtime/agents/lib/shells.d.ts +29 -0
- package/dist/packages/runtime/agents/lib/shells.js +158 -32
- package/dist/packages/runtime/agents/lib/source-context-scan.d.ts +10 -0
- package/dist/packages/runtime/agents/lib/source-context-scan.js +388 -0
- package/dist/packages/runtime/agents/lib/status.js +1 -14
- package/dist/packages/runtime/agents/lib/string-utils.d.ts +16 -0
- package/dist/packages/runtime/agents/lib/string-utils.js +36 -0
- package/dist/packages/runtime/agents/lib/types.d.ts +1 -0
- package/dist/packages/runtime/agents/providers/codex.js +2 -0
- package/dist/packages/runtime/agents/role-executors.js +2 -1
- package/dist/packages/runtime/auth/session-store.js +11 -3
- package/dist/packages/runtime/benchmark-question-draft.d.ts +3 -0
- package/dist/packages/runtime/benchmark-question-draft.js +57 -28
- package/dist/packages/runtime/build/artifact-status.d.ts +1 -1
- package/dist/packages/runtime/build/artifact-status.js +1 -1
- package/dist/packages/runtime/build/build-evidence.d.ts +2 -1
- package/dist/packages/runtime/build/build-evidence.js +11 -5
- package/dist/packages/runtime/build/build-pipeline.js +89 -5
- package/dist/packages/runtime/build/build-stage-plan.js +3 -1
- package/dist/packages/runtime/build/build-stage-runner.js +169 -32
- package/dist/packages/runtime/build/build-target.d.ts +3 -0
- package/dist/packages/runtime/build/build-target.js +25 -1
- package/dist/packages/runtime/build/check-evaluator.d.ts +1 -1
- package/dist/packages/runtime/build/check-evaluator.js +655 -4
- package/dist/packages/runtime/build/context-graph-paths.d.ts +13 -0
- package/dist/packages/runtime/build/context-graph-paths.js +27 -0
- package/dist/packages/runtime/build/index.d.ts +2 -2
- package/dist/packages/runtime/build/index.js +2 -2
- package/dist/packages/runtime/build/inspect-map.d.ts +10 -0
- package/dist/packages/runtime/build/inspect-map.js +270 -0
- package/dist/packages/runtime/build/lib/schema.d.ts +246 -53
- package/dist/packages/runtime/build/lib/schema.js +173 -15
- package/dist/packages/runtime/build/native-entrypoint.d.ts +2 -0
- package/dist/packages/runtime/build/native-entrypoint.js +286 -0
- package/dist/packages/runtime/build/runtime-contracts.js +9 -3
- package/dist/packages/runtime/build/runtime-log-paths.d.ts +3 -0
- package/dist/packages/runtime/build/runtime-log-paths.js +16 -0
- package/dist/packages/runtime/build/runtime-prompt.js +6 -4
- package/dist/packages/runtime/build/runtime-runs.js +63 -10
- package/dist/packages/runtime/build/runtime-types.d.ts +4 -1
- package/dist/packages/runtime/build/runtime.d.ts +3 -1
- package/dist/packages/runtime/build/runtime.js +3 -1
- package/dist/packages/runtime/build/source-files.js +11 -2
- package/dist/packages/runtime/build/source-inventory.d.ts +1 -0
- package/dist/packages/runtime/build/source-inventory.js +246 -7
- package/dist/packages/runtime/build/source-manifest.d.ts +11 -0
- package/dist/packages/runtime/build/source-manifest.js +30 -2
- package/dist/packages/runtime/build/stage-evidence.js +80 -11
- package/dist/packages/runtime/build/stage-manifest.d.ts +45 -0
- package/dist/packages/runtime/build/stage-manifest.js +1125 -0
- package/dist/packages/runtime/build/stage-reuse.js +12 -0
- package/dist/packages/runtime/build/stage-session.d.ts +81 -0
- package/dist/packages/runtime/build/stage-session.js +308 -0
- package/dist/packages/runtime/build/state-io.js +10 -11
- package/dist/packages/runtime/build/state-view.js +1 -1
- package/dist/packages/runtime/build/state.d.ts +1 -1
- package/dist/packages/runtime/build/state.js +1 -1
- package/dist/packages/runtime/build/summary-coverage-index.d.ts +21 -0
- package/dist/packages/runtime/build/summary-coverage-index.js +189 -0
- package/dist/packages/runtime/build/traces.js +3 -3
- package/dist/packages/runtime/build/validate-context-graph.d.ts +1 -1
- package/dist/packages/runtime/build/validate-context-graph.js +5 -5
- package/dist/packages/runtime/build/validate.d.ts +1 -1
- package/dist/packages/runtime/build/validate.js +1 -1
- package/dist/packages/runtime/client.d.ts +3 -3
- package/dist/packages/runtime/client.js +8 -13
- package/dist/packages/runtime/context-checks.js +13 -0
- package/dist/packages/runtime/context-graph-scaffold.js +2 -1
- package/dist/packages/runtime/context-graph-semantic-graph.d.ts +9 -0
- package/dist/packages/runtime/context-graph-semantic-graph.js +416 -0
- package/dist/packages/runtime/execution/lib/schema.d.ts +34 -31
- package/dist/packages/runtime/index.d.ts +2 -2
- package/dist/packages/runtime/index.js +1 -1
- package/dist/packages/runtime/native-run-handlers.d.ts +38 -0
- package/dist/packages/runtime/native-run-handlers.js +52 -33
- package/dist/packages/runtime/plan-artifact-contract.js +1 -1
- package/dist/packages/runtime/project-source-state.d.ts +4 -4
- package/dist/packages/runtime/project-source-state.js +5 -2
- package/dist/packages/runtime/project-store.d.ts +5 -0
- package/dist/packages/runtime/project-store.js +30 -3
- package/dist/packages/runtime/requested-artifacts.js +1 -1
- package/dist/packages/runtime/run-observability.js +9 -4
- package/dist/packages/runtime/runtime-action-proposals.js +3 -3
- package/dist/packages/runtime/runtime-build-plans.js +47 -3
- package/dist/packages/runtime/runtime-build-runs.js +9 -16
- package/dist/packages/runtime/runtime-caches.d.ts +26 -0
- package/dist/packages/runtime/runtime-caches.js +47 -0
- package/dist/packages/runtime/runtime-jobs.js +6 -6
- package/dist/packages/runtime/runtime-project-mutations.js +1 -0
- package/dist/packages/runtime/runtime-project-reads.d.ts +4 -1
- package/dist/packages/runtime/runtime-project-reads.js +229 -36
- package/dist/packages/runtime/runtime-proposal-helpers.js +6 -6
- package/dist/packages/runtime/runtime-resource-builders.d.ts +4 -2
- package/dist/packages/runtime/runtime-resource-builders.js +16 -14
- package/dist/packages/runtime/runtime-status.d.ts +14 -0
- package/dist/packages/runtime/runtime-status.js +15 -0
- package/dist/packages/runtime/runtime-verify-runs.js +6 -5
- package/dist/packages/runtime/runtime.d.ts +439 -22
- package/dist/packages/runtime/runtime.js +16 -2
- package/dist/packages/runtime/schemas/actions.d.ts +24 -0
- package/dist/packages/runtime/schemas/agents.d.ts +28 -0
- package/dist/packages/runtime/schemas/agents.js +33 -0
- package/dist/packages/runtime/schemas/build-plans.d.ts +181 -8
- package/dist/packages/runtime/schemas/build-plans.js +36 -2
- package/dist/packages/runtime/schemas/context-graphs.d.ts +1522 -0
- package/dist/packages/runtime/schemas/context-graphs.js +110 -0
- package/dist/packages/runtime/schemas/files.d.ts +7 -347
- package/dist/packages/runtime/schemas/files.js +1 -24
- package/dist/packages/runtime/schemas/index.d.ts +1 -0
- package/dist/packages/runtime/schemas/index.js +1 -0
- package/dist/packages/runtime/schemas/jobs.js +4 -0
- package/dist/packages/runtime/schemas/projects.d.ts +48 -21
- package/dist/packages/runtime/schemas/projects.js +34 -10
- package/dist/packages/runtime/schemas/runs.d.ts +1009 -240
- package/dist/packages/runtime/schemas/runs.js +17 -0
- package/dist/packages/runtime/service/openapi.js +1 -0
- package/dist/packages/runtime/service/operations.d.ts +1666 -145
- package/dist/packages/runtime/service/operations.js +147 -17
- package/dist/packages/runtime/service/routes.d.ts +11 -3
- package/dist/packages/runtime/service/routes.js +11 -3
- package/dist/packages/runtime/service/server-app-boot.js +2 -2
- package/dist/packages/runtime/service/server-helpers.d.ts +11 -0
- package/dist/packages/runtime/service/server-helpers.js +19 -0
- package/dist/packages/runtime/service/server-routes-action-proposals.js +4 -2
- package/dist/packages/runtime/service/server-routes-agents.js +19 -85
- package/dist/packages/runtime/service/server-routes-build-plans.js +14 -11
- package/dist/packages/runtime/service/server-routes-project-context.js +102 -7
- package/dist/packages/runtime/service/server-routes-project-jobs.js +19 -12
- package/dist/packages/runtime/service/server-routes-project-runs.js +5 -2
- package/dist/packages/runtime/service/server-routes-projects.js +6 -2
- package/dist/packages/runtime/service/server-routes-runs.js +11 -4
- package/dist/packages/runtime/verify/lib/schema.js +12 -0
- package/dist/packages/runtime/verify/test-file-guard.d.ts +2 -0
- package/dist/packages/runtime/verify/test-file-guard.js +29 -0
- package/dist/packages/runtime/verify/verify-execution.d.ts +7 -0
- package/dist/packages/runtime/verify/verify-execution.js +109 -35
- package/dist/packages/runtime/verify/verify-paths.d.ts +1 -0
- package/dist/packages/runtime/verify/verify-paths.js +4 -0
- package/dist/packages/runtime/verify/verify-specs.js +49 -39
- package/dist/packages/runtime/wire-schemas.d.ts +1 -1
- package/dist/packages/runtime/wire-schemas.js +1 -1
- package/package.json +2 -8
- package/public-repo/CONTRIBUTING.md +10 -3
- package/public-repo/README.md +122 -226
- package/public-repo/build-plans/interf-default/README.md +15 -12
- package/public-repo/build-plans/interf-default/build/stages/entrypoint/SKILL.md +74 -0
- package/public-repo/build-plans/interf-default/build/stages/knowledge/SKILL.md +95 -0
- package/public-repo/build-plans/interf-default/build/stages/summarize/SKILL.md +38 -5
- package/public-repo/build-plans/interf-default/build-plan.json +27 -23
- package/public-repo/build-plans/interf-default/build-plan.schema.json +24 -20
- package/public-repo/build-plans/interf-default/use/query/SKILL.md +8 -7
- package/public-repo/openapi/local-service.openapi.json +11637 -4213
- package/public-repo/skills/interf/SKILL.md +174 -134
- package/dist/packages/runtime/build/runtime-paths.d.ts +0 -8
- package/dist/packages/runtime/build/runtime-paths.js +0 -26
- package/dist/packages/runtime/build/state-paths.d.ts +0 -7
- package/dist/packages/runtime/build/state-paths.js +0 -22
- package/public-repo/build-plans/interf-default/build/stages/shape/SKILL.md +0 -34
- package/public-repo/build-plans/interf-default/build/stages/structure/SKILL.md +0 -28
|
@@ -23,7 +23,7 @@ import type { StageRun } from "../execution/lib/schema.js";
|
|
|
23
23
|
* the run record carries the real causal signal.
|
|
24
24
|
*/
|
|
25
25
|
export declare function computeArtifactStatuses(options: {
|
|
26
|
-
buildPlan: Pick<BuildPlanDefinition<string>, "stages" | "contextInterface"
|
|
26
|
+
buildPlan: Pick<BuildPlanDefinition<string>, "stages" | "contextInterface">;
|
|
27
27
|
contextGraphPath: string;
|
|
28
28
|
stageRuns: StageRun[];
|
|
29
29
|
/**
|
|
@@ -39,7 +39,7 @@ export function computeArtifactStatuses(options) {
|
|
|
39
39
|
}));
|
|
40
40
|
}
|
|
41
41
|
function pickContextInterface(buildPlan) {
|
|
42
|
-
return buildPlan.contextInterface
|
|
42
|
+
return buildPlan.contextInterface;
|
|
43
43
|
}
|
|
44
44
|
function buildStageWriteIndex(stages) {
|
|
45
45
|
const index = new Map();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type BuildEvidenceResource, type Readiness } from "../../contracts/lib/schema.js";
|
|
1
|
+
import { type BuildEvidenceResource, type MetricCount, type Readiness } from "../../contracts/lib/schema.js";
|
|
2
2
|
import type { BuildRun } from "../execution/lib/schema.js";
|
|
3
3
|
import type { StageEvidenceReconciliation } from "./lib/schema.js";
|
|
4
4
|
interface BuildBuildEvidenceInput {
|
|
@@ -9,6 +9,7 @@ interface BuildBuildEvidenceInput {
|
|
|
9
9
|
expectedStageCount?: number;
|
|
10
10
|
expectedOutputCount?: number;
|
|
11
11
|
stageEvidence?: readonly StageEvidenceReconciliation[];
|
|
12
|
+
primaryMetrics?: readonly MetricCount[];
|
|
12
13
|
generatedAt?: string;
|
|
13
14
|
}
|
|
14
15
|
export declare function buildBuildEvidence(input: BuildBuildEvidenceInput): BuildEvidenceResource;
|
|
@@ -25,6 +25,10 @@ function sourceFilesProcessed(stages) {
|
|
|
25
25
|
}
|
|
26
26
|
return observed;
|
|
27
27
|
}
|
|
28
|
+
function primaryMetricValue(metrics, key) {
|
|
29
|
+
const value = metrics?.find((entry) => entry.key === key)?.value;
|
|
30
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.max(0, Math.trunc(value)) : null;
|
|
31
|
+
}
|
|
28
32
|
function requiredArtifactCheckResults(artifacts) {
|
|
29
33
|
return artifacts
|
|
30
34
|
.flatMap((artifact) => artifact.check_results ?? [])
|
|
@@ -61,8 +65,10 @@ export function buildBuildEvidence(input) {
|
|
|
61
65
|
const acceptedFilesProcessed = acceptedEvidenceCounts
|
|
62
66
|
.filter((count) => count.key === "files_processed")
|
|
63
67
|
.reduce((max, count) => Math.max(max, count.value), 0);
|
|
68
|
+
const graphFilesProcessed = primaryMetricValue(input.primaryMetrics, "files_processed");
|
|
64
69
|
const filesObserved = buildRun
|
|
65
|
-
? Math.min(
|
|
70
|
+
? Math.min(graphFilesProcessed ??
|
|
71
|
+
(hasAcceptedStageEvidence ? acceptedFilesProcessed : sourceFilesProcessed(stages)), filesTotal)
|
|
66
72
|
: 0;
|
|
67
73
|
const filesState = issueState(filesObserved, filesTotal, { reviewWhenEmpty: true });
|
|
68
74
|
rows.push({
|
|
@@ -74,7 +80,7 @@ export function buildBuildEvidence(input) {
|
|
|
74
80
|
label: buildRun ? "Build stage records" : "Source inventory",
|
|
75
81
|
...(buildRun ? { run_id: buildRun.run_id, ref: `run:${buildRun.run_id}` } : { ref: "source-files" }),
|
|
76
82
|
},
|
|
77
|
-
...rowStateIssue(filesState, `${filesTotal - filesObserved} Source file${filesTotal - filesObserved === 1 ? "" : "s"} lack accepted
|
|
83
|
+
...rowStateIssue(filesState, `${filesTotal - filesObserved} Source file${filesTotal - filesObserved === 1 ? "" : "s"} lack accepted coverage records.`),
|
|
78
84
|
});
|
|
79
85
|
const stageTotal = input.expectedStageCount ?? stages[0]?.stage_total ?? stages.length;
|
|
80
86
|
const stagesSucceeded = stages.filter((stage) => stage.status === "succeeded").length;
|
|
@@ -141,16 +147,16 @@ export function buildBuildEvidence(input) {
|
|
|
141
147
|
}
|
|
142
148
|
const failed = buildRun?.status === "failed";
|
|
143
149
|
const hasBlockingRows = rowsHaveBlockingIssue(rows);
|
|
144
|
-
//
|
|
150
|
+
// Supplemental diagnostics explain the runtime readiness verdict; they do not
|
|
145
151
|
// create a second readiness source of truth.
|
|
146
152
|
const ready = Boolean(input.readiness?.ready) && !failed;
|
|
147
153
|
const summary = failed
|
|
148
154
|
? "Latest Build failed before the Context Graph was ready."
|
|
149
155
|
: ready
|
|
150
156
|
? hasBlockingRows
|
|
151
|
-
? "Ready by runtime readiness; review
|
|
157
|
+
? "Ready by runtime readiness; review supplemental diagnostic rows for follow-up."
|
|
152
158
|
: "Ready for agent task."
|
|
153
|
-
: "Context Graph is not ready; review missing
|
|
159
|
+
: "Context Graph is not ready; review missing coverage diagnostics.";
|
|
154
160
|
return BuildEvidenceResourceSchema.parse({
|
|
155
161
|
kind: "interf-build-evidence",
|
|
156
162
|
version: 1,
|
|
@@ -3,11 +3,15 @@ import { validateBuildPlanPackage } from "../../build-plans/package/local-build-
|
|
|
3
3
|
import { reportValidationFailure, } from "../../build-plans/package/build-plan-helpers.js";
|
|
4
4
|
import { validateContextGraph, } from "./validate.js";
|
|
5
5
|
import { pruneStageExecutionShells, } from "../agents/lib/shells.js";
|
|
6
|
+
import { reconcilePrunedStageExecutionSessions, } from "./stage-session.js";
|
|
6
7
|
import { buildExecutionStages, resolveBuildContext, } from "./build-target.js";
|
|
7
8
|
import { runBuildStage } from "./build-stage-runner.js";
|
|
8
9
|
import { buildPlanPackagePathForContextGraph } from "./context-graph-paths.js";
|
|
9
10
|
import { runSourceInventory } from "./source-inventory.js";
|
|
10
11
|
import { stageReuseDecision } from "./stage-reuse.js";
|
|
12
|
+
import { loadStageManifest, writeGraphManifest, } from "./stage-manifest.js";
|
|
13
|
+
import { writeContextGraphInspectMap } from "./inspect-map.js";
|
|
14
|
+
import { ensureSummaryCoverageIndex } from "./summary-coverage-index.js";
|
|
11
15
|
import { createRunEventId, createRunEventTimestamp, } from "../execution/events.js";
|
|
12
16
|
function pickStageExecutor(fallback, stage, resolve) {
|
|
13
17
|
if (!resolve)
|
|
@@ -53,6 +57,24 @@ async function emitReusedStagePassed(options) {
|
|
|
53
57
|
function reusedStageResult(summary = "reused (verified, unchanged)") {
|
|
54
58
|
return { ok: true, code: 0, summary };
|
|
55
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Deterministic connectivity floor, applied after the stage agents have produced
|
|
62
|
+
* the graph but BEFORE readiness validation. Writes a managed coverage block into
|
|
63
|
+
* `home.md` (the entrypoint spine) wikilinking every summary the build produced,
|
|
64
|
+
* so every summary note has a guaranteed inbound edge no matter how the stage
|
|
65
|
+
* agent behaved. Best-effort: assembly is already complete, so a finalization
|
|
66
|
+
* error must never fail the build (the `graph_notes_connected` check still runs
|
|
67
|
+
* and will report any real gap).
|
|
68
|
+
*/
|
|
69
|
+
function finalizeGraphConnectivity(contextGraphPath) {
|
|
70
|
+
try {
|
|
71
|
+
ensureSummaryCoverageIndex(contextGraphPath);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Never fail a built graph on the navigation-index write. The connectivity
|
|
75
|
+
// check runs next and is the source of truth on readiness.
|
|
76
|
+
}
|
|
77
|
+
}
|
|
56
78
|
export async function runBuildSummarize(options) {
|
|
57
79
|
const context = resolveBuildContext(options.contextGraphPath);
|
|
58
80
|
const stageDefinition = options.stageDefinition
|
|
@@ -69,6 +91,7 @@ export async function runBuildSummarize(options) {
|
|
|
69
91
|
executor: pickStageExecutor(options.executor, stageDefinition, options.resolveStageExecutor),
|
|
70
92
|
contextGraphPath: options.contextGraphPath,
|
|
71
93
|
project: context.contextGraphName,
|
|
94
|
+
projectIntent: context.projectIntent,
|
|
72
95
|
sourceLocator: context.sourcePath,
|
|
73
96
|
buildPlanId: context.buildPlanId,
|
|
74
97
|
stageIds: [stageDefinition.id],
|
|
@@ -90,7 +113,7 @@ export async function runBuildSummarize(options) {
|
|
|
90
113
|
contextGraphPath: options.contextGraphPath,
|
|
91
114
|
stageDefinition,
|
|
92
115
|
});
|
|
93
|
-
if (reuse.reuse) {
|
|
116
|
+
if (reuse.reuse && loadStageManifest(options.contextGraphPath, stageDefinition.id)) {
|
|
94
117
|
await emitReusedStagePassed({
|
|
95
118
|
events: options.events,
|
|
96
119
|
runId: options.runId,
|
|
@@ -128,7 +151,7 @@ export async function runBuildSummarize(options) {
|
|
|
128
151
|
};
|
|
129
152
|
}
|
|
130
153
|
export async function runBuildStages(options) {
|
|
131
|
-
const preserveMode = options.preserveStageShells ?? "
|
|
154
|
+
const preserveMode = options.preserveStageShells ?? "always";
|
|
132
155
|
if (preserveMode !== "always") {
|
|
133
156
|
pruneStageExecutionShells(options.contextGraphPath);
|
|
134
157
|
}
|
|
@@ -141,6 +164,7 @@ export async function runBuildStages(options) {
|
|
|
141
164
|
executor: sourceInventoryExecutor,
|
|
142
165
|
contextGraphPath: options.contextGraphPath,
|
|
143
166
|
project: context.contextGraphName,
|
|
167
|
+
projectIntent: context.projectIntent,
|
|
144
168
|
sourceLocator: context.sourcePath,
|
|
145
169
|
buildPlanId: context.buildPlanId,
|
|
146
170
|
stageIds: stages.map((stage) => stage.id),
|
|
@@ -158,7 +182,7 @@ export async function runBuildStages(options) {
|
|
|
158
182
|
contextGraphPath: options.contextGraphPath,
|
|
159
183
|
stageDefinition,
|
|
160
184
|
});
|
|
161
|
-
if (reuse.reuse) {
|
|
185
|
+
if (reuse.reuse && loadStageManifest(options.contextGraphPath, stageDefinition.id)) {
|
|
162
186
|
await emitReusedStagePassed({
|
|
163
187
|
events: options.events,
|
|
164
188
|
runId: options.runId,
|
|
@@ -188,16 +212,36 @@ export async function runBuildStages(options) {
|
|
|
188
212
|
if (!result.ok)
|
|
189
213
|
return result;
|
|
190
214
|
}
|
|
215
|
+
// Connectivity floor: link every summary into a deterministic navigation
|
|
216
|
+
// index before the GraphManifest rolls up coverage and connectivity metrics.
|
|
217
|
+
finalizeGraphConnectivity(options.contextGraphPath);
|
|
218
|
+
writeGraphManifest({
|
|
219
|
+
contextGraphPath: options.contextGraphPath,
|
|
220
|
+
projectId: context.contextGraphName,
|
|
221
|
+
buildPlanId: context.buildPlanId,
|
|
222
|
+
intent: context.projectIntent,
|
|
223
|
+
runId: options.runId ?? null,
|
|
224
|
+
});
|
|
225
|
+
// Refresh the developer/agent map of the built folder from already-recorded
|
|
226
|
+
// state. Best-effort: it never fails the build.
|
|
227
|
+
writeContextGraphInspectMap(options.contextGraphPath);
|
|
191
228
|
return lastResult;
|
|
192
229
|
}
|
|
193
230
|
finally {
|
|
194
231
|
if (preserveMode !== "always" && lastResult.ok) {
|
|
195
232
|
pruneStageExecutionShells(options.contextGraphPath);
|
|
233
|
+
// Pruning deleted the shells the sessions point at; downgrade those
|
|
234
|
+
// sessions so none dangles with replay_ready:true (F2).
|
|
235
|
+
reconcilePrunedStageExecutionSessions({ contextGraphPath: options.contextGraphPath });
|
|
236
|
+
// The in-try map render above reflected pre-reconcile sessions (shells the
|
|
237
|
+
// prune was about to delete). Re-render from the reconciled state so the
|
|
238
|
+
// map points only at shells still on disk (F1). Best-effort, never fails.
|
|
239
|
+
writeContextGraphInspectMap(options.contextGraphPath);
|
|
196
240
|
}
|
|
197
241
|
}
|
|
198
242
|
}
|
|
199
243
|
export async function buildContextGraph(options) {
|
|
200
|
-
const preserveMode = options.preserveStageShells ?? "
|
|
244
|
+
const preserveMode = options.preserveStageShells ?? "always";
|
|
201
245
|
if (preserveMode !== "always") {
|
|
202
246
|
pruneStageExecutionShells(options.contextGraphPath);
|
|
203
247
|
}
|
|
@@ -232,6 +276,7 @@ export async function buildContextGraph(options) {
|
|
|
232
276
|
executor: sourceInventoryExecutor,
|
|
233
277
|
contextGraphPath: options.contextGraphPath,
|
|
234
278
|
project: context.contextGraphName,
|
|
279
|
+
projectIntent: context.projectIntent,
|
|
235
280
|
sourceLocator: context.sourcePath,
|
|
236
281
|
buildPlanId: context.buildPlanId,
|
|
237
282
|
stageIds: stages.map((stage) => stage.id),
|
|
@@ -253,7 +298,7 @@ export async function buildContextGraph(options) {
|
|
|
253
298
|
contextGraphPath: options.contextGraphPath,
|
|
254
299
|
stageDefinition,
|
|
255
300
|
});
|
|
256
|
-
if (reuse.reuse) {
|
|
301
|
+
if (reuse.reuse && loadStageManifest(options.contextGraphPath, stageDefinition.id)) {
|
|
257
302
|
await emitReusedStagePassed({
|
|
258
303
|
events: options.events,
|
|
259
304
|
runId: options.runId,
|
|
@@ -286,6 +331,9 @@ export async function buildContextGraph(options) {
|
|
|
286
331
|
return result;
|
|
287
332
|
}
|
|
288
333
|
}
|
|
334
|
+
// Connectivity floor: ensure every produced summary is reachable through a
|
|
335
|
+
// deterministic navigation index BEFORE readiness is validated.
|
|
336
|
+
finalizeGraphConnectivity(options.contextGraphPath);
|
|
289
337
|
const buildPlanValidationResult = validateContextGraph(options.contextGraphPath);
|
|
290
338
|
result.ok = buildPlanValidationResult.ok;
|
|
291
339
|
result.failedStage = buildPlanValidationResult.ok ? null : buildPlanValidationResult.stage;
|
|
@@ -294,11 +342,47 @@ export async function buildContextGraph(options) {
|
|
|
294
342
|
code: buildPlanValidationResult.ok ? 0 : 1,
|
|
295
343
|
summary: buildPlanValidationResult.summary,
|
|
296
344
|
};
|
|
345
|
+
if (buildPlanValidationResult.ok) {
|
|
346
|
+
try {
|
|
347
|
+
const graphManifest = writeGraphManifest({
|
|
348
|
+
contextGraphPath: options.contextGraphPath,
|
|
349
|
+
projectId: context.contextGraphName,
|
|
350
|
+
buildPlanId: context.buildPlanId,
|
|
351
|
+
intent: context.projectIntent,
|
|
352
|
+
runId: options.runId ?? null,
|
|
353
|
+
});
|
|
354
|
+
result.stageResults["graph-manifest"] = {
|
|
355
|
+
ok: true,
|
|
356
|
+
code: 0,
|
|
357
|
+
summary: `GraphManifest recorded ${graphManifest.resources.length} resource${graphManifest.resources.length === 1 ? "" : "s"} and ${graphManifest.graph_outputs.edges} graph edge${graphManifest.graph_outputs.edges === 1 ? "" : "s"}.`,
|
|
358
|
+
};
|
|
359
|
+
// Refresh the developer/agent map (.interf/INSPECT.md) of the built
|
|
360
|
+
// folder from already-recorded state. Best-effort: it never fails the
|
|
361
|
+
// build, so a render error does not flip a ready graph to failed.
|
|
362
|
+
writeContextGraphInspectMap(options.contextGraphPath);
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
result.ok = false;
|
|
366
|
+
result.failedStage = "graph-manifest";
|
|
367
|
+
result.stageResults["graph-manifest"] = {
|
|
368
|
+
ok: false,
|
|
369
|
+
code: 1,
|
|
370
|
+
summary: `Could not write GraphManifest: ${error instanceof Error ? error.message : String(error)}`,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
}
|
|
297
374
|
return result;
|
|
298
375
|
}
|
|
299
376
|
finally {
|
|
300
377
|
if (preserveMode !== "always" && result.ok) {
|
|
301
378
|
pruneStageExecutionShells(options.contextGraphPath);
|
|
379
|
+
// Pruning deleted the shells the sessions point at; downgrade those
|
|
380
|
+
// sessions so none dangles with replay_ready:true (F2).
|
|
381
|
+
reconcilePrunedStageExecutionSessions({ contextGraphPath: options.contextGraphPath });
|
|
382
|
+
// The in-try map render above reflected pre-reconcile sessions (shells the
|
|
383
|
+
// prune was about to delete). Re-render from the reconciled state so the
|
|
384
|
+
// map points only at shells still on disk (F1). Best-effort, never fails.
|
|
385
|
+
writeContextGraphInspectMap(options.contextGraphPath);
|
|
302
386
|
}
|
|
303
387
|
}
|
|
304
388
|
}
|
|
@@ -4,7 +4,7 @@ import { listFilesRecursive } from "../../contracts/utils/filesystem.js";
|
|
|
4
4
|
import { contextGraphArtifactPath, contextGraphArtifactPathsForArtifactIds, findBuildPlanContextArtifact, readBuildPlanContextFile, } from "./context-graph-schema.js";
|
|
5
5
|
import { buildLocalSkillContractExtension, buildStageInstructions, buildPlanStageDirectory, } from "../../build-plans/package/build-plan-helpers.js";
|
|
6
6
|
import { loadContextGraphSourceManifest } from "./source-manifest.js";
|
|
7
|
-
import { getActiveBuildPlanStagePolicyNotes, } from "../../build-plans/package/build-plan-definitions.js";
|
|
7
|
+
import { getActiveBuildPlan, getActiveBuildPlanStagePolicyNotes, } from "../../build-plans/package/build-plan-definitions.js";
|
|
8
8
|
import { buildPlanPackagePathForContextGraph } from "./context-graph-paths.js";
|
|
9
9
|
import { readInterfConfig } from "../../projects/interf-detect.js";
|
|
10
10
|
import { resolveBuildContext, } from "./build-target.js";
|
|
@@ -72,6 +72,7 @@ export function buildStageContract(contextGraphPath, stageDefinition, instructio
|
|
|
72
72
|
const stageArtifacts = resolveStageContractArtifacts(contextGraphPath, stageDefinition);
|
|
73
73
|
return buildRuntimeStageContract({
|
|
74
74
|
contextGraphName: config?.name ?? "context-graph",
|
|
75
|
+
project: resolveBuildContext(contextGraphPath).project,
|
|
75
76
|
stageId: stageDefinition.id,
|
|
76
77
|
stageLabel: stageDefinition.label,
|
|
77
78
|
counts: buildStageCounts(contextGraphPath, stageDefinition),
|
|
@@ -82,6 +83,7 @@ export function buildStageContract(contextGraphPath, stageDefinition, instructio
|
|
|
82
83
|
stageReadArtifacts: stageArtifacts.reads,
|
|
83
84
|
stageWriteArtifacts: stageArtifacts.writes,
|
|
84
85
|
stageWriteContracts: stageArtifacts.writeContracts,
|
|
86
|
+
contextChecks: getActiveBuildPlan(contextGraphPath).brief?.checks ?? [],
|
|
85
87
|
buildPlanNotes: getActiveBuildPlanStagePolicyNotes(contextGraphPath, stageDefinition.id),
|
|
86
88
|
localSkillDocs: instructions.local_docs,
|
|
87
89
|
instructions,
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { writeFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
3
|
import { createStageExecutionShell, freezeStageExecutionShell, syncStageExecutionShellWrites, validateStageExecutionShellInputs, } from "../agents/lib/shells.js";
|
|
4
4
|
import { reconcileBuildStageRun } from "./runtime-reconcile.js";
|
|
5
5
|
import { refreshContextGraphArtifacts } from "./state.js";
|
|
6
6
|
import { validateBuildStage } from "./validate.js";
|
|
7
7
|
import { reconcileStageEvidence, stageEvidenceAcceptanceFailure, supportsStageEvidenceHarness, } from "./stage-evidence.js";
|
|
8
|
+
import { persistStageReviewedInputsFromShell, writeStageExpectedInputs, writeStageManifestFromOutputs, } from "./stage-manifest.js";
|
|
9
|
+
import { createNativeEntrypointExecutor, } from "./native-entrypoint.js";
|
|
8
10
|
import { executeValidatedStage, } from "../../build-plans/package/build-plan-stage-runner.js";
|
|
11
|
+
import { loadExecutionStageLedger, } from "./runtime.js";
|
|
12
|
+
import { markStageExecutionSessionsShellPreserved, recordStageExecutionSessionValidationAttempt, } from "./stage-session.js";
|
|
9
13
|
import { formatActiveBuildPlanStageLabel, } from "../../build-plans/package/build-plan-definitions.js";
|
|
10
14
|
import { reportBlankLine, reportLine, } from "../../build-plans/package/build-plan-helpers.js";
|
|
11
15
|
import { buildBuildStageExecutionPlan, } from "./build-stage-plan.js";
|
|
@@ -20,50 +24,156 @@ function boundedStageValidationAttempts(value) {
|
|
|
20
24
|
return 2;
|
|
21
25
|
return Math.max(1, Math.min(5, Math.trunc(value)));
|
|
22
26
|
}
|
|
27
|
+
function stageOutputValidationForActiveRun(validation, stageId) {
|
|
28
|
+
if (validation.ok)
|
|
29
|
+
return validation;
|
|
30
|
+
const terminalStateErrors = new Set([
|
|
31
|
+
`Stage "${stageId}" has no finished_at evidence in runtime state.`,
|
|
32
|
+
`Stage "${stageId}" is not marked succeeded in runtime state.`,
|
|
33
|
+
]);
|
|
34
|
+
const activeOutputErrors = validation.errors.filter((error) => !terminalStateErrors.has(error));
|
|
35
|
+
if (activeOutputErrors.length > 0) {
|
|
36
|
+
return {
|
|
37
|
+
...validation,
|
|
38
|
+
errors: activeOutputErrors,
|
|
39
|
+
summary: `Stage "${stageId}" failed — ${activeOutputErrors[0]}`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
...validation,
|
|
44
|
+
ok: true,
|
|
45
|
+
errors: [],
|
|
46
|
+
summary: `Stage "${stageId}" output checks passed.`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
23
49
|
function stageValidationRetryStatusLines(options) {
|
|
24
50
|
if (!options.lastFailureSummary || options.attempt <= 1)
|
|
25
51
|
return [];
|
|
26
52
|
return [
|
|
27
53
|
`Previous service validation for this stage failed on attempt ${options.attempt - 1}/${options.maxValidationAttempts}: ${options.lastFailureSummary}`,
|
|
28
|
-
"
|
|
54
|
+
"This is a fresh retry shell. Read `runtime/retry-feedback.md`, use previous shells as read-only logs, fix the exact validation failure, then rerun `node runtime/check-stage.mjs` until it prints `VALID:`.",
|
|
29
55
|
];
|
|
30
56
|
}
|
|
57
|
+
function contextGraphRelativePath(contextGraphPath, path) {
|
|
58
|
+
return relative(contextGraphPath, path).replaceAll("\\", "/");
|
|
59
|
+
}
|
|
60
|
+
function writeStageRetryFeedback(options) {
|
|
61
|
+
if (options.attempts.length === 0)
|
|
62
|
+
return;
|
|
63
|
+
writeFileSync(join(options.shellRoot, "runtime", "previous-attempts.json"), `${JSON.stringify({
|
|
64
|
+
kind: "interf-stage-previous-attempts",
|
|
65
|
+
version: 1,
|
|
66
|
+
stage_id: options.stageId,
|
|
67
|
+
attempts: options.attempts,
|
|
68
|
+
}, null, 2)}\n`);
|
|
69
|
+
writeFileSync(join(options.shellRoot, "runtime", "retry-feedback.md"), [
|
|
70
|
+
"# Retry Feedback",
|
|
71
|
+
"",
|
|
72
|
+
"This shell is a fresh retry for the current stage.",
|
|
73
|
+
"Previous attempt shells are preserved as read-only context. Do not mutate them.",
|
|
74
|
+
"Use their prompts, logs, outputs, and validation failures to repair this attempt.",
|
|
75
|
+
"",
|
|
76
|
+
"## Previous Attempts",
|
|
77
|
+
"",
|
|
78
|
+
...options.attempts.flatMap((attempt) => [
|
|
79
|
+
`### Attempt ${attempt.attempt}`,
|
|
80
|
+
"",
|
|
81
|
+
`- stage_run_id: ${attempt.stage_run_id ?? "unknown"}`,
|
|
82
|
+
`- shell: ${attempt.context_graph_relative_shell_path}`,
|
|
83
|
+
`- status: ${attempt.status}`,
|
|
84
|
+
`- validation: ${attempt.summary}`,
|
|
85
|
+
"",
|
|
86
|
+
]),
|
|
87
|
+
"## Required Action",
|
|
88
|
+
"",
|
|
89
|
+
"Write the declared outputs in this shell, record `runtime/reviewed-inputs.json`, and run `node runtime/check-stage.mjs` until it reports `VALID:`.",
|
|
90
|
+
"",
|
|
91
|
+
].join("\n"));
|
|
92
|
+
}
|
|
31
93
|
export async function runBuildStage(options) {
|
|
32
94
|
const stageDefinition = options.stageDefinition;
|
|
33
95
|
const plan = buildBuildStageExecutionPlan(options.contextGraphPath, stageDefinition);
|
|
96
|
+
writeStageExpectedInputs({
|
|
97
|
+
contextGraphPath: options.contextGraphPath,
|
|
98
|
+
stage: stageDefinition,
|
|
99
|
+
});
|
|
34
100
|
if (options.reportStep !== false) {
|
|
35
101
|
reportBlankLine(options.reporter);
|
|
36
102
|
reportLine(options.reporter, `${formatActiveBuildPlanStageLabel(options.contextGraphPath, stageDefinition.id)} (${stageDefinition.description.toLowerCase()})`);
|
|
37
103
|
}
|
|
38
|
-
const
|
|
104
|
+
const executor = stageDefinition.contractType === "build-entrypoint"
|
|
105
|
+
? createNativeEntrypointExecutor()
|
|
106
|
+
: options.executor;
|
|
39
107
|
const stageEvidenceHarness = supportsStageEvidenceHarness(stageDefinition);
|
|
40
108
|
const maxValidationAttempts = boundedStageValidationAttempts(options.maxValidationAttempts);
|
|
41
|
-
const validateStageOutputsAndEvidence = () => {
|
|
109
|
+
const validateStageOutputsAndEvidence = (shellRoot) => {
|
|
42
110
|
const shellInputValidation = validateStageExecutionShellInputs({
|
|
43
111
|
contextGraphPath: options.contextGraphPath,
|
|
44
|
-
shellRoot
|
|
112
|
+
shellRoot,
|
|
45
113
|
stage: stageDefinition,
|
|
46
114
|
});
|
|
47
115
|
if (!shellInputValidation.ok)
|
|
48
116
|
return shellInputValidation;
|
|
49
|
-
const outputValidation = validateBuildStage(options.contextGraphPath, stageDefinition.id);
|
|
50
|
-
if (!outputValidation.ok
|
|
117
|
+
const outputValidation = stageOutputValidationForActiveRun(validateBuildStage(options.contextGraphPath, stageDefinition.id), stageDefinition.id);
|
|
118
|
+
if (!outputValidation.ok)
|
|
51
119
|
return outputValidation;
|
|
52
|
-
|
|
120
|
+
if (stageEvidenceHarness) {
|
|
121
|
+
const reconciliation = reconcileStageEvidence({
|
|
122
|
+
contextGraphPath: options.contextGraphPath,
|
|
123
|
+
shellRoot,
|
|
124
|
+
stage: stageDefinition,
|
|
125
|
+
});
|
|
126
|
+
const evidenceFailure = stageEvidenceAcceptanceFailure(reconciliation);
|
|
127
|
+
if (evidenceFailure) {
|
|
128
|
+
return { ok: false, summary: evidenceFailure };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const reviewedInputs = persistStageReviewedInputsFromShell({
|
|
53
132
|
contextGraphPath: options.contextGraphPath,
|
|
54
|
-
shellRoot
|
|
55
|
-
|
|
133
|
+
shellRoot,
|
|
134
|
+
stageId: stageDefinition.id,
|
|
56
135
|
});
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
136
|
+
if (!reviewedInputs.ok) {
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
summary: `${outputValidation.summary} ${reviewedInputs.summary}`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const manifest = writeStageManifestFromOutputs({
|
|
144
|
+
contextGraphPath: options.contextGraphPath,
|
|
145
|
+
buildPlanId: plan.context.buildPlanId,
|
|
146
|
+
projectId: plan.context.contextGraphName,
|
|
147
|
+
runId: options.runId ?? null,
|
|
148
|
+
stage: stageDefinition,
|
|
149
|
+
});
|
|
150
|
+
if (!manifest) {
|
|
151
|
+
return { ok: false, summary: `Could not write StageManifest for ${stageDefinition.id}.` };
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
...outputValidation,
|
|
155
|
+
summary: `${outputValidation.summary} ${reviewedInputs.summary} StageManifest recorded ${manifest.produced.length} produced resource${manifest.produced.length === 1 ? "" : "s"}.`,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
return {
|
|
160
|
+
ok: false,
|
|
161
|
+
summary: `Could not write StageManifest for ${stageDefinition.id}: ${error instanceof Error ? error.message : String(error)}`,
|
|
162
|
+
};
|
|
60
163
|
}
|
|
61
|
-
return outputValidation;
|
|
62
164
|
};
|
|
63
165
|
let lastResult = { ok: false, code: 1 };
|
|
64
166
|
let lastFailureSummary = null;
|
|
65
|
-
|
|
66
|
-
|
|
167
|
+
const previousAttempts = [];
|
|
168
|
+
for (let attempt = 1; attempt <= maxValidationAttempts; attempt += 1) {
|
|
169
|
+
const shell = createStageExecutionShell(options.contextGraphPath, plan.context.contextGraphName, plan.context.buildPlanId, stageDefinition, plan.contract.artifacts.writes);
|
|
170
|
+
writeStageRetryFeedback({
|
|
171
|
+
contextGraphPath: options.contextGraphPath,
|
|
172
|
+
shellRoot: shell.rootPath,
|
|
173
|
+
stageId: stageDefinition.id,
|
|
174
|
+
attempts: previousAttempts,
|
|
175
|
+
});
|
|
176
|
+
try {
|
|
67
177
|
if (options.runId && options.events) {
|
|
68
178
|
await emitRunEvent(options.events, {
|
|
69
179
|
type: "stage.started",
|
|
@@ -76,12 +186,13 @@ export async function runBuildStage(options) {
|
|
|
76
186
|
});
|
|
77
187
|
}
|
|
78
188
|
const result = await executeValidatedStage({
|
|
79
|
-
executor
|
|
189
|
+
executor,
|
|
80
190
|
contextGraphPath: options.contextGraphPath,
|
|
81
191
|
executionPath: shell.rootPath,
|
|
82
192
|
targetName: plan.context.contextGraphName,
|
|
83
193
|
buildPlan: plan.context.buildPlanId,
|
|
84
194
|
buildPlanSourcePath: options.contextGraphPath,
|
|
195
|
+
buildRunId: options.runId ?? null,
|
|
85
196
|
stageDefinition,
|
|
86
197
|
instructions: plan.instructions,
|
|
87
198
|
summary: `Executing ${stageDefinition.label.toLowerCase()}.`,
|
|
@@ -94,13 +205,15 @@ export async function runBuildStage(options) {
|
|
|
94
205
|
"Write `runtime/stage-evidence.json` with source/output refs before DONE; status text alone is not accepted evidence.",
|
|
95
206
|
]
|
|
96
207
|
: []),
|
|
208
|
+
"Read `runtime/expected-inputs.json` before writing outputs.",
|
|
209
|
+
"Write `runtime/reviewed-inputs.json` with one decision per required expected input before DONE.",
|
|
97
210
|
...stageValidationRetryStatusLines({ attempt, maxValidationAttempts, lastFailureSummary }),
|
|
98
211
|
"Emit STATUS: reading declared inputs after you confirm the shell contract and local docs.",
|
|
99
|
-
"Emit STATUS: writing declared outputs after the stage starts updating the
|
|
100
|
-
`Emit DONE: ${stageDefinition.id} complete when the declared outputs and evidence are on disk.`,
|
|
212
|
+
"Emit STATUS: writing declared outputs after the stage starts updating the requested outputs.",
|
|
213
|
+
`Emit DONE: ${stageDefinition.id} complete when the declared outputs, coverage review, and evidence are on disk.`,
|
|
101
214
|
],
|
|
102
215
|
reporter: options.reporter,
|
|
103
|
-
completionCheck: () => validateStageOutputsAndEvidence().ok,
|
|
216
|
+
completionCheck: () => validateStageOutputsAndEvidence(shell.rootPath).ok,
|
|
104
217
|
onStatus: options.runId && options.events
|
|
105
218
|
? (line) => {
|
|
106
219
|
void options.events?.emit({
|
|
@@ -117,9 +230,21 @@ export async function runBuildStage(options) {
|
|
|
117
230
|
syncWrites: () => syncStageExecutionShellWrites(options.contextGraphPath, shell.rootPath, stageDefinition, plan.contract.artifacts.writes),
|
|
118
231
|
reconcile: () => reconcileBuildStageRun(options.contextGraphPath, stageDefinition),
|
|
119
232
|
refreshArtifacts: () => refreshContextGraphArtifacts(options.contextGraphPath, { ensureViewSpec: true }),
|
|
120
|
-
validate: validateStageOutputsAndEvidence,
|
|
233
|
+
validate: () => validateStageOutputsAndEvidence(shell.rootPath),
|
|
121
234
|
});
|
|
122
235
|
lastResult = result;
|
|
236
|
+
const stageRun = loadExecutionStageLedger(options.contextGraphPath);
|
|
237
|
+
const stageRunId = stageRun?.stage === stageDefinition.id ? stageRun.run_id : null;
|
|
238
|
+
if (stageRun?.stage === stageDefinition.id) {
|
|
239
|
+
recordStageExecutionSessionValidationAttempt({
|
|
240
|
+
contextGraphPath: options.contextGraphPath,
|
|
241
|
+
stageId: stageDefinition.id,
|
|
242
|
+
stageRunId: stageRun.run_id,
|
|
243
|
+
attempt,
|
|
244
|
+
status: result.ok ? "succeeded" : "failed",
|
|
245
|
+
summary: result.summary ?? `${stageDefinition.label} ${result.ok ? "passed" : "failed"}.`,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
123
248
|
if (result.ok) {
|
|
124
249
|
if (options.runId && options.events) {
|
|
125
250
|
await emitRunEvent(options.events, {
|
|
@@ -135,6 +260,14 @@ export async function runBuildStage(options) {
|
|
|
135
260
|
}
|
|
136
261
|
lastFailureSummary = result.summary ?? `${stageDefinition.label} failed with code ${result.code}.`;
|
|
137
262
|
writeFileSync(join(shell.rootPath, "runtime", "last-validation-failure.txt"), `${lastFailureSummary}\n`);
|
|
263
|
+
previousAttempts.push({
|
|
264
|
+
attempt,
|
|
265
|
+
stage_run_id: stageRunId,
|
|
266
|
+
shell_path: shell.rootPath,
|
|
267
|
+
context_graph_relative_shell_path: contextGraphRelativePath(options.contextGraphPath, shell.rootPath),
|
|
268
|
+
status: "failed",
|
|
269
|
+
summary: lastFailureSummary,
|
|
270
|
+
});
|
|
138
271
|
if (attempt < maxValidationAttempts && options.runId && options.events) {
|
|
139
272
|
await emitRunEvent(options.events, {
|
|
140
273
|
type: "log.appended",
|
|
@@ -147,19 +280,23 @@ export async function runBuildStage(options) {
|
|
|
147
280
|
});
|
|
148
281
|
}
|
|
149
282
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
timestamp: createRunEventTimestamp(),
|
|
156
|
-
stage_id: stageDefinition.id,
|
|
157
|
-
error: lastResult.summary ?? `${stageDefinition.label} failed.`,
|
|
283
|
+
finally {
|
|
284
|
+
freezeStageExecutionShell(shell.rootPath);
|
|
285
|
+
markStageExecutionSessionsShellPreserved({
|
|
286
|
+
contextGraphPath: options.contextGraphPath,
|
|
287
|
+
shellRoot: shell.rootPath,
|
|
158
288
|
});
|
|
159
289
|
}
|
|
160
|
-
return lastResult;
|
|
161
290
|
}
|
|
162
|
-
|
|
163
|
-
|
|
291
|
+
if (options.runId && options.events) {
|
|
292
|
+
await emitRunEvent(options.events, {
|
|
293
|
+
type: "stage.failed",
|
|
294
|
+
event_id: createRunEventId("event"),
|
|
295
|
+
run_id: options.runId,
|
|
296
|
+
timestamp: createRunEventTimestamp(),
|
|
297
|
+
stage_id: stageDefinition.id,
|
|
298
|
+
error: lastResult.summary ?? `${stageDefinition.label} failed.`,
|
|
299
|
+
});
|
|
164
300
|
}
|
|
301
|
+
return lastResult;
|
|
165
302
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { type BuildPlanStageDefinition } from "../../build-plans/package/build-plan-definitions.js";
|
|
2
2
|
import { type ResolvedBuildPlanId } from "../../build-plans/package/build-plan-definitions.js";
|
|
3
|
+
import type { RuntimeProjectContext } from "./lib/schema.js";
|
|
3
4
|
export interface BuildStageExecutionDefinition extends BuildPlanStageDefinition {
|
|
4
5
|
}
|
|
5
6
|
export declare function resolveBuildContext(contextGraphPath: string): {
|
|
6
7
|
contextGraphName: string;
|
|
8
|
+
project: RuntimeProjectContext;
|
|
9
|
+
projectIntent: string | null;
|
|
7
10
|
sourcePath: string;
|
|
8
11
|
projectDataDir: string;
|
|
9
12
|
buildPlanId: ResolvedBuildPlanId;
|
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
import { getActiveBuildPlan, resolveRequiredBuildPlanFromConfig, } from "../../build-plans/package/build-plan-definitions.js";
|
|
2
2
|
import { readInterfConfig, resolveSourceFolderPath, resolveSourceControlPath, } from "../../projects/interf-detect.js";
|
|
3
|
+
function normalizedIntent(value) {
|
|
4
|
+
if (typeof value !== "string")
|
|
5
|
+
return null;
|
|
6
|
+
const trimmed = value.trim();
|
|
7
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
8
|
+
}
|
|
9
|
+
function readPersistedProjectIntent(contextGraphPath, config) {
|
|
10
|
+
const parsedIntent = normalizedIntent(config?.intent);
|
|
11
|
+
if (parsedIntent)
|
|
12
|
+
return parsedIntent;
|
|
13
|
+
try {
|
|
14
|
+
return normalizedIntent(getActiveBuildPlan(contextGraphPath).brief?.intent);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
3
20
|
export function resolveBuildContext(contextGraphPath) {
|
|
4
21
|
const config = readInterfConfig(contextGraphPath);
|
|
5
22
|
const buildPlanId = resolveRequiredBuildPlanFromConfig(config, `.interf/interf.json for ${contextGraphPath}`);
|
|
23
|
+
const contextGraphName = config?.name ?? "context-graph";
|
|
24
|
+
const projectIntent = readPersistedProjectIntent(contextGraphPath, config);
|
|
6
25
|
return {
|
|
7
|
-
contextGraphName
|
|
26
|
+
contextGraphName,
|
|
27
|
+
project: {
|
|
28
|
+
id: contextGraphName,
|
|
29
|
+
intent: projectIntent,
|
|
30
|
+
},
|
|
31
|
+
projectIntent,
|
|
8
32
|
sourcePath: resolveSourceFolderPath(contextGraphPath, config),
|
|
9
33
|
projectDataDir: resolveSourceControlPath(contextGraphPath),
|
|
10
34
|
buildPlanId,
|