cool-workflow 0.1.79 → 0.1.81

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 (131) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +51 -3
  4. package/apps/architecture-review/app.json +1 -1
  5. package/apps/architecture-review-fast/app.json +64 -0
  6. package/apps/architecture-review-fast/workflow.js +153 -0
  7. package/apps/end-to-end-golden-path/app.json +1 -1
  8. package/apps/pr-review-fix-ci/app.json +1 -1
  9. package/apps/release-cut/app.json +1 -1
  10. package/apps/research-synthesis/app.json +1 -1
  11. package/dist/agent-config.js +21 -7
  12. package/dist/candidate-scoring.js +42 -22
  13. package/dist/capability-core.js +132 -17
  14. package/dist/capability-registry.js +138 -168
  15. package/dist/cli.js +97 -98
  16. package/dist/collaboration.js +5 -6
  17. package/dist/commit.js +20 -6
  18. package/dist/compare.js +18 -0
  19. package/dist/coordinator/classify.js +45 -0
  20. package/dist/coordinator/paths.js +42 -0
  21. package/dist/coordinator/util.js +129 -0
  22. package/dist/coordinator.js +127 -300
  23. package/dist/dispatch.js +35 -0
  24. package/dist/drive.js +79 -6
  25. package/dist/error-feedback.js +8 -4
  26. package/dist/evidence-reasoning.js +3 -3
  27. package/dist/execution-backend/agent.js +331 -0
  28. package/dist/execution-backend/probes.js +96 -0
  29. package/dist/execution-backend/util.js +47 -0
  30. package/dist/execution-backend.js +73 -421
  31. package/dist/mcp-server.js +79 -183
  32. package/dist/multi-agent/graph.js +84 -0
  33. package/dist/multi-agent/helpers.js +145 -0
  34. package/dist/multi-agent/paths.js +22 -0
  35. package/dist/multi-agent-eval/format.js +194 -0
  36. package/dist/multi-agent-eval/normalize.js +51 -0
  37. package/dist/multi-agent-eval.js +39 -244
  38. package/dist/multi-agent-host.js +0 -19
  39. package/dist/multi-agent.js +125 -314
  40. package/dist/node-snapshot.js +3 -3
  41. package/dist/observability/format.js +61 -0
  42. package/dist/observability/intake.js +98 -0
  43. package/dist/observability.js +14 -160
  44. package/dist/operator-ux/format.js +364 -0
  45. package/dist/operator-ux.js +22 -363
  46. package/dist/orchestrator/lifecycle-operations.js +2 -1
  47. package/dist/orchestrator/report.js +8 -0
  48. package/dist/orchestrator.js +26 -9
  49. package/dist/reclamation.js +26 -21
  50. package/dist/run-export.js +494 -25
  51. package/dist/run-registry/derive.js +172 -0
  52. package/dist/run-registry/format.js +124 -0
  53. package/dist/run-registry/gc.js +251 -0
  54. package/dist/run-registry/policy.js +16 -0
  55. package/dist/run-registry/queue.js +116 -0
  56. package/dist/run-registry.js +89 -597
  57. package/dist/run-state-schema.js +1 -0
  58. package/dist/sandbox-profile.js +43 -2
  59. package/dist/state-explosion/format.js +159 -0
  60. package/dist/state-explosion/helpers.js +82 -0
  61. package/dist/state-explosion.js +165 -304
  62. package/dist/state-node.js +19 -4
  63. package/dist/telemetry-attestation.js +55 -0
  64. package/dist/telemetry-demo.js +15 -3
  65. package/dist/telemetry-ledger.js +60 -15
  66. package/dist/topology.js +25 -8
  67. package/dist/triggers.js +33 -14
  68. package/dist/trust-audit.js +145 -33
  69. package/dist/version.js +1 -1
  70. package/dist/worker-isolation/helpers.js +51 -0
  71. package/dist/worker-isolation/paths.js +46 -0
  72. package/dist/worker-isolation.js +39 -115
  73. package/docs/agent-delegation-drive.7.md +71 -0
  74. package/docs/canonical-workflow-apps.7.md +37 -0
  75. package/docs/cli-mcp-parity.7.md +16 -0
  76. package/docs/contract-migration-tooling.7.md +6 -0
  77. package/docs/control-plane-scheduling.7.md +6 -0
  78. package/docs/dogfood/resume-drive-real-agent-2026-06-14.md +40 -0
  79. package/docs/durable-state-and-locking.7.md +8 -0
  80. package/docs/evidence-adoption-reasoning-chain.7.md +6 -0
  81. package/docs/execution-backends.7.md +6 -0
  82. package/docs/index.md +2 -0
  83. package/docs/launch/demo.tape +28 -0
  84. package/docs/launch/launch-kit.md +96 -17
  85. package/docs/launch/pre-launch-checklist.md +53 -0
  86. package/docs/multi-agent-cli-mcp-surface.7.md +8 -0
  87. package/docs/multi-agent-eval-replay-harness.7.md +6 -0
  88. package/docs/multi-agent-operator-ux.7.md +6 -0
  89. package/docs/multi-agent-trust-policy-audit.7.md +27 -0
  90. package/docs/node-snapshot-diff-replay.7.md +6 -0
  91. package/docs/observability-cost-accounting.7.md +6 -0
  92. package/docs/project-index.md +27 -6
  93. package/docs/real-execution-backends.7.md +6 -0
  94. package/docs/release-and-migration.7.md +8 -0
  95. package/docs/release-tooling.7.md +6 -0
  96. package/docs/routines.md +23 -0
  97. package/docs/run-registry-control-plane.7.md +89 -2
  98. package/docs/run-retention-reclamation.7.md +8 -0
  99. package/docs/source-context-profiles.7.md +119 -0
  100. package/docs/state-explosion-management.7.md +13 -0
  101. package/docs/team-collaboration.7.md +6 -0
  102. package/docs/trust-model.md +267 -0
  103. package/docs/unix-principles.md +49 -1
  104. package/docs/vendor-manifest-loadability.7.md +43 -0
  105. package/docs/web-desktop-workbench.7.md +6 -0
  106. package/manifest/plugin.manifest.json +1 -1
  107. package/manifest/source-context-profiles.json +142 -0
  108. package/package.json +4 -1
  109. package/scripts/agents/builtin-templates.json +7 -0
  110. package/scripts/agents/claude-p-agent.js +129 -43
  111. package/scripts/architecture-review-fast.js +362 -0
  112. package/scripts/bump-version.js +5 -10
  113. package/scripts/canonical-apps-list.js +64 -0
  114. package/scripts/canonical-apps.js +36 -4
  115. package/scripts/coverage-gate.js +211 -0
  116. package/scripts/dogfood-release.js +1 -1
  117. package/scripts/golden-path.js +4 -4
  118. package/scripts/parity-check.js +5 -0
  119. package/scripts/release-check.js +5 -1
  120. package/scripts/source-context.js +291 -0
  121. package/scripts/version-sync-check.js +5 -7
  122. package/skills/ci-triage/SKILL.md +50 -0
  123. package/skills/ci-triage/agents/openai.yaml +4 -0
  124. package/skills/cool-workflow/SKILL.md +4 -1
  125. package/skills/deploy-check/SKILL.md +55 -0
  126. package/skills/deploy-check/agents/openai.yaml +4 -0
  127. package/skills/design-qa/SKILL.md +49 -0
  128. package/skills/design-qa/agents/openai.yaml +4 -0
  129. package/skills/pr-review/SKILL.md +45 -0
  130. package/skills/pr-review/agents/openai.yaml +4 -0
  131. package/dist/capability-dispatcher.js +0 -86
