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
@@ -1,15 +1,57 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
2
+ // core/state/migrations.ts RUN_STATE_MIGRATIONS, findMigrationPath (BFS),
3
+ // migrateRunState, reverseRunState, normalizeRunState.
4
+ //
5
+ // MILESTONE 3. Byte-exact port of the old build's src/state-migrations.ts.
6
+ // Pure: no fs, no clock reads except `new Date(0)` (a fixed epoch
7
+ // constant, not a real clock read) — statePath-derived `runDir`/`cwd`
8
+ // defaults are path math over a string the caller already has, never a
9
+ // real filesystem read.
10
+ //
11
+ // Evidence: SPEC/state-core.md "src/state-migrations.ts — run-state
12
+ // migration", "Migration pipeline (migrateRunState)", "Normalization
13
+ // defaults" (docs/rebuild/PLAN.md byte-compat item 4).
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
5
47
  Object.defineProperty(exports, "__esModule", { value: true });
6
48
  exports.RUN_STATE_MIGRATIONS = void 0;
7
49
  exports.findMigrationPath = findMigrationPath;
8
50
  exports.migrateRunState = migrateRunState;
9
51
  exports.reverseRunState = reverseRunState;
10
- const node_path_1 = __importDefault(require("node:path"));
11
- const version_1 = require("./version");
12
- const run_state_schema_1 = require("./run-state-schema");
52
+ const path = __importStar(require("node:path"));
53
+ const version_1 = require("../version");
54
+ const schema_1 = require("./schema");
13
55
  exports.RUN_STATE_MIGRATIONS = [
14
56
  {
15
57
  from: version_1.LEGACY_RUN_STATE_SCHEMA_VERSION,
@@ -19,22 +61,23 @@ exports.RUN_STATE_MIGRATIONS = [
19
61
  setDefault(state, "schemaVersion", version_1.CURRENT_RUN_STATE_SCHEMA_VERSION, context, "legacy run state did not declare schemaVersion");
20
62
  },
21
63
  reverse(state, context) {
22
- // Reverse: remove schemaVersion to return to legacy format.
23
- // Only removes if the value equals CURRENT_RUN_STATE_SCHEMA_VERSION (fail-closed).
24
64
  if (state.schemaVersion === version_1.CURRENT_RUN_STATE_SCHEMA_VERSION) {
25
65
  delete state.schemaVersion;
26
- context.changes.push({ path: "schemaVersion", before: version_1.CURRENT_RUN_STATE_SCHEMA_VERSION, after: undefined, reason: "reverse: legacy run state unmarks schemaVersion" });
66
+ context.changes.push({
67
+ path: "schemaVersion",
68
+ before: version_1.CURRENT_RUN_STATE_SCHEMA_VERSION,
69
+ after: undefined,
70
+ reason: "reverse: legacy run state unmarks schemaVersion",
71
+ });
27
72
  }
28
- }
29
- }
73
+ },
74
+ },
30
75
  ];
