cool-workflow 0.1.97 → 0.2.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 (309) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +11 -2
  4. package/apps/architecture-review/app.json +1 -1
  5. package/apps/architecture-review-fast/app.json +1 -1
  6. package/apps/end-to-end-golden-path/app.json +1 -1
  7. package/apps/pr-review-fix-ci/app.json +1 -1
  8. package/apps/release-cut/app.json +1 -1
  9. package/apps/research-synthesis/app.json +1 -1
  10. package/dist/cli/dispatch.js +236 -0
  11. package/dist/cli/entry.js +120 -0
  12. package/dist/cli/io.js +21 -4
  13. package/dist/cli/parseargv.js +157 -0
  14. package/dist/cli.js +6 -33
  15. package/dist/core/capability-table.js +3534 -0
  16. package/dist/core/format/help.js +314 -0
  17. package/dist/{state-explosion/format.js → core/format/state-explosion-text.js} +10 -1
  18. package/dist/core/hash.js +137 -0
  19. package/dist/core/multi-agent/candidate-scoring.js +219 -0
  20. package/dist/core/multi-agent/collaboration.js +481 -0
  21. package/dist/core/multi-agent/coordinator.js +515 -0
  22. package/dist/core/multi-agent/eval-replay.js +306 -0
  23. package/dist/core/multi-agent/runtime.js +929 -0
  24. package/dist/core/multi-agent/topology.js +298 -0
  25. package/dist/core/multi-agent/trust-policy.js +197 -0
  26. package/dist/core/pipeline/commit-gate.js +320 -0
  27. package/dist/{pipeline-contract.js → core/pipeline/contract.js} +24 -37
  28. package/dist/core/pipeline/dispatch.js +103 -0
  29. package/dist/core/pipeline/drive-decide.js +227 -0
  30. package/dist/core/pipeline/error-feedback.js +161 -0
  31. package/dist/core/pipeline/loop-expansion.js +124 -0
  32. package/dist/{result-normalize.js → core/pipeline/result-normalize.js} +14 -37
  33. package/dist/core/pipeline/runner.js +230 -0
  34. package/dist/{contract-migration.js → core/state/contract-migration.js} +68 -92
  35. package/dist/{state-migrations.js → core/state/migrations.js} +103 -96
  36. package/dist/core/state/node-projection.js +95 -0
  37. package/dist/core/state/node-snapshot.js +230 -0
  38. package/dist/core/state/run-paths.js +93 -0
  39. package/dist/{schema-validate.js → core/state/schema-validate.js} +35 -28
  40. package/dist/core/state/schema.js +50 -0
  41. package/dist/core/state/state-explosion/digest.js +243 -0
  42. package/dist/core/state/state-explosion/graph.js +527 -0
  43. package/dist/{state-explosion → core/state/state-explosion}/helpers.js +34 -3
  44. package/dist/core/state/state-explosion/report.js +187 -0
  45. package/dist/{state-explosion → core/state/state-explosion}/size.js +25 -7
  46. package/dist/{state-node.js → core/state/state-node.js} +90 -113
  47. package/dist/core/state/types.js +19 -0
  48. package/dist/{validation.js → core/state/validation.js} +64 -131
  49. package/dist/core/trust/evidence-grounding.js +134 -0
  50. package/dist/core/trust/ledger.js +199 -0
  51. package/dist/{telemetry-attestation.js → core/trust/telemetry-attestation.js} +94 -68
  52. package/dist/core/trust/telemetry-ledger.js +127 -0
  53. package/dist/core/types.js +20 -0
  54. package/dist/core/version.js +16 -0
  55. package/dist/{workflow-app-framework.js → core/workflow-apps/app-schema.js} +337 -426
  56. package/dist/mcp/dispatch.js +104 -0
  57. package/dist/mcp/server.js +144 -0
  58. package/dist/mcp-server.js +6 -84
  59. package/dist/{agent-config.js → shell/agent-config.js} +118 -71
  60. package/dist/shell/app-run-cli.js +88 -0
  61. package/dist/shell/audit-cli.js +259 -0
  62. package/dist/shell/audit-provenance.js +83 -0
  63. package/dist/shell/candidate-scoring-io.js +459 -0
  64. package/dist/shell/collaboration-io.js +264 -0
  65. package/dist/shell/commit-summary.js +104 -0
  66. package/dist/shell/commit.js +290 -0
  67. package/dist/shell/coordinator-io.js +476 -0
  68. package/dist/shell/demo-cli.js +19 -0
  69. package/dist/shell/dispatch.js +162 -0
  70. package/dist/{doctor.js → shell/doctor.js} +123 -56
  71. package/dist/shell/drive.js +873 -0
  72. package/dist/shell/error-feedback-io.js +305 -0
  73. package/dist/shell/eval-io.js +473 -0
  74. package/dist/{multi-agent-eval/format.js → shell/eval-text.js} +78 -49
  75. package/dist/{evidence-reasoning.js → shell/evidence-reasoning.js} +124 -255
  76. package/dist/shell/exec-backend-cli.js +88 -0
  77. package/dist/shell/execution-backend/agent.js +475 -0
  78. package/dist/shell/execution-backend/ci.js +15 -0
  79. package/dist/shell/execution-backend/container.js +69 -0
  80. package/dist/shell/execution-backend/envelopes.js +55 -0
  81. package/dist/shell/execution-backend/local.js +113 -0
  82. package/dist/shell/execution-backend/probes.js +175 -0
  83. package/dist/shell/execution-backend/registry.js +402 -0
  84. package/dist/shell/execution-backend/remote.js +128 -0
  85. package/dist/shell/execution-backend/types.js +11 -0
  86. package/dist/shell/feedback-cli.js +81 -0
  87. package/dist/shell/feedback-operations.js +48 -0
  88. package/dist/shell/fs-atomic.js +276 -0
  89. package/dist/shell/harness.js +98 -0
  90. package/dist/shell/ledger-cli.js +212 -0
  91. package/dist/shell/ledger-io.js +169 -0
  92. package/dist/shell/man-cli.js +89 -0
  93. package/dist/shell/metrics-cli.js +98 -0
  94. package/dist/shell/multi-agent-cli.js +1002 -0
  95. package/dist/shell/multi-agent-host.js +563 -0
  96. package/dist/shell/multi-agent-io.js +387 -0
  97. package/dist/{multi-agent-operator-ux.js → shell/multi-agent-operator-ux.js} +234 -191
  98. package/dist/shell/node-store.js +124 -0
  99. package/dist/{observability/format.js → shell/observability-format.js} +7 -1
  100. package/dist/{observability/intake.js → shell/observability-intake.js} +79 -56
  101. package/dist/{observability.js → shell/observability.js} +159 -332
  102. package/dist/{onramp.js → shell/onramp.js} +11 -0
  103. package/dist/{operator-ux/format.js → shell/operator-ux-text.js} +250 -239
  104. package/dist/shell/operator-ux.js +431 -0
  105. package/dist/shell/orchestrator.js +231 -0
  106. package/dist/shell/pipeline-cli.js +667 -0
  107. package/dist/shell/pipeline.js +217 -0
  108. package/dist/shell/reclamation-io.js +1366 -0
  109. package/dist/shell/registry-cli.js +329 -0
  110. package/dist/{remote-source.js → shell/remote-source.js} +12 -5
  111. package/dist/shell/report-cli.js +101 -0
  112. package/dist/shell/report-view-cli.js +117 -0
  113. package/dist/{orchestrator → shell}/report.js +289 -282
  114. package/dist/shell/reporter.js +62 -0
  115. package/dist/shell/run-export-cli.js +106 -0
  116. package/dist/shell/run-export.js +680 -0
  117. package/dist/shell/run-registry-io.js +1014 -0
  118. package/dist/shell/run-store.js +164 -0
  119. package/dist/{sandbox-profile.js → shell/sandbox-profile.js} +134 -95
  120. package/dist/{scheduler.js → shell/scheduler-io.js} +248 -48
  121. package/dist/shell/scheduling-io.js +311 -0
  122. package/dist/shell/state-cli.js +181 -0
  123. package/dist/shell/state-explosion-cli.js +197 -0
  124. package/dist/shell/telemetry-cli.js +85 -0
  125. package/dist/{telemetry-demo.js → shell/telemetry-demo.js} +149 -119
  126. package/dist/shell/telemetry-ledger-io.js +132 -0
  127. package/dist/{term.js → shell/term.js} +36 -46
  128. package/dist/shell/topology-io.js +361 -0
  129. package/dist/shell/trust-audit.js +471 -0
  130. package/dist/{multi-agent-trust.js → shell/trust-policy-io.js} +67 -205
  131. package/dist/shell/verifier.js +48 -0
  132. package/dist/shell/workbench-host.js +250 -0
  133. package/dist/shell/workbench-text.js +18 -0
  134. package/dist/shell/workbench.js +175 -0
  135. package/dist/shell/worker-cli.js +124 -0
  136. package/dist/shell/worker-isolation.js +852 -0
  137. package/dist/shell/workflow-app-loader.js +650 -0
  138. package/docs/agent-delegation-drive.7.md +4 -0
  139. package/docs/cli-mcp-parity.7.md +284 -211
  140. package/docs/contract-migration-tooling.7.md +4 -0
  141. package/docs/control-plane-scheduling.7.md +4 -0
  142. package/docs/cross-agent-ledger.7.md +217 -0
  143. package/docs/designs/handoff-ledger.md +145 -0
  144. package/docs/durable-state-and-locking.7.md +4 -0
  145. package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
  146. package/docs/execution-backends.7.md +4 -0
  147. package/docs/handoff-setup.md +120 -0
  148. package/docs/multi-agent-cli-mcp-surface.7.md +4 -0
  149. package/docs/multi-agent-eval-replay-harness.7.md +4 -0
  150. package/docs/multi-agent-operator-ux.7.md +4 -0
  151. package/docs/node-snapshot-diff-replay.7.md +4 -0
  152. package/docs/observability-cost-accounting.7.md +4 -0
  153. package/docs/project-index.md +143 -71
  154. package/docs/real-execution-backends.7.md +4 -0
  155. package/docs/release-and-migration.7.md +4 -0
  156. package/docs/release-tooling.7.md +4 -0
  157. package/docs/run-registry-control-plane.7.md +4 -0
  158. package/docs/run-retention-reclamation.7.md +25 -0
  159. package/docs/state-explosion-management.7.md +4 -0
  160. package/docs/team-collaboration.7.md +4 -0
  161. package/docs/web-desktop-workbench.7.md +4 -0
  162. package/manifest/plugin.manifest.json +1 -1
  163. package/manifest/source-context-profiles.json +9 -13
  164. package/package.json +1 -1
  165. package/scripts/agents/codex-agent.js +34 -4
  166. package/scripts/agents/cw-attest-wrap.js +2 -2
  167. package/scripts/bump-version.js +4 -3
  168. package/scripts/canonical-apps.js +4 -4
  169. package/scripts/children/batch-delegate-child.js +30 -10
  170. package/scripts/dogfood-architecture-review.js +2 -3
  171. package/scripts/dogfood-release.js +3 -3
  172. package/scripts/gen-parity-doc.js +15 -2
  173. package/scripts/golden-path.js +4 -4
  174. package/scripts/onramp-check.js +1 -1
  175. package/scripts/parity-check.js +38 -21
  176. package/scripts/release-flow.js +9 -3
  177. package/scripts/sync-project-index.js +51 -27
  178. package/scripts/validate-run-state-schema.js +2 -2
  179. package/scripts/version-sync-check.js +30 -30
  180. package/dist/candidate-scoring.js +0 -729
  181. package/dist/capability-core.js +0 -1186
  182. package/dist/capability-registry.js +0 -879
  183. package/dist/cli/command-surface.js +0 -490
  184. package/dist/cli/format.js +0 -56
  185. package/dist/cli/handlers/audit.js +0 -82
  186. package/dist/cli/handlers/blackboard.js +0 -81
  187. package/dist/cli/handlers/candidate.js +0 -40
  188. package/dist/cli/handlers/clones.js +0 -34
  189. package/dist/cli/handlers/collaboration.js +0 -61
  190. package/dist/cli/handlers/eval.js +0 -40
  191. package/dist/cli/handlers/maintenance.js +0 -107
  192. package/dist/cli/handlers/multi-agent.js +0 -165
  193. package/dist/cli/handlers/node.js +0 -41
  194. package/dist/cli/handlers/operational.js +0 -155
  195. package/dist/cli/handlers/operator.js +0 -146
  196. package/dist/cli/handlers/registry.js +0 -68
  197. package/dist/cli/handlers/run.js +0 -153
  198. package/dist/cli/handlers/scheduling.js +0 -132
  199. package/dist/cli/handlers/workbench.js +0 -41
  200. package/dist/cli/handlers/worker.js +0 -45
  201. package/dist/cli/run-summary.js +0 -45
  202. package/dist/clones.js +0 -162
  203. package/dist/collaboration.js +0 -726
  204. package/dist/commit.js +0 -592
  205. package/dist/compare.js +0 -18
  206. package/dist/coordinator/classify.js +0 -45
  207. package/dist/coordinator/paths.js +0 -42
  208. package/dist/coordinator/util.js +0 -126
  209. package/dist/coordinator.js +0 -990
  210. package/dist/daemon.js +0 -44
  211. package/dist/dispatch.js +0 -250
  212. package/dist/drive.js +0 -827
  213. package/dist/error-feedback.js +0 -419
  214. package/dist/evidence-grounding.js +0 -184
  215. package/dist/execution-backend/agent.js +0 -294
  216. package/dist/execution-backend/probes.js +0 -112
  217. package/dist/execution-backend/util.js +0 -47
  218. package/dist/execution-backend.js +0 -961
  219. package/dist/gates.js +0 -48
  220. package/dist/harness.js +0 -61
  221. package/dist/loop-expansion.js +0 -60
  222. package/dist/mcp/tool-call.js +0 -434
  223. package/dist/mcp/tool-definitions.js +0 -1040
  224. package/dist/mcp-surface.js +0 -30
  225. package/dist/multi-agent/graph.js +0 -84
  226. package/dist/multi-agent/helpers.js +0 -141
  227. package/dist/multi-agent/ids.js +0 -20
  228. package/dist/multi-agent/paths.js +0 -22
  229. package/dist/multi-agent-eval/normalize.js +0 -51
  230. package/dist/multi-agent-eval.js +0 -678
  231. package/dist/multi-agent-host.js +0 -777
  232. package/dist/multi-agent.js +0 -984
  233. package/dist/node-projection.js +0 -59
  234. package/dist/node-snapshot.js +0 -260
  235. package/dist/operator-ux.js +0 -631
  236. package/dist/orchestrator/app-operations.js +0 -211
  237. package/dist/orchestrator/audit-operations.js +0 -182
  238. package/dist/orchestrator/candidate-operations.js +0 -117
  239. package/dist/orchestrator/cli-options.js +0 -294
  240. package/dist/orchestrator/collaboration-operations.js +0 -86
  241. package/dist/orchestrator/feedback-operations.js +0 -81
  242. package/dist/orchestrator/host-operations.js +0 -78
  243. package/dist/orchestrator/lifecycle-operations.js +0 -626
  244. package/dist/orchestrator/migration-operations.js +0 -44
  245. package/dist/orchestrator/multi-agent-operations.js +0 -362
  246. package/dist/orchestrator/topology-operations.js +0 -84
  247. package/dist/orchestrator.js +0 -917
  248. package/dist/pipeline-runner.js +0 -285
  249. package/dist/reclamation/hash.js +0 -72
  250. package/dist/reclamation.js +0 -812
  251. package/dist/reporter.js +0 -67
  252. package/dist/run-export.js +0 -784
  253. package/dist/run-registry/derive.js +0 -175
  254. package/dist/run-registry/format.js +0 -124
  255. package/dist/run-registry/gc.js +0 -251
  256. package/dist/run-registry/policy.js +0 -16
  257. package/dist/run-registry/queue.js +0 -115
  258. package/dist/run-registry.js +0 -850
  259. package/dist/run-state-schema.js +0 -68
  260. package/dist/scheduling.js +0 -184
  261. package/dist/state-explosion.js +0 -1014
  262. package/dist/state.js +0 -367
  263. package/dist/telemetry-ledger.js +0 -196
  264. package/dist/topology.js +0 -565
  265. package/dist/triggers.js +0 -184
  266. package/dist/trust-audit.js +0 -644
  267. package/dist/types/blackboard.js +0 -2
  268. package/dist/types/candidate.js +0 -2
  269. package/dist/types/collaboration.js +0 -2
  270. package/dist/types/core.js +0 -2
  271. package/dist/types/drive.js +0 -10
  272. package/dist/types/error-feedback.js +0 -2
  273. package/dist/types/evidence-reasoning.js +0 -2
  274. package/dist/types/execution-backend.js +0 -2
  275. package/dist/types/multi-agent.js +0 -2
  276. package/dist/types/observability.js +0 -2
  277. package/dist/types/pipeline.js +0 -2
  278. package/dist/types/reclamation.js +0 -8
  279. package/dist/types/report-bundle.js +0 -6
  280. package/dist/types/result.js +0 -2
  281. package/dist/types/run-registry.js +0 -2
  282. package/dist/types/run.js +0 -2
  283. package/dist/types/sandbox.js +0 -2
  284. package/dist/types/schedule.js +0 -2
  285. package/dist/types/state-node.js +0 -2
  286. package/dist/types/topology.js +0 -2
  287. package/dist/types/trust.js +0 -2
  288. package/dist/types/workbench.js +0 -2
  289. package/dist/types/worker.js +0 -2
  290. package/dist/types/workflow-app.js +0 -2
  291. package/dist/types.js +0 -44
  292. package/dist/util/fingerprint.js +0 -19
  293. package/dist/util/fingerprint.test.js +0 -27
  294. package/dist/verifier.js +0 -78
  295. package/dist/version.js +0 -8
  296. package/dist/workbench-host.js +0 -182
  297. package/dist/workbench.js +0 -192
  298. package/dist/worker-accept/acceptance.js +0 -114
  299. package/dist/worker-accept/blackboard-fanout.js +0 -80
  300. package/dist/worker-accept/blackboard-linkage.js +0 -19
  301. package/dist/worker-accept/context.js +0 -2
  302. package/dist/worker-accept/telemetry-ledger.js +0 -126
  303. package/dist/worker-accept/validation.js +0 -77
  304. package/dist/worker-accept/verifier-completion.js +0 -73
  305. package/dist/worker-isolation/helpers.js +0 -51
  306. package/dist/worker-isolation/paths.js +0 -46
  307. package/dist/worker-isolation.js +0 -656
  308. package/dist/workflow-api.js +0 -131
  309. /package/dist/{types → core/types}/boundary.js +0 -0
