cool-workflow 0.1.78
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/.claude-plugin/plugin.json +20 -0
- package/.codex-plugin/mcp.json +10 -0
- package/.codex-plugin/plugin.json +38 -0
- package/.mcp.json +10 -0
- package/LICENSE +24 -0
- package/README.md +638 -0
- package/apps/architecture-review/app.json +51 -0
- package/apps/architecture-review/workflow.js +116 -0
- package/apps/end-to-end-golden-path/app.json +30 -0
- package/apps/end-to-end-golden-path/workflow.js +33 -0
- package/apps/pr-review-fix-ci/app.json +59 -0
- package/apps/pr-review-fix-ci/workflow.js +90 -0
- package/apps/release-cut/app.json +54 -0
- package/apps/release-cut/workflow.js +82 -0
- package/apps/research-synthesis/app.json +50 -0
- package/apps/research-synthesis/workflow.js +76 -0
- package/apps/workflow-app-framework-demo/app.json +29 -0
- package/apps/workflow-app-framework-demo/workflow.js +44 -0
- package/dist/agent-config.js +223 -0
- package/dist/candidate-scoring.js +715 -0
- package/dist/capability-core.js +630 -0
- package/dist/capability-dispatcher.js +86 -0
- package/dist/capability-registry.js +523 -0
- package/dist/cli.js +1276 -0
- package/dist/collaboration.js +727 -0
- package/dist/commit.js +570 -0
- package/dist/contract-migration.js +234 -0
- package/dist/coordinator.js +1163 -0
- package/dist/daemon.js +44 -0
- package/dist/dispatch.js +201 -0
- package/dist/drive.js +503 -0
- package/dist/error-feedback.js +415 -0
- package/dist/evidence-grounding.js +179 -0
- package/dist/evidence-reasoning.js +733 -0
- package/dist/execution-backend.js +1279 -0
- package/dist/harness.js +61 -0
- package/dist/mcp-server.js +1615 -0
- package/dist/multi-agent-eval.js +857 -0
- package/dist/multi-agent-host.js +764 -0
- package/dist/multi-agent-operator-ux.js +537 -0
- package/dist/multi-agent-trust.js +366 -0
- package/dist/multi-agent.js +1173 -0
- package/dist/node-snapshot.js +270 -0
- package/dist/observability.js +922 -0
- package/dist/operator-ux.js +971 -0
- package/dist/orchestrator/audit-operations.js +182 -0
- package/dist/orchestrator/candidate-operations.js +117 -0
- package/dist/orchestrator/cli-options.js +288 -0
- package/dist/orchestrator/collaboration-operations.js +86 -0
- package/dist/orchestrator/feedback-operations.js +81 -0
- package/dist/orchestrator/host-operations.js +78 -0
- package/dist/orchestrator/lifecycle-operations.js +462 -0
- package/dist/orchestrator/migration-operations.js +44 -0
- package/dist/orchestrator/multi-agent-operations.js +362 -0
- package/dist/orchestrator/report.js +369 -0
- package/dist/orchestrator/topology-operations.js +84 -0
- package/dist/orchestrator.js +874 -0
- package/dist/pipeline-contract.js +92 -0
- package/dist/pipeline-runner.js +285 -0
- package/dist/reclamation.js +882 -0
- package/dist/result-normalize.js +194 -0
- package/dist/run-export.js +64 -0
- package/dist/run-registry.js +1347 -0
- package/dist/run-state-schema.js +67 -0
- package/dist/sandbox-profile.js +471 -0
- package/dist/scheduler.js +266 -0
- package/dist/scheduling.js +184 -0
- package/dist/schema-validate.js +98 -0
- package/dist/state-explosion.js +1213 -0
- package/dist/state-migrations.js +463 -0
- package/dist/state-node.js +301 -0
- package/dist/state.js +308 -0
- package/dist/telemetry-attestation.js +156 -0
- package/dist/telemetry-ledger.js +145 -0
- package/dist/topology.js +527 -0
- package/dist/triggers.js +159 -0
- package/dist/trust-audit.js +475 -0
- package/dist/types/blackboard.js +2 -0
- package/dist/types/boundary.js +29 -0
- package/dist/types/candidate.js +2 -0
- package/dist/types/collaboration.js +2 -0
- package/dist/types/core.js +2 -0
- package/dist/types/drive.js +10 -0
- package/dist/types/error-feedback.js +2 -0
- package/dist/types/evidence-reasoning.js +2 -0
- package/dist/types/execution-backend.js +2 -0
- package/dist/types/multi-agent.js +2 -0
- package/dist/types/observability.js +2 -0
- package/dist/types/pipeline.js +2 -0
- package/dist/types/reclamation.js +8 -0
- package/dist/types/result.js +2 -0
- package/dist/types/run-registry.js +2 -0
- package/dist/types/run.js +2 -0
- package/dist/types/sandbox.js +2 -0
- package/dist/types/schedule.js +2 -0
- package/dist/types/state-node.js +2 -0
- package/dist/types/topology.js +2 -0
- package/dist/types/trust.js +2 -0
- package/dist/types/workbench.js +2 -0
- package/dist/types/worker.js +2 -0
- package/dist/types/workflow-app.js +2 -0
- package/dist/types.js +43 -0
- package/dist/verifier-registry.js +46 -0
- package/dist/verifier.js +78 -0
- package/dist/version.js +8 -0
- package/dist/workbench-host.js +172 -0
- package/dist/workbench.js +190 -0
- package/dist/worker-isolation.js +1028 -0
- package/dist/workflow-api.js +98 -0
- package/dist/workflow-app-framework.js +626 -0
- package/docs/agent-delegation-drive.7.md +190 -0
- package/docs/agent-framework.md +176 -0
- package/docs/candidate-scoring.7.md +106 -0
- package/docs/canonical-workflow-apps.7.md +137 -0
- package/docs/capability-topology-registry.7.md +168 -0
- package/docs/cli-mcp-parity.7.md +373 -0
- package/docs/contract-migration-tooling.7.md +123 -0
- package/docs/control-plane-scheduling.7.md +110 -0
- package/docs/coordinator-blackboard.7.md +183 -0
- package/docs/dogfood/architecture-review-cool-workflow.md +16 -0
- package/docs/dogfood-one-real-repo.7.md +168 -0
- package/docs/durable-state-and-locking.7.md +107 -0
- package/docs/end-to-end-golden-path.7.md +117 -0
- package/docs/error-feedback.7.md +153 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +270 -0
- package/docs/execution-backends.7.md +300 -0
- package/docs/getting-started.md +99 -0
- package/docs/index.md +41 -0
- package/docs/mcp-app-surface.7.md +235 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +265 -0
- package/docs/multi-agent-eval-replay-harness.7.md +302 -0
- package/docs/multi-agent-operator-ux.7.md +314 -0
- package/docs/multi-agent-runtime-core.7.md +231 -0
- package/docs/multi-agent-topologies.7.md +103 -0
- package/docs/multi-agent-trust-policy-audit.7.md +154 -0
- package/docs/node-snapshot-diff-replay.7.md +135 -0
- package/docs/observability-cost-accounting.7.md +194 -0
- package/docs/operator-ux.7.md +180 -0
- package/docs/pipeline-runner.7.md +136 -0
- package/docs/project-index.md +261 -0
- package/docs/real-execution-backends.7.md +142 -0
- package/docs/release-and-migration.7.md +280 -0
- package/docs/release-tooling.7.md +159 -0
- package/docs/routines.md +48 -0
- package/docs/run-registry-control-plane.7.md +312 -0
- package/docs/run-retention-reclamation.7.md +191 -0
- package/docs/sandbox-profiles.7.md +137 -0
- package/docs/scheduled-tasks.md +80 -0
- package/docs/security-trust-hardening.7.md +117 -0
- package/docs/state-explosion-management.7.md +264 -0
- package/docs/state-node.7.md +96 -0
- package/docs/team-collaboration.7.md +207 -0
- package/docs/unix-principles.md +192 -0
- package/docs/verifier-gated-commit.7.md +140 -0
- package/docs/web-desktop-workbench.7.md +215 -0
- package/docs/worker-isolation.7.md +167 -0
- package/docs/workflow-app-framework.7.md +274 -0
- package/manifest/README.md +43 -0
- package/manifest/plugin.manifest.json +316 -0
- package/manifest/pricing.policy.json +14 -0
- package/package.json +79 -0
- package/scripts/agents/claude-p-agent.js +104 -0
- package/scripts/agents/claude-p-agent.sh +9 -0
- package/scripts/agents/cw-attest-keygen.js +55 -0
- package/scripts/agents/cw-attest-wrap.js +143 -0
- package/scripts/block-unapproved-tag.sh +39 -0
- package/scripts/bump-version.js +249 -0
- package/scripts/canonical-apps.js +171 -0
- package/scripts/cw.js +4 -0
- package/scripts/dist-drift-check.js +79 -0
- package/scripts/dogfood-architecture-review.js +237 -0
- package/scripts/dogfood-release.js +624 -0
- package/scripts/forward-ref-docs.js +73 -0
- package/scripts/gen-manifests.js +232 -0
- package/scripts/golden-path.js +300 -0
- package/scripts/mcp-server.js +4 -0
- package/scripts/new-feature.js +121 -0
- package/scripts/parity-check.js +213 -0
- package/scripts/release-check.js +118 -0
- package/scripts/release-flow.js +272 -0
- package/scripts/release-gate.sh +85 -0
- package/scripts/sync-project-index.js +387 -0
- package/scripts/validate-run-state-schema.js +126 -0
- package/scripts/verify-container-selfref.js +64 -0
- package/scripts/version-sync-check.js +237 -0
- package/skills/cool-workflow/SKILL.md +162 -0
- package/skills/cool-workflow/references/commands.md +282 -0
- package/tsconfig.json +16 -0
- package/ui/workbench/app.css +76 -0
- package/ui/workbench/app.js +159 -0
- package/ui/workbench/index.html +32 -0
- package/workflows/architecture-review.workflow.js +84 -0
- package/workflows/research-synthesis.workflow.js +47 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_PIPELINE_CONTRACT_ID = void 0;
|
|
4
|
+
exports.createDefaultPipelineContract = createDefaultPipelineContract;
|
|
5
|
+
exports.DEFAULT_PIPELINE_CONTRACT_ID = "cw.pipeline.default";
|
|
6
|
+
function createDefaultPipelineContract() {
|
|
7
|
+
return {
|
|
8
|
+
schemaVersion: 1,
|
|
9
|
+
id: exports.DEFAULT_PIPELINE_CONTRACT_ID,
|
|
10
|
+
title: "Cool Workflow Default Pipeline",
|
|
11
|
+
stages: [
|
|
12
|
+
{
|
|
13
|
+
id: "plan",
|
|
14
|
+
name: "Plan",
|
|
15
|
+
acceptedInputKinds: ["input"],
|
|
16
|
+
acceptedInputStatuses: ["pending", "completed"],
|
|
17
|
+
producedOutputKind: "task",
|
|
18
|
+
requiredArtifacts: ["state"]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "dispatch",
|
|
22
|
+
name: "Dispatch",
|
|
23
|
+
acceptedInputKinds: ["task"],
|
|
24
|
+
acceptedInputStatuses: ["pending"],
|
|
25
|
+
producedOutputKind: "dispatch",
|
|
26
|
+
requiredArtifacts: ["task"]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "result",
|
|
30
|
+
name: "Result",
|
|
31
|
+
acceptedInputKinds: ["dispatch"],
|
|
32
|
+
acceptedInputStatuses: ["running", "completed"],
|
|
33
|
+
producedOutputKind: "result",
|
|
34
|
+
requiredArtifacts: ["result"]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: "verify",
|
|
38
|
+
name: "Verify",
|
|
39
|
+
acceptedInputKinds: ["result", "verifier"],
|
|
40
|
+
acceptedInputStatuses: ["completed", "verified"],
|
|
41
|
+
producedOutputKind: "verifier",
|
|
42
|
+
requiredEvidence: ["cw:result"]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "commit",
|
|
46
|
+
name: "Commit",
|
|
47
|
+
acceptedInputKinds: ["verifier", "commit"],
|
|
48
|
+
acceptedInputStatuses: ["verified"],
|
|
49
|
+
producedOutputKind: "commit",
|
|
50
|
+
verifierGate: {
|
|
51
|
+
required: true,
|
|
52
|
+
acceptedStatuses: ["verified"],
|
|
53
|
+
requiredEvidence: true
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "report",
|
|
58
|
+
name: "Report",
|
|
59
|
+
acceptedInputKinds: ["commit", "result", "verifier"],
|
|
60
|
+
acceptedInputStatuses: ["committed", "completed", "verified"],
|
|
61
|
+
producedOutputKind: "report",
|
|
62
|
+
requiredArtifacts: ["report"]
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: "object"
|
|
67
|
+
},
|
|
68
|
+
outputSchema: {
|
|
69
|
+
type: "object"
|
|
70
|
+
},
|
|
71
|
+
artifactPolicy: {
|
|
72
|
+
root: ".cw/runs/<run-id>",
|
|
73
|
+
requireReadablePaths: true
|
|
74
|
+
},
|
|
75
|
+
evidencePolicy: {
|
|
76
|
+
highPriorityRequiresEvidence: true
|
|
77
|
+
},
|
|
78
|
+
failurePolicy: {
|
|
79
|
+
preserveFailureNodes: true,
|
|
80
|
+
retryableByDefault: false
|
|
81
|
+
},
|
|
82
|
+
commitPolicy: {
|
|
83
|
+
requiresVerifierGate: true,
|
|
84
|
+
acceptedVerifierStatuses: ["verified"]
|
|
85
|
+
},
|
|
86
|
+
compatibility: {
|
|
87
|
+
minSchemaVersion: 1,
|
|
88
|
+
maxSchemaVersion: 1,
|
|
89
|
+
notes: "New optional fields may be added without breaking existing run state."
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPipelineRunner = createPipelineRunner;
|
|
4
|
+
exports.getRunContract = getRunContract;
|
|
5
|
+
exports.getRunNode = getRunNode;
|
|
6
|
+
exports.findRunnablePipelineStages = findRunnablePipelineStages;
|
|
7
|
+
exports.advancePipeline = advancePipeline;
|
|
8
|
+
exports.runPipelineStage = runPipelineStage;
|
|
9
|
+
exports.failPipelineStage = failPipelineStage;
|
|
10
|
+
const pipeline_contract_1 = require("./pipeline-contract");
|
|
11
|
+
const state_1 = require("./state");
|
|
12
|
+
const error_feedback_1 = require("./error-feedback");
|
|
13
|
+
const state_node_1 = require("./state-node");
|
|
14
|
+
function createPipelineRunner(defaultOptions = {}) {
|
|
15
|
+
return {
|
|
16
|
+
getRunContract: (run, contractId) => getRunContract(run, contractId || defaultOptions.contractId),
|
|
17
|
+
getRunNode,
|
|
18
|
+
findRunnablePipelineStages: (run, contract) => findRunnablePipelineStages(run, contract),
|
|
19
|
+
runPipelineStage: (run, stageId, inputNodeId, options = {}) => runPipelineStage(run, stageId, inputNodeId, { ...defaultOptions, ...options }),
|
|
20
|
+
advancePipeline: (run, options = {}) => advancePipeline(run, { ...defaultOptions, ...options }),
|
|
21
|
+
failPipelineStage
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function getRunContract(run, contractId) {
|
|
25
|
+
const id = contractId || pipeline_contract_1.DEFAULT_PIPELINE_CONTRACT_ID;
|
|
26
|
+
const existing = (run.contracts || []).find((candidate) => candidate.id === id);
|
|
27
|
+
if (existing) {
|
|
28
|
+
(0, state_node_1.validatePipelineContract)(existing);
|
|
29
|
+
return existing;
|
|
30
|
+
}
|
|
31
|
+
if (id !== pipeline_contract_1.DEFAULT_PIPELINE_CONTRACT_ID) {
|
|
32
|
+
throw new Error(`Unknown pipeline contract for run ${run.id}: ${id}`);
|
|
33
|
+
}
|
|
34
|
+
return (0, state_node_1.upsertRunContract)(run, (0, pipeline_contract_1.createDefaultPipelineContract)());
|
|
35
|
+
}
|
|
36
|
+
function getRunNode(run, nodeId) {
|
|
37
|
+
const node = (run.nodes || []).find((candidate) => candidate.id === nodeId);
|
|
38
|
+
if (!node)
|
|
39
|
+
throw new Error(`Unknown state node for run ${run.id}: ${nodeId}`);
|
|
40
|
+
return node;
|
|
41
|
+
}
|
|
42
|
+
function findRunnablePipelineStages(run, contract = getRunContract(run)) {
|
|
43
|
+
(0, state_node_1.validatePipelineContract)(contract);
|
|
44
|
+
const runnable = [];
|
|
45
|
+
for (const node of run.nodes || []) {
|
|
46
|
+
for (const stage of contract.stages) {
|
|
47
|
+
if (!stage.acceptedInputKinds.includes(node.kind))
|
|
48
|
+
continue;
|
|
49
|
+
if (!stage.acceptedInputStatuses.includes(node.status))
|
|
50
|
+
continue;
|
|
51
|
+
if (!hasRequiredArtifacts(node, stage))
|
|
52
|
+
continue;
|
|
53
|
+
if (!hasRequiredEvidence(node, stage, contract))
|
|
54
|
+
continue;
|
|
55
|
+
if (!hasVerifierGate(node, stage, contract))
|
|
56
|
+
continue;
|
|
57
|
+
runnable.push({
|
|
58
|
+
runId: run.id,
|
|
59
|
+
contractId: contract.id,
|
|
60
|
+
stageId: stage.id,
|
|
61
|
+
inputNodeId: node.id,
|
|
62
|
+
outputKind: stage.producedOutputKind
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return runnable;
|
|
67
|
+
}
|
|
68
|
+
function advancePipeline(run, options = {}) {
|
|
69
|
+
const contract = getRunContract(run, options.contractId);
|
|
70
|
+
const runnable = findRunnablePipelineStages(run, contract);
|
|
71
|
+
if (!runnable.length) {
|
|
72
|
+
return {
|
|
73
|
+
runId: run.id,
|
|
74
|
+
contractId: contract.id,
|
|
75
|
+
status: "idle",
|
|
76
|
+
stages: [],
|
|
77
|
+
runnable
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const stages = [];
|
|
81
|
+
const autoAdvance = contract.failurePolicy?.autoAdvance ?? false;
|
|
82
|
+
for (const next of runnable) {
|
|
83
|
+
const result = runPipelineStage(run, next.stageId, next.inputNodeId, { ...options, contractId: contract.id });
|
|
84
|
+
stages.push(result);
|
|
85
|
+
if (result.status === "advanced") {
|
|
86
|
+
return { runId: run.id, contractId: contract.id, status: "advanced", stages, runnable };
|
|
87
|
+
}
|
|
88
|
+
if (!autoAdvance) {
|
|
89
|
+
return { runId: run.id, contractId: contract.id, status: "failed", stages, runnable };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
runId: run.id,
|
|
94
|
+
contractId: contract.id,
|
|
95
|
+
status: "failed",
|
|
96
|
+
stages,
|
|
97
|
+
runnable
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function runPipelineStage(run, stageId, inputNodeId, options = {}) {
|
|
101
|
+
const contract = getRunContract(run, options.contractId);
|
|
102
|
+
const inputNode = getRunNode(run, inputNodeId);
|
|
103
|
+
const stage = getContractStage(contract, stageId);
|
|
104
|
+
try {
|
|
105
|
+
(0, state_node_1.assertNodeSatisfiesContract)(inputNode, contract, stageId);
|
|
106
|
+
const targetStatus = options.outputStatus || defaultOutputStatus(stage);
|
|
107
|
+
const outputNode = (0, state_node_1.createStateNode)({
|
|
108
|
+
id: options.outputNodeId,
|
|
109
|
+
kind: stage.producedOutputKind,
|
|
110
|
+
status: targetStatus === "committed" ? "verified" : "pending",
|
|
111
|
+
loopStage: options.loopStage || inputNode.loopStage,
|
|
112
|
+
inputs: {
|
|
113
|
+
inputNodeId: inputNode.id,
|
|
114
|
+
stageId: stage.id
|
|
115
|
+
},
|
|
116
|
+
outputs: options.outputs,
|
|
117
|
+
artifacts: options.artifacts,
|
|
118
|
+
evidence: options.evidence,
|
|
119
|
+
parents: [inputNode.id],
|
|
120
|
+
contractId: contract.id,
|
|
121
|
+
metadata: {
|
|
122
|
+
...(options.metadata || {}),
|
|
123
|
+
pipelineStage: stage.id
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
const transitioned = (0, state_node_1.transitionStateNode)(outputNode, {
|
|
127
|
+
status: targetStatus,
|
|
128
|
+
loopStage: options.loopStage || outputNode.loopStage,
|
|
129
|
+
outputs: options.outputs,
|
|
130
|
+
artifacts: options.artifacts,
|
|
131
|
+
evidence: options.evidence,
|
|
132
|
+
metadata: options.metadata
|
|
133
|
+
});
|
|
134
|
+
const [linkedInput, linkedOutput] = (0, state_node_1.linkStateNodes)(inputNode, transitioned);
|
|
135
|
+
(0, state_node_1.appendRunNode)(run, linkedInput);
|
|
136
|
+
(0, state_node_1.appendRunNode)(run, linkedOutput);
|
|
137
|
+
if (shouldPersist(options))
|
|
138
|
+
(0, state_1.saveCheckpoint)(run);
|
|
139
|
+
return {
|
|
140
|
+
runId: run.id,
|
|
141
|
+
contractId: contract.id,
|
|
142
|
+
stageId,
|
|
143
|
+
inputNodeId,
|
|
144
|
+
outputNodeId: linkedOutput.id,
|
|
145
|
+
status: "advanced",
|
|
146
|
+
artifacts: linkedOutput.artifacts,
|
|
147
|
+
evidence: linkedOutput.evidence
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
if (!isStructuredPipelineError(error))
|
|
152
|
+
throw error;
|
|
153
|
+
return failPipelineStage(run, stageId, inputNode, error, { ...options, contractId: contract.id });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function failPipelineStage(run, stageId, inputNode, error, options = {}) {
|
|
157
|
+
const contract = getRunContract(run, options.contractId);
|
|
158
|
+
const stage = getContractStage(contract, stageId);
|
|
159
|
+
const structured = toStateNodeError(error, inputNode.id, shouldRetry(stage, contract));
|
|
160
|
+
const preserve = options.preserveFailureNode ??
|
|
161
|
+
stage.failure?.preserveFailureNode ??
|
|
162
|
+
contract.failurePolicy?.preserveFailureNodes ??
|
|
163
|
+
false;
|
|
164
|
+
let failedNode = (0, state_node_1.recordNodeError)((0, state_node_1.createStateNode)({
|
|
165
|
+
id: options.outputNodeId,
|
|
166
|
+
kind: stage.failure?.failureKind || "error",
|
|
167
|
+
status: "pending",
|
|
168
|
+
loopStage: options.loopStage || inputNode.loopStage,
|
|
169
|
+
inputs: {
|
|
170
|
+
inputNodeId: inputNode.id,
|
|
171
|
+
stageId: stage.id
|
|
172
|
+
},
|
|
173
|
+
outputs: options.outputs,
|
|
174
|
+
artifacts: options.artifacts,
|
|
175
|
+
evidence: options.evidence,
|
|
176
|
+
parents: [inputNode.id],
|
|
177
|
+
contractId: contract.id,
|
|
178
|
+
metadata: {
|
|
179
|
+
...(options.metadata || {}),
|
|
180
|
+
pipelineStage: stage.id,
|
|
181
|
+
preserved: preserve
|
|
182
|
+
}
|
|
183
|
+
}), structured);
|
|
184
|
+
if (preserve) {
|
|
185
|
+
const [linkedInput, linkedFailure] = (0, state_node_1.linkStateNodes)(inputNode, failedNode);
|
|
186
|
+
(0, state_node_1.appendRunNode)(run, linkedInput);
|
|
187
|
+
failedNode = (0, state_node_1.appendRunNode)(run, linkedFailure);
|
|
188
|
+
(0, error_feedback_1.recordFeedback)(run, {
|
|
189
|
+
source: "pipeline-runner",
|
|
190
|
+
error: failedNode.errors[failedNode.errors.length - 1],
|
|
191
|
+
nodeId: failedNode.id,
|
|
192
|
+
stageId,
|
|
193
|
+
contractId: contract.id,
|
|
194
|
+
path: structured.path,
|
|
195
|
+
retryable: structured.retryable,
|
|
196
|
+
evidence: failedNode.evidence,
|
|
197
|
+
artifacts: failedNode.artifacts,
|
|
198
|
+
metadata: {
|
|
199
|
+
inputNodeId: inputNode.id,
|
|
200
|
+
preservedFailureNode: true
|
|
201
|
+
}
|
|
202
|
+
}, { persist: false });
|
|
203
|
+
if (shouldPersist(options))
|
|
204
|
+
(0, state_1.saveCheckpoint)(run);
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
runId: run.id,
|
|
208
|
+
contractId: contract.id,
|
|
209
|
+
stageId,
|
|
210
|
+
inputNodeId: inputNode.id,
|
|
211
|
+
outputNodeId: preserve ? failedNode.id : undefined,
|
|
212
|
+
status: "failed",
|
|
213
|
+
error: failedNode.errors[failedNode.errors.length - 1],
|
|
214
|
+
artifacts: failedNode.artifacts,
|
|
215
|
+
evidence: failedNode.evidence
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function getContractStage(contract, stageId) {
|
|
219
|
+
(0, state_node_1.validatePipelineContract)(contract);
|
|
220
|
+
const stage = contract.stages.find((candidate) => candidate.id === stageId);
|
|
221
|
+
if (!stage)
|
|
222
|
+
throw new Error(`Unknown pipeline stage for contract ${contract.id}: ${stageId}`);
|
|
223
|
+
return stage;
|
|
224
|
+
}
|
|
225
|
+
function defaultOutputStatus(stage) {
|
|
226
|
+
if (stage.producedOutputKind === "commit")
|
|
227
|
+
return "committed";
|
|
228
|
+
return "completed";
|
|
229
|
+
}
|
|
230
|
+
function hasRequiredArtifacts(node, stage) {
|
|
231
|
+
for (const required of stage.requiredArtifacts || []) {
|
|
232
|
+
const artifact = node.artifacts.find((candidate) => candidate.id === required || candidate.kind === required);
|
|
233
|
+
if (!artifact)
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
function hasRequiredEvidence(node, stage, contract) {
|
|
239
|
+
if ((stage.requiredEvidence?.length || contract.evidencePolicy?.requireEvidence) && !node.evidence.length)
|
|
240
|
+
return false;
|
|
241
|
+
for (const required of stage.requiredEvidence || []) {
|
|
242
|
+
const evidence = node.evidence.find((candidate) => candidate.id === required || candidate.source === required);
|
|
243
|
+
if (!evidence)
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
function hasVerifierGate(node, stage, contract) {
|
|
249
|
+
const gate = stage.verifierGate;
|
|
250
|
+
const commitRequiresGate = contract.commitPolicy?.requiresVerifierGate && stage.producedOutputKind === "commit";
|
|
251
|
+
if (!gate?.required && !commitRequiresGate)
|
|
252
|
+
return true;
|
|
253
|
+
const acceptedStatuses = gate?.acceptedStatuses || contract.commitPolicy?.acceptedVerifierStatuses || ["verified"];
|
|
254
|
+
if (!acceptedStatuses.includes(node.status))
|
|
255
|
+
return false;
|
|
256
|
+
if ((gate?.requiredEvidence || contract.evidencePolicy?.requireEvidence) && !node.evidence.length)
|
|
257
|
+
return false;
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
function shouldPersist(options) {
|
|
261
|
+
return options.persist !== false;
|
|
262
|
+
}
|
|
263
|
+
function shouldRetry(stage, contract) {
|
|
264
|
+
return stage.failure?.retryable ?? contract.failurePolicy?.retryableByDefault ?? false;
|
|
265
|
+
}
|
|
266
|
+
function isStructuredPipelineError(error) {
|
|
267
|
+
return error instanceof state_node_1.PipelineContractError;
|
|
268
|
+
}
|
|
269
|
+
function toStateNodeError(error, nodeId, retryable) {
|
|
270
|
+
if (error instanceof state_node_1.PipelineContractError) {
|
|
271
|
+
return {
|
|
272
|
+
...error.structured,
|
|
273
|
+
nodeId: error.structured.nodeId || nodeId,
|
|
274
|
+
retryable: error.structured.retryable ?? retryable
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
278
|
+
return {
|
|
279
|
+
code: "pipeline-stage-error",
|
|
280
|
+
message,
|
|
281
|
+
at: new Date().toISOString(),
|
|
282
|
+
nodeId,
|
|
283
|
+
retryable
|
|
284
|
+
};
|
|
285
|
+
}
|