@sensigo/realm 0.10.1 → 0.12.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 (32) hide show
  1. package/dist/engine/comparison-expr.d.ts +43 -0
  2. package/dist/engine/comparison-expr.d.ts.map +1 -0
  3. package/dist/engine/comparison-expr.js +154 -0
  4. package/dist/engine/comparison-expr.js.map +1 -0
  5. package/dist/engine/eligibility.d.ts +17 -3
  6. package/dist/engine/eligibility.d.ts.map +1 -1
  7. package/dist/engine/eligibility.js +90 -54
  8. package/dist/engine/eligibility.js.map +1 -1
  9. package/dist/engine/precondition.d.ts.map +1 -1
  10. package/dist/engine/precondition.js +30 -47
  11. package/dist/engine/precondition.js.map +1 -1
  12. package/dist/engine/render-template.d.ts.map +1 -1
  13. package/dist/engine/render-template.js +3 -30
  14. package/dist/engine/render-template.js.map +1 -1
  15. package/dist/index.d.ts +5 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +3 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/observability/failed-attempt-record.d.ts +59 -0
  20. package/dist/observability/failed-attempt-record.d.ts.map +1 -0
  21. package/dist/observability/failed-attempt-record.js +154 -0
  22. package/dist/observability/failed-attempt-record.js.map +1 -0
  23. package/dist/store/failed-attempt-store.d.ts +36 -0
  24. package/dist/store/failed-attempt-store.d.ts.map +1 -0
  25. package/dist/store/failed-attempt-store.js +100 -0
  26. package/dist/store/failed-attempt-store.js.map +1 -0
  27. package/dist/types/workflow-definition.d.ts +13 -6
  28. package/dist/types/workflow-definition.d.ts.map +1 -1
  29. package/dist/workflow/yaml-loader.d.ts.map +1 -1
  30. package/dist/workflow/yaml-loader.js +139 -3
  31. package/dist/workflow/yaml-loader.js.map +1 -1
  32. package/package.json +1 -1
