taskflow-core 0.1.8 → 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 (193) hide show
  1. package/README.md +248 -808
  2. package/dist/agents.d.ts +12 -0
  3. package/dist/agents.d.ts.map +1 -1
  4. package/dist/agents.js +29 -1
  5. package/dist/agents.js.map +1 -1
  6. package/dist/cwd-bridge.d.ts +61 -0
  7. package/dist/cwd-bridge.d.ts.map +1 -0
  8. package/dist/cwd-bridge.js +136 -0
  9. package/dist/cwd-bridge.js.map +1 -0
  10. package/dist/detached-runner.js +31 -5
  11. package/dist/detached-runner.js.map +1 -1
  12. package/dist/deterministic.d.ts +8 -0
  13. package/dist/deterministic.d.ts.map +1 -1
  14. package/dist/deterministic.js +23 -1
  15. package/dist/deterministic.js.map +1 -1
  16. package/dist/exec/driver.d.ts +48 -0
  17. package/dist/exec/driver.d.ts.map +1 -0
  18. package/dist/exec/driver.js +410 -0
  19. package/dist/exec/driver.js.map +1 -0
  20. package/dist/exec/events.d.ts +76 -0
  21. package/dist/exec/events.d.ts.map +1 -0
  22. package/dist/exec/events.js +108 -0
  23. package/dist/exec/events.js.map +1 -0
  24. package/dist/exec/fold.d.ts +45 -0
  25. package/dist/exec/fold.d.ts.map +1 -0
  26. package/dist/exec/fold.js +122 -0
  27. package/dist/exec/fold.js.map +1 -0
  28. package/dist/exec/index.d.ts +17 -0
  29. package/dist/exec/index.d.ts.map +1 -0
  30. package/dist/exec/index.js +17 -0
  31. package/dist/exec/index.js.map +1 -0
  32. package/dist/exec/kernel-policy.d.ts +35 -0
  33. package/dist/exec/kernel-policy.d.ts.map +1 -0
  34. package/dist/exec/kernel-policy.js +184 -0
  35. package/dist/exec/kernel-policy.js.map +1 -0
  36. package/dist/exec/step-kinds.d.ts +41 -0
  37. package/dist/exec/step-kinds.d.ts.map +1 -0
  38. package/dist/exec/step-kinds.js +599 -0
  39. package/dist/exec/step-kinds.js.map +1 -0
  40. package/dist/exec/step.d.ts +94 -0
  41. package/dist/exec/step.d.ts.map +1 -0
  42. package/dist/exec/step.js +454 -0
  43. package/dist/exec/step.js.map +1 -0
  44. package/dist/flowir/canonical-hash.d.ts +101 -0
  45. package/dist/flowir/canonical-hash.d.ts.map +1 -0
  46. package/dist/flowir/canonical-hash.js +219 -0
  47. package/dist/flowir/canonical-hash.js.map +1 -0
  48. package/dist/flowir/compile.d.ts +49 -0
  49. package/dist/flowir/compile.d.ts.map +1 -0
  50. package/dist/flowir/compile.js +232 -0
  51. package/dist/flowir/compile.js.map +1 -0
  52. package/dist/flowir/cond.d.ts +76 -0
  53. package/dist/flowir/cond.d.ts.map +1 -0
  54. package/dist/flowir/cond.js +214 -0
  55. package/dist/flowir/cond.js.map +1 -0
  56. package/dist/flowir/index.d.ts +20 -23
  57. package/dist/flowir/index.d.ts.map +1 -1
  58. package/dist/flowir/index.js +47 -35
  59. package/dist/flowir/index.js.map +1 -1
  60. package/dist/flowir/meta.d.ts +4 -4
  61. package/dist/flowir/meta.d.ts.map +1 -1
  62. package/dist/flowir/phasefp.d.ts.map +1 -1
  63. package/dist/flowir/phasefp.js +13 -1
  64. package/dist/flowir/phasefp.js.map +1 -1
  65. package/dist/flowir/schema.d.ts +260 -0
  66. package/dist/flowir/schema.d.ts.map +1 -0
  67. package/dist/flowir/schema.js +234 -0
  68. package/dist/flowir/schema.js.map +1 -0
  69. package/dist/flowir/translate.d.ts.map +1 -1
  70. package/dist/flowir/translate.js +3 -0
  71. package/dist/flowir/translate.js.map +1 -1
  72. package/dist/host/runner-types.d.ts +19 -0
  73. package/dist/host/runner-types.d.ts.map +1 -1
  74. package/dist/index.d.ts +4 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +8 -0
  77. package/dist/index.js.map +1 -1
  78. package/dist/interpolate.d.ts +4 -0
  79. package/dist/interpolate.d.ts.map +1 -1
  80. package/dist/interpolate.js +14 -0
  81. package/dist/interpolate.js.map +1 -1
  82. package/dist/rates.d.ts +121 -0
  83. package/dist/rates.d.ts.map +1 -0
  84. package/dist/rates.js +187 -0
  85. package/dist/rates.js.map +1 -0
  86. package/dist/replay.d.ts +43 -50
  87. package/dist/replay.d.ts.map +1 -1
  88. package/dist/replay.js +629 -19
  89. package/dist/replay.js.map +1 -1
  90. package/dist/resources/authority.d.ts +35 -0
  91. package/dist/resources/authority.d.ts.map +1 -0
  92. package/dist/resources/authority.js +67 -0
  93. package/dist/resources/authority.js.map +1 -0
  94. package/dist/resources/backend.d.ts +302 -0
  95. package/dist/resources/backend.d.ts.map +1 -0
  96. package/dist/resources/backend.js +16 -0
  97. package/dist/resources/backend.js.map +1 -0
  98. package/dist/resources/baseline.d.ts +116 -0
  99. package/dist/resources/baseline.d.ts.map +1 -0
  100. package/dist/resources/baseline.js +447 -0
  101. package/dist/resources/baseline.js.map +1 -0
  102. package/dist/resources/canonical-json.d.ts +7 -0
  103. package/dist/resources/canonical-json.d.ts.map +1 -0
  104. package/dist/resources/canonical-json.js +75 -0
  105. package/dist/resources/canonical-json.js.map +1 -0
  106. package/dist/resources/errors.d.ts +23 -0
  107. package/dist/resources/errors.d.ts.map +1 -0
  108. package/dist/resources/errors.js +89 -0
  109. package/dist/resources/errors.js.map +1 -0
  110. package/dist/resources/execution.d.ts +90 -0
  111. package/dist/resources/execution.d.ts.map +1 -0
  112. package/dist/resources/execution.js +581 -0
  113. package/dist/resources/execution.js.map +1 -0
  114. package/dist/resources/index.d.ts +15 -0
  115. package/dist/resources/index.d.ts.map +1 -0
  116. package/dist/resources/index.js +15 -0
  117. package/dist/resources/index.js.map +1 -0
  118. package/dist/resources/journal.d.ts +138 -0
  119. package/dist/resources/journal.d.ts.map +1 -0
  120. package/dist/resources/journal.js +438 -0
  121. package/dist/resources/journal.js.map +1 -0
  122. package/dist/resources/leases.d.ts +51 -0
  123. package/dist/resources/leases.d.ts.map +1 -0
  124. package/dist/resources/leases.js +354 -0
  125. package/dist/resources/leases.js.map +1 -0
  126. package/dist/resources/permits.d.ts +52 -0
  127. package/dist/resources/permits.d.ts.map +1 -0
  128. package/dist/resources/permits.js +240 -0
  129. package/dist/resources/permits.js.map +1 -0
  130. package/dist/resources/persistence.d.ts +63 -0
  131. package/dist/resources/persistence.d.ts.map +1 -0
  132. package/dist/resources/persistence.js +522 -0
  133. package/dist/resources/persistence.js.map +1 -0
  134. package/dist/resources/registry.d.ts +56 -0
  135. package/dist/resources/registry.d.ts.map +1 -0
  136. package/dist/resources/registry.js +139 -0
  137. package/dist/resources/registry.js.map +1 -0
  138. package/dist/resources/resolve.d.ts +49 -0
  139. package/dist/resources/resolve.d.ts.map +1 -0
  140. package/dist/resources/resolve.js +309 -0
  141. package/dist/resources/resolve.js.map +1 -0
  142. package/dist/resources/sandbox.d.ts +72 -0
  143. package/dist/resources/sandbox.d.ts.map +1 -0
  144. package/dist/resources/sandbox.js +952 -0
  145. package/dist/resources/sandbox.js.map +1 -0
  146. package/dist/resources/schema.d.ts +195 -0
  147. package/dist/resources/schema.d.ts.map +1 -0
  148. package/dist/resources/schema.js +231 -0
  149. package/dist/resources/schema.js.map +1 -0
  150. package/dist/resources/types.d.ts +36 -0
  151. package/dist/resources/types.d.ts.map +1 -0
  152. package/dist/resources/types.js +75 -0
  153. package/dist/resources/types.js.map +1 -0
  154. package/dist/runner-core.d.ts +53 -0
  155. package/dist/runner-core.d.ts.map +1 -1
  156. package/dist/runner-core.js +521 -53
  157. package/dist/runner-core.js.map +1 -1
  158. package/dist/runtime/phases/approval.d.ts +23 -0
  159. package/dist/runtime/phases/approval.d.ts.map +1 -0
  160. package/dist/runtime/phases/approval.js +38 -0
  161. package/dist/runtime/phases/approval.js.map +1 -0
  162. package/dist/runtime/phases/expand.d.ts +29 -0
  163. package/dist/runtime/phases/expand.d.ts.map +1 -0
  164. package/dist/runtime/phases/expand.js +126 -0
  165. package/dist/runtime/phases/expand.js.map +1 -0
  166. package/dist/runtime/phases/parallel.d.ts +26 -0
  167. package/dist/runtime/phases/parallel.d.ts.map +1 -0
  168. package/dist/runtime/phases/parallel.js +15 -0
  169. package/dist/runtime/phases/parallel.js.map +1 -0
  170. package/dist/runtime/phases/race.d.ts +31 -0
  171. package/dist/runtime/phases/race.d.ts.map +1 -0
  172. package/dist/runtime/phases/race.js +220 -0
  173. package/dist/runtime/phases/race.js.map +1 -0
  174. package/dist/runtime/phases/script.d.ts +38 -0
  175. package/dist/runtime/phases/script.d.ts.map +1 -0
  176. package/dist/runtime/phases/script.js +177 -0
  177. package/dist/runtime/phases/script.js.map +1 -0
  178. package/dist/runtime.d.ts +68 -16
  179. package/dist/runtime.d.ts.map +1 -1
  180. package/dist/runtime.js +1091 -337
  181. package/dist/runtime.js.map +1 -1
  182. package/dist/schema.d.ts +104 -9
  183. package/dist/schema.d.ts.map +1 -1
  184. package/dist/schema.js +249 -32
  185. package/dist/schema.js.map +1 -1
  186. package/dist/store.d.ts +13 -0
  187. package/dist/store.d.ts.map +1 -1
  188. package/dist/store.js.map +1 -1
  189. package/dist/trace.d.ts +7 -1
  190. package/dist/trace.d.ts.map +1 -1
  191. package/dist/trace.js +33 -26
  192. package/dist/trace.js.map +1 -1
  193. package/package.json +7 -5
