harnery 0.22.1 → 0.24.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 (103) hide show
  1. package/README.md +1 -0
  2. package/dist/commands/workflow.d.ts.map +1 -1
  3. package/dist/commands/workflow.js +302 -5
  4. package/dist/core/work/state.d.ts +7 -0
  5. package/dist/core/work/state.d.ts.map +1 -1
  6. package/dist/core/work/state.js +112 -23
  7. package/dist/core/workflow/child-env.d.ts +10 -6
  8. package/dist/core/workflow/child-env.d.ts.map +1 -1
  9. package/dist/core/workflow/child-env.js +15 -7
  10. package/dist/core/workflow/durable-record.d.ts +7 -0
  11. package/dist/core/workflow/durable-record.d.ts.map +1 -0
  12. package/dist/core/workflow/durable-record.js +83 -0
  13. package/dist/core/workflow/engine.d.ts.map +1 -1
  14. package/dist/core/workflow/engine.js +208 -29
  15. package/dist/core/workflow/index.d.ts +2 -0
  16. package/dist/core/workflow/index.d.ts.map +1 -1
  17. package/dist/core/workflow/index.js +1 -0
  18. package/dist/core/workflow/proof.d.ts +4 -0
  19. package/dist/core/workflow/proof.d.ts.map +1 -1
  20. package/dist/core/workflow/proof.js +50 -15
  21. package/dist/core/workflow/run-state.d.ts +3 -0
  22. package/dist/core/workflow/run-state.d.ts.map +1 -1
  23. package/dist/core/workflow/run-state.js +25 -13
  24. package/dist/core/workflow/spawn-cursor.d.ts +3 -0
  25. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  26. package/dist/core/workflow/spawn-cursor.js +8 -4
  27. package/dist/core/workflow/types.d.ts +10 -0
  28. package/dist/core/workflow/types.d.ts.map +1 -1
  29. package/dist/core/workflow/workspaces/attestation-error.d.ts +7 -0
  30. package/dist/core/workflow/workspaces/attestation-error.d.ts.map +1 -0
  31. package/dist/core/workflow/workspaces/attestation-error.js +25 -0
  32. package/dist/core/workflow/workspaces/cancellation.d.ts +8 -0
  33. package/dist/core/workflow/workspaces/cancellation.d.ts.map +1 -0
  34. package/dist/core/workflow/workspaces/cancellation.js +95 -0
  35. package/dist/core/workflow/workspaces/cleanup.d.ts +9 -0
  36. package/dist/core/workflow/workspaces/cleanup.d.ts.map +1 -0
  37. package/dist/core/workflow/workspaces/cleanup.js +223 -0
  38. package/dist/core/workflow/workspaces/execution.d.ts +25 -0
  39. package/dist/core/workflow/workspaces/execution.d.ts.map +1 -0
  40. package/dist/core/workflow/workspaces/execution.js +316 -0
  41. package/dist/core/workflow/workspaces/git.d.ts +25 -0
  42. package/dist/core/workflow/workspaces/git.d.ts.map +1 -0
  43. package/dist/core/workflow/workspaces/git.js +102 -0
  44. package/dist/core/workflow/workspaces/index.d.ts +15 -0
  45. package/dist/core/workflow/workspaces/index.d.ts.map +1 -0
  46. package/dist/core/workflow/workspaces/index.js +7 -0
  47. package/dist/core/workflow/workspaces/inspect.d.ts +85 -0
  48. package/dist/core/workflow/workspaces/inspect.d.ts.map +1 -0
  49. package/dist/core/workflow/workspaces/inspect.js +255 -0
  50. package/dist/core/workflow/workspaces/integration.d.ts +32 -0
  51. package/dist/core/workflow/workspaces/integration.d.ts.map +1 -0
  52. package/dist/core/workflow/workspaces/integration.js +631 -0
  53. package/dist/core/workflow/workspaces/leases.d.ts +37 -0
  54. package/dist/core/workflow/workspaces/leases.d.ts.map +1 -0
  55. package/dist/core/workflow/workspaces/leases.js +397 -0
  56. package/dist/core/workflow/workspaces/lifecycle.d.ts +43 -0
  57. package/dist/core/workflow/workspaces/lifecycle.d.ts.map +1 -0
  58. package/dist/core/workflow/workspaces/lifecycle.js +622 -0
  59. package/dist/core/workflow/workspaces/local-git.d.ts +8 -0
  60. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -0
  61. package/dist/core/workflow/workspaces/local-git.js +1474 -0
  62. package/dist/core/workflow/workspaces/paths.d.ts +23 -0
  63. package/dist/core/workflow/workspaces/paths.d.ts.map +1 -0
  64. package/dist/core/workflow/workspaces/paths.js +191 -0
  65. package/dist/core/workflow/workspaces/recovery.d.ts +3 -0
  66. package/dist/core/workflow/workspaces/recovery.d.ts.map +1 -0
  67. package/dist/core/workflow/workspaces/recovery.js +50 -0
  68. package/dist/core/workflow/workspaces/state.d.ts +60 -0
  69. package/dist/core/workflow/workspaces/state.d.ts.map +1 -0
  70. package/dist/core/workflow/workspaces/state.js +296 -0
  71. package/dist/core/workflow/workspaces/types.d.ts +445 -0
  72. package/dist/core/workflow/workspaces/types.d.ts.map +1 -0
  73. package/dist/core/workflow/workspaces/types.js +2 -0
  74. package/dist/core/workflow/workspaces/validate.d.ts +14 -0
  75. package/dist/core/workflow/workspaces/validate.d.ts.map +1 -0
  76. package/dist/core/workflow/workspaces/validate.js +476 -0
  77. package/package.json +5 -3
  78. package/src/commands/workflow.ts +366 -8
  79. package/src/core/work/state.ts +156 -28
  80. package/src/core/workflow/child-env.ts +18 -7
  81. package/src/core/workflow/durable-record.ts +94 -0
  82. package/src/core/workflow/engine.ts +230 -30
  83. package/src/core/workflow/index.ts +74 -0
  84. package/src/core/workflow/proof.ts +70 -22
  85. package/src/core/workflow/run-state.ts +46 -11
  86. package/src/core/workflow/spawn-cursor.ts +8 -4
  87. package/src/core/workflow/types.ts +14 -0
  88. package/src/core/workflow/workspaces/attestation-error.ts +30 -0
  89. package/src/core/workflow/workspaces/cancellation.ts +137 -0
  90. package/src/core/workflow/workspaces/cleanup.ts +308 -0
  91. package/src/core/workflow/workspaces/execution.ts +412 -0
  92. package/src/core/workflow/workspaces/git.ts +125 -0
  93. package/src/core/workflow/workspaces/index.ts +89 -0
  94. package/src/core/workflow/workspaces/inspect.ts +421 -0
  95. package/src/core/workflow/workspaces/integration.ts +845 -0
  96. package/src/core/workflow/workspaces/leases.ts +517 -0
  97. package/src/core/workflow/workspaces/lifecycle.ts +792 -0
  98. package/src/core/workflow/workspaces/local-git.ts +1892 -0
  99. package/src/core/workflow/workspaces/paths.ts +247 -0
  100. package/src/core/workflow/workspaces/recovery.ts +56 -0
  101. package/src/core/workflow/workspaces/state.ts +481 -0
  102. package/src/core/workflow/workspaces/types.ts +517 -0
  103. package/src/core/workflow/workspaces/validate.ts +595 -0
