Repository navigation
Commit 322b6bf
docs(automation): a flow's record nodes treat a computed filter operand as a value, never as a query operator (#29925)
domain:skills#1 · huangyiirene · session_01J8VVAnMUWA9rufXzFaEh4J
<!-- claude-projects-attribution: {"github_login":"huangyiirene"} -->
_Requested by **Irene** · [project
thread](https://claude.ai/code/project/chan_01TJXtQ1tVD26ecLDZxFS67x?thread=cmsg_01TJXtQ1tVD26ecLDZxFS67xVJQu45A8HpRuFiXyhJtTnG)_
Fixes #29418
Clause-②: no
Metadata-protocol: none
Model: claude-fable-5-1 mandate waived by the maintainer (Fable quota
exhausted); developed on Opus; contract review by triage.
## 维护者速读
- 改了什么:自动化技能的「Filter operands」一节与 flows 文档的 CRUD filter 段落各加同一句规则:flow
记录节点(`get_record` / `update_record` / `delete_record`)把计算出的 filter
操作数当作值,永不当查询运算符;并写明作者的修法。
- 为什么改:#29404 已合并这条运行时规则(changeset 的 `Skills-docs:` 欠账),技能与文档还没讲,AI 写
flow 时会把对象或列表塞进 filter 操作数而在运行时失败。
- 风险与回滚:只改文本,外加一个 `@objectstack/skills` patch changeset(`skills/**`
随该包发布)。技能文件的 token 上限 6449 未动,新增由同文件删除重述付账(6449 → 6449,余量 0)。回滚即 revert。
- 先看:`skills/objectstack-automation/SKILL.md` 的 Filter operands
新条目与「Valid-but-silently-wrong」删掉的第 4
条;`content/docs/automation/flows.mdx` L434–438。
- 两分钟验证:`node scripts/check-skills-token-ratchet.mjs`,预期
`objectstack-automation/SKILL.md 6449 / 6449` 且 exit 0。
- 需要你做的:Tier H 受管面(`skills/**`):契约复审 PASS 后,请审阅并批准。
## What changes
1. **`skills/objectstack-automation/SKILL.md`, § Filter operands
(`config.filter`).** A new bullet after the `null` bullet states the
rule from #29404's changeset and the author's fix:
> **A computed operand is a value, never a query operator**: a string,
number, bigint, boolean or date, or at an `$in` / `$nin` / `$between`
comparand a list of them with no empty entry. Anything else fails the
node as a guard before the query runs. Make the expression evaluate to
the compared value (for a record, its `id`), and write conditions in the
filter itself.
Every fact is from the merged code: `operandValueRefusal` and
`LIST_COMPARAND_OPERATORS` in
`packages/services/service-automation/src/builtin/crud-nodes.ts` (a
value is `isAcceptedFilterComparand`, i.e. string, number, bigint,
boolean or `Date`; a list only where the operand's path ends in `$in` /
`$nin` / `$between`, with no `null` entry), and `refuseNode` makes it a
guard before the data engine is asked. No refused-value example and no
"before" behaviour.
2. **`content/docs/automation/flows.mdx`, the CRUD-node filter
paragraph** ("A CRUD node's filter: each operand computes before the
query…"). The same sentence, as its own paragraph after the
`null`-operand paragraph.
3. **The lists of failures a `fault` edge does not route** (contract
review should-fixes). The skill's ROUTES table cell now reads "filter
operand that evaluated to `null` or a non-value", and the guard list in
flows.mdx § Fault edges adds "a filter operand that evaluated to
something other than a value". Without these, the new bullet's word
"guard" was tied to no-fault-routing nowhere in the skill.
4. **`.changeset/29418-record-node-operand-value-docs.md`**:
`'@objectstack/skills': patch`, with `Clause-②: no` and
`Metadata-protocol: none` in its body (contract review must-fix).
`skills/**` ships in `@objectstack/skills`, so the change releases that
package and never takes `skip-changeset`
(`.github/workflows/pr-automation.yml` route 1). The label set at
creation was removed.
### Token budget (ceiling row not moved, no re-wrap)
New text is paid by deleting restatement in the same file. Each deletion
and where its content still lives:
| deleted | bytes | still taught at |
|:--|--:|:--|
| Valid-but-silently-wrong item 4 ("Conditions are bare CEL; only the
stdlib … is callable bare", with its blank line) | 241 |
`objectstack-formula` SKILL.md L28–30 (never wrap a field ref in `{…}`)
and L219–226 (`CEL_STDLIB_FUNCTIONS`; `PRIOR()` / an unknown function
fails the build); this file's opening blockquote and `description`
already send condition CEL there |
| "dates and money: the legacy → CEL table in **objectstack-formula**"
in item 1's token list | 74 | this file's opening blockquote: "Contract,
stdlib, legacy → CEL table: **objectstack-formula**" |
| the inline example "(`filter: { id: { dialect: 'cel', source:
'record.id' } }`)" in the first filter-operand bullet | 60 | the same
file's `update_record` example under item 3, `filter: { id: { dialect:
'cel', source: 'record.id' } }` |
| "(inbox by default)" in the `notify` node row | 19 | the `notify`
block below it: `channels: ['inbox'], // RAW; default inbox` |
| reading | before (origin/main 4e0c5d3) | after (HEAD) |
|:--|:--|:--|
| `skills/objectstack-automation/SKILL.md` | 452 lines, 25815 bytes,
6449 tokens (ceiling 6449) | 452 lines, 25814 bytes, 6449 tokens
(ceiling 6449, headroom 0) |
| all `skills/*/SKILL.md` | 4543 lines, 226490 bytes | 4543 lines,
226489 bytes |
The ceiling row in `scripts/check-skills-token-ratchet.mjs` is not
moved; the ROUTES cell's 16 added bytes used the 4 tokens of headroom
the first round left.
The state-introspection route clause on the State Machines pointer line
was a candidate and was kept:
`packages/rest/src/meta-state-route-doc-spelling.test.ts` pins this file
as a teaching site of that route.
## Tests
Text only. No eval in `skills/objectstack-automation/evals/` covers the
deleted lines (searched for `PRIOR`, `stdlib`, `bare CEL`, `legacy`,
`dates and money`; the one `legacy` hit is an ERP prompt in
`integrations-declared.json`).
## Acceptance notes
- Contract review on 47adef2 (6606363832) was FAIL. Must-fix: the
change carried `skip-changeset`, but a `skills/**` change releases
`@objectstack/skills`. Fixed in 5ee2376 with a patch changeset, and the
label removed. Both should-fixes (the ROUTES cell and the flows.mdx
guard list) are fixed in the same commit. A delta review on 5ee2376 is
owed.
## Verification
<details><summary>Local gates on 5ee2376: 68 derived, 68 run, all exit
0 (`dispatch-gates --ran`)</summary>
- On head 5ee2376, `node scripts/pm/dispatch-gates.mjs --commands`
derived 68 commands (the changeset adds nine:
`check-adr-0087-registration`, `check-changeset-no-major`,
`check-empty-changeset`, `check:changeset-gate-self-tests`,
`check:published-files` and four self-tests). All 68 ran with a 1200 s
timeout each, in a tree with `pnpm install --frozen-lockfile` and a full
`pnpm build` (118 tasks, exit 0). Each exit code was recorded before any
pipe, and all 68 exited 0, `check:skill-examples`, `check:dts-closure`,
`check:dual-build-cjs-loads` and `check:lean-entry-closure` included.
- `--ran` printed: `68 derived famil(ies) accounted for — 68 run, 0
NOT-MEASURED`. On the first head, 47adef2, 59 derived and all 59 exited
0.
- `node scripts/check-skills-token-ratchet.mjs`: exit 0,
`skills/objectstack-automation/SKILL.md 6449 / 6449 (+0)`.
- `node scripts/check-commit-card-trailers.mjs --range
origin/main..HEAD`: exit 0.
</details>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01J8VVAmczcwpTdN2WmzM6Mo
---
_Generated by [Claude
Code](https://claude.ai/code/session_01J8VVAmczcwpTdN2WmzM6Mo)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent dd9add6 commit 322b6bf
3 files changed
Lines changed: 27 additions & 9 deletions
File tree
- .changeset
- content/docs/automation
- skills/objectstack-automation
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
431 | 431 | | |
432 | 432 | | |
433 | 433 | | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
434 | 440 | | |
435 | 441 | | |
436 | 442 | | |
| |||
1983 | 1989 | | |
1984 | 1990 | | |
1985 | 1991 | | |
1986 | | - | |
| 1992 | + | |
| 1993 | + | |
1987 | 1994 | | |
1988 | 1995 | | |
1989 | 1996 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
94 | 94 | | |
95 | 95 | | |
96 | 96 | | |
97 | | - | |
| 97 | + | |
98 | 98 | | |
99 | 99 | | |
100 | 100 | | |
| |||
148 | 148 | | |
149 | 149 | | |
150 | 150 | | |
151 | | - | |
| 151 | + | |
152 | 152 | | |
153 | 153 | | |
154 | 154 | | |
| |||
195 | 195 | | |
196 | 196 | | |
197 | 197 | | |
198 | | - | |
| 198 | + | |
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
| |||
206 | 206 | | |
207 | 207 | | |
208 | 208 | | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
209 | 214 | | |
210 | 215 | | |
211 | 216 | | |
| |||
226 | 231 | | |
227 | 232 | | |
228 | 233 | | |
229 | | - | |
230 | 234 | | |
231 | 235 | | |
232 | 236 | | |
| |||
280 | 284 | | |
281 | 285 | | |
282 | 286 | | |
283 | | - | |
284 | | - | |
285 | | - | |
286 | | - | |
287 | 287 | | |
288 | 288 | | |
289 | 289 | | |
| |||
0 commit comments