Uh oh!
There was an error while loading. Please reload this page.
docs(skills): correct the automation "Verify your work" passage — conditions fail loudly at registration, node values fail at run time - #12257
Merged
Conversation
… loudly, node values fail at run time
The '## Verify your work' opening taught that a typo'd field name, an unknown
function, or a {…}-wrapped reference in a condition all fail SILENTLY at
runtime. Two of the three were false, and the same file's Common Pitfalls row
said the opposite.
AutomationEngine.validateFlowExpressions runs a fatal pass (syntax,
brace-in-CEL, unknown function) over every condition and declared bare-CEL slot
at flow registration and throws; celEngine.compile reports an unknown function
as a type fault, pinned in packages/formula. Only node VALUES take the
single-brace flow-template dialect that no validator implements — an unknown
function there raises FlowExpressionFunctionError at run time.
Rewritten to distinguish the two dialects, with a typo'd field name kept as the
one genuinely quiet case (advisory did-you-mean; os validate still errors on an
unknown record.<field>). The overlapping Common Pitfalls sentence is tightened
in the same edit — it stated the same two facts and was the other half of the
contradiction. Token-negative: 12643 -> 12642 against a 12643 ceiling.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RMTpSRF5CjMmQBFfPtPCwJ
This was referenced Aug 25, 2026
os-zhuang
marked this pull request as ready for review
August 25, 2026 23:45
os-zhuang
commented
Aug 25, 2026
ContributorAuthor
Armed for merge under the maintainer's shift-close instruction, 2026-08-25: 「当前任务处理完,合并了就下班。」 — covering the reviewed, ACCEPTed governed drafts of this round (this PR and #12274). ACCEPT record: issue comment 5412670650 on #12092. Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes#12092
skills/objectstack-automation/SKILL.md's## Verify your workopening taught that a typo'd field name, an unknown function, and a{…}-wrapped reference in a condition all fail silently at runtime. Two of those three were false, and the same file's Common Pitfalls row (item 10) said the opposite — so the published skill contradicted itself and taught an AI author to hunt for a silence the platform does not have.What the landed engine actually does — verified against this tree, not the card
Every behavioural claim in the new text was re-verified against
origin/mainateeec62a98:AutomationEngine.validateFlowExpressions(packages/services/service-automation/src/engine.ts:5304) runs the fatal pass overconfig.condition,edge.conditionand everypredicate-role slot inFLOW_NODE_EXPRESSION_PATHS, then throws with location + source + corrective hintcelEngine.compilereturnskind: 'type'forPRIOR(status); pinned bypackages/formula/src/cel-engine.test.ts("compile() rejects an unknown function as a type error") andvalidate.test.ts("rejects an unknown function call", incl. behind a short-circuit)flow-templatesingle-brace dialect)validateFlowExpressionsskipsflow-templateslots by design — "no validator implements their dialect";interpolateStringthrowsFlowExpressionFunctionError(builtin/template.ts:55,unknownFunctionErrorat:167)logger.warn-only ("logged, never thrown… strictly additive"); a near-miss bare ref is awarnings.pushdid-you-mean inpackages/formula/src/validate.ts.checkFieldExistencedoes push a hard error for an unknownrecord.-prefixed field reference — which is why the new text saysos validateerrors on that spellingThis does not contradict the value-expression half that landed with #11348 / PR #12093 — it states the same asymmetry from the other side and points at the same named error.
Second edit in the same diff, declared
The Common Pitfalls item 10 tail was tightened in the same commit. It is not drive-by scope: it was the other half of the contradiction the card names, stating the same two facts (unknown function, brace-in-CEL) in longer form. Both facts survive verbatim in meaning:
An UNKNOWN function (…) **fails the build**. And never wrap a field reference in {…} inside a condition — that's a template brace and fails as CEL: write record.x, not {record.x}.An UNKNOWN function (…) and a {…}-wrapped field ref both **fail the build**: a brace is a template, not CEL — write record.x, not {record.x}.It is also part of how the rewrite pays for itself under the ratchet.
Token budget — ⛔ ceiling untouched, change is token-NEGATIVE
Ceiling stays 12643 (set by #12093 under a quoted maintainer ruling). No ceiling was raised, and none was lowered — the ratchet prints headroom on every run, so the shrink is already visible without editing the shared ceiling map.
skills/objectstack-automation/SKILL.md— tokensskills/objectstack-automation/SKILL.md— linesSKILL.md)Lines rise while tokens fall because the new prose rewraps shorter; the ratchet's unit is
ceil(utf8 bytes / 4), and bytes went 50571 → 50568. Paid for by genuine deletion, not a re-wrap: the old passage's redundant closing paragraph ("Remember conditions are bare CEL… only string node fields use{…}templates — see objectstack-formula") is gone, since the new opening states the dialect split precisely, and item 10 was tightened as above.Gate's own verdict line:
Verification — all green at
f5d58e095Gate set derived with
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(11 families matched), re-derived after the commit and unchanged. Each verdict below is the gate's own printed line; exit codes were captured before any pipe.Plus the three
SKILL.md-triggered spec artifact gates AGENTS.md names, which the path derivation scores silent (their populations are generated artifacts) and which a body edit can genuinely stale:Two of those needed a build prerequisite in a fresh worktree before they measured anything —
@objectstack/formula+@objectstack/lintforcheck:doc-formula-expressions,@objectstack/client-reactforcheck:skill-examples. Both refused loudly rather than reporting a false green; the verdicts above are from the runs after those builds.No changeset — published-skill prose, nothing user-facing is published by it;
skip-changesetapplied.⛔ Governed surface (
skills/**) — draft, human merge only. Not to be queued, armed for auto-merge, or flipped ready (AGENTS.md Prime Directive #14).Review from
os-zhuangcould not be requested through the API: under the shared agent identityos-zhuangis this PR's author, and GitHub refusesReview cannot be requested from pull request author. Flagged for the PM rather than worked around.Generated by Claude Code