@@ -6,13 +6,17 @@
6
6
  * harness CLI under a live session inherits vars that make it exit 1 with
7
7
  * empty output; an empty-string var still reads as set. Scrub all three
8
8
  * families (CLAUDE*, CODEX*, CURSOR*) regardless of which adapter spawns —
9
- * a codex child launched from inside a Claude Code session must not
10
- * inherit CLAUDE* either.
11
- * 2. **The scrub targets SESSION vars, not credentials.** CURSOR_API_KEY
9
+ * a codex child launched from inside a Claude Code session must not inherit
10
+ * CLAUDE* either. Preserve explicit auth/config locators such as CODEX_HOME:
11
+ * changing the home silently changes which subscription account the child
12
+ * uses.
13
+ * 2. **The scrub targets SESSION vars, not credentials or auth locators.** CURSOR_API_KEY
12
14
  * matches the CURSOR* prefix but is an auth credential, so it is carved
13
- * out and re-added — a key-only cursor host must keep working. (The other
14
- * two key vars, ANTHROPIC_API_KEY and OPENAI_API_KEY, don't collide with
15
- * the scrub prefixes.)
15
+ * out and re-added — a key-only cursor host must keep working. CODEX_HOME
16
+ * is likewise preserved because codex reads its ChatGPT subscription login
17
+ * from `$CODEX_HOME/auth.json`. (The other two key vars,
18
+ * ANTHROPIC_API_KEY and OPENAI_API_KEY, don't collide with the scrub
19
+ * prefixes.)
16
20
  * 3. **subscriptionOnly deletes every API-key var** (see billing.ts) so the
17
21
  * child can only authenticate via its stored subscription login — the
18
22
  * guarantee behind `workflow run --subscription-only`.
@@ -1 +1 @@
1
- {"version":3,"file":"child-env.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/child-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY7F"}
1
+ {"version":3,"file":"child-env.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/child-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAOH,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkB7F"}
@@ -6,13 +6,17 @@
6
6
  * harness CLI under a live session inherits vars that make it exit 1 with
7
7
  * empty output; an empty-string var still reads as set. Scrub all three
8
8
  * families (CLAUDE*, CODEX*, CURSOR*) regardless of which adapter spawns —
9
- * a codex child launched from inside a Claude Code session must not
10
- * inherit CLAUDE* either.
11
- * 2. **The scrub targets SESSION vars, not credentials.** CURSOR_API_KEY
9
+ * a codex child launched from inside a Claude Code session must not inherit
10
+ * CLAUDE* either. Preserve explicit auth/config locators such as CODEX_HOME:
11
+ * changing the home silently changes which subscription account the child
12
+ * uses.
13
+ * 2. **The scrub targets SESSION vars, not credentials or auth locators.** CURSOR_API_KEY
12
14
  * matches the CURSOR* prefix but is an auth credential, so it is carved
13
- * out and re-added — a key-only cursor host must keep working. (The other
14
- * two key vars, ANTHROPIC_API_KEY and OPENAI_API_KEY, don't collide with
15
- * the scrub prefixes.)
15
+ * out and re-added — a key-only cursor host must keep working. CODEX_HOME
16
+ * is likewise preserved because codex reads its ChatGPT subscription login
17
+ * from `$CODEX_HOME/auth.json`. (The other two key vars,
18
+ * ANTHROPIC_API_KEY and OPENAI_API_KEY, don't collide with the scrub
19
+ * prefixes.)
16
20
  * 3. **subscriptionOnly deletes every API-key var** (see billing.ts) so the
