taskflow-core 0.1.8 → 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 (115) hide show
  1. package/README.md +80 -25
  2. package/dist/deterministic.d.ts +8 -0
  3. package/dist/deterministic.d.ts.map +1 -1
  4. package/dist/deterministic.js +23 -1
  5. package/dist/deterministic.js.map +1 -1
  6. package/dist/exec/driver.d.ts +47 -0
  7. package/dist/exec/driver.d.ts.map +1 -0
  8. package/dist/exec/driver.js +397 -0
  9. package/dist/exec/driver.js.map +1 -0
  10. package/dist/exec/events.d.ts +76 -0
  11. package/dist/exec/events.d.ts.map +1 -0
  12. package/dist/exec/events.js +108 -0
  13. package/dist/exec/events.js.map +1 -0
  14. package/dist/exec/fold.d.ts +45 -0
  15. package/dist/exec/fold.d.ts.map +1 -0
  16. package/dist/exec/fold.js +122 -0
  17. package/dist/exec/fold.js.map +1 -0
  18. package/dist/exec/index.d.ts +17 -0
  19. package/dist/exec/index.d.ts.map +1 -0
  20. package/dist/exec/index.js +17 -0
  21. package/dist/exec/index.js.map +1 -0
  22. package/dist/exec/kernel-policy.d.ts +35 -0
  23. package/dist/exec/kernel-policy.d.ts.map +1 -0
  24. package/dist/exec/kernel-policy.js +184 -0
  25. package/dist/exec/kernel-policy.js.map +1 -0
  26. package/dist/exec/step-kinds.d.ts +41 -0
  27. package/dist/exec/step-kinds.d.ts.map +1 -0
  28. package/dist/exec/step-kinds.js +574 -0
  29. package/dist/exec/step-kinds.js.map +1 -0
  30. package/dist/exec/step.d.ts +93 -0
  31. package/dist/exec/step.d.ts.map +1 -0
  32. package/dist/exec/step.js +436 -0
  33. package/dist/exec/step.js.map +1 -0
  34. package/dist/flowir/canonical-hash.d.ts +101 -0
  35. package/dist/flowir/canonical-hash.d.ts.map +1 -0
  36. package/dist/flowir/canonical-hash.js +219 -0
  37. package/dist/flowir/canonical-hash.js.map +1 -0
  38. package/dist/flowir/compile.d.ts +49 -0
  39. package/dist/flowir/compile.d.ts.map +1 -0
  40. package/dist/flowir/compile.js +219 -0
  41. package/dist/flowir/compile.js.map +1 -0
  42. package/dist/flowir/cond.d.ts +76 -0
  43. package/dist/flowir/cond.d.ts.map +1 -0
  44. package/dist/flowir/cond.js +214 -0
  45. package/dist/flowir/cond.js.map +1 -0
  46. package/dist/flowir/index.d.ts +20 -23
  47. package/dist/flowir/index.d.ts.map +1 -1
  48. package/dist/flowir/index.js +47 -35
  49. package/dist/flowir/index.js.map +1 -1
  50. package/dist/flowir/meta.d.ts +4 -4
  51. package/dist/flowir/meta.d.ts.map +1 -1
  52. package/dist/flowir/phasefp.d.ts.map +1 -1
  53. package/dist/flowir/phasefp.js +13 -1
  54. package/dist/flowir/phasefp.js.map +1 -1
  55. package/dist/flowir/schema.d.ts +260 -0
  56. package/dist/flowir/schema.d.ts.map +1 -0
  57. package/dist/flowir/schema.js +234 -0
  58. package/dist/flowir/schema.js.map +1 -0
  59. package/dist/flowir/translate.d.ts.map +1 -1
  60. package/dist/flowir/translate.js +3 -0
  61. package/dist/flowir/translate.js.map +1 -1
  62. package/dist/host/runner-types.d.ts +3 -0
  63. package/dist/host/runner-types.d.ts.map +1 -1
  64. package/dist/index.d.ts +2 -0
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +2 -0
  67. package/dist/index.js.map +1 -1
  68. package/dist/rates.d.ts +121 -0
  69. package/dist/rates.d.ts.map +1 -0
  70. package/dist/rates.js +187 -0
  71. package/dist/rates.js.map +1 -0
  72. package/dist/replay.d.ts +43 -50
  73. package/dist/replay.d.ts.map +1 -1
  74. package/dist/replay.js +629 -19
  75. package/dist/replay.js.map +1 -1
  76. package/dist/runner-core.d.ts +24 -0
  77. package/dist/runner-core.d.ts.map +1 -1
  78. package/dist/runner-core.js +225 -32
  79. package/dist/runner-core.js.map +1 -1
  80. package/dist/runtime/phases/approval.d.ts +23 -0
  81. package/dist/runtime/phases/approval.d.ts.map +1 -0
  82. package/dist/runtime/phases/approval.js +38 -0
  83. package/dist/runtime/phases/approval.js.map +1 -0
  84. package/dist/runtime/phases/expand.d.ts +29 -0
  85. package/dist/runtime/phases/expand.d.ts.map +1 -0
  86. package/dist/runtime/phases/expand.js +126 -0
  87. package/dist/runtime/phases/expand.js.map +1 -0
  88. package/dist/runtime/phases/parallel.d.ts +26 -0
  89. package/dist/runtime/phases/parallel.d.ts.map +1 -0
  90. package/dist/runtime/phases/parallel.js +15 -0
  91. package/dist/runtime/phases/parallel.js.map +1 -0
  92. package/dist/runtime/phases/race.d.ts +31 -0
  93. package/dist/runtime/phases/race.d.ts.map +1 -0
  94. package/dist/runtime/phases/race.js +220 -0
  95. package/dist/runtime/phases/race.js.map +1 -0
  96. package/dist/runtime/phases/script.d.ts +38 -0
  97. package/dist/runtime/phases/script.d.ts.map +1 -0
  98. package/dist/runtime/phases/script.js +139 -0
  99. package/dist/runtime/phases/script.js.map +1 -0
  100. package/dist/runtime.d.ts +29 -16
  101. package/dist/runtime.d.ts.map +1 -1
  102. package/dist/runtime.js +554 -292
  103. package/dist/runtime.js.map +1 -1
  104. package/dist/schema.d.ts +36 -4
  105. package/dist/schema.d.ts.map +1 -1
  106. package/dist/schema.js +86 -10
  107. package/dist/schema.js.map +1 -1
  108. package/dist/store.d.ts +6 -0
  109. package/dist/store.d.ts.map +1 -1
  110. package/dist/store.js.map +1 -1
  111. package/dist/trace.d.ts +4 -1
  112. package/dist/trace.d.ts.map +1 -1
  113. package/dist/trace.js +33 -26
  114. package/dist/trace.js.map +1 -1
  115. package/package.json +5 -4
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Canonical normalization of `when` / `until` / `eval` condition expressions.
3
+ *
4
+ * This is the **condition-IR seam** of the overstory-convergence roadmap's
5
+ * FlowIR compiler: it lifts a raw condition string into a stable
6
+ * {@link NormalizedCond} descriptor that two future consumers share:
7
+ *
8
+ * - **Hashing** (consumer a): structurally-equivalent conditions MUST
9
+ * normalize to the same `canonical` string so they fold identically into
10
+ * the FlowIR content hash (whitespace, operator spacing, and redundant
11
+ * enclosing parens do not change meaning → must not change the hash).
12
+ * - **Deterministic replay** (consumer b): the `when-guard` decision is
13
+ * re-evaluated from the recorded expression; `refs` tells replay exactly
14
+ * which `steps.*` / `args.*` / `env.*` inputs the guard read so it can
15
+ * rebind them from the event log without token spend.
16
+ *
17
+ * **Single source of truth — no semantic drift.** The condition grammar
18
+ * (tokenizer + recursive-descent parser + comparison/truthiness semantics)
19
+ * lives in {@link ../interpolate.ts}. This module REUSES that parser by
20
+ * delegating parse-validation (and fail-open semantics) to
21
+ * {@link tryEvaluateCondition} — it does NOT duplicate or reimplement the
22
+ * tokenizer/parser. If the parser accepts an expression, it is structurally
23
+ * valid and we normalize its surface text; if the parser rejects it, we
24
+ * fail open (see {@link normalizeCond}) so a broken guard never silently
25
+ * drops a phase — matching the project's fail-open-for-guards invariant.
26
+ *
27
+ * The `canonical` form is a surface normalization (whitespace removal +
28
+ * redundant enclosing-paren stripping with string-literal contents
29
+ * preserved), not a full AST rewrite: for valid expressions whitespace only
30
+ * separates tokens, so removing it (after protecting quoted literals) yields
31
+ * a stable concatenation that is invariant under the cosmetic differences
32
+ * hashing cares about. Reference extraction runs on the **literal-protected**
33
+ * surface so `{steps.*}` text inside string literals is never treated as a
34
+ * real dependency.
35
+ *
36
+ * Pure module: no IO, no `Date`, no randomness, never throws.
37
+ *
38
+ * @see docs/rfc-0.2.0-architecture.md §5.4 (`flowir/cond.ts` — 条件归一化)
39
+ * @see ../interpolate.ts for the shared condition parser (tokenize / CondParser / compare / tryEvaluateCondition)
40
+ */
41
+ import { tryEvaluateCondition } from "../interpolate.js";
42
+ // ---------------------------------------------------------------------------
43
+ // Reference extraction (static scan — mirrors `collectRefs` in schema.ts)
44
+ // ---------------------------------------------------------------------------
45
+ /**
46
+ * Matches `{steps.X}`, `{args.Y}`, `{env.Z}` placeholders, tolerant of
47
+ * inner whitespace (the tokenizer trims inside braces, so `{ steps.x }` and
48
+ * `{steps.x}` are the same ref). Captures the full dotted path so replay
49
+ * knows precisely which input was read (e.g. `steps.triage.json.route`).
50
+ */
51
+ const REF_RE = /\{\s*(steps|args|env)\.([a-zA-Z0-9_.-]+?)\s*\}/g;
52
+ /**
53
+ * Extract refs from expression text that has already had string literals
54
+ * replaced by placeholders (see {@link protectLiterals}). Scanning the
55
+ * protected surface prevents false-positive refs for placeholder-looking
56
+ * text that only appears inside quotes.
57
+ */
58
+ function extractRefsFromProtected(protectedText) {
59
+ const seen = new Set();
60
+ const refs = [];
61
+ REF_RE.lastIndex = 0;
62
+ let m;
63
+ while ((m = REF_RE.exec(protectedText)) !== null) {
64
+ const ref = `${m[1]}.${m[2]}`;
65
+ if (!seen.has(ref)) {
66
+ seen.add(ref);
67
+ refs.push(ref);
68
+ }
69
+ }
70
+ return refs;
71
+ }
72
+ // ---------------------------------------------------------------------------
73
+ // Canonical surface form
74
+ // ---------------------------------------------------------------------------
75
+ /**
76
+ * Protect quoted string literals (single or double quoted, with `\` escapes
77
+ * preserved byte-for-byte) by replacing each with a whitespace-free
78
+ * `\u0000<index>\u0000` placeholder. This preserves their contents
79
+ * (including internal spaces and escape sequences) through whitespace
80
+ * removal and prevents their inner parens/operators/placeholder-looking
81
+ * text from confusing the paren stripper or ref extractor.
82
+ * Returns the protected string and the list of original literals.
83
+ */
84
+ function protectLiterals(expr) {
85
+ const literals = [];
86
+ let out = "";
87
+ let i = 0;
88
+ const n = expr.length;
89
+ while (i < n) {
90
+ const c = expr[i];
91
+ if (c === '"' || c === "'") {
92
+ let j = i + 1;
93
+ let val = c; // include opening quote
94
+ while (j < n) {
95
+ if (expr[j] === "\\" && j + 1 < n) {
96
+ // Preserve the escape sequence intact (do not drop `\`).
97
+ val += expr[j] + expr[j + 1];
98
+ j += 2;
99
+ }
100
+ else if (expr[j] === c) {
101
+ val += c; // closing quote
102
+ j++;
103
+ break;
104
+ }
105
+ else {
106
+ val += expr[j];
107
+ j++;
108
+ }
109
+ }
110
+ // Unterminated string: keep whatever we scanned (incl. opening quote).
111
+ literals.push(val);
112
+ out += `\u0000${literals.length - 1}\u0000`;
113
+ i = j;
114
+ }
115
+ else {
116
+ out += c;
117
+ i++;
118
+ }
119
+ }
120
+ return { text: out, literals };
121
+ }
122
+ function restoreLiterals(text, literals) {
123
+ return text.replace(/\u0000(\d+)\u0000/g, (_m, idx) => literals[Number(idx)] ?? "");
124
+ }
125
+ /**
126
+ * Repeatedly strip a single layer of redundant enclosing parentheses — i.e.
127
+ * parens that wrap the *entire* expression: `((a==b))` → `(a==b)` → `a==b`.
128
+ * Operates on literal-protected, whitespace-free input so string contents
129
+ * and refs (which contain no parens) cannot unbalance the depth counter.
130
+ * Inner redundant parens like `a && (b)` are intentionally left in place —
131
+ * removing them correctly would require AST knowledge (precedence), which is
132
+ * the parser's job, not this normalizer's.
133
+ */
134
+ function stripEnclosingParens(s) {
135
+ for (;;) {
136
+ if (s.length < 2 || s[0] !== "(")
137
+ break;
138
+ let depth = 0;
139
+ let end = -1;
140
+ for (let k = 0; k < s.length; k++) {
141
+ const ch = s[k];
142
+ if (ch === "(")
143
+ depth++;
144
+ else if (ch === ")") {
145
+ depth--;
146
+ if (depth === 0) {
147
+ end = k;
148
+ break;
149
+ }
150
+ }
151
+ }
152
+ if (end === s.length - 1) {
153
+ s = s.slice(1, -1);
154
+ }
155
+ else {
156
+ break;
157
+ }
158
+ }
159
+ return s;
160
+ }
161
+ /**
162
+ * Produce the canonical surface form of a (parser-accepted) expression:
163
+ * protect string literals → remove all whitespace → strip redundant
164
+ * enclosing parens → restore literals. For a valid expression whitespace
165
+ * only separates tokens, so its removal is semantics-preserving and yields a
166
+ * form invariant under the cosmetic differences (spacing / redundant outer
167
+ * parens) that hashing must ignore.
168
+ */
169
+ function canonicalize(expr) {
170
+ const { text, literals } = protectLiterals(expr);
171
+ let compact = text.replace(/\s+/g, "");
172
+ compact = stripEnclosingParens(compact);
173
+ return restoreLiterals(compact, literals);
174
+ }
175
+ // ---------------------------------------------------------------------------
176
+ // normalizeCond
177
+ // ---------------------------------------------------------------------------
178
+ /**
179
+ * Normalize a `when` / `until` / `eval` condition expression.
180
+ *
181
+ * The expression is parsed (validated) by reusing the shared condition
182
+ * parser in {@link ../interpolate.ts} via {@link tryEvaluateCondition}; on a
183
+ * parse error this **fails open** — returning `{ source, canonical:
184
+ * source.trim(), refs: [] }` — so a malformed guard is never silently
185
+ * dropped and never crashes a compile/replay pass. This mirrors the
186
+ * project's fail-open-for-guards invariant (`when` parse errors → phase
187
+ * still runs). Never throws.
188
+ *
189
+ * On success, `canonical` is the whitespace/paren-normalized surface form
190
+ * (stable for hashing) and `refs` are the `steps.*` / `args.*` / `env.*`
191
+ * references the expression reads (for replay rebinding). Placeholders that
192
+ * only appear inside string literals are excluded from `refs`.
193
+ */
194
+ export function normalizeCond(expr) {
195
+ const source = typeof expr === "string" ? expr : expr == null ? "" : String(expr);
196
+ const trimmed = source.trim();
197
+ // Reuse the interpolate condition parser to validate parseability and
198
+ // inherit its fail-open semantics. An empty probing context is fine: ref
199
+ // resolution returns `undefined` for missing steps/args but never throws,
200
+ // so `error` is purely syntactic (tokenize/parse failures).
201
+ const probe = { args: {}, steps: {} };
202
+ const { error } = tryEvaluateCondition(trimmed, probe);
203
+ if (error) {
204
+ // Fail open: keep the raw (trimmed) text as canonical, no refs.
205
+ return { source, canonical: trimmed, refs: [] };
206
+ }
207
+ const { text: protectedText } = protectLiterals(trimmed);
208
+ return {
209
+ source,
210
+ canonical: canonicalize(trimmed),
211
+ refs: extractRefsFromProtected(protectedText),
212
+ };
213
+ }
214
+ //# sourceMappingURL=cond.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cond.js","sourceRoot":"","sources":["../../src/flowir/cond.ts"],"names":[],"mappings":"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"}
@@ -1,43 +1,40 @@
1
1
  /**
2
2
  * Public entry point for the FlowIR compile seam.
3
3
  *
4
- * `compileTaskflowToIR` is the read-only, content-addressed IR projection used
5
- * by:
4
+ * `compileTaskflowToIR` is the content-addressed IR projection used by:
6
5
  * - `/tf ir <flow>` / `action=ir` — render the compiled IR + hash (0 tokens)
7
6
  * - the runtime (`runTaskflowLayers`) — fold `ir.hash` into the cache key
8
- * (== `flowDefHash` in the stub; the overstory-canonical hash once the
9
- * genuine compiler is vendored) and persist `ir.meta.declaredDeps` to
10
- * `RunState` (M2 declared plane).
11
7
  *
12
- * The stub hash reuses the already-vendored overstory `flowDefHash` algorithm
13
- * (./hash.ts) so pi-taskflow and overstory share one byte-identical hashing
14
- * contract today. `usedFallbackHash` is `true` in the stub (the genuine
15
- * overstory `hashIR` is not yet wired); it flips to `false` once the compiler
16
- * is vendored, at which point the cache key's `v2:` prefix advances to `v3:`
17
- * (see docs/internal/cache-migration.md).
8
+ * **S0 (0.2.0):** the genuine compiler (`./compile.ts`) emits canonical FlowIR
9
+ * and content-addresses it with {@link hashFlowIR}. `usedFallbackHash` is
10
+ * **false** when IR is produced. The DSL-level `flowDefHash` remains available
11
+ * for the v2 cache tier (`v2:flowdef:`) during the migration window.
18
12
  *
19
- * Pure + async (Web Crypto). Never throws — a hash failure leaves `hash`
20
- * unset and `usedFallbackHash` true; the runtime degrades to the safe
21
- * flowName-only cache key (cross-run disabled for that run).
13
+ * Pure + async-compatible API (sync body; async retained for callers). Never
14
+ * throws — a hash failure leaves `hash` unset and `usedFallbackHash` true.
22
15
  *
23
- * @see docs/internal/overstory-convergence-roadmap.md §3 (M1)
24
- * @see docs/internal/rfc-flowir-compilation.md
16
+ * @see docs/rfc-0.2.0-architecture.md §5, §9 (S0)
25
17
  */