@@ -4,6 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TRUST_AUDIT_SCHEMA_VERSION = void 0;
7
+ exports.trustAuditGenesis = trustAuditGenesis;
8
+ exports.verifyTrustAudit = verifyTrustAudit;
7
9
  exports.ensureTrustAudit = ensureTrustAudit;
8
10
  exports.recordTrustAuditEvent = recordTrustAuditEvent;
9
11
  exports.recordSandboxPathDecision = recordSandboxPathDecision;
@@ -22,17 +24,139 @@ const node_fs_1 = __importDefault(require("node:fs"));
22
24
  const node_path_1 = __importDefault(require("node:path"));
23
25
  const state_1 = require("./state");
24
26
  const evidence_grounding_1 = require("./evidence-grounding");
27
+ const execution_backend_1 = require("./execution-backend");
28
+ const telemetry_attestation_1 = require("./telemetry-attestation");
25
29
  exports.TRUST_AUDIT_SCHEMA_VERSION = 1;
30
+ // ---- Tamper-evidence chain (v0.1.81) --------------------------------------
31
+ // Same discipline as telemetry-ledger.ts / reclamation.ts: the event log is
32
+ // hash-chained in APPEND order, and verifyTrustAudit recomputes every hash
33
+ // independently (never trusts a stored value), so an edited or removed event is
34
+ // detected. Durability (fsync) only guards against power loss; this guards
35
+ // against post-hoc edits — the threat an external auditor actually cares about.
36
+ //
37
+ // THREAT MODEL (be honest about the limit): the genesis is sha256(runId), so this
38
+ // detects casual/partial tampering, accidental corruption, truncation, removal,
39
+ // and forged-unchained lines — but NOT a determined local writer who re-chains the
40
+ // WHOLE log with this module's own sha256 after an edit. That is the same limit
41
+ // reclamation.ts's tombstone chain has, and it is INHERENT to a local, self-
42
+ // recomputable chain: closing it needs an anchor the writer cannot reproduce.
43
+ // CW cannot self-sign that anchor — by design CW holds NO private key (see
44
+ // telemetry-attestation.ts: "CW never holds the private key"; the AGENT signs its
45
+ // usage, CW only VERIFIES with the operator-provisioned public half). The single
46
+ // cryptographic anchor that exists is therefore the agent's telemetry signature,
47
+ // which binds agent-reported USAGE (worker-isolation cross-links the chain into it)
48
+ // — it does NOT cover CW-only sandbox/policy/commit-gate decisions, which have no
49
+ // external signer. For those, the only stronger guarantee is operational: commit
50
+ // events.jsonl to an external append-only medium (git history / a remote log) the
51
+ // local writer cannot rewrite. The chain is a strict upgrade over a bare append-
52
+ // only log, not a substitute for an external anchor — and that anchor is not
53
+ // something CW can mint for itself.
54
+ /** Single source of truth for a run's audit-paths object: the schemaVersion plus
55
+ * the three derived file paths under auditRoot(run). ensureTrustAudit /
56
+ * refreshTrustAudit spread this, and createEventId reads .eventLogPath from it, so
57
+ * the path-derivation rule lives in exactly one place. */
58
+ function trustAuditPaths(run) {
59
+ const dir = auditRoot(run);
60
+ return {
61
+ schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION,
62
+ eventLogPath: node_path_1.default.join(dir, "events.jsonl"),
63
+ summaryPath: node_path_1.default.join(dir, "summary.json"),
64
+ indexPath: node_path_1.default.join(dir, "index.json")
65
+ };
66
+ }
67
+ /** Genesis prevHash for a run's chain (no prior event). */
68
+ function trustAuditGenesis(runId) {
69
+ return (0, execution_backend_1.sha256)(`cw-trust-audit:${runId}`);
70
+ }
71
+ /** Canonical bytes the eventHash binds: every field EXCEPT eventHash itself
72
+ * (prevEventHash included, so the chain link is bound).
73
+ *
74
+ * The hash binds the PERSISTED form. `stableStringify` keeps an undefined-valued
75
+ * key as `"k":null`, but the `JSON.stringify` that writes events.jsonl DROPS such
76
+ * keys — so without this round-trip the record-time hash (over the in-memory event,
77
+ * which can carry nested undefined like an absent dispatchId in worker-sandbox
78
+ * metadata) would never match the verify-time hash (over the parsed-from-disk
79
+ * event), false-failing legitimate worker events as `trust-audit-digest-mismatch`.
80
+ * Round-tripping makes record-time == verify-time. It is identity for events with
81
+ * no undefined fields, so existing intact chains hash unchanged. */
82
+ function computeEventHash(event) {
83
+ const { eventHash, ...rest } = event;
84
+ return (0, execution_backend_1.sha256)((0, telemetry_attestation_1.stableStringify)(JSON.parse(JSON.stringify(rest))));
85
+ }
86
+ /** The hash to chain the NEXT event to: the stored eventHash, or a recompute for
87
+ * a legacy event written before the chain existed. */
88
+ function chainHashOf(event) {
89
+ return event.eventHash || computeEventHash(event);
90
+ }
91
+ /** Read events in FILE (append) order, tolerating corrupt lines — one bad line
92
+ * must not brick the whole audit read surface (it is counted, not thrown). The
93
+ * chain links append order, so this is the order verification walks. */
94
+ function readEventsRaw(eventLogPath) {
95
+ if (!node_fs_1.default.existsSync(eventLogPath))
96
+ return { events: [], corruptLines: 0 };
97
+ let corruptLines = 0;
98
+ const events = [];
99
+ for (const line of node_fs_1.default.readFileSync(eventLogPath, "utf8").split(/\n/g)) {
100
+ const trimmed = line.trim();
101
+ if (!trimmed)
102
+ continue;
103
+ try {
104
+ events.push(JSON.parse(trimmed));
105
+ }
106
+ catch {
107
+ corruptLines += 1;
108
+ }
109
+ }
110
+ return { events, corruptLines };
111
+ }
112
+ /** Re-prove the run's trust-audit chain: prevEventHash linkage (append order) +
113
+ * per-event hash recompute. A corrupt line, an edited event, or a removed event
114
+ * flips verified=false. Legacy events without a hash are reported as `unchained`
115
+ * (skipped), NOT treated as a forgery — they predate the chain. */
116
+ function verifyTrustAudit(run) {
117
+ const audit = ensureTrustAudit(run);
118
+ const { events, corruptLines } = readEventsRaw(audit.eventLogPath);
119
+ const checks = [];
120
+ let verified = corruptLines === 0;
121
+ if (corruptLines > 0)
122
+ checks.push({ name: "parse", pass: false, code: "trust-audit-corrupt-line" });
123
+ let chained = 0;
124
+ let unchained = 0;
125
+ let expectedPrev = trustAuditGenesis(run.id);
126
+ for (let i = 0; i < events.length; i++) {
127
+ const event = events[i];
128
+ const recomputed = computeEventHash(event);
129
+ if (event.eventHash === undefined) {
130
+ unchained += 1;
131
+ expectedPrev = recomputed; // advance the chain over legacy events
132
+ continue;
133
+ }
134
+ chained += 1;
135
+ if (event.eventHash !== recomputed) {
136
+ verified = false;
137
+ checks.push({ name: `event-hash[${i}]`, pass: false, code: "trust-audit-digest-mismatch" });
138
+ }
139
+ if (event.prevEventHash !== undefined && event.prevEventHash !== expectedPrev) {
140
+ verified = false;
141
+ checks.push({ name: `chain-link[${i}]`, pass: false, code: "trust-audit-chain-broken" });
142
+ }
143
+ expectedPrev = event.eventHash;
144
+ }
145
+ // A log with ANY chained event must have EVERY event chained: a single run is
146
+ // written by one code version, so it is all-chained (chain era) or all-legacy
147
+ // (pre-chain). An unchained (eventHash-less) line mixed into a chained log is a
148
+ // forgery attempt — drop the hash to be waved through as "legacy" — so it fails.
149
+ if (chained > 0 && unchained > 0) {
150
+ verified = false;
151
+ checks.push({ name: "unchained-events", pass: false, code: "trust-audit-unchained-event" });
152
+ }
153
+ return { present: events.length > 0, verified, eventCount: events.length, chained, unchained, corruptLines, checks };
154
+ }
26
155
  function ensureTrustAudit(run) {
27
156
  const auditDir = auditRoot(run);
28
157
  node_fs_1.default.mkdirSync(auditDir, { recursive: true });
29
158
  run.paths.auditDir = auditDir;
30
- const audit = {
31
- schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION,
32
- eventLogPath: node_path_1.default.join(auditDir, "events.jsonl"),
33
- summaryPath: node_path_1.default.join(auditDir, "summary.json"),
34
- indexPath: node_path_1.default.join(auditDir, "index.json")
35
- };
159
+ const audit = { ...trustAuditPaths(run) };
36
160
  run.audit = audit;
37
161
  if (!node_fs_1.default.existsSync(audit.eventLogPath))
38
162
  node_fs_1.default.writeFileSync(audit.eventLogPath, "", "utf8");
@@ -90,6 +214,12 @@ function recordTrustAuditEvent(run, input) {
90
214
  parentEventIds: unique(input.parentEventIds || []).sort(),
91
215
  metadata: scrubMetadata(input.metadata || {})
92
216
  });