17
21
  * child can only authenticate via its stored subscription login — the
18
22
  * guarantee behind `workflow run --subscription-only`.
@@ -24,6 +28,7 @@
24
28
  */
25
29
  import { API_KEY_VARS } from "./billing.js";
26
30
  const SCRUB_PREFIXES = ["CLAUDE", "CODEX", "CURSOR"];
31
+ const PRESERVED_HARNESS_VARS = new Set(["CODEX_HOME"]);
27
32
  export function buildChildEnv(runId, opts = {}) {
28
33
  const env = {};
29
34
  const keyVars = new Set(Object.values(API_KEY_VARS));
@@ -32,8 +37,11 @@ export function buildChildEnv(runId, opts = {}) {
32
37
  continue;
33
38
  if (opts.subscriptionOnly && keyVars.has(k))
34
39
  continue;
35
- if (SCRUB_PREFIXES.some((p) => k.startsWith(p)) && !keyVars.has(k))
40
+ if (SCRUB_PREFIXES.some((p) => k.startsWith(p)) &&
41
+ !keyVars.has(k) &&
42
+ !PRESERVED_HARNESS_VARS.has(k)) {
36
43
  continue;
44
+ }
37
45
  env[k] = v;
38
46
  }
39
47
  env.HARNERY_WORKFLOW_CHILD = "1";
@@ -0,0 +1,7 @@
1
+ export declare function stableDigest(value: unknown): string;
2
+ export declare function canonicalJson(value: unknown): string;
3
+ export declare function fileSha256(path: string): string;
4
+ export declare function writeImmutableJson(path: string, value: unknown): boolean;
5
+ export declare function fsyncParentDirectory(path: string): void;
6
+ export declare function readJsonRecord<T>(path: string, label: string): T;
7
+ //# sourceMappingURL=durable-record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable-record.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/durable-record.ts"],"names":[],"mappings":"AAkBA,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEnD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CA6BxE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQvD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAShE"}
@@ -0,0 +1,83 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { chmodSync, closeSync, existsSync, fsyncSync, linkSync, mkdirSync, openSync, readFileSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
3
+ import { dirname } from "node:path";
4
+ const JSON_LIMIT = 512 * 1024;
5
+ export function stableDigest(value) {
6
+ return createHash("sha256").update(canonicalJson(value)).digest("hex");
7
+ }
8
+ export function canonicalJson(value) {
9
+ return JSON.stringify(canonicalize(value));
10
+ }
11
+ export function fileSha256(path) {
12
+ return createHash("sha256").update(readFileSync(path)).digest("hex");
13
+ }
14
+ export function writeImmutableJson(path, value) {
15
+ const body = `${JSON.stringify(value, null, 2)}\n`;
16
+ if (Buffer.byteLength(body) > JSON_LIMIT) {
17
+ throw new Error(`immutable record exceeds ${JSON_LIMIT} bytes`);
18
+ }
19
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
20
+ const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
21
+ let fd;
22
+ try {
23
+ fd = openSync(temporary, "wx", 0o600);
24
+ writeFileSync(fd, body, "utf8");
25
+ fsyncSync(fd);
26
+ closeSync(fd);
27
+ fd = undefined;
28
+ try {
29
+ linkSync(temporary, path);
30
+ chmodSync(path, 0o600);
31
+ fsyncParentDirectory(path);
32
+ return true;
33
+ }
34
+ catch (error) {
35
+ if (error.code !== "EEXIST")
36
+ throw error;
37
+ const existing = readFileSync(path, "utf8");
38
+ if (existing !== body)
39
+ throw new Error(`immutable record already exists at ${path}`);
40
+ return false;
41
+ }
42
+ }
43
+ finally {
44
+ if (fd !== undefined)
45
+ closeSync(fd);
46
+ if (existsSync(temporary))
47
+ unlinkSync(temporary);
48
+ }
49
+ }
50
+ export function fsyncParentDirectory(path) {
51
+ const directory = dirname(path);
52
+ const fd = openSync(directory, "r");
53
+ try {
54
+ fsyncSync(fd);
55
+ }
56
+ finally {
57
+ closeSync(fd);
58
+ }
59
+ }
60
+ export function readJsonRecord(path, label) {
61
+ if (!existsSync(path))
62
+ throw new Error(`${label} does not exist at ${path}`);
63
+ const size = statSync(path).size;
64
+ if (size <= 0 || size > JSON_LIMIT)
65
+ throw new Error(`${label} has invalid size ${size}`);
66
+ try {
67
+ return JSON.parse(readFileSync(path, "utf8"));
68
+ }
69
+ catch (error) {
70
+ throw new Error(`cannot parse ${label} at ${path}: ${error.message}`);
71
+ }
72
+ }
73
+ function canonicalize(value) {
74
+ if (Array.isArray(value))
75
+ return value.map(canonicalize);
76
+ if (value && typeof value === "object") {
77
+ return Object.fromEntries(Object.entries(value)
78
+ .filter(([, item]) => item !== undefined)
79
+ .sort(([a], [b]) => a.localeCompare(b))
80
+ .map(([key, item]) => [key, canonicalize(item)]));
81
+ }
82
+ return value;
83
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAsCH,OAAO,KAAK,EAEV,UAAU,EAEV,SAAS,EAUV,MAAM,YAAY,CAAC;AAapB,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,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAOpF;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CA6E1F"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAuCH,OAAO,KAAK,EAEV,UAAU,EAEV,SAAS,EAUV,MAAM,YAAY,CAAC;AAyBpB,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,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAOpF;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CA6E1F"}
@@ -33,12 +33,16 @@ import { evaluatePolicy, normalizePolicy, PolicyDeniedError, policyDigest, summa
33
33
  import { assertWorkflowRunId, createWorkflowApproval } from "./approvals.js";
34
34
  import { freezeWorkflowAttemptContext } from "./attempt-context.js";
35
35
  import { probeBilling } from "./billing.js";
36
+ import { stableDigest } from "./durable-record.js";
36
37
  import { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, writeWorkflowProof, } from "./proof.js";
37
38
  import { acquireWorkflowResumeLease, assertWorkflowRunResumable, assertWorkflowScriptUnchanged, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
38
39
  import { normalizeWorkflowSpecialists, resolveSpecialistAssignment } from "./specialists.js";
39
40
  import { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.js";
40
41
  import { parseStageOutput, validateAgainstSchema } from "./validate.js";
41
42
  import { freezeWorkflowWorkContext } from "./work-context.js";
43
+ import { attestTerminal, attestWorkspaceFailure, resolveWorkspaceBinding, } from "./workspaces/execution.js";
44
+ import { appendWorkflowJournalEvent } from "./workspaces/state.js";
45
+ import { isWorkspaceAttestation } from "./workspaces/validate.js";
42
46
  const DEFAULT_MAX_AGENTS = 50;
43
47
  const DEFAULT_CONCURRENCY = 4;
44
48
  const DEFAULT_MAX_ATTEMPTS = 2;
@@ -136,13 +140,19 @@ export async function runWorkflow(scriptPath, opts) {
136
140
  }
137
141
  }
138
142
  async function executeWorkflow(scriptPath, absScript, opts, resumeState, workContext, attemptContext) {
139
- const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(absScript).href)));
140
- if (typeof mod.default !== "function") {
141
- throw new Error(`${scriptPath}: workflow script must \`export default async (ctx) => …\``);
143
+ const frozen = resumeState?.manifest.execution;
144
+ const isolation = frozen?.isolation ?? opts.isolation ?? "shared";
145
+ let sharedWorkflow;
146
+ let sharedMeta;
147
+ if (isolation === "shared") {
148
+ const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(absScript).href)));
149
+ if (typeof mod.default !== "function") {
150
+ throw new Error(`${scriptPath}: workflow script must \`export default async (ctx) => …\``);
151
+ }
152
+ const fallbackName = scriptPath.replace(/^.*\//, "").replace(/\.[cm]?js$/, "");
153
+ sharedWorkflow = mod.default;
154
+ sharedMeta = normalizeWorkflowMeta(mod.meta, fallbackName);
142
155
  }
143
- const fallbackName = scriptPath.replace(/^.*\//, "").replace(/\.[cm]?js$/, "");
144
- const meta = normalizeWorkflowMeta(mod.meta, fallbackName);
145
- const name = meta.name;
146
156
  const runId = opts.resumeRunId ??
147
157
  opts.runId ??
148
158
  `wf-${new Date().toISOString().replace(/[:.]/g, "-")}-${randomBytes(3).toString("hex")}`;
@@ -150,7 +160,6 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
150
160
  mkdirSync(runDir, { recursive: true });
151
161
  const journalPath = join(runDir, "journal.jsonl");
152
162
  const proofPath = join(runDir, "proof.json");
153
- const frozen = resumeState?.manifest.execution;
154
163
  const maxAgents = frozen?.max_agents ?? opts.maxAgents ?? DEFAULT_MAX_AGENTS;
155
164
  const concurrency = frozen?.concurrency ?? opts.concurrency ?? DEFAULT_CONCURRENCY;
156
165
  assertPositiveWorkflowBound(maxAgents, "maxAgents");
@@ -159,16 +168,105 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
159
168
  const log = opts.onLog ?? ((line) => process.stderr.write(`${line}\n`));
160
169
  const defaultHarness = frozen?.default_harness ?? opts.defaultHarness ?? "claude-code";
161
170
  const specialists = frozen?.specialists ?? (resumeState ? {} : normalizeWorkflowSpecialists(opts.specialists));
162
- const isolation = frozen?.isolation ?? opts.isolation ?? "shared";
163
171
  const networkAccess = frozen?.network_access ?? opts.networkAccess ?? "unknown";
164
172
  const policy = frozen?.policy ?? (opts.policy ? normalizePolicy(opts.policy, { baseDir: cwd }) : undefined);
165
173
  const approvalMode = frozen?.approval_mode ?? opts.approvalMode ?? "deny";
166
174
  const approvalAddressee = frozen?.approval_addressee ?? opts.approvalAddressee ?? "operator";
167
175
  const subscriptionOnly = frozen?.subscription_only ?? Boolean(opts.subscriptionOnly);
168
176
  const allowApiBilling = frozen?.allow_api_billing ?? Boolean(opts.allowApiBilling);
169
- const repoBefore = resumeState?.manifest.repository_before ?? snapshotRepo(cwd);
170
177
  const startedAt = resumeState?.manifest.started_at ?? new Date().toISOString();
171
178
  const t0 = resumeState ? Date.parse(startedAt) : Date.now();
179
+ const scriptSha256 = resumeState?.manifest.script.sha256 ?? workflowScriptDigest(absScript);
180
+ const fallbackName = scriptPath.replace(/^.*\//, "").replace(/\.[cm]?js$/, "");
181
+ const fallbackMeta = normalizeWorkflowMeta(undefined, fallbackName);
182
+ const workspaceProvider = isolation === "shared" ? undefined : opts.workspace?.provider;
183
+ let workspaceBinding;
184
+ let workspaceFallback = resumeState?.manifest.execution.workspace_fallback;
185
+ try {
186
+ workspaceBinding = await resolveWorkspaceBinding({
187
+ opts,
188
+ resumeState,
189
+ runId,
190
+ cwd,
191
+ isolation,
192
+ absScript,
193
+ scriptSha256,
194
+ provider: workspaceProvider,
195
+ workContext,
196
+ attemptContext,
197
+ policy,
198
+ onUnsupportedFallback: (evidence) => {
199
+ workspaceFallback = evidence;
200
+ },
201
+ });
202
+ }
203
+ catch (error) {
204
+ const frozenBinding = resumeState?.manifest.execution.workspace_binding;
205
+ if (!resumeState || !frozenBinding)
206
+ throw error;
207
+ const failure = error instanceof Error ? error : new Error(String(error));
208
+ const endedAt = new Date().toISOString();
209
+ const durationMs = Date.now() - t0;
210
+ const failedAttestation = await attestWorkspaceFailure(workspaceProvider, frozenBinding, error);
211
+ appendWorkflowJournalEvent(opts.coordRoot, runId, "run.resume", {
212
+ approval_id: resumeState.approvalId,
213
+ script: absScript,
214
+ resumed_at: new Date().toISOString(),
215
+ });
216
+ appendWorkflowJournalEvent(opts.coordRoot, runId, "workspace.reattach.failed", {
217
+ binding_id: frozenBinding.binding_id,
218
+ provider_id: frozenBinding.provider.id,
219
+ status: failedAttestation.status,
220
+ reason: failure.message,
221
+ attestation_sha256: stableDigest(failedAttestation),
222
+ });
223
+ appendWorkflowJournalEvent(opts.coordRoot, runId, "run.end", {
224
+ ok: false,
225
+ error: failure.message,
226
+ agents: 0,
227
+ cached: 0,
228
+ cost_usd: 0,
229
+ duration_ms: durationMs,
230
+ });
231
+ try {
232
+ const proof = buildWorkflowProof({
233
+ runId,
234
+ workItemId: opts.workItemId ?? resumeState.manifest.work_item_id,
235
+ workContext,
236
+ attemptContext,
237
+ meta: fallbackMeta,
238
+ status: "failed",
239
+ startedAt,
240
+ endedAt,
241
+ durationMs,
242
+ journalPath,
243
+ before: resumeState.manifest.repository_before,
244
+ after: resumeState.manifest.repository_before,
245
+ agents: [],
246
+ evidence: [],
247
+ harnessEvidence: opts.harnessEvidence,
248
+ policy: policy
249
+ ? {
250
+ config: policy,
251
+ decisions: [],
252
+ isolation,
253
+ networkAccess,
254
+ }
255
+ : undefined,
256
+ workspaceBinding: frozenBinding,
257
+ workspaceAttestation: failedAttestation,
258
+ error: failure.message,
259
+ });
260
+ writeWorkflowProof(proofPath, proof);
261
+ }
262
+ catch (proofError) {
263
+ throw new WorkflowRunError(`${failure.message}; recovery proof packet write also failed: ${proofError.message}`, runId, proofPath, failure);
264
+ }
265
+ throw new WorkflowRunError(failure.message, runId, proofPath, failure);
266
+ }
267
+ const effectiveIsolation = workspaceFallback?.effective_isolation ?? isolation;
268
+ const executionCwd = workspaceBinding?.active_root ?? cwd;
269
+ const executionRepoBefore = resumeState?.manifest.repository_before ?? snapshotRepo(executionCwd);
172
270
  if (!resumeState) {
173
271
  writeWorkflowRunManifest({
174
272
  coordRoot: opts.coordRoot,
@@ -178,12 +276,12 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
178
276
  work_item_id: opts.workItemId,
179
277
  work_context: workContext,
180
278
  attempt_context: attemptContext,
181
- name,
279
+ name: sharedMeta?.name ?? fallbackMeta.name,
182
280
  started_at: startedAt,
183
- script: { path: absScript, sha256: workflowScriptDigest(absScript) },
184
- repository_before: repoBefore,
281
+ script: { path: absScript, sha256: scriptSha256 },
282
+ repository_before: executionRepoBefore,
185
283
  execution: {
186
- cwd,
284
+ cwd: executionCwd,
187
285
  default_harness: defaultHarness,
188
286
  max_agents: maxAgents,
189
287
  concurrency,
@@ -195,17 +293,70 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
195
293
  network_access: networkAccess,
196
294
  policy: policy ? policy : undefined,
197
295
  specialists,
296
+ workspace_binding: workspaceBinding,
297
+ workspace_fallback: workspaceFallback,
198
298
  },
199
299
  },
200
300
  });
201
301
  }
302
+ let workflow = sharedWorkflow;
303
+ let meta = sharedMeta ?? fallbackMeta;
304
+ let initializationError;
305
+ let initializationAttestation;
306
+ if (isolation !== "shared") {
307
+ try {
308
+ const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(absScript).href)));
309
+ if (typeof mod.default !== "function") {
310
+ throw new Error(`${scriptPath}: workflow script must \`export default async (ctx) => …\``);
311
+ }
312
+ workflow = mod.default;
313
+ meta = normalizeWorkflowMeta(mod.meta, fallbackName);
314
+ }
315
+ catch (error) {
316
+ initializationError = error instanceof Error ? error : new Error(String(error));
317
+ }
318
+ }
319
+ if (workspaceBinding && workspaceProvider) {
320
+ try {
321
+ const postImport = await workspaceProvider.reattach(workspaceBinding);
322
+ if (!isWorkspaceAttestation(postImport, workspaceBinding) || postImport.status !== "ok") {
323
+ initializationAttestation = isWorkspaceAttestation(postImport, workspaceBinding)
324
+ ? postImport
325
+ : undefined;
326
+ throw new Error("workspace authority changed during workflow module initialization");
327
+ }
328
+ appendWorkflowJournalEvent(opts.coordRoot, runId, "workspace.reattach.module_initialized", {
329
+ binding_id: workspaceBinding.binding_id,
330
+ provider_id: workspaceBinding.provider.id,
331
+ attestation_sha256: stableDigest(postImport),
332
+ });
333
+ }
334
+ catch (error) {
335
+ const reattachmentError = error instanceof Error ? error : new Error(String(error));
336
+ initializationAttestation ??= await attestWorkspaceFailure(workspaceProvider, workspaceBinding, error);
337
+ initializationError = initializationError
338
+ ? new Error(`${initializationError.message}; ${reattachmentError.message}`, {
339
+ cause: reattachmentError,
340
+ })
341
+ : reattachmentError;
342
+ appendWorkflowJournalEvent(opts.coordRoot, runId, "workspace.reattach.module_initialization_failed", {
343
+ binding_id: workspaceBinding.binding_id,
344
+ provider_id: workspaceBinding.provider.id,
345
+ status: initializationAttestation.status,
346
+ reason: reattachmentError.message,
347
+ attestation_sha256: stableDigest(initializationAttestation),
348
+ });
349
+ }
350
+ }
351
+ const name = meta.name;
352
+ let observedWorkspaceAttestation = initializationAttestation;
202
353
  // Per-child fixed context overhead: children spawn in `cwd` and load its
