Repository navigation
Commit 2abc0d3
docs(spec): the guardOf docblock and its test title state the has() rule that holds now (#25367)
<!-- claude-projects-attribution: {"github_login":"os-tesla"} -->
_Requested by **Tesla** · [project
thread](https://claude.ai/code/project/chan_01AXsQkLFKRdQCqQ3RTr6Jao?thread=cmsg_01AXsQkLFKRdQCqQ3RTr6JaoAbFvsoZdKGPS2souyWMqfZ)_
Fixes #25282
Clause-②: no
Metadata-protocol: none
## What changes
Two prose edits in
`packages/spec/src/automation/flow-value-slot-template.ts` and its test.
No behaviour change.
- The `guardOf` docblock said `has()` refuses an index anywhere in its
argument (`has(a[0].b)`, `has(vars["$x"].y)`). Since PR #25275 that is
no longer true: `has()` refuses an index only as the **last** step of
its argument, and an index before it is a presence test. The docblock
now says that, and gives the reason the guard still skips a path with a
numeric segment, a `$`-named head or a keyword segment: the guard tests
every step of the path, each of those segments is read by index, so one
of the guard's tests would end on that index.
- The test title "an index anywhere in the path leaves it unguarded —
`has()` refuses one at run time" now reads "an index in the path leaves
it unguarded — a step-at-a-time guard would end a `has()` on it, which
`has()` refuses at run time". The assertions are unchanged.
## The rule, measured
Through `celEngine.evaluate` in `@objectstack/formula` at this head (a
throwaway probe test, deleted after the run), with `vars = { rows: [{
name: 'a' }], $x: { y: 1 }, record: { in: 1 } }`:
| source | answer |
|---|---|
| `has(vars.rows[0].name)` | `ok: true`, `true` |
| `has(vars.rows[0].nope)` | `ok: true`, `false` |
| `has(vars["$x"].y)` | `ok: true`, `true` |
| `has(vars.rows[0])` | refused, `has() invalid argument` |
| `has(vars["$x"])` | refused, `has() invalid argument` |
| `has(vars.record["in"])` | refused, `has() invalid argument` |
| `has(vars.rows) && has(vars.rows[0]) && has(vars.rows[0].name)` (the
guard's shape) | refused, `has() invalid argument` |
So the docblock's old examples are now accepted, and the guard the
function would build for such a path still faults on its middle step.
The behaviour (no guard) stays right; only the stated reason changed.
## Changeset
`skip-changeset`. The file is `.ts`, not one of the `src/**/*.zod.ts`
sources `@objectstack/spec` ships in `files[]`, and `guardOf` is
module-private. Measured on the built `dist/` before the edit: the old
docblock sentence ("takes a field selection over names alone") has 0
hits, while the same file's `ABSENT_SENTENCE` text (positive control) is
present in `dist/automation/index.js`. The comment does not ship.
## Tests and gates (head d3abc1c)
- `pnpm --filter @objectstack/spec build`, then `vitest run
src/automation/flow-value-slot-template.test.ts` (Test Files 1 passed,
Tests 172 passed), then `pnpm --filter @objectstack/spec typecheck`:
lock VERDICT command-exit 0.
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 79 commands. All were run with exit
codes captured before any pipe; `--ran` reconciles: 79 derived, 78 run,
1 NOT-MEASURED, 0 UNRUN. All 78 run exited 0. Three first exited 3 on a
missing prerequisite and were 0 on a rerun: `check-plugin-teardown-shape
--self-test` (after fetching its pinned fixture commit),
`@objectstack/lint check:doc-formula-expressions` (after building
formula and lint) and `check:lean-entry-closure` (after building
objectql). NOT MEASURED: `check:dual-build-cjs-loads`, reason: it needs
every package's `dist/`; left to CI.
- Dogfood: n/a (no `!` in the title, no `(narrowing)` arm).
## Acceptance notes
None.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01NxRRuV3TrQJLgFHt1pL6JA
---
_Generated by [Claude
Code](https://claude.ai/code/session_01NxRRuV3TrQJLgFHt1pL6JA)_
Credit: mig-builds proposed the same fix in fork PR #25284, closed in
favour of this PR per ruling 6358845679.
Co-authored-by: mig-builds
<54319294+mig-builds@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: mig-builds <54319294+mig-builds@users.noreply.github.com>1 parent b22ab8d commit 2abc0d3
2 files changed
Lines changed: 7 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
198 | 198 | | |
199 | 199 | | |
200 | 200 | | |
201 | | - | |
| 201 | + | |
202 | 202 | | |
203 | 203 | | |
204 | 204 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
315 | 315 | | |
316 | 316 | | |
317 | 317 | | |
318 | | - | |
319 | | - | |
320 | | - | |
321 | | - | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
322 | 324 | | |
323 | 325 | | |
324 | 326 | | |
| |||
0 commit comments