cool-workflow 0.1.98 → 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 (306) 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} +2 -2
  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 +2 -0
  139. package/docs/cli-mcp-parity.7.md +280 -219
  140. package/docs/contract-migration-tooling.7.md +2 -0
  141. package/docs/control-plane-scheduling.7.md +2 -0
  142. package/docs/durable-state-and-locking.7.md +2 -0
  143. package/docs/evidence-adoption-reasoning-chain.7.md +2 -0
  144. package/docs/execution-backends.7.md +2 -0
  145. package/docs/multi-agent-cli-mcp-surface.7.md +2 -0
  146. package/docs/multi-agent-eval-replay-harness.7.md +2 -0
  147. package/docs/multi-agent-operator-ux.7.md +2 -0
  148. package/docs/node-snapshot-diff-replay.7.md +2 -0
  149. package/docs/observability-cost-accounting.7.md +2 -0
  150. package/docs/project-index.md +132 -71
  151. package/docs/real-execution-backends.7.md +2 -0
  152. package/docs/release-and-migration.7.md +2 -0
  153. package/docs/release-tooling.7.md +2 -0
  154. package/docs/run-registry-control-plane.7.md +2 -0
  155. package/docs/run-retention-reclamation.7.md +23 -0
  156. package/docs/state-explosion-management.7.md +2 -0
  157. package/docs/team-collaboration.7.md +2 -0
  158. package/docs/web-desktop-workbench.7.md +2 -0
  159. package/manifest/plugin.manifest.json +1 -1
  160. package/manifest/source-context-profiles.json +9 -13
  161. package/package.json +1 -1
  162. package/scripts/agents/cw-attest-wrap.js +2 -2
  163. package/scripts/bump-version.js +4 -3
  164. package/scripts/canonical-apps.js +4 -4
  165. package/scripts/dogfood-architecture-review.js +2 -3
  166. package/scripts/dogfood-release.js +3 -3
  167. package/scripts/gen-parity-doc.js +15 -2
  168. package/scripts/golden-path.js +4 -4
  169. package/scripts/onramp-check.js +1 -1
  170. package/scripts/parity-check.js +38 -21
  171. package/scripts/release-flow.js +2 -2
  172. package/scripts/sync-project-index.js +51 -27
  173. package/scripts/validate-run-state-schema.js +2 -2
  174. package/scripts/version-sync-check.js +30 -30
  175. package/dist/candidate-scoring.js +0 -729
  176. package/dist/capability-core.js +0 -1189
  177. package/dist/capability-registry.js +0 -885
  178. package/dist/cli/command-surface.js +0 -494
  179. package/dist/cli/format.js +0 -56
  180. package/dist/cli/handlers/audit.js +0 -82
  181. package/dist/cli/handlers/blackboard.js +0 -81
  182. package/dist/cli/handlers/candidate.js +0 -40
  183. package/dist/cli/handlers/clones.js +0 -34
  184. package/dist/cli/handlers/collaboration.js +0 -61
  185. package/dist/cli/handlers/eval.js +0 -40
  186. package/dist/cli/handlers/ledger.js +0 -169
  187. package/dist/cli/handlers/maintenance.js +0 -107
  188. package/dist/cli/handlers/multi-agent.js +0 -165
  189. package/dist/cli/handlers/node.js +0 -41
  190. package/dist/cli/handlers/operational.js +0 -155
  191. package/dist/cli/handlers/operator.js +0 -146
  192. package/dist/cli/handlers/registry.js +0 -68
  193. package/dist/cli/handlers/run.js +0 -153
  194. package/dist/cli/handlers/scheduling.js +0 -132
  195. package/dist/cli/handlers/workbench.js +0 -41
  196. package/dist/cli/handlers/worker.js +0 -45
  197. package/dist/cli/run-summary.js +0 -45
  198. package/dist/clones.js +0 -162
  199. package/dist/collaboration.js +0 -726
  200. package/dist/commit.js +0 -592
  201. package/dist/compare.js +0 -18
  202. package/dist/coordinator/classify.js +0 -45
  203. package/dist/coordinator/paths.js +0 -42
  204. package/dist/coordinator/util.js +0 -126
  205. package/dist/coordinator.js +0 -990
  206. package/dist/daemon.js +0 -44
  207. package/dist/dispatch.js +0 -250
  208. package/dist/drive.js +0 -864
  209. package/dist/error-feedback.js +0 -419
  210. package/dist/evidence-grounding.js +0 -184
  211. package/dist/execution-backend/agent.js +0 -354
  212. package/dist/execution-backend/probes.js +0 -112
  213. package/dist/execution-backend/util.js +0 -47
  214. package/dist/execution-backend.js +0 -961
  215. package/dist/gates.js +0 -48
  216. package/dist/harness.js +0 -61
  217. package/dist/ledger.js +0 -313
  218. package/dist/loop-expansion.js +0 -60
  219. package/dist/mcp/tool-call.js +0 -470
  220. package/dist/mcp/tool-definitions.js +0 -1066
  221. package/dist/mcp-surface.js +0 -30
  222. package/dist/multi-agent/graph.js +0 -84
  223. package/dist/multi-agent/helpers.js +0 -141
  224. package/dist/multi-agent/ids.js +0 -20
  225. package/dist/multi-agent/paths.js +0 -22
  226. package/dist/multi-agent-eval/normalize.js +0 -51
  227. package/dist/multi-agent-eval.js +0 -678
  228. package/dist/multi-agent-host.js +0 -777
  229. package/dist/multi-agent.js +0 -984
  230. package/dist/node-projection.js +0 -59
  231. package/dist/node-snapshot.js +0 -260
  232. package/dist/operator-ux.js +0 -631
  233. package/dist/orchestrator/app-operations.js +0 -211
  234. package/dist/orchestrator/audit-operations.js +0 -182
  235. package/dist/orchestrator/candidate-operations.js +0 -117
  236. package/dist/orchestrator/cli-options.js +0 -294
  237. package/dist/orchestrator/collaboration-operations.js +0 -86
  238. package/dist/orchestrator/feedback-operations.js +0 -81
  239. package/dist/orchestrator/host-operations.js +0 -78
  240. package/dist/orchestrator/lifecycle-operations.js +0 -650
  241. package/dist/orchestrator/migration-operations.js +0 -44
  242. package/dist/orchestrator/multi-agent-operations.js +0 -362
  243. package/dist/orchestrator/topology-operations.js +0 -84
  244. package/dist/orchestrator.js +0 -925
  245. package/dist/pipeline-runner.js +0 -285
  246. package/dist/reclamation/hash.js +0 -72
  247. package/dist/reclamation.js +0 -812
  248. package/dist/reporter.js +0 -67
  249. package/dist/run-export.js +0 -815
  250. package/dist/run-registry/derive.js +0 -175
  251. package/dist/run-registry/format.js +0 -124
  252. package/dist/run-registry/gc.js +0 -251
  253. package/dist/run-registry/policy.js +0 -16
  254. package/dist/run-registry/queue.js +0 -115
  255. package/dist/run-registry.js +0 -850
  256. package/dist/run-state-schema.js +0 -68
  257. package/dist/scheduling.js +0 -184
  258. package/dist/state-explosion.js +0 -1014
  259. package/dist/state.js +0 -367
  260. package/dist/telemetry-ledger.js +0 -196
  261. package/dist/topology.js +0 -565
  262. package/dist/triggers.js +0 -184
  263. package/dist/trust-audit.js +0 -644
  264. package/dist/types/blackboard.js +0 -2
  265. package/dist/types/candidate.js +0 -2
  266. package/dist/types/collaboration.js +0 -2
  267. package/dist/types/core.js +0 -2
  268. package/dist/types/drive.js +0 -10
  269. package/dist/types/error-feedback.js +0 -2
  270. package/dist/types/evidence-reasoning.js +0 -2
  271. package/dist/types/execution-backend.js +0 -2
  272. package/dist/types/multi-agent.js +0 -2
  273. package/dist/types/observability.js +0 -2
  274. package/dist/types/pipeline.js +0 -2
  275. package/dist/types/reclamation.js +0 -8
  276. package/dist/types/report-bundle.js +0 -6
  277. package/dist/types/result.js +0 -2
  278. package/dist/types/run-registry.js +0 -2
  279. package/dist/types/run.js +0 -2
  280. package/dist/types/sandbox.js +0 -2
  281. package/dist/types/schedule.js +0 -2
  282. package/dist/types/state-node.js +0 -2
  283. package/dist/types/topology.js +0 -2
  284. package/dist/types/trust.js +0 -2
  285. package/dist/types/workbench.js +0 -2
  286. package/dist/types/worker.js +0 -2
  287. package/dist/types/workflow-app.js +0 -2
  288. package/dist/types.js +0 -44
  289. package/dist/util/fingerprint.js +0 -19
  290. package/dist/util/fingerprint.test.js +0 -27
  291. package/dist/verifier.js +0 -78
  292. package/dist/version.js +0 -8
  293. package/dist/workbench-host.js +0 -192
  294. package/dist/workbench.js +0 -192
  295. package/dist/worker-accept/acceptance.js +0 -114
  296. package/dist/worker-accept/blackboard-fanout.js +0 -80
  297. package/dist/worker-accept/blackboard-linkage.js +0 -19
  298. package/dist/worker-accept/context.js +0 -2
  299. package/dist/worker-accept/telemetry-ledger.js +0 -126
  300. package/dist/worker-accept/validation.js +0 -77
  301. package/dist/worker-accept/verifier-completion.js +0 -73
  302. package/dist/worker-isolation/helpers.js +0 -51
  303. package/dist/worker-isolation/paths.js +0 -46
  304. package/dist/worker-isolation.js +0 -656
  305. package/dist/workflow-api.js +0 -131
  306. /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
+ }