217
+ // Tamper-evidence chain: link this event to the prior one (append order) and
218
+ // bind its content with eventHash BEFORE persisting. verifyTrustAudit recomputes
219
+ // both independently, so a later edit or removal is detectable.
220
+ const prior = readEventsRaw(audit.eventLogPath).events;
221
+ event.prevEventHash = prior.length ? chainHashOf(prior[prior.length - 1]) : trustAuditGenesis(run.id);
222
+ event.eventHash = computeEventHash(event);
93
223
  // DURABLE append (v0.1.40 self-audit P1): the audit log is the one artifact
94
224
  // whose loss breaks audit-completeness, so fsync it before returning — never a
95
225
  // bare appendFileSync, which can drop the last event on power loss.
@@ -127,15 +257,7 @@ function recordHostAttestation(run, input) {
127
257
  }
128
258
  function listTrustAuditEvents(run) {
129
259
  const audit = ensureTrustAudit(run);
130
- if (!node_fs_1.default.existsSync(audit.eventLogPath))
131
- return [];
132
- return node_fs_1.default
133
- .readFileSync(audit.eventLogPath, "utf8")
134
- .split(/\n/g)
135
- .map((line) => line.trim())
136
- .filter(Boolean)
137
- .map((line) => JSON.parse(line))
138
- .sort(compareEvents);
260
+ return readEventsRaw(audit.eventLogPath).events.sort(compareEvents);
139
261
  }
