harnery 0.10.0 → 0.12.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.
Files changed (44) hide show
  1. package/README.md +1 -1
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +2 -0
  4. package/dist/commands/policy.d.ts +6 -0
  5. package/dist/commands/policy.d.ts.map +1 -0
  6. package/dist/commands/policy.js +42 -0
  7. package/dist/commands/workflow.d.ts.map +1 -1
  8. package/dist/commands/workflow.js +62 -2
  9. package/dist/core/policy/evaluate.d.ts +14 -0
  10. package/dist/core/policy/evaluate.d.ts.map +1 -0
  11. package/dist/core/policy/evaluate.js +238 -0
  12. package/dist/core/policy/file.d.ts +3 -0
  13. package/dist/core/policy/file.d.ts.map +1 -0
  14. package/dist/core/policy/file.js +20 -0
  15. package/dist/core/policy/index.d.ts +5 -0
  16. package/dist/core/policy/index.d.ts.map +1 -0
  17. package/dist/core/policy/index.js +3 -0
  18. package/dist/core/policy/types.d.ts +91 -0
  19. package/dist/core/policy/types.d.ts.map +1 -0
  20. package/dist/core/policy/types.js +1 -0
  21. package/dist/core/workflow/engine.d.ts +5 -0
  22. package/dist/core/workflow/engine.d.ts.map +1 -1
  23. package/dist/core/workflow/engine.js +412 -47
  24. package/dist/core/workflow/index.d.ts +5 -0
  25. package/dist/core/workflow/index.d.ts.map +1 -0
  26. package/dist/core/workflow/index.js +3 -0
  27. package/dist/core/workflow/proof.d.ts +49 -0
  28. package/dist/core/workflow/proof.d.ts.map +1 -0
  29. package/dist/core/workflow/proof.js +375 -0
  30. package/dist/core/workflow/types.d.ts +180 -0
  31. package/dist/core/workflow/types.d.ts.map +1 -1
  32. package/dist/core/workflow/types.js +1 -1
  33. package/package.json +16 -6
  34. package/src/commander.ts +2 -0
  35. package/src/commands/policy.ts +50 -0
  36. package/src/commands/workflow.ts +82 -2
  37. package/src/core/policy/evaluate.ts +311 -0
  38. package/src/core/policy/file.ts +20 -0
  39. package/src/core/policy/index.ts +26 -0
  40. package/src/core/policy/types.ts +107 -0
  41. package/src/core/workflow/engine.ts +452 -53
  42. package/src/core/workflow/index.ts +44 -0
  43. package/src/core/workflow/proof.ts +485 -0
  44. package/src/core/workflow/types.ts +210 -0
