clinkx 1.1.0 → 1.1.2
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/CHANGELOG.md +39 -1
- package/README.md +210 -177
- package/clinkx-workflows/dist/architecture-comparison/admission.d.ts +5 -0
- package/clinkx-workflows/dist/architecture-comparison/admission.js +50 -0
- package/clinkx-workflows/dist/architecture-comparison/admission.js.map +1 -0
- package/clinkx-workflows/dist/architecture-comparison/contract.d.ts +995 -0
- package/clinkx-workflows/dist/architecture-comparison/contract.js +149 -0
- package/clinkx-workflows/dist/architecture-comparison/contract.js.map +1 -0
- package/clinkx-workflows/dist/architecture-comparison/runtime.d.ts +29 -0
- package/clinkx-workflows/dist/architecture-comparison/runtime.js +387 -0
- package/clinkx-workflows/dist/architecture-comparison/runtime.js.map +1 -0
- package/clinkx-workflows/dist/contained-file.js +1 -1
- package/clinkx-workflows/dist/contained-file.js.map +1 -1
- package/clinkx-workflows/dist/council-execution-policy.d.ts +4 -2
- package/clinkx-workflows/dist/council-execution-policy.js +5 -1
- package/clinkx-workflows/dist/council-execution-policy.js.map +1 -1
- package/clinkx-workflows/dist/dashboard/activity-contract.d.ts +72 -72
- package/clinkx-workflows/dist/dashboard/contracts.d.ts +1564 -122
- package/clinkx-workflows/dist/dashboard/contracts.js +4 -0
- package/clinkx-workflows/dist/dashboard/contracts.js.map +1 -1
- package/clinkx-workflows/dist/dashboard/progress-report-contract.d.ts +12 -12
- package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.d.ts +8 -8
- package/clinkx-workflows/dist/dashboard/scanner.d.ts +3 -0
- package/clinkx-workflows/dist/dashboard/scanner.js +27 -0
- package/clinkx-workflows/dist/dashboard/scanner.js.map +1 -1
- package/clinkx-workflows/dist/dashboard/session-log-contract.d.ts +48 -48
- package/clinkx-workflows/dist/dashboard/session-log-redaction.d.ts +2 -0
- package/clinkx-workflows/dist/dashboard/session-log-redaction.js +4 -0
- package/clinkx-workflows/dist/dashboard/session-log-redaction.js.map +1 -1
- package/clinkx-workflows/dist/dashboard/verified-repair-contract.d.ts +191 -0
- package/clinkx-workflows/dist/dashboard/verified-repair-contract.js +28 -0
- package/clinkx-workflows/dist/dashboard/verified-repair-contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/index-BdpmbPps.js +115 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/style-Im5i1iAs.css +1 -0
- package/clinkx-workflows/dist/dashboard-ui/index.html +2 -2
- package/clinkx-workflows/dist/engine.d.ts +6 -0
- package/clinkx-workflows/dist/engine.js +78 -7
- package/clinkx-workflows/dist/engine.js.map +1 -1
- package/clinkx-workflows/dist/index.d.ts +3 -0
- package/clinkx-workflows/dist/index.js +3 -2
- package/clinkx-workflows/dist/index.js.map +1 -1
- package/clinkx-workflows/dist/reducers/index.d.ts +9 -1
- package/clinkx-workflows/dist/reducers/index.js +22 -0
- package/clinkx-workflows/dist/reducers/index.js.map +1 -1
- package/clinkx-workflows/dist/state.js +17 -7
- package/clinkx-workflows/dist/state.js.map +1 -1
- package/clinkx-workflows/dist/validators/architecture-comparison.d.ts +2 -0
- package/clinkx-workflows/dist/validators/architecture-comparison.js +12 -0
- package/clinkx-workflows/dist/validators/architecture-comparison.js.map +1 -0
- package/clinkx-workflows/dist/validators/index.js +4 -0
- package/clinkx-workflows/dist/validators/index.js.map +1 -1
- package/clinkx-workflows/dist/validators/verified-repair.d.ts +2 -0
- package/clinkx-workflows/dist/validators/verified-repair.js +12 -0
- package/clinkx-workflows/dist/validators/verified-repair.js.map +1 -0
- package/clinkx-workflows/dist/verification-proof.d.ts +254 -0
- package/clinkx-workflows/dist/verification-proof.js +195 -0
- package/clinkx-workflows/dist/verification-proof.js.map +1 -0
- package/clinkx-workflows/dist/verified-repair/admission.d.ts +72 -0
- package/clinkx-workflows/dist/verified-repair/admission.js +63 -0
- package/clinkx-workflows/dist/verified-repair/admission.js.map +1 -0
- package/clinkx-workflows/dist/verified-repair/contract.d.ts +1910 -0
- package/clinkx-workflows/dist/verified-repair/contract.js +127 -0
- package/clinkx-workflows/dist/verified-repair/contract.js.map +1 -0
- package/clinkx-workflows/dist/verified-repair/host.d.ts +32 -0
- package/clinkx-workflows/dist/verified-repair/host.js +2 -0
- package/clinkx-workflows/dist/verified-repair/host.js.map +1 -0
- package/clinkx-workflows/dist/verified-repair/prompts.d.ts +12 -0
- package/clinkx-workflows/dist/verified-repair/prompts.js +58 -0
- package/clinkx-workflows/dist/verified-repair/prompts.js.map +1 -0
- package/clinkx-workflows/dist/verified-repair/result.d.ts +16 -0
- package/clinkx-workflows/dist/verified-repair/result.js +102 -0
- package/clinkx-workflows/dist/verified-repair/result.js.map +1 -0
- package/clinkx-workflows/dist/verified-repair/runtime.d.ts +28 -0
- package/clinkx-workflows/dist/verified-repair/runtime.js +186 -0
- package/clinkx-workflows/dist/verified-repair/runtime.js.map +1 -0
- package/clinkx-workflows/dist/workflow-tools.d.ts +3 -0
- package/clinkx-workflows/dist/workflow-tools.js +148 -14
- package/clinkx-workflows/dist/workflow-tools.js.map +1 -1
- package/clinkx-workflows/dist/workflow-verification-contract.d.ts +539 -0
- package/clinkx-workflows/dist/workflow-verification-contract.js +52 -0
- package/clinkx-workflows/dist/workflow-verification-contract.js.map +1 -0
- package/clinkx-workflows/dist/workflow-verification.d.ts +15 -0
- package/clinkx-workflows/dist/workflow-verification.js +218 -0
- package/clinkx-workflows/dist/workflow-verification.js.map +1 -0
- package/clinkx-workflows/templates/architecture-comparison/candidate.txt +29 -0
- package/clinkx-workflows/templates/architecture-comparison/judge.txt +31 -0
- package/clinkx-workflows/templates/verified-repair/investigate.txt +20 -0
- package/clinkx-workflows/templates/verified-repair/repair.txt +11 -0
- package/clinkx-workflows/templates/verified-repair/review.txt +18 -0
- package/clinkx-workflows/workflows/architecture-comparison.yaml +133 -0
- package/clinkx-workflows/workflows/verified-repair.yaml +104 -0
- package/dist/allowed-roots.js +4 -1
- package/dist/allowed-roots.js.map +1 -1
- package/dist/codex/app-server-client.d.ts +1 -0
- package/dist/codex/app-server-client.js +3 -2
- package/dist/codex/app-server-client.js.map +1 -1
- package/dist/context-builder/diagnostics.d.ts +1 -0
- package/dist/context-builder/diagnostics.js +1 -1
- package/dist/context-builder/diagnostics.js.map +1 -1
- package/dist/context-builder/discovery.d.ts +18 -1
- package/dist/context-builder/discovery.js +69 -1
- package/dist/context-builder/discovery.js.map +1 -1
- package/dist/context-builder/handler.js +8 -1
- package/dist/context-builder/handler.js.map +1 -1
- package/dist/context-builder/lifecycle-contract.d.ts +24 -24
- package/dist/context-builder/refine-handler.js +16 -1
- package/dist/context-builder/refine-handler.js.map +1 -1
- package/dist/context-builder/secrets.d.ts +11 -0
- package/dist/context-builder/secrets.js +81 -1
- package/dist/context-builder/secrets.js.map +1 -1
- package/dist/context-builder/versions.d.ts +5 -2
- package/dist/context-builder/versions.js +5 -2
- package/dist/context-builder/versions.js.map +1 -1
- package/dist/dashboard-cli.js +10 -3
- package/dist/dashboard-cli.js.map +1 -1
- package/dist/dashboard-gateway/main.js +8 -3
- package/dist/dashboard-gateway/main.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/project-verification/contract.d.ts +537 -0
- package/dist/project-verification/contract.js +40 -0
- package/dist/project-verification/contract.js.map +1 -0
- package/dist/project-verification/files.d.ts +23 -0
- package/dist/project-verification/files.js +80 -0
- package/dist/project-verification/files.js.map +1 -0
- package/dist/project-verification/process.d.ts +7 -0
- package/dist/project-verification/process.js +115 -0
- package/dist/project-verification/process.js.map +1 -0
- package/dist/project-verification/runner.d.ts +35 -0
- package/dist/project-verification/runner.js +185 -0
- package/dist/project-verification/runner.js.map +1 -0
- package/dist/project-verification/service.d.ts +37 -0
- package/dist/project-verification/service.js +151 -0
- package/dist/project-verification/service.js.map +1 -0
- package/dist/provider-doctor.d.ts +22 -0
- package/dist/provider-doctor.js +22 -0
- package/dist/provider-doctor.js.map +1 -0
- package/dist/server.js +29 -1
- package/dist/server.js.map +1 -1
- package/dist/verification-tools.d.ts +90 -0
- package/dist/verification-tools.js +120 -0
- package/dist/verification-tools.js.map +1 -0
- package/dist/verified-repair/files.d.ts +22 -0
- package/dist/verified-repair/files.js +114 -0
- package/dist/verified-repair/files.js.map +1 -0
- package/dist/verified-repair/host.d.ts +14 -0
- package/dist/verified-repair/host.js +612 -0
- package/dist/verified-repair/host.js.map +1 -0
- package/docs/configuration.md +493 -0
- package/docs/engineering-recipes.md +415 -0
- package/docs/security.md +293 -0
- package/docs/verification/README.md +59 -0
- package/docs/verification/dashboard-real-disk.md +436 -0
- package/docs/verification/project-checks.example.json +14 -0
- package/docs/verification/project-checks.md +444 -0
- package/docs/verification/workflow-handoff.md +113 -0
- package/package.json +13 -6
- package/scripts/provider-doctor-core.mjs +364 -0
- package/scripts/provider-doctor-probe.mjs +34 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/index-JPHQVtn9.js +0 -106
- package/clinkx-workflows/dist/dashboard-ui/assets/style-DOMHk-j6.css +0 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { SchemaValidationError, OutputSizeError } from "../artifacts.js";
|
|
2
|
+
import { relative } from "node:path";
|
|
3
|
+
import { readContainedRelativeFile } from "../contained-file.js";
|
|
4
|
+
import { FixProposalSchema, InvestigationSchema, MAX_REPAIR_PACKET_BYTES, MAX_REPAIR_PROPOSAL_BYTES, RepairPacketSchema, RepairRecordSchema, RepairReviewSchema, REPAIR_REFS, assertRepairBounded, } from "./contract.js";
|
|
5
|
+
import { bytesDigest } from "../architecture-comparison/contract.js";
|
|
6
|
+
import { publishRepairRecord } from "./result.js";
|
|
7
|
+
import { hasCredentialTokenShape } from "../dashboard/session-log-redaction.js";
|
|
8
|
+
import { WorkflowCancellationError } from "../errors.js";
|
|
9
|
+
const PROVIDER_PHASES = {
|
|
10
|
+
[REPAIR_REFS.investigate]: { phase: "investigate", packet: "capture" },
|
|
11
|
+
[REPAIR_REFS.repair]: { phase: "repair", packet: "reproduce" },
|
|
12
|
+
[REPAIR_REFS.review]: { phase: "review", packet: "fixed" },
|
|
13
|
+
};
|
|
14
|
+
/** Fixed phase policy; the existing engine remains the only dispatcher. */
|
|
15
|
+
export class VerifiedRepairRuntime {
|
|
16
|
+
host;
|
|
17
|
+
runId;
|
|
18
|
+
runDir;
|
|
19
|
+
packet;
|
|
20
|
+
providerPackets = new Map();
|
|
21
|
+
retained = new Map();
|
|
22
|
+
finalization;
|
|
23
|
+
invalidArtifact;
|
|
24
|
+
constructor(host, runId, runDir) {
|
|
25
|
+
this.host = host;
|
|
26
|
+
this.runId = runId;
|
|
27
|
+
this.runDir = runDir;
|
|
28
|
+
}
|
|
29
|
+
async prepareProvider(reference, signal) {
|
|
30
|
+
if (this.invalidArtifact !== undefined)
|
|
31
|
+
throw new Error(`invalid repair provider artifact: ${this.invalidArtifact.phase}`);
|
|
32
|
+
const binding = PROVIDER_PHASES[reference];
|
|
33
|
+
if (binding === undefined)
|
|
34
|
+
throw new Error("unexpected repair provider call");
|
|
35
|
+
if (this.packet?.phase !== binding.packet)
|
|
36
|
+
throw new Error(`repair prerequisite unavailable for ${binding.phase}`);
|
|
37
|
+
await this.verifyRetained();
|
|
38
|
+
await this.host.assertProviderPhase(binding.phase, signal);
|
|
39
|
+
assertRepairBounded(this.packet, MAX_REPAIR_PACKET_BYTES);
|
|
40
|
+
this.providerPackets.set(reference, JSON.stringify(this.packet));
|
|
41
|
+
}
|
|
42
|
+
providerPacket(reference) {
|
|
43
|
+
const packet = this.providerPackets.get(reference);
|
|
44
|
+
if (packet === undefined)
|
|
45
|
+
throw new Error("repair provider packet was not prepared");
|
|
46
|
+
return packet;
|
|
47
|
+
}
|
|
48
|
+
async beforeDispatch(reference, input, signal) {
|
|
49
|
+
const binding = PROVIDER_PHASES[reference];
|
|
50
|
+
if (binding === undefined || input["continuation_id"] !== undefined ||
|
|
51
|
+
typeof input["prompt"] !== "string" || !input["prompt"].endsWith(`\n\nFROZEN REPAIR PACKET\n${this.providerPacket(reference)}`)) {
|
|
52
|
+
throw new Error("repair dispatch is not the fresh frozen packet");
|
|
53
|
+
}
|
|
54
|
+
await this.verifyRetained();
|
|
55
|
+
await this.host.assertProviderPhase(binding.phase, signal);
|
|
56
|
+
}
|
|
57
|
+
validateOutput(reference, value) {
|
|
58
|
+
const schema = reference === REPAIR_REFS.investigate ? InvestigationSchema
|
|
59
|
+
: reference === REPAIR_REFS.repair ? FixProposalSchema
|
|
60
|
+
: reference === REPAIR_REFS.review ? RepairReviewSchema
|
|
61
|
+
: reference === REPAIR_REFS.record ? RepairRecordSchema : RepairPacketSchema;
|
|
62
|
+
const parsed = schema.parse(value);
|
|
63
|
+
assertRepairBounded(parsed, MAX_REPAIR_PROPOSAL_BYTES);
|
|
64
|
+
if (hasCredentialTokenShape(JSON.stringify(parsed)))
|
|
65
|
+
throw new Error("repair artifact contains credential-like material; publication is rejected");
|
|
66
|
+
this.host.validateProviderOutput?.(parsed);
|
|
67
|
+
if (this.packet !== undefined && parsed.frozen_digest !== this.packet.frozen_digest)
|
|
68
|
+
throw new Error("repair artifact frozen identity mismatch");
|
|
69
|
+
}
|
|
70
|
+
noteInvalidArtifact(reference, error) {
|
|
71
|
+
if (!(reference in PROVIDER_PHASES))
|
|
72
|
+
return;
|
|
73
|
+
// JSON parser errors can include excerpts of untrusted provider text.
|
|
74
|
+
// Preserve the phase and failure class without copying those excerpts.
|
|
75
|
+
const message = error instanceof SchemaValidationError ? "provider artifact failed strict JSON/schema validation"
|
|
76
|
+
: error instanceof OutputSizeError ? "provider artifact exceeded repair byte limits"
|
|
77
|
+
: "provider artifact identity or semantic contract is invalid";
|
|
78
|
+
this.invalidArtifact ??= { kind: "invalid_artifact", phase: reference, message };
|
|
79
|
+
}
|
|
80
|
+
recordWritten(artifact) {
|
|
81
|
+
this.retained.set(artifact.reference, {
|
|
82
|
+
path: relative(this.runDir, artifact.filePath),
|
|
83
|
+
sha256: bytesDigest(`${JSON.stringify(artifact.parsed, null, 2)}\n`),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async reduce(operation, artifacts, signal) {
|
|
87
|
+
if (operation !== "record" && this.invalidArtifact !== undefined)
|
|
88
|
+
throw new Error(`invalid repair provider artifact: ${this.invalidArtifact.phase}`);
|
|
89
|
+
await this.verifyRetained();
|
|
90
|
+
const proposal = (reference) => {
|
|
91
|
+
const artifact = artifacts.find((entry) => entry.reference === reference);
|
|
92
|
+
if (artifact === undefined || !this.retained.has(reference))
|
|
93
|
+
throw new Error(`repair prerequisite unavailable: ${reference}`);
|
|
94
|
+
this.validateOutput(reference, artifact.parsed);
|
|
95
|
+
return artifact.parsed;
|
|
96
|
+
};
|
|
97
|
+
if (operation === "record") {
|
|
98
|
+
// The run owner publishes again after cleanup with actual terminal state.
|
|
99
|
+
// A final reducer is never the interruption publication boundary.
|
|
100
|
+
return JSON.stringify(RepairRecordSchema.parse(await this.host.record("completed")));
|
|
101
|
+
}
|
|
102
|
+
const packet = operation === "capture" ? await this.host.capture(signal)
|
|
103
|
+
: operation === "reproduce" ? await this.host.reproduce(proposal(REPAIR_REFS.investigate), signal)
|
|
104
|
+
: operation === "fixed" ? await this.host.fixed(proposal(REPAIR_REFS.repair), signal)
|
|
105
|
+
: await this.host.independently(proposal(REPAIR_REFS.review), signal);
|
|
106
|
+
const parsed = RepairPacketSchema.parse(packet);
|
|
107
|
+
if (parsed.phase !== operation || (this.packet !== undefined && parsed.frozen_digest !== this.packet.frozen_digest))
|
|
108
|
+
throw new Error("repair host packet phase or frozen identity mismatch");
|
|
109
|
+
assertRepairBounded(parsed, MAX_REPAIR_PACKET_BYTES);
|
|
110
|
+
this.packet = parsed;
|
|
111
|
+
return JSON.stringify(this.packet);
|
|
112
|
+
}
|
|
113
|
+
/** Await all owned cleanup before publication, even with an aborted run signal. */
|
|
114
|
+
finalize(status, reason, signal) {
|
|
115
|
+
this.finalization ??= this.finalizeOnce(status, reason, signal);
|
|
116
|
+
return this.finalization;
|
|
117
|
+
}
|
|
118
|
+
async cleanupUnadmitted(reason) {
|
|
119
|
+
try {
|
|
120
|
+
await this.host.abort(reason);
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
await this.host.cleanup();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async finalizeOnce(status, reason, signal) {
|
|
127
|
+
const requestedCompletion = status === "completed";
|
|
128
|
+
const finalizationErrors = [];
|
|
129
|
+
const abort = async (error) => {
|
|
130
|
+
try {
|
|
131
|
+
await this.host.abort(error);
|
|
132
|
+
}
|
|
133
|
+
catch (abortError) {
|
|
134
|
+
finalizationErrors.push(abortError);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
if (this.invalidArtifact !== undefined)
|
|
138
|
+
await abort(this.invalidArtifact);
|
|
139
|
+
if (status !== "completed")
|
|
140
|
+
await abort(reason ?? status);
|
|
141
|
+
try {
|
|
142
|
+
await this.host.cleanup();
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
finalizationErrors.push(error);
|
|
146
|
+
status = status === "completed" ? "failed" : status;
|
|
147
|
+
await abort(error);
|
|
148
|
+
}
|
|
149
|
+
if (status === "completed" && finalizationErrors.length > 0)
|
|
150
|
+
status = "failed";
|
|
151
|
+
if (requestedCompletion && signal?.aborted) {
|
|
152
|
+
status = "cancelled";
|
|
153
|
+
await abort(signal.reason ?? "cancelled during finalization");
|
|
154
|
+
}
|
|
155
|
+
let record = RepairRecordSchema.parse(await this.host.record(status));
|
|
156
|
+
if (record.run_id !== this.runId || record.execution_status !== status)
|
|
157
|
+
throw new Error("repair terminal record identity mismatch");
|
|
158
|
+
await publishRepairRecord(this.runDir, record);
|
|
159
|
+
// Cancellation can arrive while the host projection or atomic publication
|
|
160
|
+
// awaits I/O. Reproject partial facts before the owner commits terminal state.
|
|
161
|
+
if (requestedCompletion && signal?.aborted && status !== "cancelled") {
|
|
162
|
+
await abort(signal.reason ?? "cancelled during publication");
|
|
163
|
+
status = "cancelled";
|
|
164
|
+
record = RepairRecordSchema.parse(await this.host.record(status));
|
|
165
|
+
if (record.run_id !== this.runId || record.execution_status !== status)
|
|
166
|
+
throw new Error("repair terminal record identity mismatch");
|
|
167
|
+
await publishRepairRecord(this.runDir, record);
|
|
168
|
+
}
|
|
169
|
+
if (requestedCompletion && status === "cancelled")
|
|
170
|
+
throw new WorkflowCancellationError();
|
|
171
|
+
if (finalizationErrors.length > 0)
|
|
172
|
+
throw new AggregateError(finalizationErrors, "repair finalization failed after retaining terminal facts");
|
|
173
|
+
return JSON.stringify(record);
|
|
174
|
+
}
|
|
175
|
+
async verifyRetained() {
|
|
176
|
+
for (const [reference, fact] of this.retained) {
|
|
177
|
+
const read = await readContainedRelativeFile(this.runDir, fact.path, {
|
|
178
|
+
wantContent: true, requireRegular: true, requireExactRequestedPath: true,
|
|
179
|
+
maxBytes: MAX_REPAIR_PROPOSAL_BYTES,
|
|
180
|
+
});
|
|
181
|
+
if (bytesDigest(read.content) !== fact.sha256)
|
|
182
|
+
throw new Error(`retained repair artifact changed: ${reference}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/verified-repair/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,7 +26,10 @@ import type { Variable } from "./schema.js";
|
|
|
26
26
|
import { type WorkflowContextRequestedMode, type WorkflowContextPolicy } from "./context-mode-resolver.js";
|
|
27
27
|
import { type AvailableCliCapability, type ResolvedRoster } from "./roster-contract.js";
|
|
28
28
|
import type { RosterLoader } from "./rosters.js";
|
|
29
|
+
import type { VerifiedRepairHost } from "./verified-repair/host.js";
|
|
29
30
|
export interface WorkflowToolsOptions {
|
|
31
|
+
/** Root-owned contract capture, scoped edits, and native verification. */
|
|
32
|
+
readonly verifiedRepairHost?: VerifiedRepairHost | undefined;
|
|
30
33
|
/**
|
|
31
34
|
* Factory that creates a ClinkBackend for a given run.
|
|
32
35
|
* For standalone server: `(runId) => new ClinkSession({ runId })`
|
|
@@ -25,7 +25,7 @@ import { readRunStateForStatus, reapRunCancelled, WorkflowStateStore } from "./s
|
|
|
25
25
|
import { isTerminalContextBuilderLifecycleStatus, parseContextBuilderLifecycleStateV1, } from "./context-builder-lifecycle-contract.js";
|
|
26
26
|
import { validateRunId } from "./run-id.js";
|
|
27
27
|
import { validateDynamicPaths } from "./path-validation.js";
|
|
28
|
-
import { getMaxPromptBytes, getRunStateDir, getTemplatesPath, getWorkflowsContextDefault, getWorkflowsContextDefaultCurator, getWorkflowsMaxConcurrentAsync, resolveWorkspaceRoot, } from "./config.js";
|
|
28
|
+
import { getMaxPromptBytes, getRunStateDir, getRunsDir, getTemplatesPath, getWorkflowsContextDefault, getWorkflowsContextDefaultCurator, getWorkflowsMaxConcurrentAsync, resolveWorkspaceRoot, } from "./config.js";
|
|
29
29
|
import { WorkflowCancellationError, WorkflowValidationError, } from "./errors.js";
|
|
30
30
|
import { shutdownCoordinator } from "./shutdown.js";
|
|
31
31
|
import { logger } from "./logger.js";
|
|
@@ -54,6 +54,14 @@ import { validatePlanReviewCallBindings, validatePlanReviewPreparedInputPolicy,
|
|
|
54
54
|
import { ContainedFilePolicyError, readContainedRelativeFile, } from "./contained-file.js";
|
|
55
55
|
import { createDashboardRunReader } from "./dashboard/read-model.js";
|
|
56
56
|
import { ROSTER_NAME_PATTERN, ResolvedRosterSchema, } from "./roster-contract.js";
|
|
57
|
+
import { materializeArchitectureRoutes } from "./architecture-comparison/admission.js";
|
|
58
|
+
import { ARCHITECTURE_WORKFLOW } from "./architecture-comparison/contract.js";
|
|
59
|
+
import { inspectArchitectureComparisonRecord } from "./architecture-comparison/runtime.js";
|
|
60
|
+
import { VERIFIED_REPAIR_WORKFLOW, MAX_REPAIR_RECORD_BYTES, RepairRecordSchema, assertRepairBounded } from "./verified-repair/contract.js";
|
|
61
|
+
import { materializeVerifiedRepairRoutes, repairRoutesFromVariables } from "./verified-repair/admission.js";
|
|
62
|
+
import { VerifiedRepairRuntime } from "./verified-repair/runtime.js";
|
|
63
|
+
import { inspectVerifiedRepairRecord } from "./verified-repair/result.js";
|
|
64
|
+
import { readWorkflowVerification } from "./workflow-verification.js";
|
|
57
65
|
async function inspectLegacyWorkflowSessionLogGeneration(runDir, runId) {
|
|
58
66
|
try {
|
|
59
67
|
const result = await createDashboardRunReader().inspectGeneration?.(dirname(runDir), runId);
|
|
@@ -1339,7 +1347,7 @@ async function executeRunWorkflow(server, options, args, signal, progressToken)
|
|
|
1339
1347
|
throw new McpError(ErrorCode.InvalidParams, `Invalid run_id "${runId}". Must match [A-Za-z0-9_-]{1,64}.`);
|
|
1340
1348
|
}
|
|
1341
1349
|
const validatorRegistry = createValidatorRegistry();
|
|
1342
|
-
|
|
1350
|
+
let loaded = loadWorkflow(workflow, {
|
|
1343
1351
|
templatesRoot: options.templatesRoot ?? getTemplatesPath(),
|
|
1344
1352
|
workflowsPath: options.workflowsPath,
|
|
1345
1353
|
validatorRegistry,
|
|
@@ -1400,20 +1408,30 @@ async function executeRunWorkflow(server, options, args, signal, progressToken)
|
|
|
1400
1408
|
throw new McpError(ErrorCode.InvalidParams, `chairman_effort parameter is not supported for workflow "${workflow}"`);
|
|
1401
1409
|
}
|
|
1402
1410
|
resolvedVariables = validateVariables(suppliedVariables, loaded.definition.variables);
|
|
1411
|
+
try {
|
|
1412
|
+
loaded = { ...loaded, normalized: materializeArchitectureRoutes(loaded.normalized, resolvedVariables, options.planReviewAvailableCliNames ?? options.availableCliNames, options.validateInvocationOverrides) };
|
|
1413
|
+
loaded = { ...loaded, normalized: materializeVerifiedRepairRoutes(loaded.normalized, resolvedVariables, options.planReviewAvailableCliNames ?? options.availableCliNames, options.validateInvocationOverrides) };
|
|
1414
|
+
if (workflow === VERIFIED_REPAIR_WORKFLOW && options.verifiedRepairHost === undefined) {
|
|
1415
|
+
throw new Error("verified-repair requires the root host capability");
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
catch (error) {
|
|
1419
|
+
throw new McpError(ErrorCode.InvalidParams, error instanceof Error ? error.message : String(error));
|
|
1420
|
+
}
|
|
1403
1421
|
// When the runner is absent (preflight disabled / hard kill), the boundary
|
|
1404
1422
|
// validator is inert. Skip it WITHOUT evaluating the context-default env
|
|
1405
1423
|
// parsers — getWorkflowsContextDefaultCurator() throws on empty env, and a
|
|
1406
1424
|
// runner-less run_workflow must never trip context env parsing.
|
|
1407
1425
|
let contextPolicy;
|
|
1408
|
-
if (options.contextBuilderRunner != null) {
|
|
1426
|
+
if (workflow !== VERIFIED_REPAIR_WORKFLOW && options.contextBuilderRunner != null) {
|
|
1409
1427
|
contextPolicy = validateContextBuilderAnchorSufficiency(resolvedVariables, options.contextBuilderRunner, options.contextDefault ?? getWorkflowsContextDefault(), options.defaultCurator ?? getWorkflowsContextDefaultCurator());
|
|
1410
1428
|
}
|
|
1411
1429
|
validateContextSeedSourceAtAdmission(resolvedVariables, contextPolicy);
|
|
1412
1430
|
// Pre-mutex, pre-state, pre-preflight: an out-of-roots caller path costs
|
|
1413
1431
|
// zero delegate round-trips and leaves no run directory behind.
|
|
1414
1432
|
assertCallerDynamicPathsAllowed(loaded.normalized, resolvedVariables, workflow, runId);
|
|
1415
|
-
initialContextPolicy = contextPolicy ?? resolveWorkflowContextMode(undefined, options.contextDefault ?? "off", false, undefined, options.defaultCurator);
|
|
1416
|
-
if (options.contextBuilderRunner != null) {
|
|
1433
|
+
initialContextPolicy = contextPolicy ?? resolveWorkflowContextMode(undefined, workflow === VERIFIED_REPAIR_WORKFLOW ? "off" : options.contextDefault ?? "off", false, undefined, options.defaultCurator);
|
|
1434
|
+
if (workflow !== VERIFIED_REPAIR_WORKFLOW && options.contextBuilderRunner != null) {
|
|
1417
1435
|
try {
|
|
1418
1436
|
options.contextBuilderRunner.assertTaskSecretsAllowed(resolvedVariables);
|
|
1419
1437
|
}
|
|
@@ -1475,6 +1493,32 @@ async function executeRunWorkflow(server, options, args, signal, progressToken)
|
|
|
1475
1493
|
}
|
|
1476
1494
|
const isAsync = args["async"] === true;
|
|
1477
1495
|
const ownership = acquireWorkflowRun(runId, options, isAsync ? undefined : signal);
|
|
1496
|
+
let verifiedRepair;
|
|
1497
|
+
if (workflow === VERIFIED_REPAIR_WORKFLOW) {
|
|
1498
|
+
try {
|
|
1499
|
+
ownership.throwIfCancelled();
|
|
1500
|
+
const runDir = getRunStateDir(runId);
|
|
1501
|
+
if (existsSync(runDir))
|
|
1502
|
+
throw new McpError(ErrorCode.InvalidParams, `run_id ${runId} already has persisted state at ${runDir}`);
|
|
1503
|
+
const prepared = await options.verifiedRepairHost.prepare({
|
|
1504
|
+
runId, runDir, contractPath: resolvedVariables["repair_contract_path"],
|
|
1505
|
+
routes: repairRoutesFromVariables(resolvedVariables), signal: ownership.signal,
|
|
1506
|
+
});
|
|
1507
|
+
verifiedRepair = new VerifiedRepairRuntime(prepared, runId, runDir);
|
|
1508
|
+
ownership.throwIfCancelled();
|
|
1509
|
+
}
|
|
1510
|
+
catch (error) {
|
|
1511
|
+
try {
|
|
1512
|
+
await verifiedRepair?.cleanupUnadmitted(error);
|
|
1513
|
+
}
|
|
1514
|
+
finally {
|
|
1515
|
+
await ownership.finish(undefined);
|
|
1516
|
+
}
|
|
1517
|
+
if (ownership.signal.aborted)
|
|
1518
|
+
throw new WorkflowCancellationError();
|
|
1519
|
+
throw new McpError(ErrorCode.InvalidParams, error instanceof Error ? error.message : String(error));
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1478
1522
|
if (isAsync) {
|
|
1479
1523
|
// Everything between acquireMutex and the detached spawn must release the
|
|
1480
1524
|
// mutex on ANY throw, or the run slot leaks permanently (bricks the server
|
|
@@ -1562,14 +1606,24 @@ async function executeRunWorkflow(server, options, args, signal, progressToken)
|
|
|
1562
1606
|
throw err;
|
|
1563
1607
|
}
|
|
1564
1608
|
finally {
|
|
1565
|
-
|
|
1609
|
+
try {
|
|
1610
|
+
if (verifiedRepair !== undefined) {
|
|
1611
|
+
if (store === undefined)
|
|
1612
|
+
await verifiedRepair.cleanupUnadmitted(err);
|
|
1613
|
+
else
|
|
1614
|
+
await verifiedRepair.finalize(ownership.signal.aborted ? "cancelled" : "failed", err);
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
finally {
|
|
1618
|
+
await ownership.finish(store);
|
|
1619
|
+
}
|
|
1566
1620
|
}
|
|
1567
1621
|
}
|
|
1568
1622
|
if (store === undefined || effectiveDefinition === undefined) {
|
|
1569
1623
|
await ownership.finish(store);
|
|
1570
1624
|
throw new McpError(ErrorCode.InternalError, `Failed to initialize async run ${runId}`);
|
|
1571
1625
|
}
|
|
1572
|
-
void runWorkflowDetached(server, options, workflow, runId, resolvedVariables, debug, receipt, validatorRegistry, loaded, parsedMembers, parsedChairman, parsedChairmanModel, parsedChairmanEffort, true, ownership, undefined, store, effectiveDefinition, undefined, initializedPlanReview, initialContextPolicy, admittedRosterName).catch((err) => {
|
|
1626
|
+
void runWorkflowDetached(server, options, workflow, runId, resolvedVariables, debug, receipt, validatorRegistry, loaded, parsedMembers, parsedChairman, parsedChairmanModel, parsedChairmanEffort, true, ownership, undefined, store, effectiveDefinition, undefined, initializedPlanReview, initialContextPolicy, admittedRosterName, verifiedRepair).catch((err) => {
|
|
1573
1627
|
if (err instanceof WorkflowCancellationError) {
|
|
1574
1628
|
logger.info({ runId }, "workflow run cancelled");
|
|
1575
1629
|
return;
|
|
@@ -1597,7 +1651,7 @@ async function executeRunWorkflow(server, options, args, signal, progressToken)
|
|
|
1597
1651
|
}],
|
|
1598
1652
|
};
|
|
1599
1653
|
}
|
|
1600
|
-
return await runWorkflowDetached(server, options, workflow, runId, resolvedVariables, debug, receipt, validatorRegistry, loaded, parsedMembers, parsedChairman, parsedChairmanModel, parsedChairmanEffort, false, ownership, progressToken, undefined, undefined, planReviewPlan, undefined, initialContextPolicy, admittedRosterName);
|
|
1654
|
+
return await runWorkflowDetached(server, options, workflow, runId, resolvedVariables, debug, receipt, validatorRegistry, loaded, parsedMembers, parsedChairman, parsedChairmanModel, parsedChairmanEffort, false, ownership, progressToken, undefined, undefined, planReviewPlan, undefined, initialContextPolicy, admittedRosterName, verifiedRepair);
|
|
1601
1655
|
}
|
|
1602
1656
|
async function preparePlanReviewSnapshot(plan) {
|
|
1603
1657
|
try {
|
|
@@ -1789,7 +1843,7 @@ preparedSnapshot) {
|
|
|
1789
1843
|
? expandCouncilComposition(definition, parsedMembers, workflow, parsedChairman, parsedChairmanModel, parsedChairmanEffort)
|
|
1790
1844
|
: definition;
|
|
1791
1845
|
}
|
|
1792
|
-
async function runWorkflowDetached(server, options, workflow, runId, resolvedVariables, debug, receipt, validatorRegistry, loaded, parsedMembers, parsedChairman, parsedChairmanModel, parsedChairmanEffort, isAsync, ownership, progressToken, preCreatedStore, preExpandedDefinition, planReviewPlan, preInitializedPlanReview, initialContextPolicy, rosterName) {
|
|
1846
|
+
async function runWorkflowDetached(server, options, workflow, runId, resolvedVariables, debug, receipt, validatorRegistry, loaded, parsedMembers, parsedChairman, parsedChairmanModel, parsedChairmanEffort, isAsync, ownership, progressToken, preCreatedStore, preExpandedDefinition, planReviewPlan, preInitializedPlanReview, initialContextPolicy, rosterName, verifiedRepair) {
|
|
1793
1847
|
let store = preCreatedStore ?? null;
|
|
1794
1848
|
let backend = null;
|
|
1795
1849
|
let reporter;
|
|
@@ -1849,6 +1903,24 @@ async function runWorkflowDetached(server, options, workflow, runId, resolvedVar
|
|
|
1849
1903
|
const rpt = reporter; // local const for closure narrowing
|
|
1850
1904
|
const hooks = {
|
|
1851
1905
|
...storeRef.hooks,
|
|
1906
|
+
...(verifiedRepair === undefined ? {} : {
|
|
1907
|
+
onRunStateChange: async (event) => {
|
|
1908
|
+
if (event.state === "succeeded" || event.state === "failed" || event.state === "cancelled") {
|
|
1909
|
+
try {
|
|
1910
|
+
await backend?.terminate();
|
|
1911
|
+
await verifiedRepair.finalize(event.state === "succeeded" ? "completed" : event.state, event.error, signal);
|
|
1912
|
+
if (event.state === "succeeded")
|
|
1913
|
+
ownership.throwIfCancelled();
|
|
1914
|
+
}
|
|
1915
|
+
catch (error) {
|
|
1916
|
+
if (event.state === "succeeded")
|
|
1917
|
+
throw error;
|
|
1918
|
+
logger.error({ err: error, runId }, "repair terminal publication failed; preserving original execution failure");
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
await storeRef.hooks.onRunStateChange?.(event);
|
|
1922
|
+
},
|
|
1923
|
+
}),
|
|
1852
1924
|
...(rpt != null
|
|
1853
1925
|
? {
|
|
1854
1926
|
onProgress: async (event) => {
|
|
@@ -1872,11 +1944,12 @@ async function runWorkflowDetached(server, options, workflow, runId, resolvedVar
|
|
|
1872
1944
|
runDir: storeRef.runDir,
|
|
1873
1945
|
signal,
|
|
1874
1946
|
hooks,
|
|
1875
|
-
contextBuilderRunner: options.contextBuilderRunner,
|
|
1947
|
+
contextBuilderRunner: verifiedRepair === undefined ? options.contextBuilderRunner : undefined,
|
|
1876
1948
|
contextDefault: options.contextDefault,
|
|
1877
1949
|
defaultCurator: options.defaultCurator,
|
|
1878
1950
|
commitPreflightContext: storeRef.commitPreflightContext?.bind(storeRef),
|
|
1879
1951
|
initialContextPolicy,
|
|
1952
|
+
verifiedRepair,
|
|
1880
1953
|
...(options.deriveInvocationAudit === undefined
|
|
1881
1954
|
? {}
|
|
1882
1955
|
: { deriveInvocationAudit: options.deriveInvocationAudit }),
|
|
@@ -1893,6 +1966,7 @@ async function runWorkflowDetached(server, options, workflow, runId, resolvedVar
|
|
|
1893
1966
|
: {}),
|
|
1894
1967
|
});
|
|
1895
1968
|
const result = await engine.execute();
|
|
1969
|
+
const terminalRepair = await verifiedRepair?.finalize("completed", undefined, signal);
|
|
1896
1970
|
// Build summary (fail-open)
|
|
1897
1971
|
let summary;
|
|
1898
1972
|
if (receipt) {
|
|
@@ -1905,7 +1979,7 @@ async function runWorkflowDetached(server, options, workflow, runId, resolvedVar
|
|
|
1905
1979
|
}
|
|
1906
1980
|
}
|
|
1907
1981
|
const content = finalizeWorkflowPresentation({
|
|
1908
|
-
outputText: result.outputText,
|
|
1982
|
+
outputText: terminalRepair ?? result.outputText,
|
|
1909
1983
|
receipt,
|
|
1910
1984
|
debug,
|
|
1911
1985
|
summary,
|
|
@@ -1916,6 +1990,18 @@ async function runWorkflowDetached(server, options, workflow, runId, resolvedVar
|
|
|
1916
1990
|
return { content };
|
|
1917
1991
|
}
|
|
1918
1992
|
catch (error) {
|
|
1993
|
+
if (verifiedRepair !== undefined) {
|
|
1994
|
+
try {
|
|
1995
|
+
await backend?.terminate();
|
|
1996
|
+
if (store === null)
|
|
1997
|
+
await verifiedRepair.cleanupUnadmitted(error);
|
|
1998
|
+
else
|
|
1999
|
+
await verifiedRepair.finalize(signal.aborted || error instanceof WorkflowCancellationError ? "cancelled" : "failed", error);
|
|
2000
|
+
}
|
|
2001
|
+
catch (publicationError) {
|
|
2002
|
+
logger.error({ err: publicationError, runId }, "repair error publication failed; preserving original execution failure");
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
1919
2005
|
if (signal.aborted || error instanceof WorkflowCancellationError) {
|
|
1920
2006
|
await markWorkflowCancelled(store);
|
|
1921
2007
|
throw new WorkflowCancellationError();
|
|
@@ -1992,6 +2078,9 @@ async function executeResumeWorkflow(server, options, args, signal, progressToke
|
|
|
1992
2078
|
persistedBeforeMutex = null;
|
|
1993
2079
|
}
|
|
1994
2080
|
const persistedState = persistedBeforeMutex?.state;
|
|
2081
|
+
if (persistedState?.workflowName === VERIFIED_REPAIR_WORKFLOW) {
|
|
2082
|
+
throw new McpError(ErrorCode.InvalidParams, "verified-repair mutation cannot be resumed; inspect the retained result and submit a fresh explicit contract");
|
|
2083
|
+
}
|
|
1995
2084
|
if (persistedState != null &&
|
|
1996
2085
|
isPlanReviewRunState(persistedState) &&
|
|
1997
2086
|
(persistedState.status === "failed" ||
|
|
@@ -2022,6 +2111,9 @@ async function executeResumeWorkflow(server, options, args, signal, progressToke
|
|
|
2022
2111
|
debugKeepArtifacts: debug,
|
|
2023
2112
|
};
|
|
2024
2113
|
store = await WorkflowStateStore.resume(resumeOptions);
|
|
2114
|
+
if (store.runState.workflowName === VERIFIED_REPAIR_WORKFLOW) {
|
|
2115
|
+
throw new McpError(ErrorCode.InvalidParams, "verified-repair mutation cannot be resumed; inspect the retained result and submit a fresh explicit contract");
|
|
2116
|
+
}
|
|
2025
2117
|
// Open this attempt before classifying an abort during reconstruction;
|
|
2026
2118
|
// otherwise a prior terminal record would suppress markCancelled.
|
|
2027
2119
|
await store.beginResumeAttempt();
|
|
@@ -2336,7 +2428,7 @@ function parseLifecycleForStatus(value) {
|
|
|
2336
2428
|
return undefined;
|
|
2337
2429
|
}
|
|
2338
2430
|
}
|
|
2339
|
-
async function executeWorkflowRunStatus(
|
|
2431
|
+
async function executeWorkflowRunStatus(options, args) {
|
|
2340
2432
|
const runId = args["run_id"];
|
|
2341
2433
|
const includeResult = args["include_result"] === true;
|
|
2342
2434
|
if (typeof runId !== "string" || runId === "") {
|
|
@@ -2396,6 +2488,7 @@ async function executeWorkflowRunStatus(_options, args) {
|
|
|
2396
2488
|
};
|
|
2397
2489
|
// artifacts_dir is cheap (pure join, no I/O) and present for every found run.
|
|
2398
2490
|
projection["artifacts_dir"] = join(runDir, "artifacts");
|
|
2491
|
+
projection["verification"] = await readWorkflowVerification(getRunsDir(), runId);
|
|
2399
2492
|
// Read-only context-selection observability from already-persisted state.
|
|
2400
2493
|
// No file I/O — only projects state.workflow_context.context_builder and
|
|
2401
2494
|
// the state.context_builder_lifecycle snapshot.
|
|
@@ -2578,6 +2671,47 @@ async function executeWorkflowRunStatus(_options, args) {
|
|
|
2578
2671
|
}
|
|
2579
2672
|
}
|
|
2580
2673
|
}
|
|
2674
|
+
if (state.workflowName === ARCHITECTURE_WORKFLOW) {
|
|
2675
|
+
const comparison = await inspectArchitectureComparisonRecord(runDir, runId, includeResult);
|
|
2676
|
+
const { result, ...status } = comparison;
|
|
2677
|
+
projection["comparison"] = status;
|
|
2678
|
+
projection["result_available"] = status["status"] === "complete" || status["status"] === "incomplete";
|
|
2679
|
+
if (result !== undefined)
|
|
2680
|
+
projection["result"] = result;
|
|
2681
|
+
else
|
|
2682
|
+
delete projection["result"];
|
|
2683
|
+
}
|
|
2684
|
+
if (state.workflowName === VERIFIED_REPAIR_WORKFLOW) {
|
|
2685
|
+
let inspected = await inspectVerifiedRepairRecord(runDir, runId, includeResult);
|
|
2686
|
+
if (inspected.availability === "unrecorded" && lock === "stale_or_absent" && !activeRuns.has(runId)) {
|
|
2687
|
+
try {
|
|
2688
|
+
const value = await options.verifiedRepairHost?.readInterruptedRun?.({ runId, runDir });
|
|
2689
|
+
if (value === undefined)
|
|
2690
|
+
throw new Error("interrupted capture unavailable");
|
|
2691
|
+
const record = RepairRecordSchema.parse(value);
|
|
2692
|
+
if (record.run_id !== runId || record.execution_status !== "interrupted")
|
|
2693
|
+
throw new Error("interrupted repair record identity mismatch");
|
|
2694
|
+
assertRepairBounded(record, MAX_REPAIR_RECORD_BYTES);
|
|
2695
|
+
const serialized = JSON.stringify(record);
|
|
2696
|
+
inspected = { availability: "available", result_available: true,
|
|
2697
|
+
result_bytes: Buffer.byteLength(serialized), owner_acceptance: "not_recorded",
|
|
2698
|
+
execution_status: "interrupted", repair_status: record.repair_status,
|
|
2699
|
+
...(includeResult ? { result: serialized, record } : {}) };
|
|
2700
|
+
}
|
|
2701
|
+
catch {
|
|
2702
|
+
inspected = { availability: "unavailable", result_available: false, result_bytes: 0,
|
|
2703
|
+
owner_acceptance: "not_recorded", reason: "interrupted_capture_unavailable" };
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
const { result, record: _record, result_available, result_bytes, ...repair } = inspected;
|
|
2707
|
+
projection["repair"] = { ...repair, scope: repair.execution_status === "interrupted" ? "inspected_at" : "recorded_at" };
|
|
2708
|
+
projection["result_available"] = result_available;
|
|
2709
|
+
projection["result_bytes"] = result_bytes;
|
|
2710
|
+
if (result !== undefined)
|
|
2711
|
+
projection["result"] = result;
|
|
2712
|
+
else
|
|
2713
|
+
delete projection["result"];
|
|
2714
|
+
}
|
|
2581
2715
|
return {
|
|
2582
2716
|
content: [{ type: "text", text: JSON.stringify(projection) }],
|
|
2583
2717
|
};
|
|
@@ -2680,7 +2814,7 @@ function executeListWorkflows(options) {
|
|
|
2680
2814
|
supports_members: runtimeMembers,
|
|
2681
2815
|
supports_chairman: runtimeMembers,
|
|
2682
2816
|
supports_context_preflight: contextStrategy.supports_context_preflight,
|
|
2683
|
-
effective_context_default: effectiveContextDefault,
|
|
2817
|
+
effective_context_default: name === VERIFIED_REPAIR_WORKFLOW ? "disabled" : effectiveContextDefault,
|
|
2684
2818
|
fails_on_empty_selection: contextStrategy.fails_on_empty_selection,
|
|
2685
2819
|
context_anchor_variables: contextStrategy.context_anchor_variables,
|
|
2686
2820
|
context_override_variables: contextStrategy.context_override_variables,
|
|
@@ -3131,7 +3265,7 @@ export function getWorkflowToolDefinitions(workflowsPath, availableCliNames) {
|
|
|
3131
3265
|
},
|
|
3132
3266
|
{
|
|
3133
3267
|
name: "workflow_run_status",
|
|
3134
|
-
description: "Read-only status/progress of a workflow run. The full result is included only with include_result:true. Generic workflows preserve succeeded-final-call behavior; plan-review-receipts reports marker-driven availability and bytes independently of terminal status, with body-blind default polling. Every found run also carries a top-level `health` block {classification: \"ok\"|\"degraded\", reasons: string[]} computed read-time from persisted data — a run can be status:\"succeeded\" yet degraded when on_failure:continue swallowed failed calls or context preflight was partial/degraded (reasons: failed_calls_in_succeeded_run, context_partial, context_lifecycle_failed, coverage_degraded, delegate_fallback_used, context_external_gaps — the finalizer reported evidence gaps outside the delegate packet under external_gap_policy:\"degrade\", so conclusions depending on them are conditional). When a context-builder lifecycle snapshot is persisted, the `context` block additionally includes `lifecycle_status` and `coverage` {policy, status, required, selected, missing}. A parsed snapshot also projects `context.delegate.finalizer` {effective_enabled, execution_status, score?}; `score` is present only for a succeeded finalizer that recorded one, and the finalizer key is omitted when the lifecycle is missing, unparseable, or those fields are absent. While context preflight is still running (non-terminal lifecycle, no committed context yet) the `context` block is absent and a top-level `context_progress` {phase, status, updated_at, counts} reports scan progress instead. Found council runs also include a top-level `resolved_roster` of requested seat and delegate values (no provenance) when the run persisted one; older runs omit the key.",
|
|
3268
|
+
description: "Read-only status/progress of a workflow run. The full result is included only with include_result:true. Generic workflows preserve succeeded-final-call behavior; plan-review-receipts reports marker-driven availability and bytes independently of terminal status, with body-blind default polling. Every found run also carries a top-level `health` block {classification: \"ok\"|\"degraded\", reasons: string[]} computed read-time from persisted data — a run can be status:\"succeeded\" yet degraded when on_failure:continue swallowed failed calls or context preflight was partial/degraded (reasons: failed_calls_in_succeeded_run, context_partial, context_lifecycle_failed, coverage_degraded, delegate_fallback_used, context_external_gaps — the finalizer reported evidence gaps outside the delegate packet under external_gap_policy:\"degrade\", so conclusions depending on them are conditional). When a context-builder lifecycle snapshot is persisted, the `context` block additionally includes `lifecycle_status` and `coverage` {policy, status, required, selected, missing}. A parsed snapshot also projects `context.delegate.finalizer` {effective_enabled, execution_status, score?}; `score` is present only for a succeeded finalizer that recorded one, and the finalizer key is omitted when the lifecycle is missing, unparseable, or those fields are absent. While context preflight is still running (non-terminal lifecycle, no committed context yet) the `context` block is absent and a top-level `context_progress` {phase, status, updated_at, counts} reports scan progress instead. Found council runs also include a top-level `resolved_roster` of requested seat and delegate values (no provenance) when the run persisted one; older runs omit the key. Architecture comparisons additionally project comparison completeness and retained record availability independently of run execution status. Every found run has a separately versioned verification projection of historical inspected-at evidence; it establishes neither current source/runtime applicability nor owner acceptance.",
|
|
3135
3269
|
inputSchema: WORKFLOW_RUN_STATUS_SCHEMA,
|
|
3136
3270
|
annotations: { readOnlyHint: true },
|
|
3137
3271
|
},
|