cool-workflow 0.1.98 → 0.2.1

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 (315) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +1 -1
  3. package/README.md +18 -7
  4. package/apps/architecture-review/app.json +2 -2
  5. package/apps/architecture-review/workflow.js +12 -12
  6. package/apps/architecture-review-fast/app.json +1 -1
  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/cli/dispatch.js +236 -0
  12. package/dist/cli/entry.js +120 -0
  13. package/dist/cli/io.js +21 -4
  14. package/dist/cli/parseargv.js +157 -0
  15. package/dist/cli.js +6 -33
  16. package/dist/core/capability-table.js +3518 -0
  17. package/dist/core/format/help.js +314 -0
  18. package/dist/{state-explosion/format.js → core/format/state-explosion-text.js} +10 -1
  19. package/dist/core/hash.js +137 -0
  20. package/dist/core/multi-agent/candidate-scoring.js +219 -0
  21. package/dist/core/multi-agent/collaboration.js +481 -0
  22. package/dist/core/multi-agent/coordinator.js +515 -0
  23. package/dist/core/multi-agent/eval-replay.js +306 -0
  24. package/dist/core/multi-agent/runtime.js +929 -0
  25. package/dist/core/multi-agent/topology.js +298 -0
  26. package/dist/core/multi-agent/trust-policy.js +197 -0
  27. package/dist/core/pipeline/commit-gate.js +320 -0
  28. package/dist/{pipeline-contract.js → core/pipeline/contract.js} +24 -37
  29. package/dist/core/pipeline/dispatch.js +103 -0
  30. package/dist/core/pipeline/drive-decide.js +227 -0
  31. package/dist/core/pipeline/error-feedback.js +161 -0
  32. package/dist/core/pipeline/loop-expansion.js +124 -0
  33. package/dist/{result-normalize.js → core/pipeline/result-normalize.js} +14 -37
  34. package/dist/core/pipeline/runner.js +230 -0
  35. package/dist/{contract-migration.js → core/state/contract-migration.js} +68 -92
  36. package/dist/{state-migrations.js → core/state/migrations.js} +103 -96
  37. package/dist/core/state/node-projection.js +95 -0
  38. package/dist/core/state/node-snapshot.js +230 -0
  39. package/dist/core/state/run-paths.js +93 -0
  40. package/dist/{schema-validate.js → core/state/schema-validate.js} +35 -28
  41. package/dist/core/state/schema.js +50 -0
  42. package/dist/core/state/state-explosion/digest.js +243 -0
  43. package/dist/core/state/state-explosion/graph.js +527 -0
  44. package/dist/{state-explosion → core/state/state-explosion}/helpers.js +34 -3
  45. package/dist/core/state/state-explosion/report.js +187 -0
  46. package/dist/{state-explosion → core/state/state-explosion}/size.js +25 -7
  47. package/dist/{state-node.js → core/state/state-node.js} +90 -113
  48. package/dist/core/state/types.js +19 -0
  49. package/dist/{validation.js → core/state/validation.js} +64 -131
  50. package/dist/core/trust/evidence-grounding.js +134 -0
  51. package/dist/core/trust/ledger.js +199 -0
  52. package/dist/{telemetry-attestation.js → core/trust/telemetry-attestation.js} +94 -68
  53. package/dist/core/trust/telemetry-ledger.js +127 -0
  54. package/dist/core/types.js +20 -0
  55. package/dist/core/version.js +16 -0
  56. package/dist/{workflow-app-framework.js → core/workflow-apps/app-schema.js} +337 -426
  57. package/dist/mcp/dispatch.js +104 -0
  58. package/dist/mcp/server.js +144 -0
  59. package/dist/mcp-server.js +6 -84
  60. package/dist/{agent-config.js → shell/agent-config.js} +118 -71
  61. package/dist/shell/app-run-cli.js +88 -0
  62. package/dist/shell/audit-cli.js +259 -0
  63. package/dist/shell/audit-provenance.js +83 -0
  64. package/dist/shell/candidate-scoring-io.js +459 -0
  65. package/dist/shell/collaboration-io.js +264 -0
  66. package/dist/shell/commit-summary.js +104 -0
  67. package/dist/shell/commit.js +290 -0
  68. package/dist/shell/coordinator-io.js +476 -0
  69. package/dist/shell/demo-cli.js +19 -0
  70. package/dist/shell/dispatch.js +162 -0
  71. package/dist/shell/doctor.js +292 -0
  72. package/dist/shell/drive.js +885 -0
  73. package/dist/shell/error-feedback-io.js +305 -0
  74. package/dist/shell/eval-io.js +473 -0
  75. package/dist/{multi-agent-eval/format.js → shell/eval-text.js} +78 -49
  76. package/dist/{evidence-reasoning.js → shell/evidence-reasoning.js} +124 -255
  77. package/dist/shell/exec-backend-cli.js +88 -0
  78. package/dist/shell/execution-backend/agent.js +507 -0
  79. package/dist/shell/execution-backend/ci.js +15 -0
  80. package/dist/shell/execution-backend/container.js +69 -0
  81. package/dist/shell/execution-backend/envelopes.js +55 -0
  82. package/dist/shell/execution-backend/local.js +113 -0
  83. package/dist/shell/execution-backend/probes.js +175 -0
  84. package/dist/shell/execution-backend/registry.js +402 -0
  85. package/dist/shell/execution-backend/remote.js +128 -0
  86. package/dist/shell/execution-backend/types.js +11 -0
  87. package/dist/shell/feedback-cli.js +81 -0
  88. package/dist/shell/feedback-operations.js +48 -0
  89. package/dist/shell/fs-atomic.js +276 -0
  90. package/dist/shell/harness.js +98 -0
  91. package/dist/shell/ledger-cli.js +212 -0
  92. package/dist/shell/ledger-io.js +169 -0
  93. package/dist/shell/man-cli.js +89 -0
  94. package/dist/shell/metrics-cli.js +100 -0
  95. package/dist/shell/multi-agent-cli.js +1002 -0
  96. package/dist/shell/multi-agent-host.js +563 -0
  97. package/dist/shell/multi-agent-io.js +387 -0
  98. package/dist/{multi-agent-operator-ux.js → shell/multi-agent-operator-ux.js} +234 -191
  99. package/dist/shell/node-store.js +124 -0
  100. package/dist/{observability/format.js → shell/observability-format.js} +7 -1
  101. package/dist/{observability/intake.js → shell/observability-intake.js} +79 -56
  102. package/dist/{observability.js → shell/observability.js} +159 -332
  103. package/dist/{onramp.js → shell/onramp.js} +11 -0
  104. package/dist/{operator-ux/format.js → shell/operator-ux-text.js} +250 -239
  105. package/dist/shell/operator-ux.js +431 -0
  106. package/dist/shell/orchestrator.js +231 -0
  107. package/dist/shell/pipeline-cli.js +667 -0
  108. package/dist/shell/pipeline.js +217 -0
  109. package/dist/shell/reclamation-io.js +1366 -0
  110. package/dist/shell/registry-cli.js +344 -0
  111. package/dist/{remote-source.js → shell/remote-source.js} +2 -2
  112. package/dist/shell/report-cli.js +101 -0
  113. package/dist/shell/report-view-cli.js +117 -0
  114. package/dist/{orchestrator → shell}/report.js +289 -282
  115. package/dist/shell/reporter.js +62 -0
  116. package/dist/shell/run-export-cli.js +106 -0
  117. package/dist/shell/run-export.js +680 -0
  118. package/dist/shell/run-registry-io.js +1014 -0
  119. package/dist/shell/run-store.js +164 -0
  120. package/dist/{sandbox-profile.js → shell/sandbox-profile.js} +134 -95
  121. package/dist/{scheduler.js → shell/scheduler-io.js} +257 -48
  122. package/dist/shell/scheduling-io.js +321 -0
  123. package/dist/shell/state-cli.js +181 -0
  124. package/dist/shell/state-explosion-cli.js +197 -0
  125. package/dist/shell/telemetry-cli.js +85 -0
  126. package/dist/{telemetry-demo.js → shell/telemetry-demo.js} +149 -119
  127. package/dist/shell/telemetry-ledger-io.js +132 -0
  128. package/dist/{term.js → shell/term.js} +36 -46
  129. package/dist/shell/topology-io.js +361 -0
  130. package/dist/shell/trust-audit.js +472 -0
  131. package/dist/{multi-agent-trust.js → shell/trust-policy-io.js} +67 -205
  132. package/dist/shell/verifier.js +48 -0
  133. package/dist/shell/workbench-host.js +258 -0
  134. package/dist/shell/workbench-text.js +18 -0
  135. package/dist/shell/workbench.js +170 -0
  136. package/dist/shell/worker-cli.js +124 -0
  137. package/dist/shell/worker-isolation.js +852 -0
  138. package/dist/shell/workflow-app-loader.js +650 -0
  139. package/docs/agent-delegation-drive.7.md +4 -0
  140. package/docs/cli-mcp-parity.7.md +282 -219
  141. package/docs/contract-migration-tooling.7.md +4 -0
  142. package/docs/control-plane-scheduling.7.md +4 -0
  143. package/docs/durable-state-and-locking.7.md +4 -0
  144. package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
  145. package/docs/execution-backends.7.md +4 -0
  146. package/docs/multi-agent-cli-mcp-surface.7.md +4 -0
  147. package/docs/multi-agent-eval-replay-harness.7.md +4 -0
  148. package/docs/multi-agent-operator-ux.7.md +4 -0
  149. package/docs/node-snapshot-diff-replay.7.md +4 -0
  150. package/docs/observability-cost-accounting.7.md +6 -1
  151. package/docs/project-index.md +137 -71
  152. package/docs/real-execution-backends.7.md +4 -0
  153. package/docs/release-and-migration.7.md +4 -0
  154. package/docs/release-tooling.7.md +4 -0
  155. package/docs/remote-source-review.7.md +4 -4
  156. package/docs/report-verifiable-bundle.7.md +1 -1
  157. package/docs/run-registry-control-plane.7.md +4 -0
  158. package/docs/run-retention-reclamation.7.md +25 -0
  159. package/docs/security-trust-hardening.7.md +3 -1
  160. package/docs/state-explosion-management.7.md +4 -0
  161. package/docs/team-collaboration.7.md +4 -0
  162. package/docs/web-desktop-workbench.7.md +15 -1
  163. package/manifest/plugin.manifest.json +1 -1
  164. package/manifest/source-context-profiles.json +9 -13
  165. package/package.json +1 -1
  166. package/scripts/agents/agent-adapter-core.js +22 -2
  167. package/scripts/agents/claude-p-agent.js +8 -3
  168. package/scripts/agents/cw-attest-wrap.js +2 -2
  169. package/scripts/agents/gemini-agent.js +5 -1
  170. package/scripts/agents/opencode-agent.js +5 -1
  171. package/scripts/bump-version.js +4 -3
  172. package/scripts/canonical-apps.js +4 -4
  173. package/scripts/dogfood-architecture-review.js +2 -3
  174. package/scripts/dogfood-release.js +3 -3
  175. package/scripts/gen-parity-doc.js +15 -2
  176. package/scripts/golden-path.js +4 -4
  177. package/scripts/onramp-check.js +1 -1
  178. package/scripts/parity-check.js +38 -21
  179. package/scripts/release-flow.js +2 -2
  180. package/scripts/sync-project-index.js +51 -27
  181. package/scripts/validate-run-state-schema.js +2 -2
  182. package/scripts/version-sync-check.js +30 -30
  183. package/dist/candidate-scoring.js +0 -729
  184. package/dist/capability-core.js +0 -1189
  185. package/dist/capability-registry.js +0 -885
  186. package/dist/cli/command-surface.js +0 -494
  187. package/dist/cli/format.js +0 -56
  188. package/dist/cli/handlers/audit.js +0 -82
  189. package/dist/cli/handlers/blackboard.js +0 -81
  190. package/dist/cli/handlers/candidate.js +0 -40
  191. package/dist/cli/handlers/clones.js +0 -34
  192. package/dist/cli/handlers/collaboration.js +0 -61
  193. package/dist/cli/handlers/eval.js +0 -40
  194. package/dist/cli/handlers/ledger.js +0 -169
  195. package/dist/cli/handlers/maintenance.js +0 -107
  196. package/dist/cli/handlers/multi-agent.js +0 -165
  197. package/dist/cli/handlers/node.js +0 -41
  198. package/dist/cli/handlers/operational.js +0 -155
  199. package/dist/cli/handlers/operator.js +0 -146
  200. package/dist/cli/handlers/registry.js +0 -68
  201. package/dist/cli/handlers/run.js +0 -153
  202. package/dist/cli/handlers/scheduling.js +0 -132
  203. package/dist/cli/handlers/workbench.js +0 -41
  204. package/dist/cli/handlers/worker.js +0 -45
  205. package/dist/cli/run-summary.js +0 -45
  206. package/dist/clones.js +0 -162
  207. package/dist/collaboration.js +0 -726
  208. package/dist/commit.js +0 -592
  209. package/dist/compare.js +0 -18
  210. package/dist/coordinator/classify.js +0 -45
  211. package/dist/coordinator/paths.js +0 -42
  212. package/dist/coordinator/util.js +0 -126
  213. package/dist/coordinator.js +0 -990
  214. package/dist/daemon.js +0 -44
  215. package/dist/dispatch.js +0 -250
  216. package/dist/doctor.js +0 -212
  217. package/dist/drive.js +0 -864
  218. package/dist/error-feedback.js +0 -419
  219. package/dist/evidence-grounding.js +0 -184
  220. package/dist/execution-backend/agent.js +0 -354
  221. package/dist/execution-backend/probes.js +0 -112
  222. package/dist/execution-backend/util.js +0 -47
  223. package/dist/execution-backend.js +0 -961
  224. package/dist/gates.js +0 -48
  225. package/dist/harness.js +0 -61
  226. package/dist/ledger.js +0 -313
  227. package/dist/loop-expansion.js +0 -60
  228. package/dist/mcp/tool-call.js +0 -470
  229. package/dist/mcp/tool-definitions.js +0 -1066
  230. package/dist/mcp-surface.js +0 -30
  231. package/dist/multi-agent/graph.js +0 -84
  232. package/dist/multi-agent/helpers.js +0 -141
  233. package/dist/multi-agent/ids.js +0 -20
  234. package/dist/multi-agent/paths.js +0 -22
  235. package/dist/multi-agent-eval/normalize.js +0 -51
  236. package/dist/multi-agent-eval.js +0 -678
  237. package/dist/multi-agent-host.js +0 -777
  238. package/dist/multi-agent.js +0 -984
  239. package/dist/node-projection.js +0 -59
  240. package/dist/node-snapshot.js +0 -260
  241. package/dist/operator-ux.js +0 -631
  242. package/dist/orchestrator/app-operations.js +0 -211
  243. package/dist/orchestrator/audit-operations.js +0 -182
  244. package/dist/orchestrator/candidate-operations.js +0 -117
  245. package/dist/orchestrator/cli-options.js +0 -294
  246. package/dist/orchestrator/collaboration-operations.js +0 -86
  247. package/dist/orchestrator/feedback-operations.js +0 -81
  248. package/dist/orchestrator/host-operations.js +0 -78
  249. package/dist/orchestrator/lifecycle-operations.js +0 -650
  250. package/dist/orchestrator/migration-operations.js +0 -44
  251. package/dist/orchestrator/multi-agent-operations.js +0 -362
  252. package/dist/orchestrator/topology-operations.js +0 -84
  253. package/dist/orchestrator.js +0 -925
  254. package/dist/pipeline-runner.js +0 -285
  255. package/dist/reclamation/hash.js +0 -72
  256. package/dist/reclamation.js +0 -812
  257. package/dist/reporter.js +0 -67
  258. package/dist/run-export.js +0 -815
  259. package/dist/run-registry/derive.js +0 -175
  260. package/dist/run-registry/format.js +0 -124
  261. package/dist/run-registry/gc.js +0 -251
  262. package/dist/run-registry/policy.js +0 -16
  263. package/dist/run-registry/queue.js +0 -115
  264. package/dist/run-registry.js +0 -850
  265. package/dist/run-state-schema.js +0 -68
  266. package/dist/scheduling.js +0 -184
  267. package/dist/state-explosion.js +0 -1014
  268. package/dist/state.js +0 -367
  269. package/dist/telemetry-ledger.js +0 -196
  270. package/dist/topology.js +0 -565
  271. package/dist/triggers.js +0 -184
  272. package/dist/trust-audit.js +0 -644
  273. package/dist/types/blackboard.js +0 -2
  274. package/dist/types/candidate.js +0 -2
  275. package/dist/types/collaboration.js +0 -2
  276. package/dist/types/core.js +0 -2
  277. package/dist/types/drive.js +0 -10
  278. package/dist/types/error-feedback.js +0 -2
  279. package/dist/types/evidence-reasoning.js +0 -2
  280. package/dist/types/execution-backend.js +0 -2
  281. package/dist/types/multi-agent.js +0 -2
  282. package/dist/types/observability.js +0 -2
  283. package/dist/types/pipeline.js +0 -2
  284. package/dist/types/reclamation.js +0 -8
  285. package/dist/types/report-bundle.js +0 -6
  286. package/dist/types/result.js +0 -2
  287. package/dist/types/run-registry.js +0 -2
  288. package/dist/types/run.js +0 -2
  289. package/dist/types/sandbox.js +0 -2
  290. package/dist/types/schedule.js +0 -2
  291. package/dist/types/state-node.js +0 -2
  292. package/dist/types/topology.js +0 -2
  293. package/dist/types/trust.js +0 -2
  294. package/dist/types/workbench.js +0 -2
  295. package/dist/types/worker.js +0 -2
  296. package/dist/types/workflow-app.js +0 -2
  297. package/dist/types.js +0 -44
  298. package/dist/util/fingerprint.js +0 -19
  299. package/dist/util/fingerprint.test.js +0 -27
  300. package/dist/verifier.js +0 -78
  301. package/dist/version.js +0 -8
  302. package/dist/workbench-host.js +0 -192
  303. package/dist/workbench.js +0 -192
  304. package/dist/worker-accept/acceptance.js +0 -114
  305. package/dist/worker-accept/blackboard-fanout.js +0 -80
  306. package/dist/worker-accept/blackboard-linkage.js +0 -19
  307. package/dist/worker-accept/context.js +0 -2
  308. package/dist/worker-accept/telemetry-ledger.js +0 -126
  309. package/dist/worker-accept/validation.js +0 -77
  310. package/dist/worker-accept/verifier-completion.js +0 -73
  311. package/dist/worker-isolation/helpers.js +0 -51
  312. package/dist/worker-isolation/paths.js +0 -46
  313. package/dist/worker-isolation.js +0 -656
  314. package/dist/workflow-api.js +0 -131
  315. /package/dist/{types → core/types}/boundary.js +0 -0