31
- // BSD discipline: mechanism BFS shortest-path resolver over a directed graph of
32
- // migration steps. Forward edges use `from -> to`; reverse edges use `to -> from`
33
- // when a step has a `reverse()` function. Fail-closed: no path → named refusal.
76
+ /** BFS shortest path over forward edges (`from -> to`) plus reverse edges
77
+ * (`to -> from`, only when the step has a `reverse()`). */
34
78
  function findMigrationPath(steps, fromVersion, toVersion) {
35
79
  if (fromVersion === toVersion)
36
80
  return { reachable: true, path: [] };
37
- // Build adjacency: for each step, record forward (from->to) and optional reverse (to->from)
38
81
  const forward = new Map();
39
82
  const reverse = new Map();
40
83
  for (const step of steps) {
@@ -52,7 +95,6 @@ function findMigrationPath(steps, fromVersion, toVersion) {
52
95
  visited.add(fromVersion);
53
96
  while (queue.length > 0) {
54
97
  const current = queue.shift();
55
- // Try forward moves
56
98
  const fwd = forward.get(current.version) || [];
57
99
  for (const move of fwd) {
58
100
  const next = move.edge.to;
@@ -63,10 +105,9 @@ function findMigrationPath(steps, fromVersion, toVersion) {
63
105
  queue.push({ version: next, path: [...current.path, { edge: move.edge, reverse: false }] });
64
106
  }
65
107
  }
66
- // Try reverse moves (only when reverse() is defined on the step)
67
108
  const rev = reverse.get(current.version) || [];
68
109
  for (const move of rev) {
69
- const next = move.edge.from; // reverse direction
110
+ const next = move.edge.from;
70
111
  if (next === toVersion)
71
112
  return { reachable: true, path: [...current.path, { edge: move.edge, reverse: true }] };
72
113
  if (!visited.has(next)) {
@@ -83,15 +124,12 @@ function migrateRunState(input, options = {}) {
83
124
  statePath: options.statePath,
84
125
  detectedSchemaVersion: detectSchemaVersion(input),
85
126
  currentSchemaVersion: version_1.CURRENT_RUN_STATE_SCHEMA_VERSION,
86
- supportedSchemaVersions: {
87
- min: version_1.MIN_SUPPORTED_RUN_STATE_SCHEMA_VERSION,
88
- max: version_1.CURRENT_RUN_STATE_SCHEMA_VERSION
89
- },
127
+ supportedSchemaVersions: { min: version_1.MIN_SUPPORTED_RUN_STATE_SCHEMA_VERSION, max: version_1.CURRENT_RUN_STATE_SCHEMA_VERSION },
90
128
  dryRun: Boolean(options.dryRun),
91
129
  writeRequired: false,
92
130
  changes: [],
93
131
  warnings: [],
94
- errors: []
132
+ errors: [],
95
133
  };
96
134
  if (!isRecord(input)) {
97
135
  report.status = "unsupported";
@@ -117,12 +155,10 @@ function migrateRunState(input, options = {}) {
117
155
  return { run: state, report };
118
156
  }
119
157
  for (const step of resolved.path) {
120
- if (step.reverse) {
158
+ if (step.reverse)
121
159
  step.edge.reverse(state, context);
122
- }
123
- else {
160
+ else
124
161
  step.edge.migrate(state, context);
125
- }
126
162
  }
127
163
  normalizeRunState(state, context);
128
164
  validateMigratedRunState(state, report);
@@ -137,25 +173,18 @@ function migrateRunState(input, options = {}) {
137
173
  report.status = "current";
138
174
  return { run: state, report };
139
175
  }
140
- // BSD discipline: mechanism — reverse migration along the DAG graph. The caller
141
- // supplies a target version; the graph resolver finds a path (which may include
142
- // forward steps AND reverse steps). Fail-closed: no path => named refusal.
143
- // POLICY (kept out of the kernel): whether to reverse, and to which version.
144
176
  function reverseRunState(input, targetSchemaVersion, options = {}) {
145
177
  const report = {
146
178
  status: "current",
147
179
  statePath: options.statePath,
148
180
  detectedSchemaVersion: detectSchemaVersion(input),
149
181
  currentSchemaVersion: targetSchemaVersion,
150
- supportedSchemaVersions: {
151
- min: version_1.MIN_SUPPORTED_RUN_STATE_SCHEMA_VERSION,
152
- max: version_1.CURRENT_RUN_STATE_SCHEMA_VERSION
153
- },
182
+ supportedSchemaVersions: { min: version_1.MIN_SUPPORTED_RUN_STATE_SCHEMA_VERSION, max: version_1.CURRENT_RUN_STATE_SCHEMA_VERSION },
154
183
  dryRun: Boolean(options.dryRun),
155
184
  writeRequired: false,
156
185
  changes: [],
157
186
  warnings: [],
158
- errors: []
187
+ errors: [],
159
188
  };
160
189
  if (!isRecord(input)) {
161
190
  report.status = "unsupported";
@@ -180,16 +209,12 @@ function reverseRunState(input, targetSchemaVersion, options = {}) {
180
209
  report.errors.push(resolved.error || `No reverse path from schemaVersion ${report.detectedSchemaVersion} to ${targetSchemaVersion}.`);
181
210
  return { run: state, report };
182
211
  }
183
- // Apply each step along the path; reverse=true calls edge.reverse(), false calls edge.migrate()
184
212
  for (const step of resolved.path) {
185
- if (step.reverse) {
213
+ if (step.reverse)
186
214
  step.edge.reverse(state, context);
187
- }
188
- else {
215
+ else
189
216
  step.edge.migrate(state, context);
190
- }
191
217
  }
192
- // warn on destructive changes (reverse steps that mutate or remove data)
193
218
  for (const change of report.changes) {
194
219
  if (change.after === undefined && change.before !== undefined) {
195
220
  report.warnings.push(`Destructive reverse change at ${change.path}: removed ${JSON.stringify(change.before)}`);
@@ -206,14 +231,19 @@ function reverseRunState(input, targetSchemaVersion, options = {}) {
206
231
  report.status = "current";
207
232
  return { run: state, report };
208
233
  }
234
+ /** Fill in every WorkflowRun default, each recorded as a StateMigrationChange.
235
+ * Pinned defaults (docs/rebuild/PLAN.md byte-compat item 4): epoch-0 ISO timestamps,
236
+ * cwd = three dirs above the run dir else process.cwd(), workflow.limits =
237
+ * { maxAgents: 8, maxConcurrentAgents: 4 }, loopStage = "interpret" (any
238
+ * unknown value overwritten). */
209
239
  function normalizeRunState(state, context) {
210
- const runDir = context.statePath ? node_path_1.default.dirname(context.statePath) : undefined;
211
- const id = stringValue(state.id) || (runDir ? node_path_1.default.basename(runDir) : "unknown-run");
240
+ const runDir = context.statePath ? path.dirname(context.statePath) : undefined;
241
+ const id = stringValue(state.id) || (runDir ? path.basename(runDir) : "unknown-run");
212
242
  const now = new Date(0).toISOString();
213
243
  setDefault(state, "id", id, context, "run id is required");
214
244
  setDefault(state, "createdAt", stringValue(state.updatedAt) || now, context, "createdAt is required");
215
245
  setDefault(state, "updatedAt", stringValue(state.createdAt) || now, context, "updatedAt is required");
216
- setDefault(state, "cwd", runDir ? node_path_1.default.resolve(runDir, "..", "..", "..") : process.cwd(), context, "cwd is required");
246
+ setDefault(state, "cwd", runDir ? path.resolve(runDir, "..", "..", "..") : process.cwd(), context, "cwd is required");
217
247
  setDefault(state, "inputs", {}, context, "inputs must be present");
218
248
  setDefault(state, "loopStage", "interpret", context, "loopStage is required");
219
249
  if (!isLoopStage(state.loopStage))
@@ -224,23 +254,23 @@ function normalizeRunState(state, context) {
224
254
  setDefault(workflow, "summary", "", context, "workflow.summary is required", "workflow.summary");
225
255
  setDefault(workflow, "limits", { maxAgents: 8, maxConcurrentAgents: 4 }, context, "workflow.limits is required", "workflow.limits");
226
256
  const paths = ensureRecord(state, "paths", context, "run paths are required");
227
- const baseRunDir = stringValue(paths.runDir) || runDir || node_path_1.default.join(String(state.cwd), ".cw", "runs", id);
257
+ const baseRunDir = stringValue(paths.runDir) || runDir || path.join(String(state.cwd), ".cw", "runs", id);
228
258
  setDefault(paths, "runDir", baseRunDir, context, "paths.runDir is required", "paths.runDir");
229
- setDefault(paths, "state", node_path_1.default.join(baseRunDir, "state.json"), context, "paths.state is required", "paths.state");
230
- setDefault(paths, "report", node_path_1.default.join(baseRunDir, "report.md"), context, "paths.report is required", "paths.report");
231
- setDefault(paths, "tasksDir", node_path_1.default.join(baseRunDir, "tasks"), context, "paths.tasksDir is required", "paths.tasksDir");
232
- setDefault(paths, "resultsDir", node_path_1.default.join(baseRunDir, "results"), context, "paths.resultsDir is required", "paths.resultsDir");
233
- setDefault(paths, "dispatchesDir", node_path_1.default.join(baseRunDir, "dispatches"), context, "paths.dispatchesDir is required", "paths.dispatchesDir");
234
- setDefault(paths, "artifactsDir", node_path_1.default.join(baseRunDir, "artifacts"), context, "paths.artifactsDir is required", "paths.artifactsDir");
235
- setDefault(paths, "commitsDir", node_path_1.default.join(baseRunDir, "commits"), context, "paths.commitsDir is required", "paths.commitsDir");
236
- setDefault(paths, "stateNodesDir", node_path_1.default.join(baseRunDir, "nodes"), context, "paths.stateNodesDir is required", "paths.stateNodesDir");
237
- setDefault(paths, "feedbackDir", node_path_1.default.join(baseRunDir, "feedback"), context, "paths.feedbackDir is required", "paths.feedbackDir");
238
- setDefault(paths, "auditDir", node_path_1.default.join(baseRunDir, "audit"), context, "paths.auditDir is required", "paths.auditDir");
239
- setDefault(paths, "workersDir", node_path_1.default.join(baseRunDir, "workers"), context, "paths.workersDir is required", "paths.workersDir");
240
- setDefault(paths, "candidatesDir", node_path_1.default.join(baseRunDir, "candidates"), context, "paths.candidatesDir is required", "paths.candidatesDir");
241
- setDefault(paths, "multiAgentDir", node_path_1.default.join(baseRunDir, "multi-agent"), context, "paths.multiAgentDir is required", "paths.multiAgentDir");
242
- setDefault(paths, "blackboardDir", node_path_1.default.join(baseRunDir, "blackboard"), context, "paths.blackboardDir is required", "paths.blackboardDir");
243
- setDefault(paths, "topologiesDir", node_path_1.default.join(baseRunDir, "topologies"), context, "paths.topologiesDir is required", "paths.topologiesDir");
259
+ setDefault(paths, "state", path.join(baseRunDir, "state.json"), context, "paths.state is required", "paths.state");
260
+ setDefault(paths, "report", path.join(baseRunDir, "report.md"), context, "paths.report is required", "paths.report");
261
+ setDefault(paths, "tasksDir", path.join(baseRunDir, "tasks"), context, "paths.tasksDir is required", "paths.tasksDir");
262
+ setDefault(paths, "resultsDir", path.join(baseRunDir, "results"), context, "paths.resultsDir is required", "paths.resultsDir");
263
+ setDefault(paths, "dispatchesDir", path.join(baseRunDir, "dispatches"), context, "paths.dispatchesDir is required", "paths.dispatchesDir");
264
+ setDefault(paths, "artifactsDir", path.join(baseRunDir, "artifacts"), context, "paths.artifactsDir is required", "paths.artifactsDir");
265
+ setDefault(paths, "commitsDir", path.join(baseRunDir, "commits"), context, "paths.commitsDir is required", "paths.commitsDir");
266
+ setDefault(paths, "stateNodesDir", path.join(baseRunDir, "nodes"), context, "paths.stateNodesDir is required", "paths.stateNodesDir");
267
+ setDefault(paths, "feedbackDir", path.join(baseRunDir, "feedback"), context, "paths.feedbackDir is required", "paths.feedbackDir");
268
+ setDefault(paths, "auditDir", path.join(baseRunDir, "audit"), context, "paths.auditDir is required", "paths.auditDir");
269
+ setDefault(paths, "workersDir", path.join(baseRunDir, "workers"), context, "paths.workersDir is required", "paths.workersDir");
270
+ setDefault(paths, "candidatesDir", path.join(baseRunDir, "candidates"), context, "paths.candidatesDir is required", "paths.candidatesDir");
271
+ setDefault(paths, "multiAgentDir", path.join(baseRunDir, "multi-agent"), context, "paths.multiAgentDir is required", "paths.multiAgentDir");
272
+ setDefault(paths, "blackboardDir", path.join(baseRunDir, "blackboard"), context, "paths.blackboardDir is required", "paths.blackboardDir");
273
+ setDefault(paths, "topologiesDir", path.join(baseRunDir, "topologies"), context, "paths.topologiesDir is required", "paths.topologiesDir");
244
274
  ensureArray(state, "tasks", context);
245
275
  ensureArray(state, "dispatches", context);
246
276
  ensureArray(state, "commits", context);
@@ -252,9 +282,9 @@ function normalizeRunState(state, context) {
252
282
  context.errors.push("audit must be an object when present.");
253
283
  setValue(state, "audit", {
254
284
  schemaVersion: 1,
255
- eventLogPath: node_path_1.default.join(String(paths.auditDir), "events.jsonl"),
256
- summaryPath: node_path_1.default.join(String(paths.auditDir), "summary.json"),
257
- indexPath: node_path_1.default.join(String(paths.auditDir), "index.json")
285
+ eventLogPath: path.join(String(paths.auditDir), "events.jsonl"),
286
+ summaryPath: path.join(String(paths.auditDir), "summary.json"),
287
+ indexPath: path.join(String(paths.auditDir), "index.json"),
258
288
  }, context, "audit metadata is required");
259
289
  }
260
290
  ensureArray(state, "workers", context);
@@ -264,15 +294,7 @@ function normalizeRunState(state, context) {
264
294
  if (!isRecord(state.multiAgent)) {
265
295
  if (state.multiAgent !== undefined)
266
296
  context.errors.push("multiAgent must be an object when present.");
267
- setValue(state, "multiAgent", {
268
- schemaVersion: 1,
269
- runs: [],
270
- roles: [],
271
- groups: [],
272
- memberships: [],
273
- fanouts: [],
274
- fanins: []
275
- }, context, "multiAgent state is required");
297
+ setValue(state, "multiAgent", { schemaVersion: 1, runs: [], roles: [], groups: [], memberships: [], fanouts: [], fanins: [] }, context, "multiAgent state is required");
276
298
  }
277
299
  else {
278
300
  const multiAgent = state.multiAgent;
@@ -288,16 +310,7 @@ function normalizeRunState(state, context) {
288
310
  if (!isRecord(state.blackboard)) {
289
311
  if (state.blackboard !== undefined)
290
312
  context.errors.push("blackboard must be an object when present.");
291
- setValue(state, "blackboard", {
292
- schemaVersion: 1,
293
- boards: [],
294
- topics: [],
295
- messages: [],
296
- contexts: [],
297
- artifacts: [],
298
- snapshots: [],
299
- decisions: []
300
- }, context, "blackboard state is required");
313
+ setValue(state, "blackboard", { schemaVersion: 1, boards: [], topics: [], messages: [], contexts: [], artifacts: [], snapshots: [], decisions: [] }, context, "blackboard state is required");
301
314
  }
302
315
  else {
303
316
  const blackboard = state.blackboard;
@@ -313,10 +326,7 @@ function normalizeRunState(state, context) {
313
326
  if (!isRecord(state.topologies)) {
314
327
  if (state.topologies !== undefined)
315
328
  context.errors.push("topologies must be an object when present.");
316
- setValue(state, "topologies", {
317
- schemaVersion: 1,
318
- runs: []
319
- }, context, "topologies state is required");
329
+ setValue(state, "topologies", { schemaVersion: 1, runs: [] }, context, "topologies state is required");
320
330
  }
321
331
  else {
322
332
  const topologies = state.topologies;
@@ -327,9 +337,6 @@ function normalizeRunState(state, context) {
327
337
  setValue(topologies, "runs", [], context, "topologies.runs must be an array", "topologies.runs");
328
338
  }
329
339
  }
330
- // Team Collaboration (v0.1.32) is purely additive: pre-v0.1.32 runs carry no
331
- // `collaboration` and load unchanged (absent => no approvals, no review gate).
332
- // When present, normalize its append-only arrays so a partial object is honest.
333
340
  if (state.collaboration !== undefined) {
334
341
  if (!isRecord(state.collaboration)) {
335
342
  context.errors.push("collaboration must be an object when present.");
@@ -355,18 +362,18 @@ function normalizeRunState(state, context) {
355
362
  }
356
363
  }
357
364
  function validateMigratedRunState(state, report) {
358
- for (const key of run_state_schema_1.REQUIRED_TOP_LEVEL_KEYS) {
365
+ for (const key of schema_1.REQUIRED_TOP_LEVEL_KEYS) {
359
366
  if (!(key in state))
360
367
  report.errors.push(`Missing required run-state field: ${key}.`);
361
368
  }
362
369
  if (state.schemaVersion !== version_1.CURRENT_RUN_STATE_SCHEMA_VERSION) {
363
370
  report.errors.push(`Expected schemaVersion ${version_1.CURRENT_RUN_STATE_SCHEMA_VERSION}; found ${String(state.schemaVersion)}.`);
364
371
  }
365
- for (const key of run_state_schema_1.REQUIRED_RECORD_KEYS) {
372
+ for (const key of schema_1.REQUIRED_RECORD_KEYS) {
366
373
  if (key in state && !isRecord(state[key]))
367
374
  report.errors.push(`${key} must be an object.`);
368
375
  }
369
- for (const key of run_state_schema_1.REQUIRED_ARRAY_KEYS) {
376
+ for (const key of schema_1.REQUIRED_ARRAY_KEYS) {
370
377
  if (!Array.isArray(state[key]))
371
378
  report.errors.push(`${key} must be an array.`);
372
379
  }
@@ -429,7 +436,7 @@ function derivePhases(tasks) {
429
436
  id: slugify(name),
430
437
  name,
431
438
  status: tasksForPhaseCompleted(tasks, taskIds) ? "completed" : "pending",
432
- taskIds
439
+ taskIds,
433
440
  }));
434
441
  }
435
442
  function tasksForPhaseCompleted(tasks, taskIds) {
@@ -439,11 +446,11 @@ function tasksForPhaseCompleted(tasks, taskIds) {
439
446
  });
440
447
  }
441
448
  function titleize(value) {
442
- return value
449
+ return (value
443
450
  .split(/[-_\s]+/g)
444
451
  .filter(Boolean)
445
452
  .map((part) => part.slice(0, 1).toUpperCase() + part.slice(1))
446
- .join(" ") || "Workflow";
453
+ .join(" ") || "Workflow");
447
454
  }
448
455
  function slugify(value) {
449
456
  const slug = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ // core/state/node-projection.ts — the canonical StateNode projection.
3
+ //
4
+ // MILESTONE 3. Byte-exact port of the old build's src/node-projection.ts
5
+ // PLUS the `normalizeValue`/`replayStableStringify` pair it depends on
6
+ // (src/multi-agent-eval/normalize.ts:9-45). This is the SINGLE source of
7
+ // truth for the 13-field projected-node shape; node-snapshot.ts and (in a
8
+ // later milestone) reclamation.ts's tombstone chain both read from here so
9
+ // the field set can only change in one place.
10
+ //
11
+ // BYTE-IDENTITY [load-bearing]: `normalizeValue` sorts object keys, so field
12
+ // ORDER never affects the bytes — only the field SET matters.
13
+ // `replayStableStringify(value) === JSON.stringify(normalizeValue(value))`.
14
+ //
15
+ // Pure: no I/O, no wall-clock, no random.
16
+ //
17
+ // Evidence: SPEC/state-core.md "src/node-projection.ts — the canonical node
18
+ // projection", "normalizeValue ... drops the keys createdAt, updatedAt,
19
+ // recordedAt, selectedAt, replayedAt, generatedAt ...".
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.normalizeValue = normalizeValue;
22
+ exports.replayStableStringify = replayStableStringify;
23
+ exports.rawNodeProjection = rawNodeProjection;
24
+ exports.projectNodeBody = projectNodeBody;
25
+ exports.nodeProjectionDigestInput = nodeProjectionDigestInput;
26
+ const SCRUBBED_TIMESTAMP_KEYS = new Set(["createdAt", "updatedAt", "recordedAt", "selectedAt", "replayedAt", "generatedAt"]);
27
+ /** Recursively sorts object keys, drops timestamp-shaped keys, and scrubs
28
+ * timestamp/tmp-path substrings out of every string value (so a snapshot
29
+ * body captured at two different wall-clock times, in two different tmp
30
+ * dirs, is byte-identical). Ported literally from the old build's
31
+ * src/multi-agent-eval/normalize.ts — this is the ONE normalizer every
32
+ * node snapshot/replay/diff/eval-line path shares. */
33
+ function normalizeValue(value) {
34
+ if (Array.isArray(value))
35
+ return value.map(normalizeValue);
36
+ if (!value || typeof value !== "object") {
37
+ if (typeof value === "string")
38
+ return normalizeString(value);
39
+ return value;
40
+ }
41
+ const record = value;
42
+ const normalized = {};
43
+ for (const key of Object.keys(record).sort()) {
44
+ if (SCRUBBED_TIMESTAMP_KEYS.has(key))
45
+ continue;
46
+ if (key.endsWith("Path") || key === "path" || key === "cwd" || key === "runDir" || key.endsWith("Dir")) {
47
+ normalized[key] = normalizeString(String(record[key]));
48
+ }
49
+ else {
50
+ normalized[key] = normalizeValue(record[key]);
51
+ }
52
+ }
53
+ return normalized;
54
+ }
55
+ function normalizeString(value) {
56
+ return value
57
+ .replace(/[0-9]{8}T[0-9]{6}Z/g, "<timestamp>")
58
+ .replace(/[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:.]+Z/g, "<timestamp>")
59
+ .replace(/\/[^"\s]+\/\.cw\/runs\/[^"\s/]+/g, "<run-dir>")
60
+ .replace(/\/[^"\s]+\/\.cw\/evals\/[^"\s/]+/g, "<eval-dir>")
61
+ .replace(/\/var\/folders\/[^"\s]+|\/tmp\/[^"\s]+|\/private\/tmp\/[^"\s]+/g, "<tmp>");
62
+ }
63
+ /** Deterministic bytes over a normalized value. */
64
+ function replayStableStringify(value) {
65
+ return JSON.stringify(normalizeValue(value));
66
+ }
67
+ /** The ONE place that lists the 13 projected fields (no `createdAt`/
68
+ * `updatedAt`/`schemaVersion`). Add or drop a projected field here and
69
+ * every consumer follows. */
70
+ function rawNodeProjection(node) {
71
+ return {
72
+ id: node.id,
73
+ kind: node.kind,
74
+ status: node.status,
75
+ loopStage: node.loopStage,
76
+ inputs: node.inputs,
77
+ outputs: node.outputs,
78
+ artifacts: node.artifacts,
79
+ evidence: node.evidence,
80
+ errors: node.errors,
81
+ parents: node.parents,
82
+ children: node.children,
83
+ contractId: node.contractId,
84
+ metadata: node.metadata,
85
+ };
86
+ }
87
+ /** `normalizeValue(rawNodeProjection(node))` — the `NodeSnapshotBody`. */
88
+ function projectNodeBody(node) {
89
+ return normalizeValue(rawNodeProjection(node));
90
+ }
91
+ /** `replayStableStringify(rawNodeProjection(node))` — shared with a later
92
+ * milestone's reclamation tombstone chain so it cannot drift. */
93
+ function nodeProjectionDigestInput(node) {
94
+ return replayStableStringify(rawNodeProjection(node));
95
+ }