26
18
  import type { Taskflow } from "../schema.ts";
27
19
  import type { TaskflowIR } from "./meta.ts";
28
20
  /**
29
21
  * Compile a (desugared) `Taskflow` into its content-addressed IR.
30
22
  *
31
- * The returned `hash` is, in the stub, exactly `flowDefHash(def)` — the
32
- * overstory-vendored canonical-JSON + SHA-256-truncation contract. The
33
- * `usedFallbackHash` flag records that this is the *fallback* hash (non-IR-
34
- * canonical): it is `true` whenever the stub cannot guarantee IR-canonicity
35
- * (any phase with a `when`, or any hash-compute failure).
23
+ * The returned `hash` is `ir:<64-hex>` from {@link hashFlowIR} over the
24
+ * **canonical** FlowIR (key-order / node-order / condition-normalization
25
+ * invariant). `usedFallbackHash` is false when compilation produced nodes.
36
26
  *
37
- * Never throws. Returns structured diagnostics so `/tf ir` on a broken flow
38
- * yields a clean error table instead of crashing.
27
+ * Never throws.
39
28
  */
40
29
  export declare function compileTaskflowToIR(def: Taskflow): Promise<TaskflowIR>;
41
30
  export type { CompileError, CompileWarning, DeclaredDeps, FlowIR, FlowIRNode, TaskflowIR, TaskflowIRMeta, } from "./meta.ts";