@@ -0,0 +1,472 @@
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 docs/rebuild/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 docs/rebuild/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 (docs/rebuild/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
+ envVars: input.envVars?.filter(Boolean).sort(),
281
+ evidence: normalizeEvidence(run, input.evidence || [], { source: input.source, workerId: input.workerId, taskId: input.taskId, resultNodeId: input.nodeId }),
282
+ evidenceRefs: unique(input.evidenceRefs || []).sort(),
283
+ parentEventIds: unique(input.parentEventIds || []).sort(),
284
+ metadata: scrubMetadata(input.metadata || {}),
285
+ });
286
+ const prior = readEventsRaw(audit.eventLogPath);
287
+ event.prevEventHash = prior.length ? prior[prior.length - 1].eventHash || computeEventHash(prior[prior.length - 1]) : trustAuditGenesis(run.id);
288
+ event.eventHash = computeEventHash(event);
289
+ (0, fs_atomic_1.durableAppendFileSync)(audit.eventLogPath, `${JSON.stringify(event)}\n`);
290
+ return event;
291
+ }
292
+ function recordSandboxPathDecision(run, input) {
293
+ return recordTrustAuditEvent(run, {
294
+ kind: "sandbox.path",
295
+ decision: input.decision,
296
+ source: "cw-validated",
297
+ workerId: input.workerId,
298
+ taskId: input.taskId,
299
+ sandboxProfileId: input.sandboxProfileId,
300
+ policySnapshot: input.policySnapshot,
301
+ normalizedPath: input.target,
302
+ metadata: input.metadata,
303
+ });
304
+ }
305
+ /** normalizeEvidence — GROUNDING-ONLY provenance. Never carries the
306
+ * agent's command/args/model/handle (those live ONLY in
307
+ * node.metadata.agentDelegation) — this is the exact hygiene split
308
+ * exechard-evidence-triple-hygiene.case.js pins. */
309
+ function normalizeEvidence(run, evidence, provenance) {
310
+ return evidence.map((entry) => ({
311
+ ...entry,
312
+ confidence: entry.confidence || (entry.locator || entry.path || entry.summary ? "grounded" : "ungrounded"),
313
+ provenance: {
314
+ schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION,
315
+ runId: run.id,
316
+ source: provenance.source || entry.provenance?.source || "runtime-derived",
317
+ workerId: provenance.workerId || entry.provenance?.workerId,
318
+ taskId: provenance.taskId || entry.provenance?.taskId,
319
+ resultNodeId: provenance.resultNodeId || entry.provenance?.resultNodeId,
320
+ verifierNodeId: provenance.verifierNodeId || entry.provenance?.verifierNodeId,
321
+ candidateId: provenance.candidateId || entry.provenance?.candidateId,
322
+ scoreId: provenance.scoreId || entry.provenance?.scoreId,
323
+ selectionId: provenance.selectionId || entry.provenance?.selectionId,
324
+ commitId: provenance.commitId || entry.provenance?.commitId,
325
+ parentEvidenceIds: unique([...(entry.provenance?.parentEvidenceIds || []), ...(provenance.parentEvidenceIds || [])]).sort(),
326
+ auditEventIds: unique([...(entry.provenance?.auditEventIds || []), ...(provenance.auditEventIds || [])]).sort(),
327
+ note: provenance.note || entry.provenance?.note,
328
+ },
329
+ }));
330
+ }
331
+ function writeTrustAuditIndexPlaceholder(run) {
332
+ const audit = ensureTrustAudit(run);
333
+ (0, fs_atomic_1.writeJson)(audit.summaryPath, { schemaVersion: 1, runId: run.id, eventCount: readEventsRaw(audit.eventLogPath).length });
334
+ }
335
+ function countBy(values, key) {
336
+ const counts = {};
337
+ for (const value of values) {
338
+ const bucket = key(value);
339
+ counts[bucket] = (counts[bucket] || 0) + 1;
340
+ }
341
+ return counts;
342
+ }
343
+ /** MILESTONE 11 (reporting/observability) — the `## Trust Audit` report
344
+ * section's data source. A scoped-down port of the old build's
345
+ * `summarizeTrustAudit` (plugins/cool-workflow/src/trust-audit.ts:413+):
346
+ * this milestone's report.ts only renders eventCount/integrity/byDecision/
347
+ * bySource/bySandboxProfile/paths, so those are the only fields carried
348
+ * here — the old build's extra workers/candidates/commits/multiAgent/
349
+ * blackboard rollups are milestone 9's own summarizeMultiAgent/
350
+ * candidate-scoring-io/coordinator-io surfaces, not duplicated here. */
351
+ function workerRows(events, run) {
352
+ const workerIds = unique([...(run.workers || []).map((w) => w.id), ...events.map((e) => e.workerId || "")]).sort();
353
+ return workerIds.filter(Boolean).map((workerId) => {
354
+ const worker = (run.workers || []).find((w) => w.id === workerId);
355
+ const scoped = events.filter((e) => e.workerId === workerId);
356
+ return {
357
+ workerId,
358
+ taskId: worker?.taskId || scoped.find((e) => e.taskId)?.taskId,
359
+ sandboxProfileId: worker?.sandboxProfileId || scoped.find((e) => e.sandboxProfileId)?.sandboxProfileId,
360
+ decisions: countBy(scoped, (e) => e.decision),
361
+ denied: scoped.filter((e) => e.decision === "denied" || e.decision === "rejected").length,
362
+ feedbackIds: unique(scoped.flatMap((e) => e.feedbackIds || [])).sort(),
363
+ };
364
+ });
365
+ }
366
+ function candidateRows(events, run) {
367
+ const cands = run.candidates || [];
368
+ const selectionsAll = run.candidateSelections || [];
369
+ const ids = unique([...cands.map((c) => c.id), ...events.map((e) => e.candidateId || "")]).sort();
370
+ return ids.filter(Boolean).map((candidateId) => {
371
+ const candidate = cands.find((c) => c.id === candidateId);
372
+ const selections = selectionsAll.filter((s) => s.candidateId === candidateId);
373
+ const scoped = events.filter((e) => e.candidateId === candidateId);
374
+ return {
375
+ candidateId,
376
+ scoreIds: unique([...(candidate?.scores || []), ...scoped.map((e) => e.scoreId || "")]).filter(Boolean).sort(),
377
+ selectionIds: unique([...selections.map((s) => s.id), ...scoped.map((e) => e.selectionId || "")]).filter(Boolean).sort(),
378
+ evidenceCount: candidate?.evidence?.length || scoped.flatMap((e) => e.evidence || []).length,
379
+ };
380
+ });
381
+ }
382
+ function commitRows(events, run) {
383
+ const ids = unique([...(run.commits || []).map((c) => c.id), ...events.map((e) => e.commitId || "")]).sort();
384
+ return ids.filter(Boolean).map((commitId) => {
385
+ const commit = (run.commits || []).find((c) => c.id === commitId);
386
+ return {
387
+ commitId,
388
+ verifierGated: Boolean(commit?.verifierGated),
389
+ candidateId: commit?.candidateId,
390
+ selectionId: commit?.selectionId,
391
+ evidenceCount: commit?.evidence?.length || 0,
392
+ rationale: commit?.acceptanceRationale,
393
+ };
394
+ });
395
+ }
396
+ function summarizeTrustAudit(run) {
397
+ const audit = ensureTrustAudit(run);
398
+ const events = readEventsRaw(audit.eventLogPath);
399
+ const ma = run.multiAgent;
400
+ const bb = run.blackboard;
401
+ const summary = {
402
+ schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION,
403
+ runId: run.id,
404
+ generatedAt: new Date().toISOString(),
405
+ eventCount: events.length,
406
+ integrity: verifyTrustAudit(run),
407
+ eventLogPath: audit.eventLogPath,
408
+ indexPath: audit.indexPath,
409
+ summaryPath: audit.summaryPath,
410
+ byKind: countBy(events, (event) => event.kind),
411
+ byDecision: countBy(events, (event) => event.decision),
412
+ bySource: countBy(events, (event) => event.source),
413
+ bySandboxProfile: countBy(events.filter((event) => event.sandboxProfileId), (event) => event.sandboxProfileId || "none"),
414
+ workers: workerRows(events, run),
415
+ candidates: candidateRows(events, run),
416
+ commits: commitRows(events, run),
417
+ multiAgent: {
418
+ runs: ma?.runs.length || 0,
419
+ roles: ma?.roles.length || 0,
420
+ groups: ma?.groups.length || 0,
421
+ memberships: ma?.memberships.length || 0,
422
+ fanouts: ma?.fanouts.length || 0,
423
+ fanins: ma?.fanins.length || 0,
424
+ events: events.filter((e) => Boolean(e.multiAgentRunId || e.agentRoleId || e.agentGroupId || e.agentMembershipId || e.agentFanoutId || e.agentFaninId)).length,
425
+ },
426
+ blackboard: {
427
+ boards: bb?.boards.length || 0,
428
+ topics: bb?.topics.length || 0,
429
+ messages: bb?.messages.length || 0,
430
+ contexts: bb?.contexts.length || 0,
431
+ artifacts: bb?.artifacts.length || 0,
432
+ snapshots: bb?.snapshots.length || 0,
433
+ decisions: bb?.decisions.length || 0,
434
+ events: events.filter((e) => Boolean(e.blackboardId || e.blackboardTopicId || e.blackboardMessageId || e.blackboardContextId || e.blackboardArtifactRefId || e.blackboardSnapshotId || e.coordinatorDecisionId)).length,
435
+ },
436
+ topologies: {
437
+ runs: run.topologies?.runs.length || 0,
438
+ events: events.filter((e) => Boolean(e.topologyId || e.topologyRunId || e.kind.startsWith("topology."))).length,
439
+ },
440
+ multiAgentTrust: {
441
+ rolePolicies: events.filter((e) => e.kind === "multi-agent.role-policy").length,
442
+ permissionDecisions: events.filter((e) => e.kind === "multi-agent.permission").length,
443
+ blackboardWrites: events.filter((e) => e.kind === "blackboard.write").length,
444
+ messageProvenance: events.filter((e) => e.kind === "blackboard.message-provenance").length,
445
+ judgeRationales: events.filter((e) => e.kind === "judge.rationale").length,
446
+ panelDecisions: events.filter((e) => e.kind === "judge.panel-decision").length,
447
+ policyViolations: events.filter((e) => e.kind === "policy.violation").length,
448
+ },
449
+ };
450
+ // Durable: the summary/index are the read-side view of the audit log; persist
451
+ // them durably so a crash can't leave them pointing past the last durably-
452
+ // appended event. Byte-behavior port of the old build's summarizeTrustAudit.
453
+ (0, fs_atomic_1.writeJson)(audit.summaryPath, summary, { durable: true });
454
+ (0, fs_atomic_1.writeJson)(audit.indexPath, {
455
+ schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION,
456
+ runId: run.id,
457
+ events: events.map((event) => ({
458
+ id: event.id,
459
+ createdAt: event.createdAt,
460
+ kind: event.kind,
461
+ decision: event.decision,
462
+ source: event.source,
463
+ workerId: event.workerId,
464
+ taskId: event.taskId,
465
+ ...indexCorrelationIds(event),
466
+ sandboxProfileId: event.sandboxProfileId,
467
+ policyRef: event.policyRef,
468
+ })),
469
+ }, { durable: true });
470
+ run.audit = { schemaVersion: exports.TRUST_AUDIT_SCHEMA_VERSION, ...audit };
471
+ return summary;
472
+ }