@@ -0,0 +1,471 @@
1
+ "use strict";
2
+ // shell/trust-audit.ts — MILESTONE 8: extended from milestone 6+7's
3
+ // scoped-down subset to the FULL trust-audit hash chain: eventHash (the
4
+ // JSON round-trip pre-pass), verifyTrustAudit (chain-link recompute +
5
+ // the era rule — a log is fully chained OR fully legacy, never mixed),
6
+ // event append (hash-chained), the evidence normalizer, and the
7
+ // sandbox-path decision helper.
8
+ //
9
+ // The milestone-6+7 subset (recordTrustAuditEvent, recordSandboxPath-
10
+ // Decision, normalizeEvidence, ensureTrustAudit) keeps its existing
11
+ // signatures byte-for-byte — shell/commit.ts and shell/worker-
12
+ // isolation.ts already import them. This edit ADDS verifyTrustAudit +
13
+ // the era-rule check + trustAuditGenesis on top, and switches
14
+ // computeEventHash to use core/hash.ts's named `eventHashInput` export
15
+ // (byte-identical behavior to the pre-existing inline JSON-round-trip,
16
+ // now shared with the rest of the hash-dedup story per v2/PLAN.md byte-
17
+ // compat item 2).
18
+ //
19
+ // Evidence: SPEC/ledger-trust.md "Trust-audit chain", invariant 10 (era
20
+ // rule), byte-compat item 2; SPEC/pipeline-run.md's worker-accept
21
+ // references; plugins/cool-workflow/src/trust-audit.ts:1-731 (byte-exact
22
+ // source for the pieces ported here).
23
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ var desc = Object.getOwnPropertyDescriptor(m, k);
26
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
27
+ desc = { enumerable: true, get: function() { return m[k]; } };
28
+ }
29
+ Object.defineProperty(o, k2, desc);
30
+ }) : (function(o, m, k, k2) {
31
+ if (k2 === undefined) k2 = k;
32
+ o[k2] = m[k];
33
+ }));
34
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
35
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
36
+ }) : function(o, v) {
37
+ o["default"] = v;
38
+ });
39
+ var __importStar = (this && this.__importStar) || (function () {
40
+ var ownKeys = function(o) {
41
+ ownKeys = Object.getOwnPropertyNames || function (o) {
42
+ var ar = [];
43
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
44
+ return ar;
45
+ };
46
+ return ownKeys(o);
47
+ };
48
+ return function (mod) {
49
+ if (mod && mod.__esModule) return mod;
50
+ var result = {};
51
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
52
+ __setModuleDefault(result, mod);
53
+ return result;
54
+ };
55
+ })();
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ exports.TRUST_AUDIT_SCHEMA_VERSION = void 0;
58
+ exports.ensureTrustAudit = ensureTrustAudit;
59
+ exports.trustAuditGenesis = trustAuditGenesis;
60
+ exports.listTrustAuditEvents = listTrustAuditEvents;
61
+ exports.verifyTrustAudit = verifyTrustAudit;
62
+ exports.recordTrustAuditEvent = recordTrustAuditEvent;
63
+ exports.recordSandboxPathDecision = recordSandboxPathDecision;
64
+ exports.normalizeEvidence = normalizeEvidence;
65
+ exports.writeTrustAuditIndexPlaceholder = writeTrustAuditIndexPlaceholder;
66
+ exports.summarizeTrustAudit = summarizeTrustAudit;
67
+ const fs = __importStar(require("node:fs"));
68
+ const path = __importStar(require("node:path"));
69
+ const hash_1 = require("../core/hash");
70
+ const fs_atomic_1 = require("./fs-atomic");
71
+ exports.TRUST_AUDIT_SCHEMA_VERSION = 1;
72
+ function trustAuditPaths(run) {
73
+ const dir = run.paths.auditDir || path.join(run.paths.runDir, "audit");
74
+ return {
75
+ eventLogPath: path.join(dir, "events.jsonl"),
76
+ summaryPath: path.join(dir, "summary.json"),
77
+ indexPath: path.join(dir, "index.json"),
78
+ };
79
+ }
80
+ function ensureTrustAudit(run) {
81
+ const dir = run.paths.auditDir || path.join(run.paths.runDir, "audit");
82
+ fs.mkdirSync(dir, { recursive: true });
83
+ run.paths.auditDir = dir;
84
+ const audit = { schemaVersion: 1, ...trustAuditPaths(run) };
85
+ run.audit = audit;
86
+ if (!fs.existsSync(audit.eventLogPath))
87
+ fs.writeFileSync(audit.eventLogPath, "", "utf8");
88
+ return audit;
89
+ }
90
+ /** Genesis prevHash for a run's chain (no prior event). Exported so
91
+ * callers outside this module (verify tooling, tests) can recompute it
92
+ * independently rather than trusting a stored value. */
93
+ function trustAuditGenesis(runId) {
94
+ return (0, hash_1.sha256)(`cw-trust-audit:${runId}`);
95
+ }
96
+ /** Canonical bytes the eventHash binds: every field EXCEPT eventHash
97
+ * itself, via core/hash.ts's `eventHashInput` (the JSON round-trip
98
+ * pre-pass that drops nested `undefined`-valued keys BEFORE the
99
+ * sort-and-stringify step — not a formatting flag on the same shape,
100
+ * see v2/PLAN.md byte-compat item 2). Hashing the PERSISTED form this
101
+ * way makes record-time hashes equal verify-time (parsed-from-disk)
102
+ * hashes. */
103
+ function computeEventHash(event) {
104
+ const { eventHash, ...rest } = event;
105
+ void eventHash;
106
+ return (0, hash_1.sha256)((0, hash_1.eventHashInput)(rest));
107
+ }
108
+ /** Read events in FILE (append) order, tolerating corrupt lines — one
109
+ * bad line must not brick the whole audit read surface (it is counted,
110
+ * not thrown). The chain links append order, so this is the order
111
+ * verification walks. */
112
+ function readEventsRawCounted(eventLogPath) {
113
+ if (!fs.existsSync(eventLogPath))
114
+ return { events: [], corruptLines: 0 };
115
+ let corruptLines = 0;
116
+ const events = [];
117
+ for (const line of fs.readFileSync(eventLogPath, "utf8").split(/\n/g)) {
118
+ const trimmed = line.trim();
119
+ if (!trimmed)
120
+ continue;
121
+ try {
122
+ events.push(JSON.parse(trimmed));
123
+ }
124
+ catch {
125
+ corruptLines += 1;
126
+ }
127
+ }
128
+ return { events, corruptLines };
129
+ }
130
+ function readEventsRaw(eventLogPath) {
131
+ return readEventsRawCounted(eventLogPath).events;
132
+ }
133
+ /** Every recorded trust-audit event for this run, in append (file) order.
134
+ * Used by trust-policy/collaboration summaries (e.g.
135
+ * hasAcceptedJudgeRationale, summarizeMultiAgentTrust). */
136
+ function listTrustAuditEvents(run) {
137
+ return readEventsRaw(ensureTrustAudit(run).eventLogPath);
138
+ }
139
+ /** Re-prove the run's trust-audit chain: prevEventHash linkage (append
140
+ * order) + per-event hash recompute. A corrupt line, an edited event,
141
+ * or a removed event flips verified=false. Legacy events without a
142
+ * hash are reported as `unchained` (skipped), NOT treated as a forgery
143
+ * — they predate the chain.
144
+ *
145
+ * ERA RULE (v2/PLAN.md, SPEC/ledger-trust.md invariant 10): a single
146
+ * run is written by one code version, so a log is all-chained (chain
147
+ * era) or all-legacy (pre-chain). An unchained (eventHash-less) line
148
+ * mixed into an otherwise-chained log is a forgery attempt — dropping
149
+ * the hash to be waved through as "legacy" — so it fails with
150
+ * `trust-audit-unchained-event`, never silently accepted. */
151
+ function verifyTrustAudit(run) {
152
+ const audit = ensureTrustAudit(run);
153
+ const { events, corruptLines } = readEventsRawCounted(audit.eventLogPath);
154
+ const checks = [];
155
+ let verified = corruptLines === 0;
156
+ if (corruptLines > 0)
157
+ checks.push({ name: "parse", pass: false, code: "trust-audit-corrupt-line" });
158
+ let chained = 0;
159
+ let unchained = 0;
160
+ let expectedPrev = trustAuditGenesis(run.id);
161
+ for (let i = 0; i < events.length; i++) {
162
+ const event = events[i];
163
+ const recomputed = computeEventHash(event);
164
+ if (event.eventHash === undefined) {
165
+ unchained += 1;
166
+ expectedPrev = recomputed; // advance the chain over legacy events
167
+ continue;
168
+ }
169
+ chained += 1;
170
+ if (event.eventHash !== recomputed) {
171
+ verified = false;
172
+ checks.push({ name: `event-hash[${i}]`, pass: false, code: "trust-audit-digest-mismatch" });
173
+ }
174
+ if (event.prevEventHash !== undefined && event.prevEventHash !== expectedPrev) {
175
+ verified = false;
176
+ checks.push({ name: `chain-link[${i}]`, pass: false, code: "trust-audit-chain-broken" });
177
+ }
178
+ expectedPrev = event.eventHash;
179
+ }
180
+ // Era rule: a log with ANY chained event must have EVERY event chained.
181
+ if (chained > 0 && unchained > 0) {
182
+ verified = false;
183
+ checks.push({ name: "unchained-events", pass: false, code: "trust-audit-unchained-event" });
184
+ }
185
+ return { present: events.length > 0, verified, eventCount: events.length, chained, unchained, corruptLines, checks };
186
+ }
187
+ function unique(values) {
188
+ return Array.from(new Set(values.filter(Boolean)));
189
+ }
190
+ function scrubMetadata(value) {
191
+ const result = {};
192
+ for (const [key, entry] of Object.entries(value)) {
193
+ if (entry === undefined)
194
+ continue;
195
+ if (/secret|token|password|credential|authorization|api[_-]?key/i.test(key)) {
196
+ result[key] = "[redacted]";
197
+ }
198
+ else if (Array.isArray(entry)) {
199
+ result[key] = entry.map((item) => (typeof item === "string" && item.includes("=") ? item.split("=")[0] : item));
200
+ }
201
+ else if (entry && typeof entry === "object") {
202
+ result[key] = scrubMetadata(entry);
203
+ }
204
+ else {
205
+ result[key] = entry;
206
+ }
207
+ }
208
+ return Object.keys(result).length ? result : undefined;
209
+ }
210
+ function compact(value) {
211
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
212
+ }
213
+ function createEventId(run, kind) {
214
+ const count = readEventsRaw(trustAuditPaths(run).eventLogPath).length + 1;
215
+ return `audit-${(0, fs_atomic_1.safeFileName)(kind)}-${String(count).padStart(4, "0")}`;
216
+ }
217
+ /** Correlation-id keys copied verbatim (and no others) — byte-exact list/
218
+ * order to the old build's CORRELATION_ID_FIELDS. */
219
+ const CORRELATION_ID_FIELDS = [
220
+ "candidateId",
221
+ "scoreId",
222
+ "selectionId",
223
+ "commitId",
224
+ "multiAgentRunId",
225
+ "agentRoleId",
226
+ "agentGroupId",
227
+ "agentMembershipId",
228
+ "agentFanoutId",
229
+ "agentFaninId",
230
+ "blackboardId",
231
+ "blackboardTopicId",
232
+ "blackboardMessageId",
233
+ "blackboardContextId",
234
+ "blackboardArtifactRefId",
235
+ "blackboardSnapshotId",
236
+ "coordinatorDecisionId",
237
+ "topologyId",
238
+ "topologyRunId",
239
+ ];
240
+ function pickCorrelationIds(source) {
241
+ const picked = {};
242
+ for (const field of CORRELATION_ID_FIELDS)
243
+ picked[field] = source[field];
244
+ return picked;
245
+ }
246
+ /** The audit index historically omits scoreId (byte-exact to the old build's
247
+ * INDEX_OMITTED_CORRELATION_IDS). */
248
+ const INDEX_OMITTED_CORRELATION_IDS = new Set(["scoreId"]);
249
+ function indexCorrelationIds(event) {
250
+ const picked = {};
251
+ for (const field of CORRELATION_ID_FIELDS) {
252
+ if (INDEX_OMITTED_CORRELATION_IDS.has(field))
253
+ continue;
254
+ picked[field] = event[field];
255
+ }
256
+ return picked;
257
+ }
258
+ function recordTrustAuditEvent(run, input) {
259
+ const audit = ensureTrustAudit(run);
260
+ const event = compact({
261
+ schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION,
262
+ id: createEventId(run, input.kind),
263
+ createdAt: new Date().toISOString(),
264
+ runId: run.id,
265
+ kind: input.kind,
266
+ decision: input.decision,
267
+ source: input.source,
268
+ actor: input.actor,
269
+ workerId: input.workerId,
270
+ taskId: input.taskId,
271
+ nodeId: input.nodeId,
272
+ feedbackIds: input.feedbackIds?.filter(Boolean).sort(),
273
+ ...pickCorrelationIds(input),
274
+ sandboxProfileId: input.sandboxProfileId || input.policySnapshot?.id,
275
+ policyRef: input.policyRef || (input.policySnapshot?.id ? `run.sandboxProfiles.${input.policySnapshot.id}` : undefined),
276
+ policySnapshot: input.policySnapshot,
277
+ normalizedPath: input.normalizedPath ? path.resolve(input.normalizedPath) : undefined,
278
+ command: input.command,
279
+ networkTarget: input.networkTarget,
280
+ evidence: normalizeEvidence(run, input.evidence || [], { source: input.source, workerId: input.workerId, taskId: input.taskId, resultNodeId: input.nodeId }),
281
+ evidenceRefs: unique(input.evidenceRefs || []).sort(),
282
+ parentEventIds: unique(input.parentEventIds || []).sort(),
283
+ metadata: scrubMetadata(input.metadata || {}),
284
+ });
285
+ const prior = readEventsRaw(audit.eventLogPath);
286
+ event.prevEventHash = prior.length ? prior[prior.length - 1].eventHash || computeEventHash(prior[prior.length - 1]) : trustAuditGenesis(run.id);
287
+ event.eventHash = computeEventHash(event);
288
+ (0, fs_atomic_1.durableAppendFileSync)(audit.eventLogPath, `${JSON.stringify(event)}\n`);
289
+ return event;
290
+ }
291
+ function recordSandboxPathDecision(run, input) {
292
+ return recordTrustAuditEvent(run, {
293
+ kind: "sandbox.path",
294
+ decision: input.decision,
295
+ source: "cw-validated",
296
+ workerId: input.workerId,
297
+ taskId: input.taskId,
298
+ sandboxProfileId: input.sandboxProfileId,
299
+ policySnapshot: input.policySnapshot,
300
+ normalizedPath: input.target,
301
+ metadata: input.metadata,
302
+ });
303
+ }
304
+ /** normalizeEvidence — GROUNDING-ONLY provenance. Never carries the
305
+ * agent's command/args/model/handle (those live ONLY in
306
+ * node.metadata.agentDelegation) — this is the exact hygiene split
307
+ * exechard-evidence-triple-hygiene.case.js pins. */
308
+ function normalizeEvidence(run, evidence, provenance) {
309
+ return evidence.map((entry) => ({
310
+ ...entry,
311
+ confidence: entry.confidence || (entry.locator || entry.path || entry.summary ? "grounded" : "ungrounded"),
312
+ provenance: {
313
+ schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION,
314
+ runId: run.id,
315
+ source: provenance.source || entry.provenance?.source || "runtime-derived",
316
+ workerId: provenance.workerId || entry.provenance?.workerId,
317
+ taskId: provenance.taskId || entry.provenance?.taskId,
318
+ resultNodeId: provenance.resultNodeId || entry.provenance?.resultNodeId,
319
+ verifierNodeId: provenance.verifierNodeId || entry.provenance?.verifierNodeId,
320
+ candidateId: provenance.candidateId || entry.provenance?.candidateId,
321
+ scoreId: provenance.scoreId || entry.provenance?.scoreId,
322
+ selectionId: provenance.selectionId || entry.provenance?.selectionId,
323
+ commitId: provenance.commitId || entry.provenance?.commitId,
324
+ parentEvidenceIds: unique([...(entry.provenance?.parentEvidenceIds || []), ...(provenance.parentEvidenceIds || [])]).sort(),
325
+ auditEventIds: unique([...(entry.provenance?.auditEventIds || []), ...(provenance.auditEventIds || [])]).sort(),
326
+ note: provenance.note || entry.provenance?.note,
327
+ },
328
+ }));
329
+ }
330
+ function writeTrustAuditIndexPlaceholder(run) {
331
+ const audit = ensureTrustAudit(run);
332
+ (0, fs_atomic_1.writeJson)(audit.summaryPath, { schemaVersion: 1, runId: run.id, eventCount: readEventsRaw(audit.eventLogPath).length });
333
+ }
334
+ function countBy(values, key) {
335
+ const counts = {};
336
+ for (const value of values) {
337
+ const bucket = key(value);
338
+ counts[bucket] = (counts[bucket] || 0) + 1;
339
+ }
340
+ return counts;
341
+ }
342
+ /** MILESTONE 11 (reporting/observability) — the `## Trust Audit` report
343
+ * section's data source. A scoped-down port of the old build's
344
+ * `summarizeTrustAudit` (plugins/cool-workflow/src/trust-audit.ts:413+):
345
+ * this milestone's report.ts only renders eventCount/integrity/byDecision/
346
+ * bySource/bySandboxProfile/paths, so those are the only fields carried
347
+ * here — the old build's extra workers/candidates/commits/multiAgent/
348
+ * blackboard rollups are milestone 9's own summarizeMultiAgent/
349
+ * candidate-scoring-io/coordinator-io surfaces, not duplicated here. */
350
+ function workerRows(events, run) {
351
+ const workerIds = unique([...(run.workers || []).map((w) => w.id), ...events.map((e) => e.workerId || "")]).sort();
352
+ return workerIds.filter(Boolean).map((workerId) => {
353
+ const worker = (run.workers || []).find((w) => w.id === workerId);
354
+ const scoped = events.filter((e) => e.workerId === workerId);
355
+ return {
356
+ workerId,
357
+ taskId: worker?.taskId || scoped.find((e) => e.taskId)?.taskId,
358
+ sandboxProfileId: worker?.sandboxProfileId || scoped.find((e) => e.sandboxProfileId)?.sandboxProfileId,
359
+ decisions: countBy(scoped, (e) => e.decision),
360
+ denied: scoped.filter((e) => e.decision === "denied" || e.decision === "rejected").length,
361
+ feedbackIds: unique(scoped.flatMap((e) => e.feedbackIds || [])).sort(),
362
+ };
363
+ });
364
+ }
365
+ function candidateRows(events, run) {
366
+ const cands = run.candidates || [];
367
+ const selectionsAll = run.candidateSelections || [];
368
+ const ids = unique([...cands.map((c) => c.id), ...events.map((e) => e.candidateId || "")]).sort();
369
+ return ids.filter(Boolean).map((candidateId) => {
370
+ const candidate = cands.find((c) => c.id === candidateId);
371
+ const selections = selectionsAll.filter((s) => s.candidateId === candidateId);
372
+ const scoped = events.filter((e) => e.candidateId === candidateId);
373
+ return {
374
+ candidateId,
375
+ scoreIds: unique([...(candidate?.scores || []), ...scoped.map((e) => e.scoreId || "")]).filter(Boolean).sort(),
376
+ selectionIds: unique([...selections.map((s) => s.id), ...scoped.map((e) => e.selectionId || "")]).filter(Boolean).sort(),
377
+ evidenceCount: candidate?.evidence?.length || scoped.flatMap((e) => e.evidence || []).length,
378
+ };
379
+ });
380
+ }
381
+ function commitRows(events, run) {
382
+ const ids = unique([...(run.commits || []).map((c) => c.id), ...events.map((e) => e.commitId || "")]).sort();
383
+ return ids.filter(Boolean).map((commitId) => {
384
+ const commit = (run.commits || []).find((c) => c.id === commitId);
385
+ return {
386
+ commitId,
387
+ verifierGated: Boolean(commit?.verifierGated),
388
+ candidateId: commit?.candidateId,
389
+ selectionId: commit?.selectionId,
390
+ evidenceCount: commit?.evidence?.length || 0,
391
+ rationale: commit?.acceptanceRationale,
392
+ };
393
+ });
394
+ }
395
+ function summarizeTrustAudit(run) {
396
+ const audit = ensureTrustAudit(run);
397
+ const events = readEventsRaw(audit.eventLogPath);
398
+ const ma = run.multiAgent;
399
+ const bb = run.blackboard;
400
+ const summary = {
401
+ schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION,
402
+ runId: run.id,
403
+ generatedAt: new Date().toISOString(),
404
+ eventCount: events.length,
405
+ integrity: verifyTrustAudit(run),
406
+ eventLogPath: audit.eventLogPath,
407
+ indexPath: audit.indexPath,
408
+ summaryPath: audit.summaryPath,
409
+ byKind: countBy(events, (event) => event.kind),
410
+ byDecision: countBy(events, (event) => event.decision),
411
+ bySource: countBy(events, (event) => event.source),
412
+ bySandboxProfile: countBy(events.filter((event) => event.sandboxProfileId), (event) => event.sandboxProfileId || "none"),
413
+ workers: workerRows(events, run),
414
+ candidates: candidateRows(events, run),
415
+ commits: commitRows(events, run),
416
+ multiAgent: {
417
+ runs: ma?.runs.length || 0,
418
+ roles: ma?.roles.length || 0,
419
+ groups: ma?.groups.length || 0,
420
+ memberships: ma?.memberships.length || 0,
421
+ fanouts: ma?.fanouts.length || 0,
422
+ fanins: ma?.fanins.length || 0,
423
+ events: events.filter((e) => Boolean(e.multiAgentRunId || e.agentRoleId || e.agentGroupId || e.agentMembershipId || e.agentFanoutId || e.agentFaninId)).length,
424
+ },
425
+ blackboard: {
426
+ boards: bb?.boards.length || 0,
427
+ topics: bb?.topics.length || 0,
428
+ messages: bb?.messages.length || 0,
429
+ contexts: bb?.contexts.length || 0,
430
+ artifacts: bb?.artifacts.length || 0,
431
+ snapshots: bb?.snapshots.length || 0,
432
+ decisions: bb?.decisions.length || 0,
433
+ events: events.filter((e) => Boolean(e.blackboardId || e.blackboardTopicId || e.blackboardMessageId || e.blackboardContextId || e.blackboardArtifactRefId || e.blackboardSnapshotId || e.coordinatorDecisionId)).length,
434
+ },
435
+ topologies: {
436
+ runs: run.topologies?.runs.length || 0,
437
+ events: events.filter((e) => Boolean(e.topologyId || e.topologyRunId || e.kind.startsWith("topology."))).length,
438
+ },
439
+ multiAgentTrust: {
440
+ rolePolicies: events.filter((e) => e.kind === "multi-agent.role-policy").length,
441
+ permissionDecisions: events.filter((e) => e.kind === "multi-agent.permission").length,
442
+ blackboardWrites: events.filter((e) => e.kind === "blackboard.write").length,
443
+ messageProvenance: events.filter((e) => e.kind === "blackboard.message-provenance").length,
444
+ judgeRationales: events.filter((e) => e.kind === "judge.rationale").length,
445
+ panelDecisions: events.filter((e) => e.kind === "judge.panel-decision").length,
446
+ policyViolations: events.filter((e) => e.kind === "policy.violation").length,
447
+ },
448
+ };
449
+ // Durable: the summary/index are the read-side view of the audit log; persist
450
+ // them durably so a crash can't leave them pointing past the last durably-
451
+ // appended event. Byte-behavior port of the old build's summarizeTrustAudit.
452
+ (0, fs_atomic_1.writeJson)(audit.summaryPath, summary, { durable: true });
453
+ (0, fs_atomic_1.writeJson)(audit.indexPath, {
454
+ schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION,
455
+ runId: run.id,
456
+ events: events.map((event) => ({
457
+ id: event.id,
458
+ createdAt: event.createdAt,
459
+ kind: event.kind,
460
+ decision: event.decision,
461
+ source: event.source,
462
+ workerId: event.workerId,
463
+ taskId: event.taskId,
464
+ ...indexCorrelationIds(event),
465
+ sandboxProfileId: event.sandboxProfileId,
466
+ policyRef: event.policyRef,
467
+ })),
468
+ }, { durable: true });
469
+ run.audit = { schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION, ...audit };
470
+ return summary;
471
+ }