140
262
  /** Search audit events by kind, worker, or candidate (v0.1.65).
141
263
  * Filters are AND-ed; empty filters match all. */
@@ -159,6 +281,7 @@ function summarizeTrustAudit(run) {
159
281
  runId: run.id,
160
282
  generatedAt: new Date().toISOString(),
161
283
  eventCount: events.length,
284
+ integrity: verifyTrustAudit(run),
162
285
  eventLogPath: audit.eventLogPath,
163
286
  indexPath: audit.indexPath,
164
287
  summaryPath: audit.summaryPath,
@@ -255,12 +378,7 @@ function summarizeTrustAudit(run) {
255
378
  return summary;
256
379
  }
257
380
  function refreshTrustAudit(run) {
258
- const audit = {
259
- schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION,
260
- eventLogPath: node_path_1.default.join(auditRoot(run), "events.jsonl"),
261
- summaryPath: node_path_1.default.join(auditRoot(run), "summary.json"),
262
- indexPath: node_path_1.default.join(auditRoot(run), "index.json")
263
- };
381
+ const audit = { ...trustAuditPaths(run) };
264
382
  node_fs_1.default.mkdirSync(node_path_1.default.dirname(audit.eventLogPath), { recursive: true });
265
383
  if (!node_fs_1.default.existsSync(audit.eventLogPath))
266
384
  node_fs_1.default.writeFileSync(audit.eventLogPath, "", "utf8");
@@ -365,15 +483,7 @@ function auditRoot(run) {
365
483
  return run.paths.auditDir || node_path_1.default.join(run.paths.runDir, "audit");
366
484
  }
367
485
  function readEvents(eventLogPath) {
368
- if (!node_fs_1.default.existsSync(eventLogPath))
369
- return [];
370
- return node_fs_1.default
371
- .readFileSync(eventLogPath, "utf8")
372
- .split(/\n/g)
373
- .map((line) => line.trim())
374
- .filter(Boolean)
375
- .map((line) => JSON.parse(line))
376
- .sort(compareEvents);
486
+ return readEventsRaw(eventLogPath).events.sort(compareEvents);
377
487
  }
378
488
  function workerRows(events, run) {
379
489
  const workerIds = unique([...(run.workers || []).map((worker) => worker.id), ...events.map((event) => event.workerId || "")]).sort();
@@ -419,9 +529,11 @@ function commitRows(events, run) {
419
529
  });
420
530
  }
421
531
  function createEventId(run, kind) {
422
- const stamp = new Date().toISOString().replace(/[-:]/g, "").replace(/\..+/, "Z");
423
- const count = readEvents(node_path_1.default.join(auditRoot(run), "events.jsonl")).length + 1;
424
- return `audit-${(0, state_1.safeFileName)(kind)}-${stamp}-${String(count).padStart(4, "0")}`;
532
+ // Deterministic (FreeBSD-audit L12/L13): chain-local sequence (event-log length),
533
+ // no wall-clock stamp — event.id is bound into the eventHash chain (computeEventHash),
534
+ // so a stable id keeps the chain reproducible on replay.
535
+ const count = readEvents(trustAuditPaths(run).eventLogPath).length + 1;
536
+ return `audit-${(0, state_1.safeFileName)(kind)}-${String(count).padStart(4, "0")}`;
425
537
  }
426
538
  function redactPolicy(policy) {
427
539
  if (!policy)
package/dist/version.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MIN_SUPPORTED_RUN_STATE_SCHEMA_VERSION = exports.LEGACY_RUN_STATE_SCHEMA_VERSION = exports.CURRENT_RUN_STATE_SCHEMA_VERSION = exports.WORKFLOW_APP_SCHEMA_VERSION = exports.CURRENT_COOL_WORKFLOW_VERSION = void 0;
4
- exports.CURRENT_COOL_WORKFLOW_VERSION = "0.1.79";
4
+ exports.CURRENT_COOL_WORKFLOW_VERSION = "0.1.81";
5
5
  exports.WORKFLOW_APP_SCHEMA_VERSION = 1;
6
6
  exports.CURRENT_RUN_STATE_SCHEMA_VERSION = 1;
7
7
  exports.LEGACY_RUN_STATE_SCHEMA_VERSION = 0;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.structuredError = structuredError;
4
+ exports.isBoundaryViolation = isBoundaryViolation;
5
+ exports.isStateNodeError = isStateNodeError;
6
+ exports.mergeScopes = mergeScopes;
7
+ exports.unique = unique;
8
+ exports.compactMetadata = compactMetadata;
9
+ exports.countBy = countBy;
10
+ function structuredError(code, message, options = {}) {
11
+ return {
12
+ code,
13
+ message,
14
+ at: new Date().toISOString(),
15
+ path: options.path,
16
+ retryable: options.retryable,
17
+ details: options.details
18
+ };
19
+ }
20
+ function isBoundaryViolation(value) {
21
+ return Boolean(value && typeof value === "object" && "allowedPaths" in value && "message" in value);
22
+ }
23
+ function isStateNodeError(value) {
24
+ return Boolean(value && typeof value === "object" && "code" in value && "message" in value);
25
+ }
26
+ function mergeScopes(left, right) {
27
+ const merged = [...left];
28
+ for (const scope of right) {
29
+ const index = merged.findIndex((candidate) => candidate.id === scope.id);
30
+ if (index >= 0)
31
+ merged[index] = scope;
32
+ else
33
+ merged.push(scope);
34
+ }
35
+ return merged;
36
+ }
37
+ function unique(values) {
38
+ return Array.from(new Set(values.filter(Boolean)));
39
+ }
40
+ function compactMetadata(value) {
41
+ const entries = Object.entries(value).filter(([, entry]) => entry !== undefined);
42
+ return entries.length ? Object.fromEntries(entries) : undefined;
43
+ }
44
+ function countBy(items, key) {
45
+ const counts = {};
46
+ for (const item of items) {
47
+ const value = key(item);
48
+ counts[value] = (counts[value] || 0) + 1;
49
+ }
50
+ return counts;
51
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.WORKER_MANIFEST_FILE = exports.WORKER_SCOPE_FILE = void 0;
7
+ exports.manifestPath = manifestPath;
8
+ exports.workerScopePath = workerScopePath;
9
+ exports.workerArtifacts = workerArtifacts;
10
+ exports.createWorkerId = createWorkerId;
11
+ // Path, artifact, and id derivation for worker isolation. Pure functions of a
12
+ // WorkerScope (or run + taskId) — no run-state mutation, no disk I/O. Carved out
13
+ // of worker-isolation.ts following the established router pattern
14
+ // (run-registry/{format,policy}.ts, orchestrator/*-operations.ts).
15
+ //
16
+ // BEHAVIOR-PRESERVING — pure code movement, zero logic change. Re-exported from
17
+ // worker-isolation.ts so the public surface is byte-unchanged.
18
+ const node_path_1 = __importDefault(require("node:path"));
19
+ const state_1 = require("../state");
20
+ exports.WORKER_SCOPE_FILE = "worker.json";
21
+ exports.WORKER_MANIFEST_FILE = "manifest.json";
22
+ function manifestPath(scope) {
23
+ return node_path_1.default.join(scope.workerDir, exports.WORKER_MANIFEST_FILE);
24
+ }
25
+ function workerScopePath(scope) {
26
+ return node_path_1.default.join(scope.workerDir, exports.WORKER_SCOPE_FILE);
27
+ }
28
+ function workerArtifacts(scope) {
29
+ return [
30
+ { id: "worker", kind: "json", path: workerScopePath(scope) },
31
+ { id: "worker-manifest", kind: "json", path: manifestPath(scope) },
32
+ { id: "worker-input", kind: "markdown", path: scope.inputPath }
33
+ ];
34
+ }
35
+ // Deterministic worker id (v0.1.40 self-audit P2): a wall-clock stamp + Math.random()
36
+ // made every dispatch mint a different id, so audit references were not reproducible
37
+ // across re-runs of the same inputs. The id is now derived from the task plus a
38
+ // per-task sequence (count of worker scopes already allocated for that task + 1),
39
+ // so re-running the same workflow yields byte-identical worker ids while retries of
40
+ // the SAME task still get a fresh, unique id. (workerId is excluded from the
41
+ // snapshot source fingerprint, so this does not change replay digests.)
42
+ function createWorkerId(run, taskId) {
43
+ const prefix = `worker-${(0, state_1.safeFileName)(taskId)}-`;
44
+ const seq = (run.workers || []).filter((scope) => scope.id.startsWith(prefix)).length + 1;
45
+ return `${prefix}${String(seq).padStart(4, "0")}`;
46
+ }