@@ -0,0 +1,101 @@
1
+ /**
2
+ * # Genuine content-addressed hash over canonical FlowIR
3
+ *
4
+ * This is pi-taskflow's **own** content-addressed hash (Q5=own) over the
5
+ * canonical {@link FlowIR} type contract defined in `./schema.ts`. Unlike
6
+ * `./hash.ts`'s `flowDefHash` — which fingerprints the *DSL Taskflow
7
+ * definition* (vendored from overstory, async Web Crypto, truncated to 16
8
+ * bytes / 32 hex) — this module hashes the *compiled IR* synchronously with
9
+ * `node:crypto` SHA-256 (full 64-hex-char digest). The two answer different
10
+ * questions:
11
+ *
12
+ * - `flowDefHash(def)` — "did the *flow definition* change?" (DSL-level)
13
+ * - `hashFlowIR(ir)` — "is this *compiled IR* the same IR?" (IR-level)
14
+ *
15
+ * Wired into `compileTaskflowToIR` via `hashFlowIR` (`ir:<64-hex>`).
16
+ * The IR-level hash is the content-addressed key the event-sourced kernel
17
+ * (batch 2, `flowir/compile.ts`) will use to deduplicate compiled graphs and
18
+ * to key per-phase fingerprints (`hashNode`) independent of surface formatting.
19
+ *
20
+ * ## Canonicalization guarantees
21
+ *
22
+ * {@link canonicalizeFlowIR} produces a DETERMINISTIC serialization that is
23
+ * invariant under the cosmetic differences two logically-equivalent IRs may
24
+ * differ by:
25
+ *
26
+ * - **Object key order** — all object keys are stable-sorted (UTF-16 code
27
+ * units), so reordering fields on a node or on the IR object does not
28
+ * change the canonical form.
29
+ * - **Node array order** — `nodes` is re-sorted by `id` (stable), so two IRs
30
+ * that list the same nodes in different order canonicalize identically.
31
+ * Other arrays (`inject`, `emits`, `deps`, `edges`) keep their order —
32
+ * their ordering is semantically meaningful (declared-read order, edge
33
+ * declaration order) and must be preserved.
34
+ * - **Condition spelling** — a node's `when` guard is canonicalized via
35
+ * {@link normalizeCond} (`./cond.ts`), which collapses whitespace, operator
36
+ * spacing, and redundant enclosing parens while preserving string-literal
37
+ * contents. Equivalent conditions canonicalize identically.
38
+ * - **Insignificant formatting** — `undefined` optional fields are dropped,
39
+ * so their presence/absence does not change the hash.
40
+ *
41
+ * Two logically-equivalent FlowIRs (key reorder, whitespace, equivalent
42
+ * condition spelling) MUST canonicalize to the same string.
43
+ *
44
+ * ## Domain-separated digests
45
+ *
46
+ * Return values are prefixed:
47
+ * - `hashFlowIR` → `ir:<64-hex>`
48
+ * - `hashNode` → `node:<64-hex>`
49
+ *
50
+ * so IR-level and node-level digests never collide in a shared cache key
51
+ * namespace.
52
+ *
53
+ * ## Purity
54
+ *
55
+ * Zero runtime deps besides `node:crypto`. No IO, no `Date`, no randomness,
56
+ * never throws. The hash is synchronous (unlike `flowDefHash`).
57
+ *
58
+ * Exported from the FlowIR barrel (`./index.ts`) for consumers; **not yet
59
+ * wired** into runtime/cache — `usedFallbackHash` is untouched. Wiring
60
+ * happens in batch 2.
61
+ *
62
+ * @see ./schema.ts for the canonical FlowIR type contract.
63
+ * @see ./cond.ts for condition normalization (`normalizeCond`).
64
+ * @see ./hash.ts for the DSL-level `flowDefHash` (vendored from overstory).
65
+ */
66
+ import type { FlowIR, FlowIRNode } from "./schema.ts";
67
+ /**
68
+ * Deterministic, order- and whitespace-independent canonical serialization of
69
+ * a {@link FlowIR}.
70
+ *
71
+ * - `nodes` is re-sorted by `id` (stable) so node-list order does not affect
72
+ * the result.
73
+ * - Each node's `when` guard is canonicalized via {@link normalizeCond}.
74
+ * - All object keys are stable-sorted; `undefined` optionals are dropped.
75
+ * - `inject`/`emits`/`deps`/`edges` arrays keep their order (semantic).
76
+ *
77
+ * Two logically-equivalent FlowIRs MUST canonicalize to the same string.
78
+ * Never throws.
79
+ */
80
+ export declare function canonicalizeFlowIR(ir: FlowIR): string;
81
+ /**
82
+ * Deterministic canonical serialization of a single {@link FlowIRNode}, for
83
+ * per-node content addressing. Same canonicalization rules as
84
+ * {@link canonicalizeFlowIR} applied to one node (`when` normalized, keys
85
+ * sorted, `undefined` optionals dropped, `inject`/`emits`/`deps` order
86
+ * preserved). Never throws.
87
+ */
88
+ export declare function canonicalizeNode(node: FlowIRNode): string;
89
+ /**
90
+ * Domain-separated content hash of a compiled FlowIR.
91
+ * Returns `ir:<64 lowercase hex SHA-256 chars>` over {@link canonicalizeFlowIR}.
92
+ * Synchronous. Never throws.
93
+ */
94
+ export declare function hashFlowIR(ir: FlowIR): string;
95
+ /**
96
+ * Domain-separated per-node content hash.
97
+ * Returns `node:<64 lowercase hex SHA-256 chars>` over {@link canonicalizeNode}.
98
+ * Synchronous. Never throws.
99
+ */
100
+ export declare function hashNode(node: FlowIRNode): string;
101
+ //# sourceMappingURL=canonical-hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-hash.d.ts","sourceRoot":"","sources":["../../src/flowir/canonical-hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA8EtD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAoBrD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAEzD;AAMD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAGjD"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * # Genuine content-addressed hash over canonical FlowIR
3
+ *
4
+ * This is pi-taskflow's **own** content-addressed hash (Q5=own) over the
5
+ * canonical {@link FlowIR} type contract defined in `./schema.ts`. Unlike
6
+ * `./hash.ts`'s `flowDefHash` — which fingerprints the *DSL Taskflow
7
+ * definition* (vendored from overstory, async Web Crypto, truncated to 16
8
+ * bytes / 32 hex) — this module hashes the *compiled IR* synchronously with
9
+ * `node:crypto` SHA-256 (full 64-hex-char digest). The two answer different
10
+ * questions:
11
+ *
12
+ * - `flowDefHash(def)` — "did the *flow definition* change?" (DSL-level)
13
+ * - `hashFlowIR(ir)` — "is this *compiled IR* the same IR?" (IR-level)
14
+ *
15
+ * Wired into `compileTaskflowToIR` via `hashFlowIR` (`ir:<64-hex>`).
16
+ * The IR-level hash is the content-addressed key the event-sourced kernel
17
+ * (batch 2, `flowir/compile.ts`) will use to deduplicate compiled graphs and
18
+ * to key per-phase fingerprints (`hashNode`) independent of surface formatting.
19
+ *
20
+ * ## Canonicalization guarantees
21
+ *
22
+ * {@link canonicalizeFlowIR} produces a DETERMINISTIC serialization that is
23
+ * invariant under the cosmetic differences two logically-equivalent IRs may
24
+ * differ by:
25
+ *
26
+ * - **Object key order** — all object keys are stable-sorted (UTF-16 code
27
+ * units), so reordering fields on a node or on the IR object does not
28
+ * change the canonical form.
29
+ * - **Node array order** — `nodes` is re-sorted by `id` (stable), so two IRs
30
+ * that list the same nodes in different order canonicalize identically.
31
+ * Other arrays (`inject`, `emits`, `deps`, `edges`) keep their order —
32
+ * their ordering is semantically meaningful (declared-read order, edge
33
+ * declaration order) and must be preserved.
34
+ * - **Condition spelling** — a node's `when` guard is canonicalized via
35
+ * {@link normalizeCond} (`./cond.ts`), which collapses whitespace, operator
36
+ * spacing, and redundant enclosing parens while preserving string-literal
37
+ * contents. Equivalent conditions canonicalize identically.
38
+ * - **Insignificant formatting** — `undefined` optional fields are dropped,
39
+ * so their presence/absence does not change the hash.
40
+ *
41
+ * Two logically-equivalent FlowIRs (key reorder, whitespace, equivalent
42
+ * condition spelling) MUST canonicalize to the same string.
43
+ *
44
+ * ## Domain-separated digests
45
+ *
46
+ * Return values are prefixed:
47
+ * - `hashFlowIR` → `ir:<64-hex>`
48
+ * - `hashNode` → `node:<64-hex>`
49
+ *
50
+ * so IR-level and node-level digests never collide in a shared cache key
51
+ * namespace.
52
+ *
53
+ * ## Purity
54
+ *
55
+ * Zero runtime deps besides `node:crypto`. No IO, no `Date`, no randomness,
56
+ * never throws. The hash is synchronous (unlike `flowDefHash`).
57
+ *
58
+ * Exported from the FlowIR barrel (`./index.ts`) for consumers; **not yet
59
+ * wired** into runtime/cache — `usedFallbackHash` is untouched. Wiring
60
+ * happens in batch 2.
61
+ *
62
+ * @see ./schema.ts for the canonical FlowIR type contract.
63
+ * @see ./cond.ts for condition normalization (`normalizeCond`).
64
+ * @see ./hash.ts for the DSL-level `flowDefHash` (vendored from overstory).
65
+ */
66
+ import { createHash } from "node:crypto";
67
+ import { normalizeCond } from "./cond.js";
68
+ // ---------------------------------------------------------------------------
69
+ // Canonical serializer (key-sorted, undefined-dropped, array-order-preserving)
70
+ // ---------------------------------------------------------------------------
71
+ /**
72
+ * Deterministic serialization of a plain-JSON-compatible value: recursively
73
+ * key-sorts objects (UTF-16 code units), drops `undefined` values, preserves
74
+ * array order, and uses `JSON.stringify` for primitives/null. This mirrors
75
+ * the canonical-JSON convention used by `./hash.ts`'s `canonicalJson` (itself
76
+ * vendored from overstory) so the two hashes share the same primitive
77
+ * encoding — but this serializer is local to the IR hash so the IR-level
78
+ * contract can evolve independently of the overstory-vendored DSL hash.
79
+ *
80
+ * The value passed in MUST be pre-canonicalized (nodes sorted by id, `when`
81
+ * normalized) — this function does not know about FlowIR semantics, it only
82
+ * guarantees key-order independence and `undefined`-dropping.
83
+ */
84
+ function canonicalSerialize(value) {
85
+ if (value === null)
86
+ return "null";
87
+ if (typeof value === "boolean")
88
+ return JSON.stringify(value);
89
+ if (typeof value === "number")
90
+ return JSON.stringify(value);
91
+ if (typeof value === "string")
92
+ return JSON.stringify(value);
93
+ if (Array.isArray(value)) {
94
+ return `[${value.map((item) => canonicalSerialize(item)).join(",")}]`;
95
+ }
96
+ if (typeof value === "object") {
97
+ const record = value;
98
+ const keys = Object.keys(record)
99
+ .filter((key) => record[key] !== undefined)
100
+ .sort();
101
+ const body = keys.map((key) => `${JSON.stringify(key)}:${canonicalSerialize(record[key])}`);
102
+ return `{${body.join(",")}}`;
103
+ }
104
+ // undefined / function / symbol / bigint at this layer — not representable.
105
+ return "null";
106
+ }
107
+ // ---------------------------------------------------------------------------
108
+ // Canonical node object (drops undefined, normalizes `when`)
109
+ // ---------------------------------------------------------------------------
110
+ /**
111
+ * Project a {@link FlowIRNode} into a plain canonical object form: fields are
112
+ * emitted in a fixed order (order is irrelevant — `canonicalSerialize`
113
+ * re-sorts keys, but emitting canonically makes the intermediate form
114
+ * human-inspectable), `when` is normalized via {@link normalizeCond} so
115
+ * equivalent condition spellings collapse, and `undefined` optionals are
116
+ * omitted so their presence/absence does not affect the hash.
117
+ *
118
+ * `inject`/`emits`/`deps` arrays are preserved verbatim (order is semantic —
119
+ * declared-read order matters for fingerprinting).
120
+ */
121
+ function canonicalNodeObject(node) {
122
+ const obj = {
123
+ id: node.id,
124
+ kind: node.kind,
125
+ inject: node.inject,
126
+ emits: node.emits,
127
+ };
128
+ if (node.when !== undefined) {
129
+ obj.when = normalizeCond(node.when).canonical;
130
+ }
131
+ if (node.task !== undefined)
132
+ obj.task = node.task;
133
+ if (node.condRef !== undefined)
134
+ obj.condRef = node.condRef;
135
+ if (node.deps !== undefined)
136
+ obj.deps = node.deps;
137
+ if (node.join !== undefined)
138
+ obj.join = node.join;
139
+ if (node.timeout !== undefined)
140
+ obj.timeout = node.timeout;
141
+ if (node.payload !== undefined)
142
+ obj.payload = node.payload;
143
+ return obj;
144
+ }
145
+ // ---------------------------------------------------------------------------
146
+ // Public canonicalization
147
+ // ---------------------------------------------------------------------------
148
+ /**
149
+ * Deterministic, order- and whitespace-independent canonical serialization of
150
+ * a {@link FlowIR}.
151
+ *
152
+ * - `nodes` is re-sorted by `id` (stable) so node-list order does not affect
153
+ * the result.
154
+ * - Each node's `when` guard is canonicalized via {@link normalizeCond}.
155
+ * - All object keys are stable-sorted; `undefined` optionals are dropped.
156
+ * - `inject`/`emits`/`deps`/`edges` arrays keep their order (semantic).
157
+ *
158
+ * Two logically-equivalent FlowIRs MUST canonicalize to the same string.
159
+ * Never throws.
160
+ */
161
+ export function canonicalizeFlowIR(ir) {
162
+ // Stable sort by node id — node-list order is not semantic.
163
+ const sortedNodes = [...ir.nodes].sort((a, b) => {
164
+ if (a.id < b.id)
165
+ return -1;
166
+ if (a.id > b.id)
167
+ return 1;
168
+ return 0;
169
+ });
170
+ const obj = {
171
+ name: ir.name,
172
+ nodes: sortedNodes.map((n) => canonicalNodeObject(n)),
173
+ };
174
+ if (ir.version !== undefined)
175
+ obj.version = ir.version;
176
+ if (ir.edges !== undefined)
177
+ obj.edges = ir.edges;
178
+ if (ir.args !== undefined)
179
+ obj.args = ir.args;
180
+ if (ir.budget !== undefined)
181
+ obj.budget = ir.budget;
182
+ if (ir.concurrency !== undefined)
183
+ obj.concurrency = ir.concurrency;
184
+ if (ir.meta !== undefined)
185
+ obj.meta = ir.meta;
186
+ return canonicalSerialize(obj);
187
+ }
188
+ /**
189
+ * Deterministic canonical serialization of a single {@link FlowIRNode}, for
190
+ * per-node content addressing. Same canonicalization rules as
191
+ * {@link canonicalizeFlowIR} applied to one node (`when` normalized, keys
192
+ * sorted, `undefined` optionals dropped, `inject`/`emits`/`deps` order
193
+ * preserved). Never throws.
194
+ */
195
+ export function canonicalizeNode(node) {
196
+ return canonicalSerialize(canonicalNodeObject(node));
197
+ }
198
+ // ---------------------------------------------------------------------------
199
+ // Content-addressed hashing (node:crypto SHA-256, domain-prefixed)
200
+ // ---------------------------------------------------------------------------
201
+ /**
202
+ * Domain-separated content hash of a compiled FlowIR.
203
+ * Returns `ir:<64 lowercase hex SHA-256 chars>` over {@link canonicalizeFlowIR}.
204
+ * Synchronous. Never throws.
205
+ */
206
+ export function hashFlowIR(ir) {
207
+ const hex = createHash("sha256").update(canonicalizeFlowIR(ir), "utf8").digest("hex");
208
+ return `ir:${hex}`;
209
+ }
210
+ /**
211
+ * Domain-separated per-node content hash.
212
+ * Returns `node:<64 lowercase hex SHA-256 chars>` over {@link canonicalizeNode}.
213
+ * Synchronous. Never throws.
214
+ */
215
+ export function hashNode(node) {
216
+ const hex = createHash("sha256").update(canonicalizeNode(node), "utf8").digest("hex");
217
+ return `node:${hex}`;
218
+ }
219
+ //# sourceMappingURL=canonical-hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-hash.js","sourceRoot":"","sources":["../../src/flowir/canonical-hash.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Genuine Taskflow → FlowIR compiler (RFC §5.2, S0).
3
+ *
4
+ * This graduates the stub `translateTaskflow` into a **canonical** IR emitter:
5
+ * 1:1 phase→node projection (native multi-node lowering deferred per §12),
6
+ * declared inject/emits, explicit edges, normalized `when` via {@link normalizeCond},
7
+ * and richer optional node fields (`task`, `deps`, `join`, `timeout`, `condRef`).
8
+ *
9
+ * Pure, synchronous, never throws — diagnostics live in the return value so
10
+ * `/tf ir` on a broken flow still yields a structured report.
11
+ *
12
+ * @see docs/rfc-0.2.0-architecture.md §5
13
+ * @see ./translate.ts (stub; still used for sidecar field list parity)
14
+ */
15
+ import { type Taskflow } from "../schema.ts";
16
+ import type { FlowIR as CanonicalFlowIR } from "./schema.ts";
17
+ import type { CompileError, CompileWarning, FlowIR, TaskflowIRMeta } from "./meta.ts";
18
+ /**
19
+ * Result of {@link compileTaskflowToFlowIR}: canonical IR + declared meta + diagnostics.
20
+ * `usedFallbackHash` is **false** when the IR is well-formed enough to content-address
21
+ * (always, unless hard errors prevent IR emission).
22
+ *
23
+ * Named separately from Mermaid `compileTaskflow` in `../compile.ts` (diagram).
24
+ */
25
+ export interface CompileTaskflowToFlowIRResult {
26
+ /** Canonical FlowIR (superset of the stub projection). */
27
+ canonical: CanonicalFlowIR;
28
+ /** Stub-compatible IR projection (same nodes without requiring consumers to import schema.ts). */
29
+ ir: FlowIR;
30
+ meta: TaskflowIRMeta;
31
+ warnings: CompileWarning[];
32
+ errors: CompileError[];
33
+ /** False once the genuine compiler owns the hash (S0). */
34
+ usedFallbackHash: boolean;
35
+ }
36
+ /**
37
+ * Compile a (desugared) Taskflow into canonical FlowIR.
38
+ *
39
+ * - One node per phase (1:1).
40
+ * - `inject` = `{steps.*}` refs ∪ `dependsOn` (minus self).
41
+ * - `emits` = `[phase.id]`.
42
+ * - `edges` synthesized from inject for graph consumers.
43
+ * - `when` kept as source text; `condRef` = normalizeCond(canonical) when present.
44
+ * - Optional fields: task, deps, join, timeout copied when set.
45
+ *
46
+ * Never throws.
47
+ */
48
+ export declare function compileTaskflowToFlowIR(def: Taskflow): CompileTaskflowToFlowIRResult;
49
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/flowir/compile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAwD,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAGnG,OAAO,KAAK,EACX,MAAM,IAAI,eAAe,EAIzB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACX,YAAY,EACZ,cAAc,EAEd,MAAM,EAEN,cAAc,EACd,MAAM,WAAW,CAAC;AAwFnB;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAC7C,0DAA0D;IAC1D,SAAS,EAAE,eAAe,CAAC;IAC3B,kGAAkG;IAClG,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,0DAA0D;IAC1D,gBAAgB,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,QAAQ,GAAG,6BAA6B,CA+HpF"}
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Genuine Taskflow → FlowIR compiler (RFC §5.2, S0).
3
+ *
4
+ * This graduates the stub `translateTaskflow` into a **canonical** IR emitter:
5
+ * 1:1 phase→node projection (native multi-node lowering deferred per §12),
6
+ * declared inject/emits, explicit edges, normalized `when` via {@link normalizeCond},
7
+ * and richer optional node fields (`task`, `deps`, `join`, `timeout`, `condRef`).
8
+ *
9
+ * Pure, synchronous, never throws — diagnostics live in the return value so
10
+ * `/tf ir` on a broken flow still yields a structured report.
11
+ *
12
+ * @see docs/rfc-0.2.0-architecture.md §5
13
+ * @see ./translate.ts (stub; still used for sidecar field list parity)
14
+ */
15
+ import { collectRefs, PHASE_TYPES } from "../schema.js";
16
+ import { cwdArgName } from "../cwd-bridge.js";
17
+ import { normalizeCond } from "./cond.js";
18
+ // Keep in sync with translate.ts SIDECAR_PHASE_FIELDS (round-trip lossless).
19
+ const SIDECAR_PHASE_FIELDS = [
20
+ "agent",
21
+ "task",
22
+ "over",
23
+ "as",
24
+ "branches",
25
+ "from",
26
+ "use",
27
+ "def",
28
+ "with",
29
+ "run",
30
+ "input",
31
+ "timeout",
32
+ "until",
33
+ "maxIterations",
34
+ "convergence",
35
+ "reflexion",
36
+ "variants",
37
+ "judge",
38
+ "judgeAgent",
39
+ "mode",
40
+ "dependsOn",
41
+ "join",
42
+ "when",
43
+ "retry",
44
+ "output",
45
+ "expect",
46
+ "model",
47
+ "thinking",
48
+ "tools",
49
+ "cwd",
50
+ "final",
51
+ "optional",
52
+ "idempotent",
53
+ "concurrency",
54
+ "context",
55
+ "contextLimit",
56
+ "onBlock",
57
+ "eval",
58
+ "score",
59
+ "cache",
60
+ "shareContext",
61
+ "cancelLosers",
62
+ "expandMode",
63
+ "maxNodes",
64
+ ];
65
+ const NODE_FIELD_KEYS = new Set(["task", "dependsOn", "join", "when", "timeout"]);
66
+ const VALID_KINDS = new Set(PHASE_TYPES);
67
+ function sidecarForPhase(phase) {
68
+ const out = {};
69
+ const rec = phase;
70
+ for (const k of SIDECAR_PHASE_FIELDS) {
71
+ if (k in rec && rec[k] !== undefined)
72
+ out[k] = rec[k];
73
+ }
74
+ return out;
75
+ }
76
+ function payloadForPhase(phase) {
77
+ const sidecar = sidecarForPhase(phase);
78
+ for (const key of NODE_FIELD_KEYS)
79
+ delete sidecar[key];
80
+ const argName = cwdArgName(phase.cwd);
81
+ if (argName !== undefined) {
82
+ // Canonical IR records logical resource semantics only. The authored raw
83
+ // placeholder remains in meta.sidecar for lossless decompilation.
84
+ delete sidecar.cwd;
85
+ sidecar.cwdUse = {
86
+ kind: "invocation-relative-arg",
87
+ arg: argName,
88
+ access: "read-write",
89
+ intent: "existing-directory",
90
+ };
91
+ }
92
+ return Object.keys(sidecar).length > 0 ? sidecar : undefined;
93
+ }
94
+ function asKind(type) {
95
+ const k = (type ?? "agent");
96
+ if (VALID_KINDS.has(k))
97
+ return k;
98
+ // Unknown kinds still project as agent for IR shape; validation is source of truth.
99
+ return "agent";
100
+ }
101
+ /**
102
+ * Compile a (desugared) Taskflow into canonical FlowIR.
103
+ *
104
+ * - One node per phase (1:1).
105
+ * - `inject` = `{steps.*}` refs ∪ `dependsOn` (minus self).
106
+ * - `emits` = `[phase.id]`.
107
+ * - `edges` synthesized from inject for graph consumers.
108
+ * - `when` kept as source text; `condRef` = normalizeCond(canonical) when present.
109
+ * - Optional fields: task, deps, join, timeout copied when set.
110
+ *
111
+ * Never throws.
112
+ */
113
+ export function compileTaskflowToFlowIR(def) {
114
+ const warnings = [];
115
+ const errors = [];
116
+ const declaredDeps = {};
117
+ const sidecarPhases = {};
118
+ const knownIds = new Set((def.phases ?? []).map((p) => p.id));
119
+ if (!def.name || typeof def.name !== "string") {
120
+ errors.push({ code: "missing-name", message: "Taskflow.name is required" });
121
+ }
122
+ if (!Array.isArray(def.phases) || def.phases.length === 0) {
123
+ errors.push({ code: "empty-phases", message: "Taskflow.phases must be a non-empty array" });
124
+ }
125
+ const nodes = [];
126
+ const edges = [];
127
+ for (const phase of def.phases ?? []) {
128
+ if (!phase?.id) {
129
+ errors.push({ code: "missing-phase-id", message: "Phase missing id" });
130
+ continue;
131
+ }
132
+ const refs = collectRefs(phase);
133
+ const reads = new Set(refs.steps.filter((id) => id !== phase.id));
134
+ for (const d of phase.dependsOn ?? []) {
135
+ if (d !== phase.id)
136
+ reads.add(d);
137
+ }
138
+ for (const d of phase.from ?? []) {
139
+ if (d !== phase.id)
140
+ reads.add(d);
141
+ }
142
+ const inject = Array.from(reads);
143
+ declaredDeps[phase.id] = { reads: inject, writes: [phase.id] };
144
+ for (const r of refs.steps) {
145
+ if (r !== phase.id && !knownIds.has(r)) {
146
+ warnings.push({
147
+ phaseId: phase.id,
148
+ message: `references {steps.${r}.*} but no phase '${r}' exists`,
149
+ });
150
+ }
151
+ }
152
+ const kind = asKind(phase.type);
153
+ if (phase.type && !VALID_KINDS.has(phase.type)) {
154
+ warnings.push({
155
+ phaseId: phase.id,
156
+ message: `unknown phase type '${phase.type}' — projected as kind 'agent'`,
157
+ });
158
+ }
159
+ const node = {
160
+ id: phase.id,
161
+ kind,
162
+ inject,
163
+ emits: [phase.id],
164
+ };
165
+ if (phase.when !== undefined) {
166
+ node.when = phase.when;
167
+ const n = normalizeCond(phase.when);
168
+ // condRef is a stable, hashable form of the guard (not a storage key).
169
+ node.condRef = n.canonical || undefined;
170
+ }
171
+ if (typeof phase.task === "string")
172
+ node.task = phase.task;
173
+ if (phase.dependsOn && phase.dependsOn.length > 0)
174
+ node.deps = [...phase.dependsOn];
175
+ if (phase.join === "all" || phase.join === "any")
176
+ node.join = phase.join;
177
+ if (typeof phase.timeout === "number")
178
+ node.timeout = phase.timeout;
179
+ const payload = payloadForPhase(phase);
180
+ if (payload)
181
+ node.payload = payload;
182
+ for (const from of inject) {
183
+ edges.push({ from, to: phase.id });
184
+ }
185
+ sidecarPhases[phase.id] = sidecarForPhase(phase);
186
+ nodes.push(node);
187
+ }
188
+ const canonical = {
189
+ name: def.name || "unnamed",
190
+ version: typeof def.version === "number" ? def.version : 1,
191
+ nodes,
192
+ edges: edges.length > 0 ? edges : undefined,
193
+ args: def.args,
194
+ budget: def.budget,
195
+ concurrency: def.concurrency,
196
+ meta: {
197
+ source: "taskflow-core",
198
+ irVersion: 1,
199
+ // These flow-level switches change agent discovery / runtime inputs and
200
+ // therefore MUST participate in the content-addressed cache identity.
201
+ // Keeping them in canonical meta preserves the 1:1 node projection while
202
+ // preventing two semantically different flows from sharing an IR hash.
203
+ annotations: {
204
+ agentScope: def.agentScope ?? "user",
205
+ contextSharing: def.contextSharing ?? false,
206
+ },
207
+ },
208
+ };
209
+ // Stub-compatible projection: strip fields meta.FlowIR doesn't declare but keep inject/emits/when/kind.
210
+ const ir = {
211
+ name: canonical.name,
212
+ nodes: nodes.map((n) => ({
213
+ id: n.id,
214
+ kind: n.kind,
215
+ inject: n.inject,
216
+ emits: n.emits,
217
+ when: n.when,
218
+ })),
219
+ args: def.args,
220
+ budget: def.budget,
221
+ concurrency: def.concurrency,
222
+ };
223
+ const meta = {
224
+ sourceFlowName: def.name || "unnamed",
225
+ declaredDeps,
226
+ sidecar: { phases: sidecarPhases },
227
+ };
228
+ // Genuine compiler owns the IR hash when we produced nodes.
229
+ const usedFallbackHash = nodes.length === 0 || errors.some((e) => e.code === "empty-phases");
230
+ return { canonical, ir, meta, warnings, errors, usedFallbackHash };
231
+ }
232
+ //# sourceMappingURL=compile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/flowir/compile.ts"],"names":[],"mappings":"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"}