@@ -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,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,CAyChF;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,375 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { policyDigest } from "../policy/index.js";
5
+ import { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.js";
6
+ const MAX_ACCEPTANCE_CRITERIA = 50;
7
+ const MAX_EVIDENCE_RECORDS = 200;
8
+ const MAX_PACKET_BYTES = 512 * 1024;
9
+ const MAX_NAME_CHARS = 200;
10
+ const MAX_OBJECTIVE_CHARS = 2_000;
11
+ const MAX_CRITERION_CHARS = 500;
12
+ const MAX_LABEL_CHARS = 200;
13
+ const MAX_SUMMARY_CHARS = 2_000;
14
+ const MAX_REF_CHARS = 1_000;
15
+ const ACCEPTANCE_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
16
+ const RUN_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/;
17
+ export function normalizeWorkflowMeta(meta, fallbackName) {
18
+ const name = boundedRequired(meta?.name ?? fallbackName, "workflow name", MAX_NAME_CHARS);
19
+ const objective = boundedOptional(meta?.objective, "workflow objective", MAX_OBJECTIVE_CHARS);
20
+ const description = boundedOptional(meta?.description, "workflow description", MAX_OBJECTIVE_CHARS);
21
+ const acceptance = meta?.acceptance ?? [];
22
+ if (!Array.isArray(acceptance))
23
+ throw new Error("workflow acceptance must be an array");
24
+ if (acceptance.length > MAX_ACCEPTANCE_CRITERIA) {
25
+ throw new Error(`workflow acceptance exceeds ${MAX_ACCEPTANCE_CRITERIA} criteria`);
26
+ }
27
+ const seen = new Set();
28
+ const normalized = acceptance.map((criterion, index) => {
29
+ if (!criterion || typeof criterion !== "object") {
30
+ throw new Error(`workflow acceptance[${index}] must be an object`);
31
+ }
32
+ const id = boundedRequired(criterion.id, `workflow acceptance[${index}].id`, 64);
33
+ if (!ACCEPTANCE_ID.test(id)) {
34
+ throw new Error(`workflow acceptance id ${JSON.stringify(id)} must match ${ACCEPTANCE_ID.source}`);
35
+ }
36
+ if (seen.has(id))
37
+ throw new Error(`duplicate workflow acceptance id ${JSON.stringify(id)}`);
38
+ seen.add(id);
39
+ return {
40
+ id,
41
+ statement: boundedRequired(criterion.statement, `workflow acceptance[${index}].statement`, MAX_CRITERION_CHARS),
42
+ };
43
+ });
44
+ return { name, description, objective, acceptance: normalized };
45
+ }
46
+ export function createEvidenceRecord(input) {
47
+ if (input.sequence > MAX_EVIDENCE_RECORDS) {
48
+ throw new Error(`workflow evidence exceeds ${MAX_EVIDENCE_RECORDS} records`);
49
+ }
50
+ const value = input.value;
51
+ const acceptanceIds = value.acceptanceIds ?? [];
52
+ if (!Array.isArray(acceptanceIds))
53
+ throw new Error("evidence acceptanceIds must be an array");
54
+ const uniqueAcceptanceIds = [...new Set(acceptanceIds)];
55
+ for (const id of uniqueAcceptanceIds) {
56
+ if (typeof id !== "string" || !input.acceptanceIds.has(id)) {
57
+ throw new Error(`evidence references unknown acceptance id ${JSON.stringify(id)}`);
58
+ }
59
+ }
60
+ return {
61
+ id: `e${input.sequence}`,
62
+ source: "workflow",
63
+ recorded_at: input.recordedAt ?? new Date().toISOString(),
64
+ kind: enumValue(value.kind, ["test", "command", "artifact", "change", "review", "observation"], "evidence kind"),
65
+ status: enumValue(value.status, ["passed", "failed", "observed", "unknown"], "evidence status"),
66
+ label: boundedRequired(value.label, "evidence label", MAX_LABEL_CHARS),
67
+ summary: boundedOptional(value.summary, "evidence summary", MAX_SUMMARY_CHARS),
68
+ ref: boundedOptional(value.ref, "evidence ref", MAX_REF_CHARS),
69
+ stage: boundedOptional(input.stage, "evidence stage", MAX_LABEL_CHARS),
70
+ acceptance_ids: uniqueAcceptanceIds,
71
+ };
72
+ }
73
+ export function rollupAcceptance(criteria, evidence) {
74
+ const results = criteria.map((criterion) => {
75
+ const attached = evidence.filter((item) => item.acceptance_ids.includes(criterion.id));
76
+ const failed = attached.filter((item) => item.status === "failed");
77
+ const passed = attached.filter((item) => item.status === "passed");
78
+ const decisive = failed.length > 0 ? failed : passed;
79
+ const status = failed.length > 0 ? "unsatisfied" : passed.length > 0 ? "satisfied" : "unknown";
80
+ return {
81
+ ...criterion,
82
+ status,
83
+ evidence_ids: attached.map((item) => item.id),
84
+ sources: [...new Set(decisive.map((item) => item.source))],
85
+ };
86
+ });
87
+ return {
88
+ criteria: results,
89
+ summary: {
90
+ satisfied: results.filter((item) => item.status === "satisfied").length,
91
+ unsatisfied: results.filter((item) => item.status === "unsatisfied").length,
92
+ unknown: results.filter((item) => item.status === "unknown").length,
93
+ total: results.length,
94
+ },
95
+ };
96
+ }
97
+ export function digestResult(value, kind) {
98
+ const resolvedKind = kind ?? (typeof value === "string" ? "text" : "json");
99
+ const serialized = resolvedKind === "text" ? String(value) : (JSON.stringify(value) ?? "null");
100
+ return {
101
+ kind: resolvedKind,
102
+ sha256: createHash("sha256").update(serialized).digest("hex"),
103
+ bytes: Buffer.byteLength(serialized),
104
+ };
105
+ }
106
+ export function buildWorkflowProof(input) {
107
+ const acceptance = rollupAcceptance(input.meta.acceptance, input.evidence);
108
+ const repository = buildRepoEvidence(input.before, input.after);
109
+ const agents = input.agents.map((agent) => ({
110
+ ...agent,
111
+ label: clipped(agent.label, MAX_LABEL_CHARS),
112
+ model: clippedOptional(agent.model, MAX_LABEL_CHARS),
113
+ session_id: clippedOptional(agent.session_id, MAX_REF_CHARS),
114
+ error: clippedOptional(agent.error, MAX_SUMMARY_CHARS),
115
+ }));
116
+ const harnesses = buildHarnessCoverage(agents, input.harnessEvidence);
117
+ const unknowns = buildUnknowns(agents, harnesses, repository);
118
+ const journal = readFileSync(input.journalPath);
119
+ return {
120
+ schema_version: WORKFLOW_PROOF_SCHEMA_VERSION,
121
+ run: {
122
+ id: input.runId,
123
+ name: input.meta.name,
124
+ status: input.status,
125
+ started_at: input.startedAt,
126
+ ended_at: input.endedAt,
127
+ duration_ms: input.durationMs,
128
+ objective: input.meta.objective,
129
+ error: clippedOptional(input.error, MAX_SUMMARY_CHARS),
130
+ result: input.result === undefined ? undefined : digestResult(input.result),
131
+ },
132
+ acceptance,
133
+ agents,
134
+ evidence: input.evidence,
135
+ policy: input.policy ? buildPolicyProof(input.policy) : undefined,
136
+ repository,
137
+ harnesses,
138
+ unknowns,
139
+ integrity: {
140
+ journal: {
141
+ path: "journal.jsonl",
142
+ sha256: createHash("sha256").update(journal).digest("hex"),
143
+ bytes: journal.byteLength,
144
+ },
145
+ },
146
+ };
147
+ }
148
+ function buildPolicyProof(input) {
149
+ const decisions = input.decisions.map((decision) => ({
150
+ ...decision,
151
+ reason: clipped(decision.reason, MAX_SUMMARY_CHARS),
152
+ request: {
153
+ ...decision.request,
154
+ action: clipped(decision.request.action, MAX_REF_CHARS),
155
+ path: clippedOptional(decision.request.path, MAX_REF_CHARS),
156
+ target: clippedOptional(decision.request.target, MAX_REF_CHARS),
157
+ },
158
+ }));
159
+ return {
160
+ schema_version: input.config.schema_version,
161
+ name: input.config.name,
162
+ sha256: policyDigest(input.config),
163
+ isolation: input.isolation,
164
+ network_access: input.networkAccess,
165
+ config: input.config,
166
+ decisions,
167
+ summary: {
168
+ allowed: decisions.filter((decision) => decision.verdict === "allow").length,
169
+ denied: decisions.filter((decision) => decision.verdict === "deny").length,
170
+ asked: decisions.filter((decision) => decision.initial_verdict === "ask").length,
171
+ total: decisions.length,
172
+ },
173
+ };
174
+ }
175
+ export function writeWorkflowProof(path, proof) {
176
+ const body = `${JSON.stringify(proof, null, 2)}\n`;
177
+ const bytes = Buffer.byteLength(body);
178
+ if (bytes > MAX_PACKET_BYTES) {
179
+ throw new Error(`workflow proof is ${bytes} bytes; limit is ${MAX_PACKET_BYTES}`);
180
+ }
181
+ mkdirSync(dirname(path), { recursive: true });
182
+ const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
183
+ try {
184
+ writeFileSync(temporary, body, { encoding: "utf8", flag: "wx", mode: 0o600 });
185
+ renameSync(temporary, path);
186
+ chmodSync(path, 0o600);
187
+ }
188
+ finally {
189
+ if (existsSync(temporary))
190
+ unlinkSync(temporary);
191
+ }
192
+ }
193
+ export function readWorkflowProof(coordRoot, runId) {
194
+ if (!RUN_ID.test(runId))
195
+ throw new Error(`invalid workflow run id ${JSON.stringify(runId)}`);
196
+ const path = join(coordRoot, ".harnery", "workflows", runId, "proof.json");
197
+ if (!existsSync(path))
198
+ throw new Error(`workflow run ${runId} has no proof packet at ${path}`);
199
+ const size = statSync(path).size;
200
+ if (size > MAX_PACKET_BYTES) {
201
+ throw new Error(`workflow proof is ${size} bytes; limit is ${MAX_PACKET_BYTES}`);
202
+ }
203
+ let proof;
204
+ try {
205
+ proof = JSON.parse(readFileSync(path, "utf8"));
206
+ }
207
+ catch (error) {
208
+ throw new Error(`cannot parse workflow proof at ${path}: ${error.message}`);
209
+ }
210
+ if (proof.schema_version !== WORKFLOW_PROOF_SCHEMA_VERSION || proof.run?.id !== runId) {
211
+ throw new Error(`workflow proof at ${path} has an unsupported or mismatched schema`);
212
+ }
213
+ return proof;
214
+ }
215
+ export function renderWorkflowProof(proof) {
216
+ const lines = [
217
+ `run ${proof.run.id} (${proof.run.name}): ${proof.run.status}`,
218
+ `duration: ${Math.round(proof.run.duration_ms / 1000)}s`,
219
+ ];
220
+ if (proof.run.objective)
221
+ lines.push(`objective: ${proof.run.objective}`);
222
+ const summary = proof.acceptance.summary;
223
+ lines.push(`acceptance: ${summary.satisfied} satisfied, ${summary.unsatisfied} unsatisfied, ${summary.unknown} unknown`);
224
+ for (const criterion of proof.acceptance.criteria) {
225
+ const mark = criterion.status === "satisfied" ? "PASS" : criterion.status === "unsatisfied" ? "FAIL" : "?";
226
+ const refs = criterion.evidence_ids.length > 0 ? ` [${criterion.evidence_ids.join(", ")}]` : "";
227
+ lines.push(` ${mark} ${criterion.id}: ${criterion.statement}${refs}`);
228
+ }
229
+ lines.push(`evidence: ${proof.evidence.length} record(s); agents: ${proof.agents.length}`);
230
+ if (proof.policy) {
231
+ lines.push(`policy: ${proof.policy.name}; ${proof.policy.summary.allowed} allowed, ` +
232
+ `${proof.policy.summary.denied} denied, ${proof.policy.summary.asked} asked`);
233
+ }
234
+ const repo = proof.repository;
235
+ const drift = repo.drift;
236
+ lines.push(`repository: branch ${repo.before.branch ?? "unknown"} -> ${repo.after.branch ?? "unknown"}; ` +
237
+ `HEAD ${short(repo.before.head)} -> ${short(repo.after.head)}; ` +
238
+ `${drift.dirty_paths_added.length} dirty added, ${drift.dirty_paths_cleared.length} cleared`);
239
+ if (proof.unknowns.length > 0) {
240
+ lines.push(`unknowns: ${proof.unknowns.length}`);
241
+ for (const unknown of proof.unknowns)
242
+ lines.push(` - ${unknown.message}`);
243
+ }
244
+ lines.push(`journal sha256: ${proof.integrity.journal.sha256}`);
245
+ return `${lines.join("\n")}\n`;
246
+ }
247
+ function buildRepoEvidence(beforeRaw, afterRaw) {
248
+ const before = normalizeRepoSnapshot(beforeRaw);
249
+ const after = normalizeRepoSnapshot(afterRaw);
250
+ const beforeDirty = new Set(before.dirty_paths);
251
+ const afterDirty = new Set(after.dirty_paths);
252
+ const retained = after.dirty_paths.filter((path) => beforeDirty.has(path));
253
+ const incomplete = Boolean(before.dirty_paths_truncated || after.dirty_paths_truncated || retained.length > 0);
254
+ return {
255
+ source: "engine",
256
+ before,
257
+ after,
258
+ drift: {
259
+ branch_changed: before.branch !== after.branch,
260
+ head_changed: before.head !== after.head,
261
+ dirty_paths_added: after.dirty_paths.filter((path) => !beforeDirty.has(path)),
262
+ dirty_paths_cleared: before.dirty_paths.filter((path) => !afterDirty.has(path)),
263
+ dirty_paths_retained: retained,
264
+ incomplete,
265
+ note: incomplete
266
+ ? "Snapshots cannot prove whether retained dirty paths changed during the run, and truncated lists may omit paths."
267
+ : undefined,
268
+ },
269
+ };
270
+ }
271
+ function normalizeRepoSnapshot(snapshot) {
272
+ return {
273
+ cwd: snapshot.cwd,
274
+ root: snapshot.root,
275
+ branch: snapshot.branch,
276
+ head: snapshot.head,
277
+ dirty_paths: snapshot.dirty_paths,
278
+ dirty_paths_truncated: snapshot.dirty_paths_truncated,
279
+ };
280
+ }
281
+ function buildHarnessCoverage(agents, claims) {
282
+ return [...new Set(agents.map((agent) => agent.harness))].map((harness) => {
283
+ const harnessAgents = agents.filter((agent) => agent.harness === harness);
284
+ return {
285
+ harness,
286
+ tool_evidence: claims?.[harness]?.toolEvidence ?? {
287
+ support: "unknown",
288
+ note: "No harness capability claim was supplied to this workflow run.",
289
+ },
290
+ observed: {
291
+ final_results: harnessAgents.filter((agent) => agent.result).length,
292
+ session_ids: harnessAgents.filter((agent) => agent.session_id).length,
293
+ costs: harnessAgents.filter((agent) => agent.cost_usd !== undefined).length,
294
+ },
295
+ };
296
+ });
297
+ }
298
+ function buildUnknowns(agents, harnesses, repository) {
299
+ const unknowns = [];
300
+ for (const harness of harnesses) {
301
+ if (harness.tool_evidence.support === "unknown") {
302
+ unknowns.push({
303
+ code: "harness_capability_unregistered",
304
+ harness: harness.harness,
305
+ message: `${harness.harness}: tool-evidence capability was not registered for this run.`,
306
+ });
307
+ }
308
+ else if (harness.tool_evidence.support !== "supported") {
309
+ unknowns.push({
310
+ code: "tool_evidence_unavailable",
311
+ harness: harness.harness,
312
+ message: `${harness.harness}: adapter-native tool evidence is ${harness.tool_evidence.support}.`,
313
+ });
314
+ }
315
+ }
316
+ for (const agent of agents.filter((item) => item.status !== "failed")) {
317
+ if (agent.cost_usd === undefined) {
318
+ unknowns.push({
319
+ code: "agent_cost_unreported",
320
+ harness: agent.harness,
321
+ agent_id: agent.id,
322
+ message: `${agent.id}: ${agent.harness} did not report per-run cost.`,
323
+ });
324
+ }
325
+ if (!agent.session_id) {
326
+ unknowns.push({
327
+ code: "agent_session_unreported",
328
+ harness: agent.harness,
329
+ agent_id: agent.id,
330
+ message: `${agent.id}: ${agent.harness} did not report a child session id.`,
331
+ });
332
+ }
333
+ }
334
+ if (repository.drift.incomplete) {
335
+ unknowns.push({
336
+ code: "repository_drift_incomplete",
337
+ message: repository.drift.note ?? "Repository drift is incomplete.",
338
+ });
339
+ }
340
+ return unknowns;
341
+ }
342
+ function boundedRequired(value, field, max) {
343
+ if (typeof value !== "string" || value.trim() === "")
344
+ throw new Error(`${field} is required`);
345
+ const normalized = value.trim();
346
+ if (normalized.length > max)
347
+ throw new Error(`${field} exceeds ${max} characters`);
348
+ return normalized;
349
+ }
350
+ function boundedOptional(value, field, max) {
351
+ if (value === undefined)
352
+ return undefined;
353
+ if (typeof value !== "string")
354
+ throw new Error(`${field} must be a string`);
355
+ const normalized = value.trim();
356
+ if (normalized === "")
357
+ return undefined;
358
+ if (normalized.length > max)
359
+ throw new Error(`${field} exceeds ${max} characters`);
360
+ return normalized;
361
+ }
362
+ function enumValue(value, values, field) {
363
+ if (typeof value === "string" && values.includes(value))
364
+ return value;
365
+ throw new Error(`${field} must be one of: ${values.join(", ")}`);
366
+ }
367
+ function short(value) {
368
+ return value ? value.slice(0, 8) : "unknown";
369
+ }
370
+ function clipped(value, max) {
371
+ return value.length <= max ? value : `${value.slice(0, Math.max(0, max - 1))}…`;
372
+ }
373
+ function clippedOptional(value, max) {
374
+ return value === undefined ? undefined : clipped(value, max);
375
+ }
@@ -6,7 +6,162 @@
6
6
  *
7
7
  * Design record: decision 0015 (portable coordination-aware workflows).
8
8
  */
9
+ import type { DispatchCostEstimator, ExternalMutationRequest, NormalizedPolicy, PolicyAskResolver, PolicyDecision, PolicyIsolation, PolicyNetworkAccess, PolicySpec } from "../policy/index.js";
9
10
  import type { BillingMode, BillingProber } from "./billing.js";
11
+ export declare const WORKFLOW_PROOF_SCHEMA_VERSION: 1;
12
+ export type EvidenceKind = "test" | "command" | "artifact" | "change" | "review" | "observation";
13
+ export type EvidenceStatus = "passed" | "failed" | "observed" | "unknown";
14
+ export type EvidenceSource = "workflow" | "engine";
15
+ export type AcceptanceStatus = "satisfied" | "unsatisfied" | "unknown";
16
+ export type WorkflowRunStatus = "succeeded" | "failed";
17
+ export interface AcceptanceCriterion {
18
+ /** Stable identifier referenced by evidence, for example `tests-pass`. */
19
+ id: string;
20
+ statement: string;
21
+ }
22
+ export interface WorkflowEvidenceInput {
23
+ kind: EvidenceKind;
24
+ status: EvidenceStatus;
25
+ label: string;
26
+ summary?: string;
27
+ /** Inspectable local path, URL, command name, or other bounded reference. */
28
+ ref?: string;
29
+ /** Declared acceptance criteria this evidence bears on. */
30
+ acceptanceIds?: string[];
31
+ }
32
+ export interface WorkflowEvidenceRecord {
33
+ id: string;
34
+ source: EvidenceSource;
35
+ recorded_at: string;
36
+ kind: EvidenceKind;
37
+ status: EvidenceStatus;
38
+ label: string;
39
+ summary?: string;
40
+ ref?: string;
41
+ stage?: string;
42
+ acceptance_ids: string[];
43
+ }
44
+ export interface AcceptanceResult extends AcceptanceCriterion {
45
+ status: AcceptanceStatus;
46
+ evidence_ids: string[];
47
+ /** Sources behind the decisive evidence. Empty when status is unknown. */
48
+ sources: EvidenceSource[];
49
+ }
50
+ export interface AcceptanceSummary {
51
+ satisfied: number;
52
+ unsatisfied: number;
53
+ unknown: number;
54
+ total: number;
55
+ }
56
+ export interface ResultDigest {
57
+ kind: "text" | "json";
58
+ sha256: string;
59
+ bytes: number;
60
+ }
61
+ export interface WorkflowAgentProof {
62
+ id: string;
63
+ label: string;
64
+ stage?: string;
65
+ harness: HarnessName;
66
+ model?: string;
67
+ status: "succeeded" | "failed" | "cached";
68
+ attempts: number;
69
+ duration_ms: number;
70
+ cost_usd?: number;
71
+ session_id?: string;
72
+ result?: ResultDigest;
73
+ error?: string;
74
+ }
75
+ export interface WorkflowRepoSnapshot {
76
+ cwd: string;
77
+ root?: string;
78
+ branch?: string;
79
+ head?: string;
80
+ dirty_paths: string[];
81
+ dirty_paths_truncated?: boolean;
82
+ }
83
+ export interface WorkflowRepoEvidence {
84
+ source: "engine";
85
+ before: WorkflowRepoSnapshot;
86
+ after: WorkflowRepoSnapshot;
87
+ drift: {
88
+ branch_changed: boolean;
89
+ head_changed: boolean;
90
+ dirty_paths_added: string[];
91
+ dirty_paths_cleared: string[];
92
+ dirty_paths_retained: string[];
93
+ /** True when snapshots cannot prove whether every retained dirty path changed. */
94
+ incomplete: boolean;
95
+ note?: string;
96
+ };
97
+ }
98
+ export interface HarnessEvidenceCoverage {
99
+ harness: HarnessName;
100
+ tool_evidence: {
101
+ support: "supported" | "partial" | "unsupported" | "unknown";
102
+ note?: string;
103
+ };
104
+ observed: {
105
+ final_results: number;
106
+ session_ids: number;
107
+ costs: number;
108
+ };
109
+ }
110
+ export interface WorkflowProofUnknown {
111
+ code: "tool_evidence_unavailable" | "harness_capability_unregistered" | "agent_cost_unreported" | "agent_session_unreported" | "repository_drift_incomplete";
112
+ message: string;
113
+ harness?: HarnessName;
114
+ agent_id?: string;
115
+ }
116
+ export interface WorkflowProof {
117
+ schema_version: typeof WORKFLOW_PROOF_SCHEMA_VERSION;
118
+ run: {
119
+ id: string;
120
+ name: string;
121
+ status: WorkflowRunStatus;
122
+ started_at: string;
123
+ ended_at: string;
124
+ duration_ms: number;
125
+ objective?: string;
126
+ error?: string;
127
+ result?: ResultDigest;
128
+ };
129
+ acceptance: {
130
+ criteria: AcceptanceResult[];
131
+ summary: AcceptanceSummary;
132
+ };
133
+ agents: WorkflowAgentProof[];
134
+ evidence: WorkflowEvidenceRecord[];
135
+ policy?: WorkflowPolicyProof;
136
+ repository: WorkflowRepoEvidence;
137
+ harnesses: HarnessEvidenceCoverage[];
138
+ unknowns: WorkflowProofUnknown[];
139
+ integrity: {
140
+ journal: {
141
+ path: "journal.jsonl";
142
+ sha256: string;
143
+ bytes: number;
144
+ };
145
+ };
146
+ }
147
+ export interface WorkflowPolicyProof {
148
+ schema_version: 1;
149
+ name: string;
150
+ sha256: string;
151
+ isolation: PolicyIsolation;
152
+ network_access: PolicyNetworkAccess;
153
+ config: NormalizedPolicy;
154
+ decisions: PolicyDecision[];
155
+ summary: {
156
+ allowed: number;
157
+ denied: number;
158
+ asked: number;
159
+ total: number;
160
+ };
161
+ }
162
+ export interface HarnessEvidenceCapability {
163
+ toolEvidence: HarnessEvidenceCoverage["tool_evidence"];
164
+ }
10
165
  /** JSON-schema *subset* accepted by stage gates (see validate.ts). */
11
166
  export interface StageSchema {
12
167
  type: "object" | "array" | "string" | "number" | "boolean";
@@ -86,10 +241,16 @@ export interface WorkflowContext {
86
241
  stage: (title: string) => void;
87
242
  /** Narrate progress (stderr + journal). */
88
243
  log: (message: string) => void;
244
+ /** Attach a bounded, sourced receipt to the run and optional acceptance criteria. */
245
+ evidence: (input: WorkflowEvidenceInput) => string;
246
+ /** Authorize one host-mediated external mutation before performing it. */
247
+ authorize: (input: ExternalMutationRequest) => Promise<PolicyDecision>;
89
248
  }
90
249
  export interface WorkflowMeta {
91
250
  name: string;
92
251
  description?: string;
252
+ objective?: string;
253
+ acceptance?: AcceptanceCriterion[];
93
254
  }
94
255
  /** Loaded script shape: `export const meta` + `export default async (ctx) => …`. */
95
256
  export interface WorkflowModule {
@@ -127,6 +288,21 @@ export interface EngineOpts {
127
288
  allowApiBilling?: boolean;
128
289
  /** Billing-probe override for tests (default: the real probeBilling). */
129
290
  probeBilling?: BillingProber;
291
+ /** Capability claims used to state whether adapter-native tool evidence was
292
+ * available. Missing claims remain unknown. */
293
+ harnessEvidence?: Readonly<Record<HarnessName, HarnessEvidenceCapability | undefined>>;
294
+ /** Immutable host policy. Workflow scripts and model prompts cannot replace it. */
295
+ policy?: PolicySpec | NormalizedPolicy;
296
+ /** Host callback for ASK. Missing, invalid, throwing, or timed-out resolution denies. */
297
+ resolvePolicyAsk?: PolicyAskResolver;
298
+ /** Host-owned cost projection. Required to allow budgeted dispatches with known pricing. */
299
+ estimateDispatchCost?: DispatchCostEstimator;
300
+ /** Maximum wait for an ASK resolver (default 60 seconds). */
301
+ policyAskTimeoutMs?: number;
302
+ /** Execution boundary created by the host (default shared). */
303
+ isolation?: PolicyIsolation;
304
+ /** Network state of spawned harness subprocesses (default unknown). */
305
+ networkAccess?: PolicyNetworkAccess;
130
306
  }
131
307
  export interface RunReport {
132
308
  runId: string;
@@ -139,6 +315,8 @@ export interface RunReport {
139
315
  costUsd: number;
140
316
  durationMs: number;
141
317
  journalPath: string;
318
+ proofPath: string;
319
+ acceptance: AcceptanceSummary;
142
320
  /** Estimated tokens of repo instructions (CLAUDE.md/AGENTS.md at the child
143
321
  * cwd) that EVERY child cache-writes on spawn — the fixed per-child context
144
322
  * overhead a fan-out multiplies. bytes/4 heuristic; 0 when no such file. */
@@ -148,5 +326,7 @@ export interface RunReport {
148
326
  harness: HarnessName;
149
327
  mode: BillingMode;
150
328
  }>;
329
+ /** Policy verdict totals when the host supplied a policy. */
330
+ policy?: WorkflowPolicyProof["summary"];
151
331
  }
152
332
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/types.ts"],"names":[],"mappings":"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"}
@@ -6,4 +6,4 @@
6
6
  *
7
7
  * Design record: decision 0015 (portable coordination-aware workflows).
8
8
  */
9
- export {};
9
+ export const WORKFLOW_PROOF_SCHEMA_VERSION = 1;