@@ -0,0 +1,43 @@
1
+ /** The comparison operators Realm understands, longest tokens first for greedy matching. */
2
+ export type ComparisonOp = '==' | '!=' | '>=' | '<=' | '>' | '<';
3
+ export type ComparisonInvalidReason = 'empty' | 'compound_and' | 'compound_or' | 'multiple_operators';
4
+ /** The result of splitting one condition leaf. Never thrown — malformed input returns `invalid`. */
5
+ export type ComparisonSplit = {
6
+ kind: 'comparison';
7
+ lhsPath: string;
8
+ op: ComparisonOp;
9
+ rhsRaw: string;
10
+ } | {
11
+ kind: 'path';
12
+ path: string;
13
+ } | {
14
+ kind: 'invalid';
15
+ reason: ComparisonInvalidReason;
16
+ parts?: string[];
17
+ };
18
+ /**
19
+ * Splits `input` on every occurrence of single-character `delimiter` that is NOT inside a quoted
20
+ * string. Single or double quotes both open/close quote state; the other quote type is ignored while
21
+ * inside a quote. Returns raw substrings — no trimming, no quote stripping.
22
+ *
23
+ * (Moved here from render-template.ts so both template rendering and condition splitting share one
24
+ * quote-aware primitive; render-template imports it from this module.)
25
+ */
26
+ export declare function splitOnUnquotedDelimiter(input: string, delimiter: string): string[];
27
+ /**
28
+ * Split one condition leaf, quote-aware, into a comparison `{ lhsPath, op, rhsRaw }`, a bare
29
+ * `{ path }`, or `{ invalid, reason }`. Operator tokens and `and`/`or` keywords inside quoted
30
+ * regions are ignored. Never throws.
31
+ *
32
+ * - `and`/`or` (unquoted) → `invalid` with `parts` (the split candidates, for an actionable error).
33
+ * - exactly one unquoted operator → `comparison`.
34
+ * - more than one → `invalid` (`multiple_operators`).
35
+ * - none → `path` (a bare path; the caller validates its shape with {@link isPathShaped}).
36
+ */
37
+ export declare function splitComparison(input: string): ComparisonSplit;
38
+ /**
39
+ * True when `s` is a bare dot-path: starts with a letter/underscore and contains only word chars,
40
+ * `.`, or `-` (no spaces, no operators). Used to reject a non-path LHS at load time.
41
+ */
42
+ export declare function isPathShaped(s: string): boolean;
43
+ //# sourceMappingURL=comparison-expr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparison-expr.d.ts","sourceRoot":"","sources":["../../src/engine/comparison-expr.ts"],"names":[],"mappings":"AAWA,4FAA4F;AAC5F,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC;AAEjE,MAAM,MAAM,uBAAuB,GAC/B,OAAO,GACP,cAAc,GACd,aAAa,GACb,oBAAoB,CAAC;AAEzB,oGAAoG;AACpG,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,uBAAuB,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3E;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAyBnF;AAiED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAiC9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/C"}
@@ -0,0 +1,154 @@
1
+ // comparison-expr.ts — zero-dependency, quote-aware splitting for Realm's condition leaves.
2
+ //
3
+ // This module is the SINGLE source of truth for how a one-line condition leaf is split into a
4
+ // comparison, a bare path, or an "invalid" verdict. It is used by:
5
+ // - load-time validation (yaml-loader) — to reject compound / malformed leaves with a loud error;
6
+ // - runtime evaluation (evaluateWhenCondition, evaluateGuardConditions, evaluatePrecondition) — so
7
+ // the split used to validate a leaf is the SAME split used to evaluate it (no validate/eval drift).
8
+ //
9
+ // It MUST stay zero-dependency (no import from render-template/eligibility/precondition) to avoid an
10
+ // import cycle — those modules import FROM here.
11
+ /**
12
+ * Splits `input` on every occurrence of single-character `delimiter` that is NOT inside a quoted
13
+ * string. Single or double quotes both open/close quote state; the other quote type is ignored while
14
+ * inside a quote. Returns raw substrings — no trimming, no quote stripping.
15
+ *
16
+ * (Moved here from render-template.ts so both template rendering and condition splitting share one
17
+ * quote-aware primitive; render-template imports it from this module.)
18
+ */
19
+ export function splitOnUnquotedDelimiter(input, delimiter) {
20
+ const segments = [];
21
+ let current = '';
22
+ let inSingle = false;
23
+ let inDouble = false;
24
+ for (const ch of input) {
25
+ if (ch === '"' && !inSingle) {
26
+ inDouble = !inDouble;
27
+ current += ch;
28
+ continue;
29
+ }
30
+ if (ch === "'" && !inDouble) {
31
+ inSingle = !inSingle;
32
+ current += ch;
33
+ continue;
34
+ }
35
+ if (ch === delimiter && !inSingle && !inDouble) {
36
+ segments.push(current);
37
+ current = '';
38
+ continue;
39
+ }
40
+ current += ch;
41
+ }
42
+ segments.push(current);
43
+ return segments;
44
+ }
45
+ /**
46
+ * Returns `expr` with every character inside a quoted region (and the quote chars themselves)
47
+ * replaced by a space, preserving length so positions in the mask map 1:1 to the original. Used to
48
+ * find operators/keywords while ignoring quoted content.
49
+ */
50
+ function maskQuoted(expr) {
51
+ let out = '';
52
+ let inSingle = false;
53
+ let inDouble = false;
54
+ for (const ch of expr) {
55
+ if (ch === '"' && !inSingle) {
56
+ inDouble = !inDouble;
57
+ out += ' ';
58
+ continue;
59
+ }
60
+ if (ch === "'" && !inDouble) {
61
+ inSingle = !inSingle;
62
+ out += ' ';
63
+ continue;
64
+ }
65
+ out += inSingle || inDouble ? ' ' : ch;
66
+ }
67
+ return out;
68
+ }
69
+ const TWO_CHAR_OPS = ['>=', '<=', '==', '!='];
70
+ /** Find all unquoted comparison-operator occurrences in `mask` (2-char ops take precedence). */
71
+ function findOperators(mask) {
72
+ const found = [];
73
+ let i = 0;
74
+ while (i < mask.length) {
75
+ const two = mask.slice(i, i + 2);
76
+ if (TWO_CHAR_OPS.includes(two)) {
77
+ found.push({ pos: i, op: two, len: 2 });
78
+ i += 2;
79
+ continue;
80
+ }
81
+ const one = mask[i];
82
+ if (one === '>' || one === '<') {
83
+ found.push({ pos: i, op: one, len: 1 });
84
+ i += 1;
85
+ continue;
86
+ }
87
+ i += 1;
88
+ }
89
+ return found;
90
+ }
91
+ /** Split `expr` on an unquoted whitespace-delimited keyword (e.g. `and`), using the mask. */
92
+ function splitOnUnquotedKeyword(expr, mask, keyword) {
93
+ const re = new RegExp(`\\s${keyword}\\s`, 'g');
94
+ const parts = [];
95
+ let last = 0;
96
+ let m;
97
+ while ((m = re.exec(mask)) !== null) {
98
+ parts.push(expr.slice(last, m.index).trim());
99
+ last = m.index + m[0].length;
100
+ }
101
+ parts.push(expr.slice(last).trim());
102
+ return parts;
103
+ }
104
+ /**
105
+ * Split one condition leaf, quote-aware, into a comparison `{ lhsPath, op, rhsRaw }`, a bare
106
+ * `{ path }`, or `{ invalid, reason }`. Operator tokens and `and`/`or` keywords inside quoted
107
+ * regions are ignored. Never throws.
108
+ *
109
+ * - `and`/`or` (unquoted) → `invalid` with `parts` (the split candidates, for an actionable error).
110
+ * - exactly one unquoted operator → `comparison`.
111
+ * - more than one → `invalid` (`multiple_operators`).
112
+ * - none → `path` (a bare path; the caller validates its shape with {@link isPathShaped}).
113
+ */
114
+ export function splitComparison(input) {
115
+ const expr = input.trim();
116
+ if (expr === '')
117
+ return { kind: 'invalid', reason: 'empty' };
118
+ const mask = maskQuoted(expr);
119
+ // Boolean composition keywords take priority — they produce the most actionable error.
120
+ if (/\sand\s/.test(mask)) {
121
+ return {
122
+ kind: 'invalid',
123
+ reason: 'compound_and',
124
+ parts: splitOnUnquotedKeyword(expr, mask, 'and'),
125
+ };
126
+ }
127
+ if (/\sor\s/.test(mask)) {
128
+ return {
129
+ kind: 'invalid',
130
+ reason: 'compound_or',
131
+ parts: splitOnUnquotedKeyword(expr, mask, 'or'),
132
+ };
133
+ }
134
+ const ops = findOperators(mask);
135
+ if (ops.length === 0)
136
+ return { kind: 'path', path: expr };
137
+ if (ops.length > 1)
138
+ return { kind: 'invalid', reason: 'multiple_operators' };
139
+ const { pos, op, len } = ops[0];
140
+ return {
141
+ kind: 'comparison',
142
+ lhsPath: expr.slice(0, pos).trim(),
143
+ op,
144
+ rhsRaw: expr.slice(pos + len).trim(),
145
+ };
146
+ }
147
+ /**
148
+ * True when `s` is a bare dot-path: starts with a letter/underscore and contains only word chars,
149
+ * `.`, or `-` (no spaces, no operators). Used to reject a non-path LHS at load time.
150
+ */
151
+ export function isPathShaped(s) {
152
+ return /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(s);
153
+ }
154
+ //# sourceMappingURL=comparison-expr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparison-expr.js","sourceRoot":"","sources":["../../src/engine/comparison-expr.ts"],"names":[],"mappings":"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"}
@@ -13,11 +13,25 @@ export declare function deriveRunPhase(run: Pick<RunRecord, 'pending_gate' | 'te
13
13
  */
14
14
  export declare function triggerRuleSatisfied(step: StepDefinition, run: RunRecord): boolean;
15
15
  /**
16
- * Evaluates a when-condition expression against prior step evidence.
17
- * Supports: path == 'value', path != 'value', path > n, path < n, path >= n, path <= n.
18
- * Returns false on parse error or missing value.
16
+ * Evaluates a single `when`-condition LEAF against prior step evidence (per-leaf; the array-AND
17
+ * folding lives in {@link evaluateWhen}). Splitting is quote-aware via the shared splitter, so the
18
+ * leaf is split the same way at load and at runtime (no validate/eval divergence).
19
+ *
20
+ * Absent-LHS semantics (unique to `when`):
21
+ * - `== null` / `!= null` (bare null RHS) → loose presence test (`lhs == null` / `lhs != null`),
22
+ * covering both a missing path and a present-`null` value uniformly.
23
+ * - relational `> < >= <=` → both operands must be numeric, else false (no `null→0` coercion).
24
+ * - any other operator with an undefined LHS → false (symmetric `undefined → false`).
25
+ * - bare path → `Boolean(resolved)`.
26
+ * A resolved LHS uses strict `===`/`!==` (equality) or numeric-guarded relational comparison.
19
27
  */
20
28
  export declare function evaluateWhenCondition(expr: string, evidenceByStep: Record<string, Record<string, unknown>>, runParams?: Record<string, unknown>): boolean;
29
+ /**
30
+ * AND-folds a `when` clause (`string | string[]`) over the per-leaf {@link evaluateWhenCondition}.
31
+ * A bare string is a single leaf; an array is the implicit AND of its leaves. An array NEVER reaches
32
+ * the single-string evaluator — normalization happens here, in one place.
33
+ */
34
+ export declare function evaluateWhen(clause: string | string[], evidenceByStep: Record<string, Record<string, unknown>>, runParams?: Record<string, unknown>): boolean;
21
35
  /**
22
36
  * Builds the evidenceByStep map from a run record's evidence array.
23
37
  * Merges gate_response snapshots on top of execution snapshots so that
@@ -1 +1 @@
1
- {"version":3,"file":"eligibility.d.ts","sourceRoot":"","sources":["../../src/engine/eligibility.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EAEf,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAGvD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,IAAI,CACP,SAAS,EACP,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,iBAAiB,GACjB,YAAY,GACZ,cAAc,CACjB,GACA,QAAQ,CAsBV;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CA0ClF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACvD,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACtC,OAAO,CAyDT;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAe3F;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,GAAG,MAAM,EAAE,CAqC1F;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,GAAG,MAAM,EAAE,CAkC/F;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAU1F;AAqDD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,GAAG,MAAM,EAAE,CA+CvF"}
1
+ {"version":3,"file":"eligibility.d.ts","sourceRoot":"","sources":["../../src/engine/eligibility.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EAEf,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAIvD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,IAAI,CACP,SAAS,EACP,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,iBAAiB,GACjB,YAAY,GACZ,cAAc,CACjB,GACA,QAAQ,CAsBV;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CA0ClF;AA+BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACvD,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACtC,OAAO,CAiDT;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACvD,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACtC,OAAO,CAGT;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAe3F;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,GAAG,MAAM,EAAE,CAqC1F;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,kBAAkB,EAAE,GAAG,EAAE,SAAS,GAAG,MAAM,EAAE,CAkC/F;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAU1F;AAqDD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,kBAAkB,GAAG,MAAM,EAAE,CA4CvF"}
@@ -1,4 +1,5 @@
1
1
  import { resolvePath } from './render-template.js';
2
+ import { splitComparison } from './comparison-expr.js';
2
3
  /**
3
4
  * Derives the run_phase from the run record fields.
4
5
  * Called after every store write to keep run_phase consistent.
@@ -67,69 +68,105 @@ export function triggerRuleSatisfied(step, run) {
67
68
  deps.every((d) => !run.failed_steps.includes(d)));
68
69
  }
69
70
  }
71
+ /** Parse a `when` RHS literal, flagging the bare `null` token (drives the 1c presence-test). */
72
+ function parseWhenRhs(rhs) {
73
+ if ((rhs.startsWith("'") && rhs.endsWith("'")) || (rhs.startsWith('"') && rhs.endsWith('"'))) {
74
+ return { value: rhs.slice(1, -1), isBareNull: false };
75
+ }
76
+ if (rhs === 'true')
77
+ return { value: true, isBareNull: false };
78
+ if (rhs === 'false')
79
+ return { value: false, isBareNull: false };
80
+ if (rhs === 'null')
81
+ return { value: null, isBareNull: true };
82
+ const n = Number(rhs);
83
+ return { value: Number.isNaN(n) ? rhs : n, isBareNull: false };
84
+ }
85
+ /** Relational comparison requiring both operands numeric (no JS null→0 coercion). */
86
+ function compareNumeric(op, lhs, rhs) {
87
+ if (typeof lhs !== 'number' || typeof rhs !== 'number')
88
+ return false;
89
+ switch (op) {
90
+ case '>':
91
+ return lhs > rhs;
92
+ case '<':
93
+ return lhs < rhs;
94
+ case '>=':
95
+ return lhs >= rhs;
96
+ case '<=':
97
+ return lhs <= rhs;
98
+ default:
99
+ return false;
100
+ }
101
+ }
70
102
  /**
71
- * Evaluates a when-condition expression against prior step evidence.
72
- * Supports: path == 'value', path != 'value', path > n, path < n, path >= n, path <= n.
73
- * Returns false on parse error or missing value.
103
+ * Evaluates a single `when`-condition LEAF against prior step evidence (per-leaf; the array-AND
104
+ * folding lives in {@link evaluateWhen}). Splitting is quote-aware via the shared splitter, so the
105
+ * leaf is split the same way at load and at runtime (no validate/eval divergence).
106
+ *
107
+ * Absent-LHS semantics (unique to `when`):
108
+ * - `== null` / `!= null` (bare null RHS) → loose presence test (`lhs == null` / `lhs != null`),
109
+ * covering both a missing path and a present-`null` value uniformly.
110
+ * - relational `> < >= <=` → both operands must be numeric, else false (no `null→0` coercion).
111
+ * - any other operator with an undefined LHS → false (symmetric `undefined → false`).
112
+ * - bare path → `Boolean(resolved)`.
113
+ * A resolved LHS uses strict `===`/`!==` (equality) or numeric-guarded relational comparison.
74
114
  */
75
115
  export function evaluateWhenCondition(expr, evidenceByStep, runParams = {}) {
76
- // when-condition paths are relative to step outputs: "step_id.field" resolves
77
- // directly against evidenceByStep (e.g. step_a.confidence == high).
78
- // "run.params.field" resolves against run start params.
116
+ // when-condition paths are relative to step outputs: "step_id.field" resolves directly against
117
+ // evidenceByStep; "run.params.field" resolves against run start params.
79
118
  const root = { ...evidenceByStep, run: { params: runParams } };
80
- const operators = [
81
- [' >= ', (a, b) => a >= b],
82
- [' <= ', (a, b) => a <= b],
83
- [' != ', (a, b) => a !== b],
84
- [' == ', (a, b) => a === b],
85
- [' > ', (a, b) => a > b],
86
- [' < ', (a, b) => a < b],
87
- ];
88
- for (const [op, compare] of operators) {
89
- const idx = expr.indexOf(op);
90
- if (idx === -1)
91
- continue;
92
- const lhsPath = expr.slice(0, idx).trim();
93
- const rhs = expr.slice(idx + op.length).trim();
94
- let leftVal;
95
- try {
96
- leftVal = resolvePath(lhsPath, root);
97
- }
98
- catch {
99
- return false;
100
- }
101
- let rightVal;
102
- if ((rhs.startsWith("'") && rhs.endsWith("'")) || (rhs.startsWith('"') && rhs.endsWith('"'))) {
103
- rightVal = rhs.slice(1, -1);
104
- }
105
- else if (rhs === 'true') {
106
- rightVal = true;
107
- }
108
- else if (rhs === 'false') {
109
- rightVal = false;
110
- }
111
- else if (rhs === 'null') {
112
- rightVal = null;
113
- }
114
- else {
115
- const n = Number(rhs);
116
- rightVal = Number.isNaN(n) ? rhs : n;
117
- }
119
+ const split = splitComparison(expr);
120
+ // A compound/malformed leaf is rejected at load; if one reaches runtime it is never eligible.
121
+ if (split.kind === 'invalid')
122
+ return false;
123
+ if (split.kind === 'path') {
118
124
  try {
119
- return compare(leftVal, rightVal);
125
+ return Boolean(resolvePath(split.path, root));
120
126
  }
121
127
  catch {
122
128
  return false;
123
129
  }
124
130
  }
125
- // No operator: treat the path value as a truthy/falsy boolean.
131
+ const { lhsPath, op, rhsRaw } = split;
132
+ let lhs;
126
133
  try {
127
- const val = resolvePath(expr.trim(), root);
128
- return Boolean(val);
134
+ lhs = resolvePath(lhsPath, root);
129
135
  }
130
136
  catch {
131
137
  return false;
132
138
  }
139
+ const { value: rhs, isBareNull } = parseWhenRhs(rhsRaw);
140
+ if (lhs === undefined) {
141
+ // Presence test first (covers missing + present-null uniformly via loose null).
142
+ if ((op === '==' || op === '!=') && isBareNull) {
143
+ return op === '==' ? lhs == null : lhs != null;
144
+ }
145
+ // Relational on an absent LHS → false (numeric guard); any other op on absent → false.
146
+ return false;
147
+ }
148
+ switch (op) {
149
+ case '==':
150
+ return lhs === rhs;
151
+ case '!=':
152
+ return lhs !== rhs;
153
+ case '>':
154
+ case '<':
155
+ case '>=':
156
+ case '<=':
157
+ return compareNumeric(op, lhs, rhs);
158
+ default:
159
+ return false;
160
+ }
161
+ }
162
+ /**
163
+ * AND-folds a `when` clause (`string | string[]`) over the per-leaf {@link evaluateWhenCondition}.
164
+ * A bare string is a single leaf; an array is the implicit AND of its leaves. An array NEVER reaches
165
+ * the single-string evaluator — normalization happens here, in one place.
166
+ */
167
+ export function evaluateWhen(clause, evidenceByStep, runParams = {}) {
168
+ const leaves = Array.isArray(clause) ? clause : [clause];
169
+ return leaves.every((leaf) => evaluateWhenCondition(leaf, evidenceByStep, runParams));
133
170
  }
134
171
  /**
135
172
  * Builds the evidenceByStep map from a run record's evidence array.
@@ -186,9 +223,9 @@ export function findEligibleSteps(definition, run) {
186
223
  // Trigger rule evaluation.
187
224
  if (!triggerRuleSatisfied(step, run))
188
225
  continue;
189
- // when-condition evaluation.
226
+ // when-condition evaluation (string | string[] implicit-AND).
190
227
  if (step.when !== undefined) {
191
- if (!evaluateWhenCondition(step.when, evidenceByStep, run.params))
228
+ if (!evaluateWhen(step.when, evidenceByStep, run.params))
192
229
  continue;
193
230
  }
194
231
  eligible.push(stepName);
@@ -222,10 +259,10 @@ export function findEligibleGuardSteps(definition, run) {
222
259
  // Trigger rule evaluation.
223
260
  if (!triggerRuleSatisfied(step, run))
224
261
  continue;
225
- // when-condition evaluation.
262
+ // when-condition evaluation (string | string[] implicit-AND).
226
263
  if (step.when !== undefined) {
227
264
  const evidenceByStep = buildEvidenceByStep(run);
228
- if (!evaluateWhenCondition(step.when, evidenceByStep, run.params))
265
+ if (!evaluateWhen(step.when, evidenceByStep, run.params))
229
266
  continue;
230
267
  }
231
268
  eligible.push(stepName);
@@ -315,8 +352,7 @@ export function propagateSkips(run, definition) {
315
352
  const allDepsSettled = deps.every((d) => tempRun.completed_steps.includes(d) ||
316
353
  tempRun.failed_steps.includes(d) ||
317
354
  skipped.includes(d));
318
- if (allDepsSettled &&
319
- !evaluateWhenCondition(step.when, buildEvidenceByStep(run), run.params)) {
355
+ if (allDepsSettled && !evaluateWhen(step.when, buildEvidenceByStep(run), run.params)) {
320
356
  skipped.push(stepName);
321
357
  changed = true;
322
358
  }
@@ -1 +1 @@
1
- {"version":3,"file":"eligibility.js","sourceRoot":"","sources":["../../src/engine/eligibility.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eligibility.js","sourceRoot":"","sources":["../../src/engine/eligibility.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAqB,MAAM,sBAAsB,CAAC;AAE1E;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,GAQC;IAED,4FAA4F;IAC5F,sFAAsF;IACtF,+FAA+F;IAC/F,mGAAmG;IACnG,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,WAAW,CAAC;IACvD,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,cAAc,CAAC;IAC1D,iFAAiF;IACjF,gGAAgG;IAChG,kGAAkG;IAClG,0FAA0F;IAC1F,8FAA8F;IAC9F,uFAAuF;IACvF,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACnD,IAAI,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,SAAS,CAAC;IAC1C,4FAA4F;IAC5F,wFAAwF;IACxF,gGAAgG;IAChG,IAAI,GAAG,CAAC,eAAe,KAAK,qBAAqB;QAAE,OAAO,WAAW,CAAC;IACtE,IAAI,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACjD,+FAA+F;IAC/F,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAoB,EAAE,GAAc;IACvE,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,IAAI,GAAgB,IAAI,CAAC,YAAY,IAAI,aAAa,CAAC;IAE7D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa;YAChB,qDAAqD;YACrD,OAAO,CACL,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAClD,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CACjD,CAAC;QAEJ,KAAK,YAAY;YACf,4BAA4B;YAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAEzD,KAAK,UAAU;YACb,0FAA0F;YAC1F,OAAO,IAAI,CAAC,KAAK,CACf,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC/B,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC5B,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAChC,CAAC;QAEJ,KAAK,YAAY;YACf,oCAAoC;YACpC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAExD,KAAK,aAAa;YAChB,uCAAuC;YACvC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3D,KAAK,aAAa;YAChB,uEAAuE;YACvE,OAAO,CACL,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACnF,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CACjD,CAAC;IACN,CAAC;AACH,CAAC;AAED,gGAAgG;AAChG,SAAS,YAAY,CAAC,GAAW;IAC/B,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAC9D,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAChE,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAC7D,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AACjE,CAAC;AAED,qFAAqF;AACrF,SAAS,cAAc,CAAC,EAAgB,EAAE,GAAY,EAAE,GAAY;IAClE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACrE,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,GAAG;YACN,OAAO,GAAG,GAAG,GAAG,CAAC;QACnB,KAAK,GAAG;YACN,OAAO,GAAG,GAAG,GAAG,CAAC;QACnB,KAAK,IAAI;YACP,OAAO,GAAG,IAAI,GAAG,CAAC;QACpB,KAAK,IAAI;YACP,OAAO,GAAG,IAAI,GAAG,CAAC;QACpB;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAY,EACZ,cAAuD,EACvD,YAAqC,EAAE;IAEvC,+FAA+F;IAC/F,wEAAwE;IACxE,MAAM,IAAI,GAA4B,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;IAExF,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAEpC,8FAA8F;IAC9F,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAE3C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACtC,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAExD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,gFAAgF;QAChF,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC,IAAI,UAAU,EAAE,CAAC;YAC/C,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;QACjD,CAAC;QACD,uFAAuF;QACvF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,IAAI;YACP,OAAO,GAAG,KAAK,GAAG,CAAC;QACrB,KAAK,IAAI;YACP,OAAO,GAAG,KAAK,GAAG,CAAC;QACrB,KAAK,GAAG,CAAC;QACT,KAAK,GAAG,CAAC;QACT,KAAK,IAAI,CAAC;QACV,KAAK,IAAI;YACP,OAAO,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACtC;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAyB,EACzB,cAAuD,EACvD,YAAqC,EAAE;IAEvC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACzD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC;AACxF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAc;IAChD,MAAM,cAAc,GAA4C,EAAE,CAAC;IACnE,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YAClC,0EAA0E;YAC1E,iEAAiE;YACjE,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG;gBAC7B,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBACvC,GAAG,IAAI,CAAC,cAAc;aACvB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC;QACrD,CAAC;IACH,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAA8B,EAAE,GAAc;IAC9E,iGAAiG;IACjG,4FAA4F;IAC5F,IAAI,GAAG,CAAC,cAAc;QAAE,OAAO,EAAE,CAAC;IAClC,oEAAoE;IACpE,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAE9C,MAAM,cAAc,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,mEAAmE;QACnE,2DAA2D;QAC3D,IAAI,IAAI,CAAC,SAAS,KAAK,OAAO;YAAE,SAAS;QAEzC,6BAA6B;QAC7B,IACE,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACtC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACnC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACpC,CAAC;YACD,SAAS;QACX,CAAC;QAED,2BAA2B;QAC3B,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC;YAAE,SAAS;QAE/C,8DAA8D;QAC9D,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC;gBAAE,SAAS;QACrE,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAA8B,EAAE,GAAc;IACnF,4FAA4F;IAC5F,6DAA6D;IAC7D,IAAI,GAAG,CAAC,cAAc;QAAE,OAAO,EAAE,CAAC;IAClC,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAE9C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,IAAI,IAAI,CAAC,SAAS,KAAK,OAAO;YAAE,SAAS;QAEzC,mBAAmB;QACnB,IACE,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACtC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACnC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACpC,CAAC;YACD,SAAS;QACX,CAAC;QAED,2BAA2B;QAC3B,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC;YAAE,SAAS;QAE/C,8DAA8D;QAC9D,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,cAAc,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;YAChD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC;gBAAE,SAAS;QACrE,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAc,EAAE,UAA8B;IAC/E,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC/C,OAAO,CACL,QAAQ,CAAC,KAAK,CACZ,CAAC,IAAI,EAAE,EAAE,CACP,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC;QAClC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC/B,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CACnC,IAAI,GAAG,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,CACxC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,6BAA6B,CAAC,IAAoB,EAAE,GAAc;IACzE,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,IAAI,GAAgB,IAAI,CAAC,YAAY,IAAI,aAAa,CAAC;IAE7D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa;YAChB,mFAAmF;YACnF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAE5F,KAAK,YAAY;YACf,mFAAmF;YACnF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/F,KAAK,UAAU;YACb,uFAAuF;YACvF,mEAAmE;YACnE,OAAO,IAAI,CAAC;QAEd,KAAK,YAAY;YACf,mFAAmF;YACnF,sEAAsE;YACtE,OAAO,IAAI,CAAC,IAAI,CACd,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,oBAAoB;gBACpD,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CACvE,CAAC;QAEJ,KAAK,aAAa;YAChB,mFAAmF;YACnF,4EAA4E;YAC5E,OAAO,IAAI,CAAC,IAAI,CACd,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,oBAAoB;gBACvD,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CACpE,CAAC;QAEJ,KAAK,aAAa;YAChB,+DAA+D;YAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,GAAc,EAAE,UAA8B;IAC3E,MAAM,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC;IACvC,IAAI,OAAO,GAAG,IAAI,CAAC;IAEnB,OAAO,OAAO,EAAE,CAAC;QACf,OAAO,GAAG,KAAK,CAAC;QAChB,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,gDAAgD;YAChD,IACE,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACtC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACxC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAC1B,CAAC;gBACD,SAAS;YACX,CAAC;YAED,2EAA2E;YAC3E,MAAM,OAAO,GAAc,EAAE,GAAG,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;YAC9D,IAAI,CAAC,6BAA6B,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;gBAClD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACvB,OAAO,GAAG,IAAI,CAAC;gBACf,SAAS;YACX,CAAC;YAED,+EAA+E;YAC/E,8EAA8E;YAC9E,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;gBACnC,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAC/B,CAAC,CAAC,EAAE,EAAE,CACJ,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACnC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAChC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CACtB,CAAC;gBACF,IAAI,cAAc,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;oBACrF,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACvB,OAAO,GAAG,IAAI,CAAC;gBACjB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"precondition.d.ts","sourceRoot":"","sources":["../../src/engine/precondition.ts"],"names":[],"mappings":"AAyDA;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtD,OAAO,CAiBT;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,yEAAyE;IACzE,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EAAE,EACvB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtD,kBAAkB,GAAG,IAAI,CAiB3B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EAAE,EACvB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtD,kBAAkB,EAAE,CAatB;AAMD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,oBAAoB,EAAE,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,oBAAoB,EAAE,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAAE,EACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtD,sBAAsB,CAwDxB"}
1
+ {"version":3,"file":"precondition.d.ts","sourceRoot":"","sources":["../../src/engine/precondition.ts"],"names":[],"mappings":"AA0DA;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtD,OAAO,CAcT;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,yEAAyE;IACzE,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EAAE,EACvB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtD,kBAAkB,GAAG,IAAI,CAY3B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EAAE,EACvB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtD,kBAAkB,EAAE,CAQtB;AAMD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,oBAAoB,EAAE,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,oBAAoB,EAAE,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAAE,EACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACtD,sBAAsB,CAiDxB"}
@@ -1,5 +1,6 @@
1
1
  // Precondition evaluator — evaluates step precondition expressions against
2
2
  // the run's collected evidence map before allowing a step to execute.
3
+ import { splitComparison } from './comparison-expr.js';
3
4
  /**
4
5
  * Resolves a dot-separated path into a nested object.
5
6
  * Returns `undefined` if any segment is missing.
@@ -66,21 +67,19 @@ function compare(lhs, op, rhs) {
66
67
  * Example: "validate_candidates.result.accepted_count > 0"
67
68
  */
68
69
  export function evaluatePrecondition(expression, evidenceByStep) {
69
- const match = /^([\w-]+)\.([\w.]+)\s*(>=|<=|!=|>|<|==)\s*(\S.*)$/.exec(expression);
70
- if (match === null)
70
+ // Split via the shared quote-aware splitter (same split used at load) — see comparison-expr.ts.
71
+ // A precondition is a comparison only; a bare path / compound / malformed leaf → false (the old
72
+ // regex's no-match behavior). Absent LHS → false. Coercion is unchanged (compare/parseLiteral).
73
+ const split = splitComparison(expression);
74
+ if (split.kind !== 'comparison')
71
75
  return false;
72
- const stepName = match[1];
73
- const fieldPath = match[2];
74
- const op = match[3];
75
- const literalRaw = match[4];
76
- const stepEvidence = evidenceByStep[stepName];
77
- if (stepEvidence === undefined)
78
- return false;
79
- const lhs = resolvePath(stepEvidence, fieldPath);
76
+ // resolvePath(evidenceByStep, "step.field") walks the dotted path — equivalent to the old
77
+ // two-step (evidenceByStep[step] then resolvePath of the field path).
78
+ const lhs = resolvePath(evidenceByStep, split.lhsPath);
80
79
  if (lhs === undefined)
81
80
  return false;
82
- const rhs = parseLiteral(literalRaw);
83
- return compare(lhs, op, rhs);
81
+ const rhs = parseLiteral(split.rhsRaw);
82
+ return compare(lhs, split.op, rhs);
84
83
  }
85
84
  /**
86
85
  * Evaluates all preconditions in order. Returns the first failure, or null if all pass.
@@ -89,15 +88,9 @@ export function checkPreconditions(preconditions, evidenceByStep) {
89
88
  for (const expression of preconditions) {
90
89
  const passed = evaluatePrecondition(expression, evidenceByStep);
91
90
  if (!passed) {
92
- // Resolve the LHS value for the failure message.
93
- const match = /^([\w-]+)\.([\w.]+)/.exec(expression);
94
- let resolvedValue = undefined;
95
- if (match !== null) {
96
- const stepEvidence = evidenceByStep[match[1]];
97
- if (stepEvidence !== undefined) {
98
- resolvedValue = resolvePath(stepEvidence, match[2]);
99
- }
100
- }
91
+ // Resolve the LHS value for the failure message (shared splitter — see comparison-expr.ts).
92
+ const split = splitComparison(expression);
93
+ const resolvedValue = split.kind === 'comparison' ? resolvePath(evidenceByStep, split.lhsPath) : undefined;
101
94
  return { expression, passed: false, resolved_value: resolvedValue };
102
95
  }
103
96
  }
@@ -111,14 +104,8 @@ export function checkPreconditions(preconditions, evidenceByStep) {
111
104
  export function evaluateAllPreconditions(preconditions, evidenceByStep) {
112
105
  return preconditions.map((expression) => {
113
106
  const passed = evaluatePrecondition(expression, evidenceByStep);
114
- const match = /^([\w-]+)\.([\w.]+)/.exec(expression);
115
- let resolvedValue = undefined;
116
- if (match !== null) {
117
- const stepEvidence = evidenceByStep[match[1]];
118
- if (stepEvidence !== undefined) {
119
- resolvedValue = resolvePath(stepEvidence, match[2]);
120
- }
121
- }
107
+ const split = splitComparison(expression);
108
+ const resolvedValue = split.kind === 'comparison' ? resolvePath(evidenceByStep, split.lhsPath) : undefined;
122
109
  return { expression, passed, resolved_value: resolvedValue };
123
110
  });
124
111
  }
@@ -141,23 +128,17 @@ export function evaluateGuardConditions(conditions, evidenceByStep) {
141
128
  const root = evidenceByStep;
142
129
  const results = [];
143
130
  for (const condition of conditions) {
144
- const operators = ['>=', '<=', '!=', '==', '>', '<'];
145
- let matched = false;
146
- for (const op of operators) {
147
- const opWithSpaces = ` ${op} `;
148
- const idx = condition.indexOf(opWithSpaces);
149
- if (idx === -1)
150
- continue;
151
- matched = true;
152
- const lhsPath = condition.slice(0, idx).trim();
153
- const rhs = condition.slice(idx + opWithSpaces.length).trim();
154
- // Resolve LHS.
131
+ // Split via the shared quote-aware splitter (same split used at load) — see comparison-expr.ts.
132
+ // Absent-policy and type-coercion are UNCHANGED from the original indexOf-scan: an unresolved
133
+ // LHS or a non-numeric relational comparison is a resolution_error; a bare path is a truthy test.
134
+ const split = splitComparison(condition);
135
+ if (split.kind === 'comparison') {
136
+ const { lhsPath, op, rhsRaw } = split;
155
137
  const lhsValue = resolvePath(root, lhsPath);
156
138
  if (lhsValue === undefined) {
157
139
  return { kind: 'resolution_error', condition, unresolvable_path: lhsPath };
158
140
  }
159
- // Parse RHS literal.
160
- const rhsValue = parseLiteral(rhs);
141
+ const rhsValue = parseLiteral(rhsRaw);
161
142
  // Numeric operators require both sides to be numbers.
162
143
  if (op !== '==' &&
163
144
  op !== '!=' &&
@@ -166,17 +147,19 @@ export function evaluateGuardConditions(conditions, evidenceByStep) {
166
147
  }
167
148
  const passed = compare(lhsValue, op, rhsValue);
168
149
  results.push({ condition, resolved_value: lhsValue, passed });
169
- break;
170
150
  }
171
- if (!matched) {
151
+ else if (split.kind === 'path') {
172
152
  // Bare path — truthy/falsy check.
173
- const path = condition.trim();
174
- const value = resolvePath(root, path);
153
+ const value = resolvePath(root, split.path);
175
154
  if (value === undefined) {
176
- return { kind: 'resolution_error', condition, unresolvable_path: path };
155
+ return { kind: 'resolution_error', condition, unresolvable_path: split.path };
177
156
  }
178
157
  results.push({ condition, resolved_value: value, passed: Boolean(value) });
179
158
  }
159
+ else {
160
+ // Compound/malformed leaf is rejected at load; if one reaches runtime, treat as unresolvable.
161
+ return { kind: 'resolution_error', condition, unresolvable_path: condition };
162
+ }
180
163
  }
181
164
  const anyFailed = results.some((r) => !r.passed);
182
165
  if (anyFailed) {