42
31
  export { phaseFingerprint } from "./phasefp.ts";
32
+ export { compileTaskflowToFlowIR, type CompileTaskflowToFlowIRResult } from "./compile.ts";
33
+ export { translateTaskflow } from "./translate.ts";
34
+ export { FlowIRNodeKind } from "./schema.ts";
35
+ export type { FlowIREdge, FlowIRBudget, FlowIRMeta, FlowIR as CanonicalFlowIR, FlowIRNode as CanonicalFlowIRNode, } from "./schema.ts";
36
+ export { FlowIRNodeSchema, FlowIREdgeSchema, FlowIRSchema, isFlowIRNode, assertFlowIR, } from "./schema.ts";
37
+ export type { NormalizedCond } from "./cond.ts";
38
+ export { normalizeCond } from "./cond.ts";
39
+ export { canonicalizeFlowIR, hashFlowIR, hashNode } from "./canonical-hash.ts";
43
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/flowir/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAmB5E;AAED,YAAY,EACX,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,MAAM,EACN,UAAU,EACV,UAAU,EACV,cAAc,GACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/flowir/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAmB5E;AAED,YAAY,EACX,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,MAAM,EACN,UAAU,EACV,UAAU,EACV,cAAc,GACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,KAAK,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAoBnD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EACX,UAAU,EACV,YAAY,EACZ,UAAU,EACV,MAAM,IAAI,eAAe,EACzB,UAAU,IAAI,mBAAmB,GACjC,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,YAAY,GACZ,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,62 +1,74 @@
1
1
  /**
2
2
  * Public entry point for the FlowIR compile seam.
3
3
  *
4
- * `compileTaskflowToIR` is the read-only, content-addressed IR projection used
5
- * by:
4
+ * `compileTaskflowToIR` is the content-addressed IR projection used by:
6
5
  * - `/tf ir <flow>` / `action=ir` — render the compiled IR + hash (0 tokens)
7
6
  * - the runtime (`runTaskflowLayers`) — fold `ir.hash` into the cache key
8
- * (== `flowDefHash` in the stub; the overstory-canonical hash once the
9
- * genuine compiler is vendored) and persist `ir.meta.declaredDeps` to
10
- * `RunState` (M2 declared plane).
11
7
  *
12
- * The stub hash reuses the already-vendored overstory `flowDefHash` algorithm
13
- * (./hash.ts) so pi-taskflow and overstory share one byte-identical hashing
14
- * contract today. `usedFallbackHash` is `true` in the stub (the genuine
15
- * overstory `hashIR` is not yet wired); it flips to `false` once the compiler
16
- * is vendored, at which point the cache key's `v2:` prefix advances to `v3:`
17
- * (see docs/internal/cache-migration.md).
8
+ * **S0 (0.2.0):** the genuine compiler (`./compile.ts`) emits canonical FlowIR
9
+ * and content-addresses it with {@link hashFlowIR}. `usedFallbackHash` is
10
+ * **false** when IR is produced. The DSL-level `flowDefHash` remains available
11
+ * for the v2 cache tier (`v2:flowdef:`) during the migration window.
18
12
  *
19
- * Pure + async (Web Crypto). Never throws — a hash failure leaves `hash`
20
- * unset and `usedFallbackHash` true; the runtime degrades to the safe
21
- * flowName-only cache key (cross-run disabled for that run).
13
+ * Pure + async-compatible API (sync body; async retained for callers). Never
14
+ * throws — a hash failure leaves `hash` unset and `usedFallbackHash` true.
22
15
  *
23
- * @see docs/internal/overstory-convergence-roadmap.md §3 (M1)
24
- * @see docs/internal/rfc-flowir-compilation.md
16
+ * @see docs/rfc-0.2.0-architecture.md §5, §9 (S0)
25
17
  */
