From c83738e9492db58c1d47877e2ce47122d8438aec Mon Sep 17 00:00:00 2001 From: mig-builds <54319294+mig-builds@users.noreply.github.com> Date: Thu, 22 Oct 2026 21:51:52 +0200 Subject: [PATCH] docs(spec): clarify has index guard --- .../spec/src/automation/flow-value-slot-template.test.ts | 2 +- packages/spec/src/automation/flow-value-slot-template.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/spec/src/automation/flow-value-slot-template.test.ts b/packages/spec/src/automation/flow-value-slot-template.test.ts index 605c23497ac..54f2be9b92d 100644 --- a/packages/spec/src/automation/flow-value-slot-template.test.ts +++ b/packages/spec/src/automation/flow-value-slot-template.test.ts @@ -198,7 +198,7 @@ describe('a head CEL claims is read through `vars`, the route a `$`-named head t expect(refusalOf('{record.true}')).not.toContain('the guarded form'); }); - it('an index anywhere in the path leaves it unguarded — `has()` refuses one at run time', () => { + it('an indexed intermediate segment stays unguarded even though `has()` accepts it at run time', () => { expect(refusalOf('{rows.0.name}')).toContain("source: 'rows[0].name' }"); expect(refusalOf('{rows.0.name}')).not.toContain('the guarded form'); }); diff --git a/packages/spec/src/automation/flow-value-slot-template.ts b/packages/spec/src/automation/flow-value-slot-template.ts index dbff1e7810d..daeb629423b 100644 --- a/packages/spec/src/automation/flow-value-slot-template.ts +++ b/packages/spec/src/automation/flow-value-slot-template.ts @@ -315,10 +315,10 @@ type Write = (source: string) => string; /** * A `has()` guard for a path of keys — the absent-variable and absent-key - * remedy. `has()` takes a field selection over names alone: an index anywhere - * in its argument (`has(a[0].b)`, `has(vars["$x"].y)`) is refused when it - * runs, so a path with a numeric segment, a `$`-named head or a keyword - * segment gets no guard. + * remedy. `has()` refuses an index only when it is the final selection in its + * argument. A path with a numeric segment still gets no guard because this + * guard builder only emits field selections over names; `$`-named heads and + * keyword segments likewise get no guard. * * The guard tests one step at a time, from `vars`, which holds only the * variables the run has bound: `has(vars.source) && has(vars.source.id) ?