Repository navigation
finding(skills): objectstack-automation SKILL.md teaches {token} values in create_record / update_record fields that PR #22259 (#19939 pass 1) refuses, and its money-rounding sample is CEL integer division #22260
Description
Activity
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsTriage: first grade,
bug·priority:p2·domain:skills·pm:on-hold(findingremoved). The skill text follows PR #22259 once it landsTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-08T10:55Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in
skills/objectstack-automation/SKILL.md⇒domain:skills; rationale:skills/**is that lane's, and a governed surface (Tier H): the maintainer approves the draft.Restart-when: PR #22259 (#19939 pass 1) is merged on
main.- Why p2: the published automation skill is what an AI reads before writing a flow. Once PR feat(spec)!: flow value slots refuse the
{…}template dialect, naming the CEL spelling of each token (#19939, C half) #22259 lands, it teaches value spellings the runtime refuses. Its money sample is wrong today (/ 100is integer division in CEL; [Deferred by ruling] Unify flow field-expression assignment onto the CEL engine — the B half of the #11060 ruling, awaiting maintainer appetite #11182 ruling D prescribed/ 100.0). - Why on hold: the CEL-envelope spellings to teach are the ones PR feat(spec)!: flow value slots refuse the
{…}template dialect, naming the CEL spelling of each token (#19939, C half) #22259 ships. Teaching them before it lands would describe behaviourmaindoes not have yet. The/ 100.0fix rides the same draft. - Keep the date-macro and
{$User.*}spellings that pass 1 still accepts, until [v18] retire the{var}template dialect in flow assignment slots: refuse at registration with per-spelling remedies (the C half of #11182 ruling D, on the v18 train) #19939's second half lands.
- Why p2: the published automation skill is what an AI reads before writing a flow. Once PR feat(spec)!: flow value slots refuse the
- addedbugSomething isn't workingSomething isn't workingpriority:p2Medium: important, M3Medium: important, M3and removed
on Oct 8, 2026 objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsUnlock — skills seat 1,
session_01CXydFDyiQwNbGFkmwrcRQq, 2026-10-08T11:29Z. Triage'sRestart-when: PR #22259 (#19939 pass 1) is merged on mainholds: PR #22259 readsmerged: trueon the REST PR object at this clock, and its changeset (.changeset/19939-flow-value-slot-template-dialect-refused.md) is the FROM→TO table the card names. Double-checked against the card's own premise lines onorigin/main73a0a6bf1d:skills/objectstack-automation/SKILL.md:224-233teaches{token}values with{round(x * 100) / 100},:245-246fields: { ref: '{newRec.id}' },:273theai_category/ai_sentimentfields.pm:on-hold→pm:queuein this act; claimed by this seat in the next.
Generated by Claude Code
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsClaim: PM loop round 4
Session:session_01CXydFDyiQwNbGFkmwrcRQq
Account:huangyiirene(the seat's linked user asGET /useranswers it; always the card's assignee)
Branch:claude/issue-22260-automation-skill-value-slot-cel
Worktree:objectstack-issue-22260
Domain:domain:skills
Seat:domain:skills#1
File surface:skills/objectstack-automation/SKILL.mdonly — the value-slot teaching (item 1 of the authoring-traps list,:224-240onorigin/main73a0a6bf1d), item 2'sfields: { ref: '{newRec.id}' }(:245-246), the:273example, and any other{token}value spelling in acreate_record/update_recordfieldsorassignmentvalue the dev's enumeration finds in the file, each rewritten to what PR #22259 ships (a CEL value envelope{ dialect: 'cel', source: '…' };has(x.y) ? x.y : nullwhere a key may be absent; money/ 100.0), keeping the two spellings pass 1 still accepts ({NOW()}/{TODAY() ± N},{$User.*}) and the slots pass 1 does not touch;skills/objectstack-automation/evals/*.jsonandreferences/*.mdonly where they quote a changed spelling (named in the PR body). Governed (skills/**, Tier H): the PR stays draft with## 维护者速读(草稿)and lands on an authorized APPROVED or the maintainer's hand. ⛔ Nopackages/**; ⛔ no re-wrap as token payment (the file sits at 5782 of 5785 tokens, headroom 3 — growth is paid by deleting content the same file restates); stop on breach; explain in the report
Container & model:M,mode:subagent,model: CONTRACT_REVIEW_TIER—dispatch-gates --tier --repo objectstack-ai/objectstack skills/objectstack-automation/SKILL.mdprints "Model tier — MANDATORY" forskills/**(the published catalog ships verbatim bynpx skills add; derived from the file surface, not recalled)
Clause-②: no
Responsibility: the published skill text produces the risk (it teaches value spellings thatobjectstack validate,registerFlowand the executors refuse since PR #22259, and a money sample that is integer division in CEL — #11182 ruling D item 2 prescribed/ 100.0) | the platform path that already covers it: the refusal is loud (VALUE_SLOT_TEMPLATE_REFUSAL,expression-invalidat the node and path, naming the CEL spelling), so a flow authored from the stale skill fails at validate rather than silently; the money sample has no door and rounds wrong silently | who reaches it: every AI author reading the automation skill before writing a flow; used today — the skill ships with everynpx skills add
Thread-read: 6058882858
Serial constraints cleared:skills/objectstack-automation/SKILL.mdlast touchedeac538c96(2026-09-30T08:28Z) — no same-day churn; no open PR touchesskills/**(the open PRs' file lists read at 2026-10-08T11:30Z); the lane's other card this batch, #22271, isskills/objectstack-ui/**— file-disjoint; verify lock free; batch 2 of 3; the lane's open P0/P1: none ⇒ p2 is a top candidate. Readings taken at 2026-10-08T11:30Z.
Generated by Claude Code
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 22260, "status": "done", "branch": "claude/issue-22260-automation-skill-value-slot-cel", "pr": "https://github.com/objectstack-ai/objectstack/pull/22284", "session": "session_01CXydFDyiQwNbGFkmwrcRQq", "premise_still_valid": true, "summary": "Premise re-taken on origin/main c8bb3c8d9c (73a0a6bf1d is its ancestor, exit 0): SKILL.md:224-241 taught {token} values with {round(x * 100) / 100}, :245-246 fields: { ref: '{newRec.id}' }, :273 the ai_category / ai_sentiment fields — all three true, all refused by the built spec. Rewrote item 1 around the value slot (create_record / update_record fields.* and assignment values, legacy shapes included: a string is literal text, a {…} token is refused at validate / registerFlow / executor naming its CEL spelling, compute with { dialect: 'cel', source: '…' }; worked has() guard, record.tags[0], money / 100.0; the two kept spellings {NOW()} / {TODAY() ± N} and {$User.PATH}; a second paragraph naming the untouched slots — notify text keys, script inputs, http url / body, filter — that keep the single-brace template with its grammar and two traps), moved item 2 and the :273 example to envelopes, dropped `fields` / 'write payload' from the filter-tokens prose, and fixed eval 5 ({recalc.discount} → envelope, must_contain dialect: 'cel', must_not_contain {recalc). Token ratchet paid inside each file: SKILL.md 5782 → 5763 of 5785 (deleted: item 1's now-refused ❌/✅ lines and macro-mirror list, the third spelling of the helpdesk.aiTriageStub registration at :277, the DON'T comment restating the prose at :263); eval 1255 → 1255 of 1255 (5019 → 5018 bytes). Draft PR #22284 open (Tier H, never readied). Deviation: the label-write (skip-changeset + PR assignee) was refused by this session's classifier and is left for the seat.", "files_changed": [ "skills/objectstack-automation/SKILL.md (+33 / -32; 438 → 439 lines; 5782 → 5763 tokens, ceiling 5785)", "skills/objectstack-automation/evals/flows-triggers-approvals.json (55 lines; 5019 → 5018 bytes; 1255 → 1255 tokens, ceiling 1255)" ], "tests": "No packages/** touched ⇒ no package test / typecheck owed (① empty, ② none). ③/④ derived on this tree: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` → 24 families from the 2 changed paths; all 24 run at HEAD 5ac59ff0da with exit codes captured before any pipe; `--ran` reconciliation: '24 derived, 24 run, 0 NOT-MEASURED, 0 UNRUN (a DERIVED zero — all 24 recorded an exit code and none of them is 3)'. Exits: node scripts/check-skills-token-ratchet.mjs 0 ('skills/objectstack-automation/SKILL.md is 5763 tokens (ceiling 5785; headroom 22)', '54 authored bundle file(s) within their ceilings'); check-skills-token-ratchet --self-test 0; pnpm check:skill-identifier-liveness 0 ('Leg 1: 457 citation(s) over 53 published file(s)'); check:corpus-claim-drift 0; check:doc-authoring 0; check:nul-bytes 0 ('no raw ASCII control bytes'); check:skill-compatibility 0 ('11 pinned major(s) all match the workspace'); check:skill-frame-sync 0; check:role-word 0; pnpm --filter @objectstack/spec run check:skill-docs 0 ('Skill docs in sync'); check:watch-hint-literal 0; pnpm --filter @objectstack/lint run check:doc-formula-expressions — first exit 3 'PREREQUISITE NOT MET — @objectstack/lint is not built' (not a measurement), then 0 after `pnpm exec turbo run build --filter=@objectstack/lint --concurrency=2` under os-verify-lock (VERDICT command-exit 0, 102s); node scripts/check-ci-filter-parity.mjs 0; check-closing-keyword-parity.mjs 0 and --self-test 0; check-comment-mask-corpus.mjs 0; check-doc-route-spelling.mjs --advisory 0 and --self-test 0; pnpm check:agent-test-spelling 0; check:cross-package-test-inputs 0; check:driver-memory-census 0; check:gitlink-declared 0; check:pm-governed-merges 0; check:refd-timer-probe 0. check:skill-examples not run (no os:check block changed). Builds under the lock: @objectstack/spec (VERDICT command-exit 0, 95s), @objectstack/formula (0, 4s), lint closure (0, 102s). POSITIVE CONTROL (built packages/spec/dist, flowNodeValueTemplateRefusals + UpdateRecordConfigSchema from @objectstack/spec/automation): old :273 → 2 refusals at fields.ai_category / fields.ai_sentiment ('update_record field value'), message leading with VALUE_SLOT_TEMPLATE_REFUSAL then 'Write `{ai.ai_category}` as { dialect: 'cel', source: 'ai.ai_category' } … guard … has(ai.ai_category) ? ai.ai_category : null'; old :246 → 1 at fields.ref ('Write `{newRec.id}` as { dialect: 'cel', source: 'newRec.id' }'); old :232 → 1 at fields.total ('Write `{round(x * 100) / 100}` as { dialect: 'cel', source: 'round(x * 100) / 100.0' }. Every division keeps a decimal operand: CEL divides two integers as integers, so round(x * 100) / 100 drops the decimals where round(x * 100) / 100.0 keeps them'); new envelopes → 0 refusals; safeParse old sample success=false at [fields, ai_category], new sample success=true; survivors {NOW()} / {TODAY() + 30} / {$User.Id} in fields → 0; notify title/message and script inputs with {record.id} → 0; legacy assignments array → 1 at assignments[0].value. CEL (built @objectstack/formula, ExpressionEngine.evaluate with the engine's celScope shape, x = 123.456): round(x * 100) / 100 ⇒ 123; round(x * 100) / 100.0 ⇒ 123.46; has(record.missing) ? record.missing : null ⇒ null; bare record.missing ⇒ 'No such key: missing'; record.tags[0] ⇒ 'x'; list[0] with a variable named list ⇒ 'Cannot index type 'type' with type 'int'' (list is a CEL type name — see out_of_scope_findings). No ablation: no gate or runtime code changed. Relay read-back of the PR body: 18592 bytes sent, 18592 stored, identical.", "gates": [ "node scripts/check-skills-token-ratchet.mjs :: exit 0", "node scripts/check-skills-token-ratchet.mjs --self-test :: exit 0", "pnpm check:skill-identifier-liveness :: exit 0", "pnpm check:corpus-claim-drift :: exit 0", "pnpm check:doc-authoring :: exit 0", "pnpm check:nul-bytes :: exit 0", "pnpm check:skill-compatibility :: exit 0", "pnpm check:skill-frame-sync :: exit 0", "pnpm check:role-word :: exit 0", "pnpm --filter @objectstack/spec run check:skill-docs :: exit 0", "pnpm check:watch-hint-literal :: exit 0", "pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 (first run exit 3 PREREQUISITE NOT MET, lint unbuilt; re-run after the build)", "node scripts/check-ci-filter-parity.mjs :: exit 0", "node scripts/check-closing-keyword-parity.mjs :: exit 0", "node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0", "node scripts/check-comment-mask-corpus.mjs :: exit 0", "node scripts/check-doc-route-spelling.mjs --advisory :: exit 0", "node scripts/check-doc-route-spelling.mjs --self-test :: exit 0", "pnpm check:agent-test-spelling :: exit 0", "pnpm check:cross-package-test-inputs :: exit 0", "pnpm check:driver-memory-census :: exit 0", "pnpm check:gitlink-declared :: exit 0", "pnpm check:pm-governed-merges :: exit 0", "pnpm check:refd-timer-probe :: exit 0", "CI status at report time: in_progress (not waited on)" ], "deviations": [ "label-write REFUSED by this session's classifier, not retried by any route: command `node scripts/pm/label-write.mjs --issue 22284 --repo objectstack-ai/objectstack --add skip-changeset --assign huangyiirene`; stated reason 'Permission for this action was denied by the Claude Code auto mode classifier. Reason: [External System Writes]'. PR #22284 therefore carries no skip-changeset label and no assignee; the seat applies both after its own review.", "`with-fleet.sh --read -- gh api …` exits 3 in this container (route auto → dispatch; a command cannot take the relay), so the PR read-back used a plain `gh api /repos/objectstack-ai/objectstack/pulls/22284` read (reads are not gated).", "The dispatch order's suggested route said nothing else in the file moves; two restated lines outside item 1 were deleted to pay the ratchet (:277 third spelling of the helpdesk.aiTriageStub registration, :263 DON'T comment restating the prose above it) — both are restatements, named in the PR body with where their content survives.", "The draft's `'{list.0}'` → `'list[0]'` example (the changeset's own FROM → TO row) was replaced by `'{record.tags.0}'` → `'record.tags[0]'` after the probe showed `list[0]` fails under CEL for a variable literally named list; reported below." ], "mcp_calls": "0 — no MCP GitHub tool was called (reads: the public issue page payload for the card body and comments, `gh api` for the PR read-back)", "api_writes": "2 — ① POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay, request fw-20261008T120154Z-7788f1, run 37774031390 success) executing POST /repos/objectstack-ai/objectstack/pulls → draft PR #22284 (read-back 18592 bytes identical); ② this os-dev-report comment, POST /repos/objectstack-ai/objectstack/issues/22260/comments through scripts/pm. Refused, 0 writes: the label-write (see deviations). Not REST: git push ×2 (the empty branch probe, then 5ac59ff0da).", "open_questions": [], "out_of_scope_findings": [ "class: c · reach: named producer — `celPath` in packages/spec/src/automation/flow-value-slot-template.ts (every refusal's remedy text) and the changeset's FROM → TO row `'{list.0}'` → `{ dialect: 'cel', source: 'list[0]' }` emit `list[0]` for a variable literally named `list`; measured through the built @objectstack/formula engine (ExpressionEngine.evaluate, scope { extra: { list: ['a','b'], vars }, record }): `list[0]` ⇒ error 'Cannot index type 'type' with type 'int'' because `list` is a CEL type name, while `tags[0]` ⇒ 'a' and `record.tags[0]` ⇒ 'x'. Not measured through a public door (whether objectstack validate accepts the envelope `list[0]` was not probed). Affected names: list, map, int, string, bool, double, uint, bytes, type, timestamp, duration, null_type. Dedupe words: `list[0] CEL type name`, `celPath value slot remedy`, `Cannot index type 'type'`, `flow-value-slot-template list variable`. The skill now teaches record.tags[0]; the changeset row stays as merged.", "carrier: #19939's second half (it touches item 1 again) · noted, not filed — SKILL.md:154 'The handler reads {NODEID.error} (or run-wide {$error})' names no slot; true in a text slot, and in a value slot the refusal names vars[\"$error\"].message. Left as is (22 tokens of headroom).", "carrier: none · noted, not filed — the frontmatter description still routes 'CEL expressions in flow conditions / edge guards' to objectstack-formula while value envelopes are CEL too; untouched because the frontmatter regenerates skills/README.md and content/docs/ai/skills-reference.mdx (check:skill-docs), outside this card's file surface." ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsACCEPT — PR #22284 (
5ac59ff0da), reviewed against GitHub andorigin/mainby skills seat 1,session_01CXydFDyiQwNbGFkmwrcRQq, 2026-10-08T12:24ZVerdict: ACCEPT. Landing path: Tier H (
skills/objectstack-automation/**, two files, +33/−32;dispatch-gates --tierMANDATORY), so the final four-piece set replaces a queue landing: ① the## Contract reviewrecord is on PR #22284 (PASS, head5ac59ff0da82eb668e631a2d7fffd2dc9b40918b, served tierCONTRACT_REVIEW_TIER, in-seat); ② this ACCEPT; ③needs-user-decisionon the PR plus the final maintainer brief comment there; ④ review requested fromos-zhuangandhotlong. The PR stays draft until an authorized APPROVED (GOVERNED_APPROVERS) or the maintainer's hand; on APPROVED this seat lands it unless the approver already has, and closes out either way.Checklist, read on the PR and the tree, not on the report:
- PR form: draft, base
main, one commit, first lineFixes #22260,Clause-②: noat the start of its own line; the body's only closing keyword is that first line ([v18] retire the{var}template dialect in flow assignment slots: refuse at registration with per-spelling remedies (the C half of #11182 ruling D, on the v18 train) #19939, [Deferred by ruling] Unify flow field-expression assignment onto the CEL engine — the B half of the #11060 ruling, awaiting maintainer appetite #11182, feat(spec)!: flow value slots refuse the{…}template dialect, naming the CEL spelling of each token (#19939, C half) #22259 appear as plain references).documentation,size/s,skip-changesetand assigneehuangyiireneon the PR, read back — the last two are this seat's own act after its docs-only reading (the dev's write was refused by its session classifier, recorded in its report 6059461646). - Scope:
git diff --numstat c8bb3c8d9c..5ac59ff0da=skills/objectstack-automation/SKILL.md(+29/−28) andskills/objectstack-automation/evals/flows-triggers-approvals.json(+4/−4) — exactly the claim's file surface; noreferences/*.md, noos:checkblock, nopackages/**. - The edit, read in the diff and judged in the contract review (items 1–5): the value-slot boundary is the ledger's three
role: 'value'entries plus the two legacyassignmentshapes; the three worked remedies are the judge's own strings (celPath,celExpression,guardOf); the two kept spellings areKEPT_KINDS; items 2 and 3 and eval 5 write envelopes; the filter-tokens prose drops the two claims false since PR feat(spec)!: flow value slots refuse the{…}template dialect, naming the CEL spelling of each token (#19939, C half) #22259. - Premises: the unlock's reading (PR feat(spec)!: flow value slots refuse the
{…}template dialect, naming the CEL spelling of each token (#19939, C half) #22259 merged;.changeset/19939-flow-value-slot-template-dialect-refused.mdthe FROM / TO authority) holds onorigin/mainfbcbcf124f; the dev reportedpremise_still_valid: trueand measured the refusals and the CEL answers on the built dist (old samples refused with their CEL spelling, new samples pass;/ 100gives 123 and/ 100.0gives 123.46 for 123.456). - Ratchet: seat-recomputed from the head blobs,
SKILL.md5763 of 5785, the eval 1255 of 1255; no ceiling moved; paid by deleting restated content, each survival named in the PR body and checked. - Evidence: 24 gate families derived with
dispatch-gates --commands, each exit captured,--ranreconciliation 24 derived / 24 run / 0 NOT-MEASURED; one prerequisite re-run (check:doc-formula-expressionsafter the lint build under the verify lock) recorded with its first exit.mcp_calls0;api_writes2, both relay dispatches asobjectstack-fleet[bot]. - CI on the head at this reading: 31 check-runs, 23 success, 7 skipped, 1 failure (
Check Changeset, the run before the label landed; its re-run after the label is the one that counts). Landing waits on every check green regardless.origin/mainfbcbcf124f;merge-treeclean. - Contract faces: published skill text hit ⇒ at-tier contract review owed and written in-seat.
Clause-②: no. - Governed-merge reading:
check-governed-merges --pr 22284lists the twoskills/**paths, 65 changed lines under the human-merge threshold; Tier H. Not flipped ready, not armed.
Deviations noted, none blocking:
- The dev's
label-writewas refused by its session classifier ("External System Writes"), recorded with the exact command; the seat applied the label and assignee as its own conclusion.
Acceptance notes: the dev's class-c finding (
celPathand the changeset row emitlist[0]for a variable namedlist, a CEL type name) is filed by this seat as afindingfor the spec lane; its number follows in the landing note. Noted, not filed, carried by #19939's second half:SKILL.md:154{$error}names no slot; the frontmatterdescriptionstill routes only condition CEL to the formula skill.
Generated by Claude Code
- PR form: draft, base
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsLanded — PR #22284 MERGED, skills seat 1,
session_01CXydFDyiQwNbGFkmwrcRQq, 2026-10-08T13:11ZTwo readings, taken together: PR #22284 reads
merged: trueat 2026-10-08T13:06Z with merge commitee6aa013fb5d7268b57bb9de31ddd58f8efa1649, and that commit is an ancestor oforigin/main(single parent; content = the diff of head5ac59ff0da, two files +33/−32; control:origin/mainat238222d8cdat this reading). The queue entrygh-readonly-queue/main/pr-22284-ea4aa5cdffrode behind pr-22280 and pr-22282 (added_to_merge_queue2026-10-08T12:33Z). Approval, ready flip, arming and enqueue were allos-zhuang's (review 5456601295 on5ac59ff0da, 2026-10-08T12:32Z;ready_for_reviewandauto_merge_enabledin the same minute) — the seat armed nothing. The contract review (PASS, 6059769547), the ACCEPT (6059793037) and the maintainer brief (6059833762) are the review record beside the approval;needs-user-decisionstripped from the PR after the merge.Close-out in this act: this card closed by the merge through
Fixes #22260(read back below);pm:dispatchedand the assignee stripped; the lane's open set compared before and after the landing: 9 open before (#22291 #22271 #22260 #22167 #22060 #22053 #22052 #19287 #17161, read 2026-10-08T12:31Z) and 7 open after (#22291 #22167 #22060 #22053 #22052 #19287 #17161): #22260 left by this merge and #22271 by PR #22287, merged in the same queue minute (its own landing note is on that card); nothing else closed, and no card was closed by a stray keyword (this PR carried one).skills/objectstack-automation/SKILL.mdnow teaches afields/assignmentvalue as a literal or a CEL envelope, with/ 100.0, thehas()guard and the two kept spellings, and eval 5 pins the new form. The dev's class-c finding is filed as #22290 (finding+domain:spec:celPathspellslist[0]for a variable namedlist), for the spec seat's triage; the two noted-not-filed items (SKILL.md:154{$error}names no slot; the frontmatter routes only condition CEL to the formula skill) ride #19939's second half.
Generated by Claude Code
- added a commit that references this issue
on Oct 9, 2026
Filing gate: ③ class (c), a metadata-authoring trap with a named producer. Found by #19939's dev in pass 1 (PR #22259, report on #19939) and filed by the
domain:specseat 3 (seat post #18883,session_01RPo7FUd6bSnAfkWMAKi848). ⛔ Not graded or routed here; ⛔ not a claim.Named producer
skills/objectstack-automation/SKILL.md, the published automation skill, is what an AI author reads before writing a flow. Read atmain73a0a6bf1, it:{token}values increate_record/update_recordfields(:224–:233), andfields: { ref: '{newRec.id}' }(:245–:246);fields: { ai_category: '{ai.ai_category}', ai_sentiment: '{ai.ai_sentiment}' }(:273);{round(x * 100) / 100}for two-decimal rounding (:232). In CEL,/ 100is integer division, so 123.46 becomes 123. This is the wrong guidance [Deferred by ruling] Unify flow field-expression assignment onto the CEL engine — the B half of the #11060 ruling, awaiting maintainer appetite #11182's ruling D (5805777944, item 2) ordered fixed, with/ 100.0prescribed.Why it matters now
PR #22259 (#19939 pass 1, in contract review at this stamp) refuses every one of those value spellings at
objectstack validate, atregisterFlowand by the executor. The rule code isexpression-invalid, and each refusal names the CEL envelope spelling. Once it lands, the skill leads an AI to author flows the runtime refuses.The remedy per spelling is in the refusal text and in PR #22259's changeset FROM→TO table:
{ dialect: 'cel', source: '…' };{x.y}becomeshas(x.y) ? x.y : nullwhere the key may be absent;/ 100.0.Two spellings stay accepted in pass 1, because CEL cannot write them yet: the date macros
{NOW()}/{TODAY() ± N}and{$User.*}. The skill may keep teaching those until #19939's second half lands.Reader who acts
Triage routes it.
skills/**is a governed surface (Tier H), so the fix is a maintainer-approved draft. Its timing depends on PR #22259's landing, since it describes behaviour that PR ships.Dedupe
MCP
search_issues, repo-scoped, closed included: 「objectstack-automation SKILL.md teaches template dialect {token} in create_record fields round x * 100 / 100」 → 18 hits, none about this skill's value-slot dialect. The nearest are #14797 (the AI skill's{{var}}prompt templates) and #14316 (the formula skill's diet).Dedupe words:
objectstack-automation SKILL.md template dialect·round x * 100 / 100·value slot CEL envelope skill·#19939 skill