26
- import { flowDefHash } from "./hash.js";
27
- import { translateTaskflow } from "./translate.js";
18
+ import { compileTaskflowToFlowIR } from "./compile.js";
19
+ import { hashFlowIR } from "./canonical-hash.js";
28
20
  /**
29
21
  * Compile a (desugared) `Taskflow` into its content-addressed IR.
30
22
  *
31
- * The returned `hash` is, in the stub, exactly `flowDefHash(def)` — the
32
- * overstory-vendored canonical-JSON + SHA-256-truncation contract. The
33
- * `usedFallbackHash` flag records that this is the *fallback* hash (non-IR-
34
- * canonical): it is `true` whenever the stub cannot guarantee IR-canonicity
35
- * (any phase with a `when`, or any hash-compute failure).
23
+ * The returned `hash` is `ir:<64-hex>` from {@link hashFlowIR} over the
24
+ * **canonical** FlowIR (key-order / node-order / condition-normalization
25
+ * invariant). `usedFallbackHash` is false when compilation produced nodes.
36
26
  *
37
- * Never throws. Returns structured diagnostics so `/tf ir` on a broken flow
38
- * yields a clean error table instead of crashing.
27
+ * Never throws.
39
28
  */
40
29
  export async function compileTaskflowToIR(def) {
41
- const t = translateTaskflow(def);
30
+ const c = compileTaskflowToFlowIR(def);
42
31
  let hash;
43
32
  try {
44
- hash = await flowDefHash(def);
33
+ if (c.canonical.nodes.length > 0) {
34
+ hash = hashFlowIR(c.canonical);
35
+ }
45
36
  }
46
37
  catch {
47
38
  hash = undefined;
48
39
  }
49
40
  return {
50
- ir: t.ir,
51
- meta: t.meta,
41
+ ir: c.ir,
42
+ meta: c.meta,
52
43
  hash,
53
- warnings: t.warnings,
54
- errors: t.errors,
55
- // Stub: the fallback hash is used whenever (a) any phase has a `when`
56
- // (translateTaskflow flags it) OR (b) the hash computation itself failed.
57
- // Once the genuine overstory compiler is vendored, condition (a) drops.
58
- usedFallbackHash: t.usedFallbackHash || hash === undefined,
44
+ warnings: c.warnings,
45
+ errors: c.errors,
46
+ // Fallback only when we could not content-address the IR.
47
+ usedFallbackHash: c.usedFallbackHash || hash === undefined,
59
48
  };
60
49
  }
