harnery 0.12.2 → 0.14.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 +2 -1
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +2 -0
- package/dist/commands/work.d.ts +4 -0
- package/dist/commands/work.d.ts.map +1 -0
- package/dist/commands/work.js +281 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +193 -0
- package/dist/core/policy/types.d.ts +1 -1
- package/dist/core/policy/types.d.ts.map +1 -1
- package/dist/core/work/index.d.ts +3 -0
- package/dist/core/work/index.d.ts.map +1 -0
- package/dist/core/work/index.js +2 -0
- package/dist/core/work/read.d.ts +2 -0
- package/dist/core/work/read.d.ts.map +1 -0
- package/dist/core/work/read.js +1 -0
- package/dist/core/work/runner.d.ts +10 -0
- package/dist/core/work/runner.d.ts.map +1 -0
- package/dist/core/work/runner.js +63 -0
- package/dist/core/work/state.d.ts +109 -0
- package/dist/core/work/state.d.ts.map +1 -0
- package/dist/core/work/state.js +698 -0
- package/dist/core/workflow/approvals.d.ts +71 -0
- package/dist/core/workflow/approvals.d.ts.map +1 -0
- package/dist/core/workflow/approvals.js +288 -0
- package/dist/core/workflow/engine.d.ts +6 -0
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +243 -43
- package/dist/core/workflow/index.d.ts +6 -2
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +3 -1
- package/dist/core/workflow/proof.d.ts +1 -0
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +1 -0
- package/dist/core/workflow/run-state.d.ts +44 -0
- package/dist/core/workflow/run-state.d.ts.map +1 -0
- package/dist/core/workflow/run-state.js +233 -0
- package/dist/core/workflow/types.d.ts +16 -0
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/package.json +11 -1
- package/src/commander.ts +2 -0
- package/src/commands/work.ts +367 -0
- package/src/commands/workflow.ts +226 -0
- package/src/core/policy/types.ts +1 -1
- package/src/core/work/index.ts +24 -0
- package/src/core/work/read.ts +15 -0
- package/src/core/work/runner.ts +81 -0
- package/src/core/work/state.ts +900 -0
- package/src/core/workflow/approvals.ts +393 -0
- package/src/core/workflow/engine.ts +288 -44
- package/src/core/workflow/index.ts +31 -1
- package/src/core/workflow/proof.ts +2 -0
- package/src/core/workflow/run-state.ts +290 -0
- package/src/core/workflow/types.ts +16 -0
|
@@ -30,8 +30,10 @@ import { isAbsolute, join, resolve } from "node:path";
|
|
|
30
30
|
import { pathToFileURL } from "node:url";
|
|
31
31
|
import { snapshotRepo } from "../context/index.js";
|
|
32
32
|
import { evaluatePolicy, normalizePolicy, PolicyDeniedError, policyDigest, summarizePolicyRequest, } from "../policy/index.js";
|
|
33
|
+
import { assertWorkflowRunId, createWorkflowApproval } from "./approvals.js";
|
|
33
34
|
import { probeBilling } from "./billing.js";
|
|
34
35
|
import { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, writeWorkflowProof, } from "./proof.js";
|
|
36
|
+
import { acquireWorkflowResumeLease, assertWorkflowRunResumable, assertWorkflowScriptUnchanged, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
|
|
35
37
|
import { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.js";
|
|
36
38
|
import { parseStageOutput, validateAgainstSchema } from "./validate.js";
|
|
37
39
|
const DEFAULT_MAX_AGENTS = 50;
|
|
@@ -51,8 +53,61 @@ export class WorkflowRunError extends Error {
|
|
|
51
53
|
this.proofPath = proofPath;
|
|
52
54
|
}
|
|
53
55
|
}
|
|
56
|
+
export class WorkflowParkedError extends Error {
|
|
57
|
+
runId;
|
|
58
|
+
approvalId;
|
|
59
|
+
journalPath;
|
|
60
|
+
constructor(message, runId, approvalId, journalPath) {
|
|
61
|
+
super(message);
|
|
62
|
+
this.name = "WorkflowParkedError";
|
|
63
|
+
this.runId = runId;
|
|
64
|
+
this.approvalId = approvalId;
|
|
65
|
+
this.journalPath = journalPath;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
54
68
|
export async function runWorkflow(scriptPath, opts) {
|
|
69
|
+
if (opts.runId && opts.resumeRunId) {
|
|
70
|
+
throw new Error("runId and resumeRunId are mutually exclusive");
|
|
71
|
+
}
|
|
72
|
+
if (opts.runId)
|
|
73
|
+
assertWorkflowRunId(opts.runId);
|
|
74
|
+
if (opts.workItemId && !/^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/.test(opts.workItemId)) {
|
|
75
|
+
throw new Error(`invalid work item id ${JSON.stringify(opts.workItemId)}`);
|
|
76
|
+
}
|
|
77
|
+
if (opts.resumeRunId && opts.resumeFrom) {
|
|
78
|
+
throw new Error("resumeRunId and resumeFrom are mutually exclusive");
|
|
79
|
+
}
|
|
80
|
+
const resumeState = opts.resumeRunId
|
|
81
|
+
? assertWorkflowRunResumable(opts.coordRoot, opts.resumeRunId)
|
|
82
|
+
: undefined;
|
|
83
|
+
if (resumeState !== undefined &&
|
|
84
|
+
opts.workItemId !== undefined &&
|
|
85
|
+
resumeState.manifest.work_item_id !== opts.workItemId) {
|
|
86
|
+
throw new Error(`workflow run ${opts.resumeRunId} belongs to a different work item`);
|
|
87
|
+
}
|
|
55
88
|
const absScript = isAbsolute(scriptPath) ? scriptPath : resolve(process.cwd(), scriptPath);
|
|
89
|
+
if (resumeState) {
|
|
90
|
+
if (resolve(resumeState.manifest.script.path) !== resolve(absScript)) {
|
|
91
|
+
throw new Error(`workflow run ${opts.resumeRunId} belongs to a different script`);
|
|
92
|
+
}
|
|
93
|
+
assertWorkflowScriptUnchanged(resumeState.manifest);
|
|
94
|
+
}
|
|
95
|
+
const releaseResumeLease = opts.resumeRunId
|
|
96
|
+
? acquireWorkflowResumeLease(opts.coordRoot, opts.resumeRunId)
|
|
97
|
+
: undefined;
|
|
98
|
+
try {
|
|
99
|
+
if (resumeState) {
|
|
100
|
+
// Recheck under the exclusive lease. Another process may have completed
|
|
101
|
+
// the run between the optimistic read and lease acquisition.
|
|
102
|
+
assertWorkflowRunResumable(opts.coordRoot, resumeState.manifest.run_id);
|
|
103
|
+
}
|
|
104
|
+
return await executeWorkflow(scriptPath, absScript, opts, resumeState);
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
releaseResumeLease?.();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async function executeWorkflow(scriptPath, absScript, opts, resumeState) {
|
|
56
111
|
const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(absScript).href)));
|
|
57
112
|
if (typeof mod.default !== "function") {
|
|
58
113
|
throw new Error(`${scriptPath}: workflow script must \`export default async (ctx) => …\``);
|
|
@@ -60,20 +115,58 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
60
115
|
const fallbackName = scriptPath.replace(/^.*\//, "").replace(/\.[cm]?js$/, "");
|
|
61
116
|
const meta = normalizeWorkflowMeta(mod.meta, fallbackName);
|
|
62
117
|
const name = meta.name;
|
|
63
|
-
const runId =
|
|
118
|
+
const runId = opts.resumeRunId ??
|
|
119
|
+
opts.runId ??
|
|
120
|
+
`wf-${new Date().toISOString().replace(/[:.]/g, "-")}-${randomBytes(3).toString("hex")}`;
|
|
64
121
|
const runDir = join(opts.coordRoot, ".harnery", "workflows", runId);
|
|
65
122
|
mkdirSync(runDir, { recursive: true });
|
|
66
123
|
const journalPath = join(runDir, "journal.jsonl");
|
|
67
124
|
const proofPath = join(runDir, "proof.json");
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
const
|
|
125
|
+
const frozen = resumeState?.manifest.execution;
|
|
126
|
+
const maxAgents = frozen?.max_agents ?? opts.maxAgents ?? DEFAULT_MAX_AGENTS;
|
|
127
|
+
const concurrency = frozen?.concurrency ?? opts.concurrency ?? DEFAULT_CONCURRENCY;
|
|
128
|
+
assertPositiveWorkflowBound(maxAgents, "maxAgents");
|
|
129
|
+
assertPositiveWorkflowBound(concurrency, "concurrency");
|
|
130
|
+
const cwd = frozen?.cwd ?? opts.cwd ?? opts.coordRoot;
|
|
71
131
|
const log = opts.onLog ?? ((line) => process.stderr.write(`${line}\n`));
|
|
72
|
-
const defaultHarness = opts.defaultHarness ?? "claude-code";
|
|
73
|
-
const isolation = opts.isolation ?? "shared";
|
|
74
|
-
const networkAccess = opts.networkAccess ?? "unknown";
|
|
75
|
-
const policy = opts.policy ? normalizePolicy(opts.policy, { baseDir: cwd }) : undefined;
|
|
76
|
-
const
|
|
132
|
+
const defaultHarness = frozen?.default_harness ?? opts.defaultHarness ?? "claude-code";
|
|
133
|
+
const isolation = frozen?.isolation ?? opts.isolation ?? "shared";
|
|
134
|
+
const networkAccess = frozen?.network_access ?? opts.networkAccess ?? "unknown";
|
|
135
|
+
const policy = frozen?.policy ?? (opts.policy ? normalizePolicy(opts.policy, { baseDir: cwd }) : undefined);
|
|
136
|
+
const approvalMode = frozen?.approval_mode ?? opts.approvalMode ?? "deny";
|
|
137
|
+
const approvalAddressee = frozen?.approval_addressee ?? opts.approvalAddressee ?? "operator";
|
|
138
|
+
const subscriptionOnly = frozen?.subscription_only ?? Boolean(opts.subscriptionOnly);
|
|
139
|
+
const allowApiBilling = frozen?.allow_api_billing ?? Boolean(opts.allowApiBilling);
|
|
140
|
+
const repoBefore = resumeState?.manifest.repository_before ?? snapshotRepo(cwd);
|
|
141
|
+
const startedAt = resumeState?.manifest.started_at ?? new Date().toISOString();
|
|
142
|
+
const t0 = resumeState ? Date.parse(startedAt) : Date.now();
|
|
143
|
+
if (!resumeState) {
|
|
144
|
+
writeWorkflowRunManifest({
|
|
145
|
+
coordRoot: opts.coordRoot,
|
|
146
|
+
manifest: {
|
|
147
|
+
schema_version: 1,
|
|
148
|
+
run_id: runId,
|
|
149
|
+
work_item_id: opts.workItemId,
|
|
150
|
+
name,
|
|
151
|
+
started_at: startedAt,
|
|
152
|
+
script: { path: absScript, sha256: workflowScriptDigest(absScript) },
|
|
153
|
+
repository_before: repoBefore,
|
|
154
|
+
execution: {
|
|
155
|
+
cwd,
|
|
156
|
+
default_harness: defaultHarness,
|
|
157
|
+
max_agents: maxAgents,
|
|
158
|
+
concurrency,
|
|
159
|
+
subscription_only: subscriptionOnly,
|
|
160
|
+
allow_api_billing: allowApiBilling,
|
|
161
|
+
approval_mode: approvalMode,
|
|
162
|
+
approval_addressee: approvalAddressee,
|
|
163
|
+
isolation,
|
|
164
|
+
network_access: networkAccess,
|
|
165
|
+
policy: policy ? policy : undefined,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
}
|
|
77
170
|
// Per-child fixed context overhead: children spawn in `cwd` and load its
|
|
78
171
|
// repo-instructions file into their system prompt, cache-writing it once
|
|
79
172
|
// per child. A fan-out multiplies this, so surface it BEFORE the burn.
|
|
@@ -83,12 +176,14 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
83
176
|
`instructions from ${cwd}; a fan-out multiplies this per agent`);
|
|
84
177
|
}
|
|
85
178
|
// Resume: journaled results of a prior run, keyed by agent-call identity.
|
|
86
|
-
const
|
|
87
|
-
|
|
179
|
+
const resumeSource = opts.resumeRunId ?? opts.resumeFrom;
|
|
180
|
+
const resumeCache = resumeSource
|
|
181
|
+
? loadResumeCache(opts.coordRoot, resumeSource)
|
|
88
182
|
: new Map();
|
|
89
|
-
|
|
183
|
+
const history = opts.resumeRunId ? loadRunHistory(journalPath) : undefined;
|
|
184
|
+
let agentsSpawned = history?.agentsSpawned ?? 0;
|
|
90
185
|
let agentsCached = 0;
|
|
91
|
-
let costUsd = 0;
|
|
186
|
+
let costUsd = history?.costUsd ?? 0;
|
|
92
187
|
let reservedCostUsd = 0;
|
|
93
188
|
let currentStage = "";
|
|
94
189
|
let agentSeq = 0;
|
|
@@ -97,7 +192,7 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
97
192
|
const billingProbed = new Map();
|
|
98
193
|
const agentProofs = new Map();
|
|
99
194
|
const evidenceRecords = [];
|
|
100
|
-
const policyDecisions = [];
|
|
195
|
+
const policyDecisions = new Map(history?.policyDecisions.map((decision) => [decision.id, decision]));
|
|
101
196
|
const acceptanceIds = new Set(meta.acceptance.map((criterion) => criterion.id));
|
|
102
197
|
const journal = (event, data) => {
|
|
103
198
|
const line = JSON.stringify({
|
|
@@ -149,7 +244,7 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
149
244
|
if (!policy) {
|
|
150
245
|
throw new Error("external mutation authorization requires a host policy");
|
|
151
246
|
}
|
|
152
|
-
if (policyDecisions.
|
|
247
|
+
if (policyDecisions.size >= MAX_POLICY_DECISIONS && !policyDecisions.has(`p${policySeq + 1}`)) {
|
|
153
248
|
throw new Error(`workflow policy decision cap reached (${MAX_POLICY_DECISIONS}); split the workflow or reduce protected actions`);
|
|
154
249
|
}
|
|
155
250
|
const request = summarizePolicyRequest(rawRequest);
|
|
@@ -169,10 +264,8 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
169
264
|
let reason = evaluation.reason;
|
|
170
265
|
if (evaluation.verdict === "ask") {
|
|
171
266
|
resolvedBy = "fail_closed";
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
267
|
+
let immediateResolution = false;
|
|
268
|
+
if (opts.resolvePolicyAsk) {
|
|
176
269
|
try {
|
|
177
270
|
const resolution = await withTimeout(Promise.resolve(opts.resolvePolicyAsk(request, evaluation)), opts.policyAskTimeoutMs ?? DEFAULT_POLICY_ASK_TIMEOUT_MS);
|
|
178
271
|
if (!resolution || (resolution.verdict !== "allow" && resolution.verdict !== "deny")) {
|
|
@@ -182,12 +275,54 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
182
275
|
verdict = resolution.verdict;
|
|
183
276
|
resolvedBy = "host";
|
|
184
277
|
reason = boundedPolicyReason(resolution.reason ?? evaluation.reason);
|
|
278
|
+
immediateResolution = true;
|
|
185
279
|
}
|
|
186
280
|
}
|
|
187
281
|
catch (error) {
|
|
188
282
|
reason = `${evaluation.reason}; approval failed closed: ${error.message}`;
|
|
189
283
|
}
|
|
190
284
|
}
|
|
285
|
+
else {
|
|
286
|
+
reason = `${evaluation.reason}; no host approval resolver is configured`;
|
|
287
|
+
}
|
|
288
|
+
if (!immediateResolution && approvalMode === "park") {
|
|
289
|
+
const stored = createWorkflowApproval({
|
|
290
|
+
coordRoot: opts.coordRoot,
|
|
291
|
+
runId,
|
|
292
|
+
decisionId: id,
|
|
293
|
+
addressedTo: approvalAddressee,
|
|
294
|
+
policy: { name: policy.name, sha256: policyDigest(policy) },
|
|
295
|
+
request,
|
|
296
|
+
evaluation,
|
|
297
|
+
});
|
|
298
|
+
if (stored.approval.status === "pending") {
|
|
299
|
+
if (stored.created) {
|
|
300
|
+
journal("approval.requested", {
|
|
301
|
+
approval_id: stored.approval.request.id,
|
|
302
|
+
decision_id: id,
|
|
303
|
+
addressed_to: stored.approval.request.addressed_to,
|
|
304
|
+
request_sha256: stored.approval.request.request_sha256,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
journal("run.parked", {
|
|
308
|
+
approval_id: stored.approval.request.id,
|
|
309
|
+
decision_id: id,
|
|
310
|
+
phase: request.phase,
|
|
311
|
+
action: request.action,
|
|
312
|
+
});
|
|
313
|
+
throw new WorkflowParkedError(`workflow parked for approval ${stored.approval.request.id}: ${evaluation.reason}`, runId, stored.approval.request.id, journalPath);
|
|
314
|
+
}
|
|
315
|
+
verdict = stored.approval.decision.verdict;
|
|
316
|
+
resolvedBy = "approval";
|
|
317
|
+
reason = boundedPolicyReason(stored.approval.decision.reason ?? evaluation.reason);
|
|
318
|
+
journal("approval.consumed", {
|
|
319
|
+
approval_id: stored.approval.request.id,
|
|
320
|
+
decision_id: id,
|
|
321
|
+
verdict,
|
|
322
|
+
actor: stored.approval.decision.actor,
|
|
323
|
+
decided_at: stored.approval.decision.decided_at,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
191
326
|
}
|
|
192
327
|
const decision = {
|
|
193
328
|
id,
|
|
@@ -201,7 +336,7 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
201
336
|
rule_codes: evaluation.rules.map((rule) => rule.code),
|
|
202
337
|
request,
|
|
203
338
|
};
|
|
204
|
-
policyDecisions.
|
|
339
|
+
policyDecisions.set(decision.id, decision);
|
|
205
340
|
journal("policy.resolve", { ...decision });
|
|
206
341
|
if (decision.verdict === "deny") {
|
|
207
342
|
throw new PolicyDeniedError(`policy ${JSON.stringify(policy.name)} denied ${request.phase} ${JSON.stringify(request.action)}: ${decision.reason}`, decision.id);
|
|
@@ -236,6 +371,11 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
236
371
|
const key = agentCallKey(currentStage, harness, agentOpts, prompt);
|
|
237
372
|
const cached = resumeCache.get(key);
|
|
238
373
|
if (cached) {
|
|
374
|
+
// Exact-run replay skips dispatch authorization because no dispatch
|
|
375
|
+
// occurs, but it must still reserve the original policy slot so a later
|
|
376
|
+
// durable ASK resolves against the same pN identity.
|
|
377
|
+
if (policy && opts.resumeRunId)
|
|
378
|
+
policySeq++;
|
|
239
379
|
agentsCached++;
|
|
240
380
|
agentProof.status = "cached";
|
|
241
381
|
agentProof.result = digestResult(cached.value, cached.kind);
|
|
@@ -247,7 +387,7 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
247
387
|
model: agentOpts.model ?? null,
|
|
248
388
|
kind: cached.kind,
|
|
249
389
|
});
|
|
250
|
-
log(`[${name}] ${currentStage || "(no stage)"} → ${id} ${label} (cached from ${
|
|
390
|
+
log(`[${name}] ${currentStage || "(no stage)"} → ${id} ${label} (cached from ${resumeSource})`);
|
|
251
391
|
return cached.value;
|
|
252
392
|
}
|
|
253
393
|
if (policy) {
|
|
@@ -327,19 +467,19 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
327
467
|
billingProbed.set(harness, probe);
|
|
328
468
|
journal("billing.probe", {
|
|
329
469
|
harness,
|
|
330
|
-
mode:
|
|
470
|
+
mode: subscriptionOnly ? "subscription" : probe.mode,
|
|
331
471
|
api_key_source: probe.apiKeySource,
|
|
332
472
|
login: probe.login,
|
|
333
|
-
subscription_only:
|
|
473
|
+
subscription_only: subscriptionOnly,
|
|
334
474
|
});
|
|
335
|
-
if (
|
|
475
|
+
if (subscriptionOnly) {
|
|
336
476
|
if (probe.login === "absent") {
|
|
337
477
|
throw new Error(`subscription-only: no stored login detected for ${harness}; ` +
|
|
338
478
|
`log the harness CLI in (or drop --subscription-only for a key-only host)`);
|
|
339
479
|
}
|
|
340
480
|
log(`[billing] ${harness}: subscription-only (API-key vars scrubbed from child env)`);
|
|
341
481
|
}
|
|
342
|
-
else if (probe.mode === "api-key-override" && !
|
|
482
|
+
else if (probe.mode === "api-key-override" && !allowApiBilling) {
|
|
343
483
|
throw new Error(`${probe.apiKeySource} is set AND a stored ${harness} login exists — the key silently ` +
|
|
344
484
|
`overrides your subscription auth, so children would bill per-token API rates. ` +
|
|
345
485
|
`Either unset ${probe.apiKeySource}, run with --subscription-only to scrub it from ` +
|
|
@@ -392,7 +532,7 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
392
532
|
maxTurns: agentOpts.maxTurns ?? DEFAULT_MAX_TURNS,
|
|
393
533
|
cwd,
|
|
394
534
|
runId,
|
|
395
|
-
subscriptionOnly
|
|
535
|
+
subscriptionOnly,
|
|
396
536
|
});
|
|
397
537
|
agentProof.attempts = attempt;
|
|
398
538
|
agentProof.duration_ms += last.durationMs;
|
|
@@ -413,6 +553,7 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
413
553
|
key,
|
|
414
554
|
attempts: attempt,
|
|
415
555
|
cost_usd: last.costUsd,
|
|
556
|
+
total_cost_usd: agentCostUsd,
|
|
416
557
|
duration_ms: last.durationMs,
|
|
417
558
|
session_id: last.sessionId,
|
|
418
559
|
result_kind: "text",
|
|
@@ -435,6 +576,7 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
435
576
|
key,
|
|
436
577
|
attempts: attempt,
|
|
437
578
|
cost_usd: last.costUsd,
|
|
579
|
+
total_cost_usd: agentCostUsd,
|
|
438
580
|
duration_ms: last.durationMs,
|
|
439
581
|
session_id: last.sessionId,
|
|
440
582
|
result_kind: "json",
|
|
@@ -511,20 +653,28 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
511
653
|
});
|
|
512
654
|
};
|
|
513
655
|
const ctx = { agent, parallel, stage, log, evidence, authorize };
|
|
514
|
-
const t0 = Date.now();
|
|
515
|
-
const startedAt = new Date(t0).toISOString();
|
|
516
|
-
journal("run.start", {
|
|
517
|
-
name,
|
|
518
|
-
script: absScript,
|
|
519
|
-
objective: meta.objective ?? null,
|
|
520
|
-
acceptance: meta.acceptance,
|
|
521
|
-
max_agents: maxAgents,
|
|
522
|
-
concurrency,
|
|
523
|
-
policy: policy ? { name: policy.name, sha256: policyDigest(policy) } : null,
|
|
524
|
-
isolation,
|
|
525
|
-
network_access: networkAccess,
|
|
526
|
-
});
|
|
527
656
|
try {
|
|
657
|
+
if (resumeState) {
|
|
658
|
+
journal("run.resume", {
|
|
659
|
+
approval_id: resumeState.approvalId,
|
|
660
|
+
script: absScript,
|
|
661
|
+
resumed_at: new Date().toISOString(),
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
else {
|
|
665
|
+
journal("run.start", {
|
|
666
|
+
name,
|
|
667
|
+
work_item_id: opts.workItemId ?? null,
|
|
668
|
+
script: absScript,
|
|
669
|
+
objective: meta.objective ?? null,
|
|
670
|
+
acceptance: meta.acceptance,
|
|
671
|
+
max_agents: maxAgents,
|
|
672
|
+
concurrency,
|
|
673
|
+
policy: policy ? { name: policy.name, sha256: policyDigest(policy) } : null,
|
|
674
|
+
isolation,
|
|
675
|
+
network_access: networkAccess,
|
|
676
|
+
});
|
|
677
|
+
}
|
|
528
678
|
const result = await mod.default(ctx);
|
|
529
679
|
const endedAt = new Date().toISOString();
|
|
530
680
|
const durationMs = Date.now() - t0;
|
|
@@ -539,6 +689,7 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
539
689
|
try {
|
|
540
690
|
proof = buildWorkflowProof({
|
|
541
691
|
runId,
|
|
692
|
+
workItemId: opts.workItemId ?? resumeState?.manifest.work_item_id,
|
|
542
693
|
meta,
|
|
543
694
|
status: "succeeded",
|
|
544
695
|
startedAt,
|
|
@@ -551,7 +702,12 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
551
702
|
evidence: evidenceRecords,
|
|
552
703
|
harnessEvidence: opts.harnessEvidence,
|
|
553
704
|
policy: policy
|
|
554
|
-
? {
|
|
705
|
+
? {
|
|
706
|
+
config: policy,
|
|
707
|
+
decisions: Array.from(policyDecisions.values()),
|
|
708
|
+
isolation,
|
|
709
|
+
networkAccess,
|
|
710
|
+
}
|
|
555
711
|
: undefined,
|
|
556
712
|
result,
|
|
557
713
|
});
|
|
@@ -562,6 +718,7 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
562
718
|
}
|
|
563
719
|
const report = {
|
|
564
720
|
runId,
|
|
721
|
+
workItemId: opts.workItemId ?? resumeState?.manifest.work_item_id,
|
|
565
722
|
name,
|
|
566
723
|
result,
|
|
567
724
|
agentsSpawned,
|
|
@@ -574,14 +731,14 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
574
731
|
contextTokensPerChildEstimate,
|
|
575
732
|
billing: Array.from(billingProbed.values()).map((p) => ({
|
|
576
733
|
harness: p.harness,
|
|
577
|
-
mode:
|
|
734
|
+
mode: subscriptionOnly ? "subscription" : p.mode,
|
|
578
735
|
})),
|
|
579
736
|
policy: proof.policy?.summary,
|
|
580
737
|
};
|
|
581
738
|
return report;
|
|
582
739
|
}
|
|
583
740
|
catch (err) {
|
|
584
|
-
if (err instanceof WorkflowRunError)
|
|
741
|
+
if (err instanceof WorkflowParkedError || err instanceof WorkflowRunError)
|
|
585
742
|
throw err;
|
|
586
743
|
const endedAt = new Date().toISOString();
|
|
587
744
|
const durationMs = Date.now() - t0;
|
|
@@ -596,6 +753,7 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
596
753
|
try {
|
|
597
754
|
const proof = buildWorkflowProof({
|
|
598
755
|
runId,
|
|
756
|
+
workItemId: opts.workItemId ?? resumeState?.manifest.work_item_id,
|
|
599
757
|
meta,
|
|
600
758
|
status: "failed",
|
|
601
759
|
startedAt,
|
|
@@ -608,7 +766,12 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
608
766
|
evidence: evidenceRecords,
|
|
609
767
|
harnessEvidence: opts.harnessEvidence,
|
|
610
768
|
policy: policy
|
|
611
|
-
? {
|
|
769
|
+
? {
|
|
770
|
+
config: policy,
|
|
771
|
+
decisions: Array.from(policyDecisions.values()),
|
|
772
|
+
isolation,
|
|
773
|
+
networkAccess,
|
|
774
|
+
}
|
|
612
775
|
: undefined,
|
|
613
776
|
error: err.message,
|
|
614
777
|
});
|
|
@@ -676,6 +839,38 @@ function loadResumeCache(coordRoot, resumeFrom) {
|
|
|
676
839
|
}
|
|
677
840
|
return cache;
|
|
678
841
|
}
|
|
842
|
+
function loadRunHistory(path) {
|
|
843
|
+
const agentIds = new Set();
|
|
844
|
+
const agentCosts = new Map();
|
|
845
|
+
const decisions = new Map();
|
|
846
|
+
for (const line of readFileSync(path, "utf8").split("\n")) {
|
|
847
|
+
if (!line.trim())
|
|
848
|
+
continue;
|
|
849
|
+
const event = JSON.parse(line);
|
|
850
|
+
if (event.event === "agent.start" && typeof event.id === "string") {
|
|
851
|
+
agentIds.add(event.id);
|
|
852
|
+
}
|
|
853
|
+
if (event.event === "agent.end" && typeof event.id === "string") {
|
|
854
|
+
const cost = event.total_cost_usd ?? event.cost_usd;
|
|
855
|
+
if (typeof cost === "number" && Number.isFinite(cost) && cost >= 0) {
|
|
856
|
+
agentCosts.set(event.id, cost);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
if (event.event === "policy.resolve" &&
|
|
860
|
+
typeof event.id === "string" &&
|
|
861
|
+
(event.verdict === "allow" || event.verdict === "deny") &&
|
|
862
|
+
typeof event.resolved_by === "string" &&
|
|
863
|
+
event.request &&
|
|
864
|
+
typeof event.request === "object") {
|
|
865
|
+
decisions.set(event.id, event);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
return {
|
|
869
|
+
agentsSpawned: agentIds.size,
|
|
870
|
+
costUsd: round4(Array.from(agentCosts.values()).reduce((sum, value) => sum + value, 0)),
|
|
871
|
+
policyDecisions: Array.from(decisions.values()),
|
|
872
|
+
};
|
|
873
|
+
}
|
|
679
874
|
function round4(n) {
|
|
680
875
|
return Math.round(n * 10_000) / 10_000;
|
|
681
876
|
}
|
|
@@ -684,6 +879,11 @@ function assertAgentCapacity(agentsSpawned, maxAgents) {
|
|
|
684
879
|
throw new Error(`workflow agent cap reached (${maxAgents}); raise --max-agents deliberately if the fan-out is intended`);
|
|
685
880
|
}
|
|
686
881
|
}
|
|
882
|
+
function assertPositiveWorkflowBound(value, field) {
|
|
883
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
884
|
+
throw new Error(`${field} must be a positive safe integer`);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
687
887
|
function boundedPolicyReason(value) {
|
|
688
888
|
const normalized = Array.from(value, (character) => {
|
|
689
889
|
const code = character.charCodeAt(0);
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export type { CreateWorkflowApprovalInput, ResolveWorkflowApprovalInput, WorkflowApproval, WorkflowApprovalDecision, WorkflowApprovalRequest, WorkflowApprovalStatus, } from "./approvals.js";
|
|
2
|
+
export { assertWorkflowRunId, createWorkflowApproval, listWorkflowApprovals, readWorkflowApproval, renderWorkflowApproval, resolveWorkflowApproval, WORKFLOW_APPROVAL_SCHEMA_VERSION, workflowApprovalId, } from "./approvals.js";
|
|
3
|
+
export { runWorkflow, WorkflowParkedError, WorkflowRunError } from "./engine.js";
|
|
2
4
|
export { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, readWorkflowProof, renderWorkflowProof, rollupAcceptance, writeWorkflowProof, } from "./proof.js";
|
|
3
|
-
export type {
|
|
5
|
+
export type { WorkflowRunManifest } from "./run-state.js";
|
|
6
|
+
export { acquireWorkflowResumeLease, assertWorkflowRunResumable, assertWorkflowScriptUnchanged, readWorkflowRunManifest, WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION, workflowRunManifestPath, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
|
|
7
|
+
export type { AcceptanceCriterion, AcceptanceResult, AcceptanceStatus, AcceptanceSummary, AgentOpts, EngineOpts, EvidenceKind, EvidenceSource, EvidenceStatus, HarnessEvidenceCapability, HarnessEvidenceCoverage, HarnessName, ResultDigest, RunReport, Spawner, SpawnRequest, SpawnResult, StageSchema, WorkflowAgentProof, WorkflowApprovalMode, WorkflowContext, WorkflowEvidenceInput, WorkflowEvidenceRecord, WorkflowMeta, WorkflowModule, WorkflowPolicyProof, WorkflowProof, WorkflowProofUnknown, WorkflowRepoEvidence, WorkflowRepoSnapshot, WorkflowRunStatus, } from "./types.js";
|
|
4
8
|
export { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.js";
|
|
5
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,EAChC,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,uBAAuB,EACvB,oCAAoC,EACpC,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,YAAY,EACZ,cAAc,EACd,cAAc,EACd,yBAAyB,EACzB,uBAAuB,EACvB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,OAAO,EACP,YAAY,EACZ,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { assertWorkflowRunId, createWorkflowApproval, listWorkflowApprovals, readWorkflowApproval, renderWorkflowApproval, resolveWorkflowApproval, WORKFLOW_APPROVAL_SCHEMA_VERSION, workflowApprovalId, } from "./approvals.js";
|
|
2
|
+
export { runWorkflow, WorkflowParkedError, WorkflowRunError } from "./engine.js";
|
|
2
3
|
export { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, readWorkflowProof, renderWorkflowProof, rollupAcceptance, writeWorkflowProof, } from "./proof.js";
|
|
4
|
+
export { acquireWorkflowResumeLease, assertWorkflowRunResumable, assertWorkflowScriptUnchanged, readWorkflowRunManifest, WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION, workflowRunManifestPath, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
|
|
3
5
|
export { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/proof.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EAEzB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EAEZ,aAAa,EAId,MAAM,YAAY,CAAC;AAepB,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC,CAAC,CAAC;IAClF,MAAM,CAAC,EAAE;QACP,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QACnC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;QACrC,SAAS,EAAE,eAAe,CAAC;QAC3B,aAAa,EAAE,mBAAmB,CAAC;KACpC,CAAC;IACF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,YAAY,EAAE,MAAM,GACnB,sBAAsB,CAqCxB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,KAAK,EAAE,qBAAqB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,sBAAsB,CA6BzB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,QAAQ,EAAE,sBAAsB,EAAE,GACjC;IAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAuB9D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,YAAY,CAQjF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/proof.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EAEzB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EAEZ,aAAa,EAId,MAAM,YAAY,CAAC;AAepB,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,mBAAmB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,GAAG,SAAS,CAAC,CAAC,CAAC;IAClF,MAAM,CAAC,EAAE;QACP,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QACnC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;QACrC,SAAS,EAAE,eAAe,CAAC;QAC3B,aAAa,EAAE,mBAAmB,CAAC;KACpC,CAAC;IACF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,YAAY,EAAE,MAAM,GACnB,sBAAsB,CAqCxB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,KAAK,EAAE,qBAAqB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,sBAAsB,CA6BzB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,QAAQ,EAAE,sBAAsB,EAAE,GACjC;IAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAAC,OAAO,EAAE,iBAAiB,CAAA;CAAE,CAuB9D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,YAAY,CAQjF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,aAAa,CA0ChF;AAgCD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAe3E;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAkBjF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAoChE"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { RepoSnapshot } from "../context/index.js";
|
|
2
|
+
import { type NormalizedPolicy, type PolicyIsolation, type PolicyNetworkAccess } from "../policy/index.js";
|
|
3
|
+
export declare const WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION: 1;
|
|
4
|
+
export interface WorkflowRunManifest {
|
|
5
|
+
schema_version: typeof WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION;
|
|
6
|
+
run_id: string;
|
|
7
|
+
work_item_id?: string;
|
|
8
|
+
name: string;
|
|
9
|
+
started_at: string;
|
|
10
|
+
script: {
|
|
11
|
+
path: string;
|
|
12
|
+
sha256: string;
|
|
13
|
+
};
|
|
14
|
+
repository_before: RepoSnapshot;
|
|
15
|
+
execution: {
|
|
16
|
+
cwd: string;
|
|
17
|
+
default_harness: string;
|
|
18
|
+
max_agents: number;
|
|
19
|
+
concurrency: number;
|
|
20
|
+
subscription_only: boolean;
|
|
21
|
+
allow_api_billing: boolean;
|
|
22
|
+
approval_mode: "deny" | "park";
|
|
23
|
+
approval_addressee: string;
|
|
24
|
+
isolation: PolicyIsolation;
|
|
25
|
+
network_access: PolicyNetworkAccess;
|
|
26
|
+
policy?: NormalizedPolicy;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface WriteWorkflowRunManifestInput {
|
|
30
|
+
coordRoot: string;
|
|
31
|
+
manifest: WorkflowRunManifest;
|
|
32
|
+
}
|
|
33
|
+
export declare function workflowScriptDigest(scriptPath: string): string;
|
|
34
|
+
export declare function writeWorkflowRunManifest(input: WriteWorkflowRunManifestInput): string;
|
|
35
|
+
export declare function readWorkflowRunManifest(coordRoot: string, runId: string): WorkflowRunManifest;
|
|
36
|
+
export declare function assertWorkflowRunResumable(coordRoot: string, runId: string): {
|
|
37
|
+
manifest: WorkflowRunManifest;
|
|
38
|
+
approvalId: string;
|
|
39
|
+
};
|
|
40
|
+
export declare function assertWorkflowScriptUnchanged(manifest: WorkflowRunManifest): void;
|
|
41
|
+
export declare function workflowRunManifestPath(coordRoot: string, runId: string): string;
|
|
42
|
+
/** Acquire an exclusive, crash-recoverable lease for one resume segment. */
|
|
43
|
+
export declare function acquireWorkflowResumeLease(coordRoot: string, runId: string): () => void;
|
|
44
|
+
//# sourceMappingURL=run-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-state.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/run-state.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAEzB,MAAM,oBAAoB,CAAC;AAG5B,eAAO,MAAM,oCAAoC,EAAG,CAAU,CAAC;AAK/D,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,OAAO,oCAAoC,CAAC;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,iBAAiB,EAAE,YAAY,CAAC;IAChC,SAAS,EAAE;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,iBAAiB,EAAE,OAAO,CAAC;QAC3B,iBAAiB,EAAE,OAAO,CAAC;QAC3B,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC;QAC/B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,SAAS,EAAE,eAAe,CAAC;QAC3B,cAAc,EAAE,mBAAmB,CAAC;QACpC,MAAM,CAAC,EAAE,gBAAgB,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B,GAAG,MAAM,CAmBrF;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,CAgC7F;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ;IAAE,QAAQ,EAAE,mBAAmB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CA4BvD;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CASjF;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhF;AAED,4EAA4E;AAC5E,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,IAAI,CA0CvF"}
|