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
@@ -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" (v2/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 (v2/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
+ }