61
50
  export { phaseFingerprint } from "./phasefp.js";
51
+ export { compileTaskflowToFlowIR } from "./compile.js";
52
+ export { translateTaskflow } from "./translate.js";
53
+ // ---------------------------------------------------------------------------
54
+ // Canonical FlowIR type contract + content-addressed hash (batch-1 additions)
55
+ // ---------------------------------------------------------------------------
56
+ //
57
+ // `./meta.ts` exposes the *stub* 1:1 projection (`FlowIR`/`FlowIRNode` with
58
+ // `kind: string`) that `translateTaskflow` emits today. `./schema.ts` defines
59
+ // the *canonical* contract — a strict superset (extra optional fields) with a
60
+ // *closed* `kind` union (`FlowIRNodeKind`). Both are surfaced here:
61
+ //
62
+ // - `FlowIR` / `FlowIRNode` → the stub projection (meta.ts), used by
63
+ // `compileTaskflowToIR` / `TaskflowIR`.
64
+ // - `CanonicalFlowIR` / `CanonicalFlowIRNode` → the canonical contract
65
+ // (schema.ts); the shape the compiler
66
+ // emits and `hashFlowIR` content-addresses.
67
+ //
68
+ // The canonical names are re-exported under `Canonical*` aliases to avoid a
69
+ // duplicate-export clash with meta.ts's stub `FlowIR`/`FlowIRNode`.
70
+ export { FlowIRNodeKind } from "./schema.js";
71
+ export { FlowIRNodeSchema, FlowIREdgeSchema, FlowIRSchema, isFlowIRNode, assertFlowIR, } from "./schema.js";
72
+ export { normalizeCond } from "./cond.js";
73
+ export { canonicalizeFlowIR, hashFlowIR, hashNode } from "./canonical-hash.js";
62
74
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/flowir/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGnD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAa;IACtD,MAAM,CAAC,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,IAAwB,CAAC;IAC7B,IAAI,CAAC;QACJ,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACR,IAAI,GAAG,SAAS,CAAC;IAClB,CAAC;IACD,OAAO;QACN,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI;QACJ,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,sEAAsE;QACtE,0EAA0E;QAC1E,wEAAwE;QACxE,gBAAgB,EAAE,CAAC,CAAC,gBAAgB,IAAI,IAAI,KAAK,SAAS;KAC1D,CAAC;AACH,CAAC;AAYD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/flowir/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAa;IACtD,MAAM,CAAC,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,IAAwB,CAAC;IAC7B,IAAI,CAAC;QACJ,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,IAAI,GAAG,SAAS,CAAC;IAClB,CAAC;IACD,OAAO;QACN,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI;QACJ,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,0DAA0D;QAC1D,gBAAgB,EAAE,CAAC,CAAC,gBAAgB,IAAI,IAAI,KAAK,SAAS;KAC1D,CAAC;AACH,CAAC;AAYD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAsC,MAAM,cAAc,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,8EAA8E;AAC9E,oEAAoE;AACpE,EAAE;AACF,iFAAiF;AACjF,iFAAiF;AACjF,yEAAyE;AACzE,+EAA+E;AAC/E,qFAAqF;AACrF,EAAE;AACF,4EAA4E;AAC5E,oEAAoE;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQ7C,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,YAAY,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
@@ -87,14 +87,14 @@ export interface TaskflowIRMeta {
87
87
  }