203
354
  // repo-instructions file into their system prompt, cache-writing it once
204
355
  // per child. A fan-out multiplies this, so surface it BEFORE the burn.
205
- const contextTokensPerChildEstimate = estimateInstructionTokens(cwd);
356
+ const contextTokensPerChildEstimate = estimateInstructionTokens(executionCwd);
206
357
  if (contextTokensPerChildEstimate > 0) {
207
358
  log(`[context] each child cache-writes ~${Math.round(contextTokensPerChildEstimate / 1000)}K tokens of repo ` +
208
- `instructions from ${cwd}; a fan-out multiplies this per agent`);
359
+ `instructions from ${executionCwd}; a fan-out multiplies this per agent`);
209
360
  }
210
361
  // Resume: journaled results of a prior run, keyed by agent-call identity.
211
362
  const resumeSource = opts.resumeRunId ?? opts.resumeFrom;
@@ -434,7 +585,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
434
585
  const estimateRequest = summarizePolicyRequest({
435
586
  phase: "dispatch",
436
587
  action: "spawn agent",
437
- path: cwd,
588
+ path: executionCwd,
438
589
  harness,
439
590
  model: agentOpts.model,
440
591
  effort: agentOpts.effort,
@@ -442,7 +593,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
442
593
  max_turns: agentOpts.maxTurns ?? DEFAULT_MAX_TURNS,
443
594
  timeout_ms: agentOpts.timeoutMs ?? DEFAULT_TIMEOUT_MS,
444
595
  prompt_bytes: Buffer.byteLength(dispatchPrompt),
445
- isolation,
596
+ isolation: effectiveIsolation,
446
597
  network_access: networkAccess,
447
598
  current_cost_usd: round4(costUsd + reservedCostUsd),
448
599
  projected_cost_usd: null,
@@ -571,7 +722,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
571
722
  effort: agentOpts.effort,
572
723
  timeoutMs: agentOpts.timeoutMs ?? DEFAULT_TIMEOUT_MS,
573
724
  maxTurns: agentOpts.maxTurns ?? DEFAULT_MAX_TURNS,
574
- cwd,
725
+ cwd: executionCwd,
575
726
  runId,
576
727
  subscriptionOnly,
577
728
  });
