harnery 0.10.0 → 0.11.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.
@@ -1 +1 @@
1
- {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA0BnD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA+FjF"}
1
+ {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA8BnD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA+IjF"}
@@ -9,7 +9,7 @@ export function registerWorkflowCommand(program, emit) {
9
9
  .description("Run bounded, schema-gated multi-subagent workflow scripts.");
10
10
  workflow
11
11
  .command("run <script>")
12
- .description("Execute a workflow script (plain JS: `export default async ({agent, parallel, stage, log}) => …`). " +
12
+ .description("Execute a workflow script (plain JS: `export default async ({agent, parallel, stage, log, evidence}) => …`). " +
13
13
  "Subagents spawn as headless harness-CLI subprocesses, coordination-registered.")
14
14
  .option("--max-agents <n>", "Total-agent ceiling for the run (default 50)")
15
15
  .option("--concurrency <n>", "Concurrent-subagent cap (default 4)")
@@ -59,6 +59,12 @@ export function registerWorkflowCommand(program, emit) {
59
59
  maxAgents: opts.maxAgents ? Number.parseInt(opts.maxAgents, 10) : undefined,
60
60
  concurrency: opts.concurrency ? Number.parseInt(opts.concurrency, 10) : undefined,
61
61
  cwd: opts.cwd,
62
+ harnessEvidence: Object.fromEntries(registry
63
+ .list()
64
+ .map((adapter) => [
65
+ adapter.profile.id,
66
+ { toolEvidence: adapter.profile.capabilities.toolEvidence },
67
+ ])),
62
68
  });
63
69
  if (opts.json) {
64
70
  emit.config({ format: "json" });
@@ -71,11 +77,48 @@ export function registerWorkflowCommand(program, emit) {
71
77
  : "";
72
78
  emit.text(`run ${report.runId} (${report.name}) finished: ${report.agentsSpawned} agent(s)${cachedPart}, ` +
73
79
  `$${report.costUsd.toFixed(4)}, ${Math.round(report.durationMs / 1000)}s\n${billingPart}` +
80
+ `acceptance: ${report.acceptance.satisfied} satisfied, ${report.acceptance.unsatisfied} unsatisfied, ` +
81
+ `${report.acceptance.unknown} unknown\n` +
74
82
  `journal: ${report.journalPath}\n` +
83
+ `proof: ${report.proofPath}\n` +
75
84
  `result: ${typeof report.result === "string" ? report.result : JSON.stringify(report.result, null, 2)}\n`);
76
85
  }
77
86
  catch (err) {
78
- emit.error({ code: "workflow_failed", message: err.message });
87
+ const proofPath = typeof err === "object" && err !== null && "proofPath" in err
88
+ ? String(err.proofPath)
89
+ : undefined;
90
+ emit.error({
91
+ code: "workflow_failed",
92
+ message: `${err.message}${proofPath ? `\nproof: ${proofPath}` : ""}`,
93
+ });
94
+ process.exit(1);
95
+ }
96
+ });
97
+ workflow
98
+ .command("proof <run-id>")
99
+ .description("Show the bounded proof packet for a completed workflow run.")
100
+ .option("--json", "Emit the stored proof packet as JSON")
101
+ .action(async (runId, opts) => {
102
+ const coordRoot = findCoordRoot();
103
+ if (!coordRoot) {
104
+ emit.error({
105
+ code: "no_coord_root",
106
+ message: "no .harnery/ coordination root found; run `init` first",
107
+ });
108
+ process.exit(1);
109
+ }
110
+ try {
111
+ const { readWorkflowProof, renderWorkflowProof } = await import("../core/workflow/proof.js");
112
+ const proof = readWorkflowProof(coordRoot, runId);
113
+ if (opts.json) {
114
+ emit.config({ format: "json" });
115
+ emit.data(proof);
116
+ return;
117
+ }
118
+ emit.text(renderWorkflowProof(proof));
119
+ }
120
+ catch (err) {
121
+ emit.error({ code: "workflow_proof_failed", message: err.message });
79
122
  process.exit(1);
80
123
  }
81
124
  });
@@ -17,5 +17,10 @@
17
17
  * cost, duration, and child session id (the resume + web-UI substrate).
18
18
  */
19
19
  import type { EngineOpts, RunReport } from "./types.js";
20
+ export declare class WorkflowRunError extends Error {
21
+ readonly runId: string;
22
+ readonly proofPath: string;
23
+ constructor(message: string, runId: string, proofPath: string, cause?: unknown);
24
+ }
20
25
  export declare function runWorkflow(scriptPath: string, opts: EngineOpts): Promise<RunReport>;
21
26
  //# sourceMappingURL=engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,KAAK,EAEV,UAAU,EAEV,SAAS,EAIV,MAAM,YAAY,CAAC;AASpB,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAgS1F"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAeH,OAAO,KAAK,EAEV,UAAU,EAEV,SAAS,EAOV,MAAM,YAAY,CAAC;AAUpB,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAM/E;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAqa1F"}
@@ -28,29 +28,46 @@ import { createHash, randomBytes } from "node:crypto";
28
28
  import { appendFileSync, existsSync, mkdirSync, readFileSync, statSync } from "node:fs";
29
29
  import { isAbsolute, join, resolve } from "node:path";
30
30
  import { pathToFileURL } from "node:url";
31
+ import { snapshotRepo } from "../context/index.js";
31
32
  import { probeBilling } from "./billing.js";
33
+ import { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, writeWorkflowProof, } from "./proof.js";
34
+ import { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.js";
32
35
  import { parseStageOutput, validateAgainstSchema } from "./validate.js";
33
36
  const DEFAULT_MAX_AGENTS = 50;
34
37
  const DEFAULT_CONCURRENCY = 4;
35
38
  const DEFAULT_MAX_ATTEMPTS = 2;
36
39
  const DEFAULT_TIMEOUT_MS = 300_000;
37
40
  const DEFAULT_MAX_TURNS = 25;
41
+ export class WorkflowRunError extends Error {
42
+ runId;
43
+ proofPath;
44
+ constructor(message, runId, proofPath, cause) {
45
+ super(message, cause === undefined ? undefined : { cause });
46
+ this.name = "WorkflowRunError";
47
+ this.runId = runId;
48
+ this.proofPath = proofPath;
49
+ }
50
+ }
38
51
  export async function runWorkflow(scriptPath, opts) {
39
52
  const absScript = isAbsolute(scriptPath) ? scriptPath : resolve(process.cwd(), scriptPath);
40
53
  const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(absScript).href)));
41
54
  if (typeof mod.default !== "function") {
42
55
  throw new Error(`${scriptPath}: workflow script must \`export default async (ctx) => …\``);
43
56
  }
44
- const name = mod.meta?.name ?? scriptPath.replace(/^.*\//, "").replace(/\.[cm]?js$/, "");
57
+ const fallbackName = scriptPath.replace(/^.*\//, "").replace(/\.[cm]?js$/, "");
58
+ const meta = normalizeWorkflowMeta(mod.meta, fallbackName);
59
+ const name = meta.name;
45
60
  const runId = `wf-${new Date().toISOString().replace(/[:.]/g, "-")}-${randomBytes(3).toString("hex")}`;
46
61
  const runDir = join(opts.coordRoot, ".harnery", "workflows", runId);
47
62
  mkdirSync(runDir, { recursive: true });
48
63
  const journalPath = join(runDir, "journal.jsonl");
64
+ const proofPath = join(runDir, "proof.json");
49
65
  const maxAgents = opts.maxAgents ?? DEFAULT_MAX_AGENTS;
50
66
  const concurrency = opts.concurrency ?? DEFAULT_CONCURRENCY;
51
67
  const cwd = opts.cwd ?? opts.coordRoot;
52
68
  const log = opts.onLog ?? ((line) => process.stderr.write(`${line}\n`));
53
69
  const defaultHarness = opts.defaultHarness ?? "claude-code";
70
+ const repoBefore = snapshotRepo(cwd);
54
71
  // Per-child fixed context overhead: children spawn in `cwd` and load its
55
72
  // repo-instructions file into their system prompt, cache-writing it once
56
73
  // per child. A fan-out multiplies this, so surface it BEFORE the burn.
@@ -68,9 +85,15 @@ export async function runWorkflow(scriptPath, opts) {
68
85
  let costUsd = 0;
69
86
  let currentStage = "";
70
87
  let agentSeq = 0;
88
+ let evidenceSeq = 0;
71
89
  const billingProbed = new Map();
90
+ const agentProofs = new Map();
91
+ const evidenceRecords = [];
92
+ const acceptanceIds = new Set(meta.acceptance.map((criterion) => criterion.id));
72
93
  const journal = (event, data) => {
73
94
  const line = JSON.stringify({
95
+ schema_version: WORKFLOW_PROOF_SCHEMA_VERSION,
96
+ run_id: runId,
74
97
  ts: new Date().toISOString(),
75
98
  event,
76
99
  stage: currentStage,
@@ -103,14 +126,35 @@ export async function runWorkflow(scriptPath, opts) {
103
126
  }
104
127
  const id = `a${++agentSeq}`;
105
128
  const label = agentOpts.label ?? `${prompt.slice(0, 60).replace(/\s+/g, " ")}…`;
129
+ const proofLabel = agentOpts.label ?? id;
106
130
  const maxAttempts = agentOpts.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
131
+ const agentProof = {
132
+ id,
133
+ label: proofLabel,
134
+ stage: currentStage || undefined,
135
+ harness,
136
+ model: agentOpts.model,
137
+ status: "failed",
138
+ attempts: 0,
139
+ duration_ms: 0,
140
+ };
141
+ agentProofs.set(id, agentProof);
107
142
  // Call identity for resume: same stage + harness + model + effort + turns + schema
108
143
  // + ORIGINAL prompt → same key. Retry-mutated prompts never enter the key.
109
144
  const key = agentCallKey(currentStage, harness, agentOpts, prompt);
110
145
  const cached = resumeCache.get(key);
111
146
  if (cached) {
112
147
  agentsCached++;
113
- journal("agent.cached", { id, label, key, kind: cached.kind });
148
+ agentProof.status = "cached";
149
+ agentProof.result = digestResult(cached.value, cached.kind);
150
+ journal("agent.cached", {
151
+ id,
152
+ label,
153
+ key,
154
+ harness,
155
+ model: agentOpts.model ?? null,
156
+ kind: cached.kind,
157
+ });
114
158
  log(`[${name}] ${currentStage || "(no stage)"} → ${id} ${label} (cached from ${opts.resumeFrom})`);
115
159
  return cached.value;
116
160
  }
@@ -154,6 +198,7 @@ export async function runWorkflow(scriptPath, opts) {
154
198
  }
155
199
  }
156
200
  if (agentsSpawned >= maxAgents) {
201
+ agentProof.error = `workflow agent cap reached (${maxAgents})`;
157
202
  throw new Error(`workflow agent cap reached (${maxAgents}); raise --max-agents deliberately if the fan-out is intended`);
158
203
  }
159
204
  agentsSpawned++;
@@ -170,6 +215,7 @@ export async function runWorkflow(scriptPath, opts) {
170
215
  log(`[${name}] ${currentStage || "(no stage)"} → ${id} [${harness}] ${label}`);
171
216
  let attemptPrompt = prompt;
172
217
  let last = null;
218
+ let agentCostUsd = 0;
173
219
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
174
220
  last = await spawner({
175
221
  prompt: attemptPrompt,
@@ -181,12 +227,20 @@ export async function runWorkflow(scriptPath, opts) {
181
227
  runId,
182
228
  subscriptionOnly: opts.subscriptionOnly,
183
229
  });
230
+ agentProof.attempts = attempt;
231
+ agentProof.duration_ms += last.durationMs;
232
+ agentCostUsd += last.costUsd ?? 0;
184
233
  costUsd += last.costUsd ?? 0;
185
234
  if (!last.ok) {
186
235
  journal("agent.attempt_failed", { id, attempt, error: last.error });
187
236
  continue; // spawn-level failure: retry with the original prompt
188
237
  }
189
238
  if (!agentOpts.schema) {
239
+ agentProof.status = "succeeded";
240
+ agentProof.cost_usd =
241
+ agentCostUsd > 0 || last.costUsd !== undefined ? agentCostUsd : undefined;
242
+ agentProof.session_id = last.sessionId;
243
+ agentProof.result = digestResult(last.text, "text");
190
244
  journal("agent.end", {
191
245
  id,
192
246
  key,
@@ -204,6 +258,11 @@ export async function runWorkflow(scriptPath, opts) {
204
258
  ? [parsed.error]
205
259
  : validateAgainstSchema(parsed.value, agentOpts.schema);
206
260
  if (problems.length === 0) {
261
+ agentProof.status = "succeeded";
262
+ agentProof.cost_usd =
263
+ agentCostUsd > 0 || last.costUsd !== undefined ? agentCostUsd : undefined;
264
+ agentProof.session_id = last.sessionId;
265
+ agentProof.result = digestResult(parsed.value, "json");
207
266
  journal("agent.end", {
208
267
  id,
209
268
  key,
@@ -227,8 +286,16 @@ export async function runWorkflow(scriptPath, opts) {
227
286
  const reason = last?.ok
228
287
  ? `schema validation failed after ${maxAttempts} attempt(s)`
229
288
  : (last?.error ?? "spawn failed");
289
+ agentProof.cost_usd =
290
+ agentCostUsd > 0 || last?.costUsd !== undefined ? agentCostUsd : undefined;
291
+ agentProof.session_id = last?.sessionId;
292
+ agentProof.error = reason;
230
293
  journal("agent.failed", { id, error: reason });
231
- throw new Error(`agent ${id} (${label}): ${reason}`);
294
+ throw new Error(`agent ${proofLabel}: ${reason}`);
295
+ }
296
+ catch (error) {
297
+ agentProof.error ??= error.message;
298
+ throw error;
232
299
  }
233
300
  finally {
234
301
  release();
@@ -248,11 +315,62 @@ export async function runWorkflow(scriptPath, opts) {
248
315
  journal("stage.start", { title });
249
316
  log(`[${name}] ── stage: ${title}`);
250
317
  };
251
- const ctx = { agent, parallel, stage, log };
318
+ const evidence = (input) => {
319
+ const record = createEvidenceRecord({
320
+ value: input,
321
+ sequence: evidenceSeq + 1,
322
+ acceptanceIds,
323
+ stage: currentStage || undefined,
324
+ });
325
+ evidenceSeq++;
326
+ evidenceRecords.push(record);
327
+ journal("evidence.recorded", { ...record });
328
+ return record.id;
329
+ };
330
+ const ctx = { agent, parallel, stage, log, evidence };
252
331
  const t0 = Date.now();
253
- journal("run.start", { name, script: absScript, max_agents: maxAgents, concurrency });
332
+ const startedAt = new Date(t0).toISOString();
333
+ journal("run.start", {
334
+ name,
335
+ script: absScript,
336
+ objective: meta.objective ?? null,
337
+ acceptance: meta.acceptance,
338
+ max_agents: maxAgents,
339
+ concurrency,
340
+ });
254
341
  try {
255
342
  const result = await mod.default(ctx);
343
+ const endedAt = new Date().toISOString();
344
+ const durationMs = Date.now() - t0;
345
+ journal("run.end", {
346
+ ok: true,
347
+ agents: agentsSpawned,
348
+ cached: agentsCached,
349
+ cost_usd: round4(costUsd),
350
+ duration_ms: durationMs,
351
+ });
352
+ let proof;
353
+ try {
354
+ proof = buildWorkflowProof({
355
+ runId,
356
+ meta,
357
+ status: "succeeded",
358
+ startedAt,
359
+ endedAt,
360
+ durationMs,
361
+ journalPath,
362
+ before: repoBefore,
363
+ after: snapshotRepo(cwd),
364
+ agents: Array.from(agentProofs.values()),
365
+ evidence: evidenceRecords,
366
+ harnessEvidence: opts.harnessEvidence,
367
+ result,
368
+ });
369
+ writeWorkflowProof(proofPath, proof);
370
+ }
371
+ catch (error) {
372
+ throw new WorkflowRunError(`workflow completed but its proof packet could not be written: ${error.message}`, runId, proofPath, error);
373
+ }
256
374
  const report = {
257
375
  runId,
258
376
  name,
@@ -260,32 +378,53 @@ export async function runWorkflow(scriptPath, opts) {
260
378
  agentsSpawned,
261
379
  agentsCached,
262
380
  costUsd: round4(costUsd),
263
- durationMs: Date.now() - t0,
381
+ durationMs,
264
382
  journalPath,
383
+ proofPath,
384
+ acceptance: proof.acceptance.summary,
265
385
  contextTokensPerChildEstimate,
266
386
  billing: Array.from(billingProbed.values()).map((p) => ({
267
387
  harness: p.harness,
268
388
  mode: opts.subscriptionOnly ? "subscription" : p.mode,
269
389
  })),
270
390
  };
271
- journal("run.end", {
272
- ok: true,
273
- agents: agentsSpawned,
274
- cached: agentsCached,
275
- cost_usd: report.costUsd,
276
- duration_ms: report.durationMs,
277
- });
278
391
  return report;
279
392
  }
280
393
  catch (err) {
394
+ if (err instanceof WorkflowRunError)
395
+ throw err;
396
+ const endedAt = new Date().toISOString();
397
+ const durationMs = Date.now() - t0;
281
398
  journal("run.end", {
282
399
  ok: false,
283
400
  error: err.message,
284
401
  agents: agentsSpawned,
285
402
  cached: agentsCached,
286
403
  cost_usd: round4(costUsd),
404
+ duration_ms: durationMs,
287
405
  });
288
- throw err;
406
+ try {
407
+ const proof = buildWorkflowProof({
408
+ runId,
409
+ meta,
410
+ status: "failed",
411
+ startedAt,
412
+ endedAt,
413
+ durationMs,
414
+ journalPath,
415
+ before: repoBefore,
416
+ after: snapshotRepo(cwd),
417
+ agents: Array.from(agentProofs.values()),
418
+ evidence: evidenceRecords,
419
+ harnessEvidence: opts.harnessEvidence,
420
+ error: err.message,
421
+ });
422
+ writeWorkflowProof(proofPath, proof);
423
+ }
424
+ catch (proofError) {
425
+ throw new WorkflowRunError(`${err.message}; proof packet write also failed: ${proofError.message}`, runId, proofPath, err);
426
+ }
427
+ throw new WorkflowRunError(err.message, runId, proofPath, err);
289
428
  }
290
429
  }
291
430
  /** Stable identity for one agent() call, for the resume cache. The ORIGINAL
@@ -0,0 +1,5 @@
1
+ export { runWorkflow, WorkflowRunError } from "./engine.js";
2
+ export { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, readWorkflowProof, renderWorkflowProof, rollupAcceptance, writeWorkflowProof, } from "./proof.js";
3
+ export type { AcceptanceCriterion, AcceptanceResult, AcceptanceStatus, AcceptanceSummary, AgentOpts, EngineOpts, EvidenceKind, EvidenceSource, EvidenceStatus, HarnessEvidenceCapability, HarnessEvidenceCoverage, HarnessName, ResultDigest, RunReport, Spawner, SpawnRequest, SpawnResult, StageSchema, WorkflowAgentProof, WorkflowContext, WorkflowEvidenceInput, WorkflowEvidenceRecord, WorkflowMeta, WorkflowModule, WorkflowProof, WorkflowProofUnknown, WorkflowRepoEvidence, WorkflowRepoSnapshot, WorkflowRunStatus, } from "./types.js";
4
+ export { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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;AAC5D,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,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,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { runWorkflow, WorkflowRunError } from "./engine.js";
2
+ export { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, readWorkflowProof, renderWorkflowProof, rollupAcceptance, writeWorkflowProof, } from "./proof.js";
3
+ export { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.js";
@@ -0,0 +1,42 @@
1
+ import type { RepoSnapshot } from "../context/index.js";
2
+ import type { AcceptanceCriterion, AcceptanceResult, AcceptanceSummary, HarnessEvidenceCapability, ResultDigest, WorkflowAgentProof, WorkflowEvidenceInput, WorkflowEvidenceRecord, WorkflowMeta, WorkflowProof } from "./types.js";
3
+ export interface NormalizedWorkflowMeta {
4
+ name: string;
5
+ description?: string;
6
+ objective?: string;
7
+ acceptance: AcceptanceCriterion[];
8
+ }
9
+ export interface BuildWorkflowProofInput {
10
+ runId: string;
11
+ meta: NormalizedWorkflowMeta;
12
+ status: "succeeded" | "failed";
13
+ startedAt: string;
14
+ endedAt: string;
15
+ durationMs: number;
16
+ journalPath: string;
17
+ before: RepoSnapshot;
18
+ after: RepoSnapshot;
19
+ agents: WorkflowAgentProof[];
20
+ evidence: WorkflowEvidenceRecord[];
21
+ harnessEvidence?: Readonly<Record<string, HarnessEvidenceCapability | undefined>>;
22
+ result?: unknown;
23
+ error?: string;
24
+ }
25
+ export declare function normalizeWorkflowMeta(meta: WorkflowMeta | undefined, fallbackName: string): NormalizedWorkflowMeta;
26
+ export declare function createEvidenceRecord(input: {
27
+ value: WorkflowEvidenceInput;
28
+ sequence: number;
29
+ acceptanceIds: ReadonlySet<string>;
30
+ stage?: string;
31
+ recordedAt?: string;
32
+ }): WorkflowEvidenceRecord;
33
+ export declare function rollupAcceptance(criteria: AcceptanceCriterion[], evidence: WorkflowEvidenceRecord[]): {
34
+ criteria: AcceptanceResult[];
35
+ summary: AcceptanceSummary;
36
+ };
37
+ export declare function digestResult(value: unknown, kind?: "text" | "json"): ResultDigest;
38
+ export declare function buildWorkflowProof(input: BuildWorkflowProofInput): WorkflowProof;
39
+ export declare function writeWorkflowProof(path: string, proof: WorkflowProof): void;
40
+ export declare function readWorkflowProof(coordRoot: string, runId: string): WorkflowProof;
41
+ export declare function renderWorkflowProof(proof: WorkflowProof): string;
42
+ //# sourceMappingURL=proof.d.ts.map
@@ -0,0 +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,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EAEzB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,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,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,CAwChF;AAED,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,CA8BhE"}