88
88
  /**
89
89
  * The composite compile result (RFC §5). `ir`/`hash` are present unless
90
- * synthesis failed (stub never fails). `usedFallbackHash` is `true` whenever
91
- * the stub cannot produce an overstory-canonical hash (always, in the stub:
92
- * the hash is the `flowDefHash` fallback; flips to `false` once the genuine
93
- * compiler is vendored).
90
+ * synthesis failed. `usedFallbackHash` is `false` once the genuine compiler
91
+ * (S0 / `flowir/compile.ts`) content-addresses the IR via `hashFlowIR`; it is
92
+ * `true` only when IR could not be produced (empty phases / hard errors).
94
93
  */
95
94
  export interface TaskflowIR {
96
95
  ir?: FlowIR;
97
96
  meta: TaskflowIRMeta;
97
+ /** Content-addressed IR hash: `ir:<64-hex>` from `hashFlowIR` (S0). */
98
98
  hash?: string;
99
99
  warnings: CompileWarning[];
100
100
  errors: CompileError[];
@@ -1 +1 @@
1
- {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/flowir/meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAMrD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC5B,6EAA6E;IAC7E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb;0EACsE;IACtE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gEAAgE;IAChE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,sEAAsE;AACtE,MAAM,WAAW,MAAM;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,kFAAkF;AAClF,MAAM,WAAW,YAAY;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CAChB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC3C,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;CAC1B"}
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/flowir/meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAMrD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC5B,6EAA6E;IAC7E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb;0EACsE;IACtE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gEAAgE;IAChE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,sEAAsE;AACtE,MAAM,WAAW,MAAM;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,kFAAkF;AAClF,MAAM,WAAW,YAAY;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CAChB;AAMD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC3C,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,cAAc,CAAC;IACrB,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;CAC1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"phasefp.d.ts","sourceRoot":"","sources":["../../src/flowir/phasefp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,EAAsC,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AA0BjF;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAyClG"}
1
+ {"version":3,"file":"phasefp.d.ts","sourceRoot":"","sources":["../../src/flowir/phasefp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,EAAsC,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AA0BjF;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAqDlG"}
@@ -117,7 +117,19 @@ export async function phaseFingerprint(def, phaseId) {
117
117
  // sorts OBJECT keys but preserves ARRAY order, so we sort the array
118
118
  // explicitly for determinism independent of dependency walk order.
119
119
  const depsPayload = closurePhases.map((p) => ({ id: p.id, def: stripPolicy(p) }));
120
- const payload = { self: stripPolicy(phase), deps: depsPayload };
120
+ // Agent discovery scope is a flow-level input to every agent-running phase:
121
+ // the same agent name may resolve to different user/project definitions.
122
+ // Fold it into every phase fingerprint so per-item and per-phase cache reuse
123
+ // cannot cross that semantic boundary. contextSharing is included as an
124
+ // explicit belt-and-suspenders marker (sharing already falls back above).
125
+ const payload = {
126
+ flow: {
127
+ agentScope: def.agentScope ?? "user",
128
+ contextSharing: def.contextSharing ?? false,
129
+ },
130
+ self: stripPolicy(phase),
131
+ deps: depsPayload,
132
+ };
121
133
  return hashCanonical(canonicalJson(payload));
122
134
  }
123
135
  //# sourceMappingURL=phasefp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"phasefp.js","sourceRoot":"","sources":["../../src/flowir/phasefp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"phasefp.js","sourceRoot":"","sources":["../../src/flowir/phasefp.ts"],"names":[],"mappings":"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"}