@@ -689,8 +840,8 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
689
840
  return authorizePolicyRequest({
690
841
  phase: "external_mutation",
691
842
  action: input.action,
692
- path: input.path ? resolve(cwd, input.path) : undefined,
693
- isolation,
843
+ path: input.path ? resolve(executionCwd, input.path) : undefined,
844
+ isolation: effectiveIsolation,
694
845
  network_access: network,
695
846
  service: input.service,
696
847
  target: input.target,
@@ -728,13 +879,27 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
728
879
  concurrency,
729
880
  specialists: Object.keys(specialists),
730
881
  policy: policy ? { name: policy.name, sha256: policyDigest(policy) } : null,
731
- isolation,
882
+ isolation: effectiveIsolation,
732
883
  network_access: networkAccess,
884
+ workspace_binding: workspaceBinding
885
+ ? { binding_id: workspaceBinding.binding_id, provider_id: workspaceBinding.provider.id }
886
+ : null,
733
887
  });
734
888
  }
735
- const result = await mod.default(ctx);
889
+ if (initializationError)
890
+ throw initializationError;
891
+ if (!workflow)
892
+ throw new Error("workflow module initialization did not produce an executable");
893
+ const result = await workflow(ctx);
736
894
  const endedAt = new Date().toISOString();
737
895
  const durationMs = Date.now() - t0;
896
+ const workspaceAttestation = workspaceBinding
897
+ ? await attestTerminal(workspaceProvider, workspaceBinding)
898
+ : undefined;
899
+ observedWorkspaceAttestation = workspaceAttestation;
900
+ if (workspaceAttestation && workspaceAttestation.status !== "ok") {
901
+ throw new Error(`terminal workspace attestation ${workspaceAttestation.status}: ${workspaceAttestation.provider_drift.join("; ") || "provider could not prove the workspace"}`);
902
+ }
738
903
  journal("run.end", {
739
904
  ok: true,
740
905
  agents: agentsSpawned,
@@ -755,8 +920,8 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
755
920
  endedAt,
756
921
  durationMs,
757
922
  journalPath,
758
- before: repoBefore,
759
- after: snapshotRepo(cwd),
923
+ before: executionRepoBefore,
924
+ after: snapshotRepo(executionCwd),
760
925
  agents: Array.from(agentProofs.values()),
761
926
  evidence: evidenceRecords,
762
927
  harnessEvidence: opts.harnessEvidence,
@@ -764,10 +929,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
764
929
  ? {
765
930
  config: policy,
766
931
  decisions: Array.from(policyDecisions.values()),
767
- isolation,
932
+ isolation: effectiveIsolation,
768
933
  networkAccess,
769
934
  }
770
935
  : undefined,
936
+ workspaceBinding,
937
+ workspaceAttestation,
938
+ workspaceFallback,
771
939
  result,
772
940
  });
773
941
  writeWorkflowProof(proofPath, proof);
@@ -793,11 +961,15 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
793
961
  mode: subscriptionOnly ? "subscription" : p.mode,
794
962
  })),
795
963
  policy: proof.policy?.summary,
964
+ workspaceBinding,
796
965
  };
797
966
  return report;
798
967
  }
799
968
  catch (err) {
800
- if (err instanceof WorkflowParkedError || err instanceof WorkflowRunError)
969
+ if (err instanceof WorkflowParkedError) {
970
+ throw err;
971
+ }
972
+ if (err instanceof WorkflowRunError)
801
973
  throw err;
802
974
  const endedAt = new Date().toISOString();
803
975
  const durationMs = Date.now() - t0;
@@ -810,6 +982,10 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
810
982
  duration_ms: durationMs,
811
983
  });
812
984
  try {
985
+ const workspaceAttestation = workspaceBinding
986
+ ? (observedWorkspaceAttestation ??
987
+ (await attestTerminal(workspaceProvider, workspaceBinding)))
988
+ : undefined;
813
989
  const proof = buildWorkflowProof({
814
990
  runId,
815
991
  workItemId: opts.workItemId ?? resumeState?.manifest.work_item_id,
@@ -821,8 +997,8 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
821
997
  endedAt,
822
998
  durationMs,
823
999
  journalPath,
824
- before: repoBefore,
825
- after: snapshotRepo(cwd),
1000
+ before: executionRepoBefore,
1001
+ after: snapshotRepo(executionCwd),
826
1002
  agents: Array.from(agentProofs.values()),
827
1003
  evidence: evidenceRecords,
828
1004
  harnessEvidence: opts.harnessEvidence,
@@ -830,10 +1006,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
830
1006
  ? {
831
1007
  config: policy,
832
1008
  decisions: Array.from(policyDecisions.values()),
833
- isolation,
1009
+ isolation: effectiveIsolation,
834
1010
  networkAccess,
835
1011
  }
836
1012
  : undefined,
1013
+ workspaceBinding,
1014
+ workspaceAttestation,
1015
+ workspaceFallback,
837
1016
  error: err.message,
838
1017
  });
839
1018
  writeWorkflowProof(proofPath, proof);
@@ -7,4 +7,6 @@ export type { WorkflowRunManifest } from "./run-state.js";
7
7
  export { acquireWorkflowResumeLease, assertWorkflowRunResumable, assertWorkflowScriptUnchanged, readWorkflowRunManifest, WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION, workflowRunManifestPath, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
8
8
  export type { AcceptanceCriterion, AcceptanceResult, AcceptanceStatus, AcceptanceSummary, AgentOpts, EngineOpts, EvidenceKind, EvidenceSource, EvidenceStatus, HarnessEvidenceCapability, HarnessEvidenceCoverage, HarnessName, ResultDigest, RunReport, Spawner, SpawnRequest, SpawnResult, StageSchema, WorkflowAgentProof, WorkflowApprovalMode, WorkflowAttemptContext, WorkflowAttemptFailureCause, WorkflowAttemptPriorContext, WorkflowAttemptUnresolvedCriterion, WorkflowContext, WorkflowEvidenceInput, WorkflowEvidenceRecord, WorkflowMeta, WorkflowModule, WorkflowPolicyProof, WorkflowProof, WorkflowProofUnknown, WorkflowRepoEvidence, WorkflowRepoSnapshot, WorkflowRunStatus, WorkflowSpecialistProfile, WorkflowWorkContext, } from "./types.js";
9
9
  export { WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION, WORKFLOW_PROOF_SCHEMA_VERSION, WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION, } from "./types.js";
10
+ export type { ApplyIntegrationInput, AuthorizedIntegrationPlan, AuthorizedProviderIntegrationInput, CancelWorkspaceInput, CleanupWorkspaceInput, FilesystemIdentity, IntegrationApplyAttempt, IntegrationApplyReceipt, IntegrationAuthorization, IntegrationPlan, IntegrationReviewRecord, IntegrationTarget, LocalGitWorktreeProviderOptions, PrepareIntegrationInput, ProviderIntegrationInput, ProviderIntegrationPreview, ProviderIntegrationResult, ProviderUnknown, ProviderUnsupportedReason, RepositoryBinding, ValidatedFilesystemPath, WorkflowWorkspaceInspection, WorkflowWorkspaceSelection, WorkflowWorkspaceStatus, WorkflowWorkspaceVerification, WorkspaceAllocationRequest, WorkspaceAttestation, WorkspaceBinding, WorkspaceBoundExecutionEvidence, WorkspaceCancellationReceipt, WorkspaceCancellationResult, WorkspaceCleanupAttempt, WorkspaceCleanupIntent, WorkspaceCleanupMode, WorkspaceCleanupReceipt, WorkspaceCleanupResult, WorkspaceCompatibilityExecutionEvidence, WorkspaceExecutionEvidence, WorkspaceIntegrationState, WorkspaceIsolation, WorkspaceLifecycleProjection, WorkspaceLifecycleProjectionInput, WorkspaceLifecycleState, WorkspaceObservation, WorkspaceOwner, WorkspaceProbeInput, WorkspaceProbeResult, WorkspaceProofOutcome, WorkspaceProvider, WorkspaceProviderCapabilities, WorkspaceProviderRef, WorkspaceResourceState, WorkspaceUnsupportedExecutionEvidence, } from "./workspaces/index.js";
11
+ export { applyIntegration, assertWorkspaceLifecycleTransition, cancelWorkspace, cleanupWorkspace, createLocalGitWorktreeProvider, deriveWorkspaceLifecycle, IntegrationPrepareParkedError, inspectWorkflowWorkspace, isWorkspaceLifecycleState, listWorkflowWorkspaceInspections, prepareIntegration, probeLocalGitWorktreeProvider, readWorkflowWorkspaceStatus, renderWorkflowWorkspaceStatus, validateProviderEventChain, WORKSPACE_BINDING_SCHEMA_VERSION, WORKSPACE_RECEIPT_SCHEMA_VERSION, } from "./workspaces/index.js";
10
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
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,EACL,4BAA4B,EAC5B,iCAAiC,EACjC,+BAA+B,GAChC,MAAM,sBAAsB,CAAC;AAC9B,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,sBAAsB,EACtB,2BAA2B,EAC3B,2BAA2B,EAC3B,kCAAkC,EAClC,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,uCAAuC,EACvC,6BAA6B,EAC7B,oCAAoC,GACrC,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/index.ts"],"names":[],"mappings":"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"}
@@ -4,3 +4,4 @@ export { runWorkflow, WorkflowParkedError, WorkflowRunError } from "./engine.js"
4
4
  export { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, readWorkflowProof, renderWorkflowProof, rollupAcceptance, writeWorkflowProof, } from "./proof.js";
5
5
  export { acquireWorkflowResumeLease, assertWorkflowRunResumable, assertWorkflowScriptUnchanged, readWorkflowRunManifest, WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION, workflowRunManifestPath, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
6
6
  export { WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION, WORKFLOW_PROOF_SCHEMA_VERSION, WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION, } from "./types.js";
7
+ export { applyIntegration, assertWorkspaceLifecycleTransition, cancelWorkspace, cleanupWorkspace, createLocalGitWorktreeProvider, deriveWorkspaceLifecycle, IntegrationPrepareParkedError, inspectWorkflowWorkspace, isWorkspaceLifecycleState, listWorkflowWorkspaceInspections, prepareIntegration, probeLocalGitWorktreeProvider, readWorkflowWorkspaceStatus, renderWorkflowWorkspaceStatus, validateProviderEventChain, WORKSPACE_BINDING_SCHEMA_VERSION, WORKSPACE_RECEIPT_SCHEMA_VERSION, } from "./workspaces/index.js";
@@ -1,6 +1,7 @@
1
1
  import type { RepoSnapshot } from "../context/index.js";
2
2
  import type { NormalizedPolicy, PolicyDecision, PolicyIsolation, PolicyNetworkAccess } from "../policy/index.js";
3
3
  import type { AcceptanceCriterion, AcceptanceResult, AcceptanceSummary, HarnessEvidenceCapability, ResultDigest, WorkflowAgentProof, WorkflowAttemptContext, WorkflowEvidenceInput, WorkflowEvidenceRecord, WorkflowMeta, WorkflowProof, WorkflowWorkContext } from "./types.js";
4
+ import type { WorkspaceAttestation, WorkspaceBinding, WorkspaceUnsupportedExecutionEvidence } from "./workspaces/index.js";
4
5
  export interface NormalizedWorkflowMeta {
5
6
  name: string;
6
7
  description?: string;
@@ -29,6 +30,9 @@ export interface BuildWorkflowProofInput {
29
30
  isolation: PolicyIsolation;
30
31
  networkAccess: PolicyNetworkAccess;
31
32
  };
33
+ workspaceBinding?: WorkspaceBinding;
34
+ workspaceAttestation?: WorkspaceAttestation;
35
+ workspaceFallback?: WorkspaceUnsupportedExecutionEvidence;
32
36
  result?: unknown;
33
37
  error?: string;
34
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/proof.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/proof.ts"],"names":[],"mappings":"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"}