Skip to content

docs(skills): the formula catalogue is the bare-callable public subset, not everything that resolves - #15519

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-13933-formula-skill-callable-wording
Sep 5, 2026
Merged

docs(skills): the formula catalogue is the bare-callable public subset, not everything that resolves#15519
os-zhuang merged 1 commit into
mainfrom
claude/issue-13933-formula-skill-callable-wording

Conversation

@claude

@claude claude Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #13933

Ruling item 3 only. Items 1, 2 and 4 are already true on main — the membership rule is load-bearing in packages/formula/src/validate.ts, the drift pin packages/formula/src/cel-stdlib-drift.test.ts exists, and the oracle carve-out sits in the same docblock. This PR is the skills half, and nothing else.

What was wrong

The published formula skill told an author that the catalogue is everything that resolves. It is not, and the engine's own docblock has said so since the drift pin landed: CEL_STDLIB_FUNCTIONS is the bare-callable public subset — the names an author may write as fn(x). Receiver-only methods (s.split(','), list.map(...)) resolve when called on a value, and four bare primitives (bytes, dyn, type, uint) resolve but are withheld from the catalogue by an authoring decision.

The claim was false in the safe direction — it under-promises, so no author was ever broken by it. Corrected anyway, in the skill's own voice, keeping the sentence that was true and useful: an unknown name still fails os build with a no-matching-overload type error.

⛔ No edit to packages/formula/**, to CEL_STDLIB_FUNCTIONS, or to any other skill. The four withheld names are named as withheld, never added to any list the skill presents as callable.

Every occurrence fixed — both in skills/objectstack-formula/SKILL.md, none left behind

site before after
L134, stdlib section intro Its exported CEL_STDLIB_FUNCTIONS is the canonical list, pinned by two tests: every entry resolves at runtime, and this table documents them all. Its exported CEL_STDLIB_FUNCTIONS is the advertised bare-callable subset, pinned by two tests: every entry resolves at runtime, and this table documents them all.
L197, the callout under the table Only the functions above are callable. An UNKNOWN function — PRIOR(), a legacy ISBLANK(), a typo'd isBlnk()fails os build with a "no matching overload" type error, rather than silently no-op'ing the predicate at run time. Use previous.x (not PRIOR()), isBlank() (not ISBLANK()). The list above is CEL_STDLIB_FUNCTIONS — the bare-callable public subset: the names you may write as fn(x). Receiver methods (s.split(','), list.map(...)) are called on a value, never bare, and are not in this table; four bare primitives (bytes, dyn, type, uint) resolve but are withheld from the catalogue by an authoring decision — don't reach for them. An UNKNOWN function — PRIOR(), a legacy ISBLANK(), a typo'd isBlnk()fails os build with a "no matching overload" type error, rather than silently no-op'ing the predicate at run time. Use previous.x (not PRIOR()), isBlank() (not ISBLANK()).

Searched the whole published catalogue for the claim family (only the functions, canonical list, are callable, full/complete/exhaustive list, documents them all). Inside this skill those two sites are all of them. skills/objectstack-formula/references/_index.md is generator-owned and carries no such claim, so nothing there needed a hand-edit — and none was made.

One number deliberately NOT published

The ruling's sentence names 33 receiver methods. That count is not written into the skill, on purpose. The drift pin makes the four withheld names an executable ledger — expect(withheld).toEqual([...WITHHELD_BARE_CALLABLE_BUILTINS]) — so naming them cannot go stale silently. The receiver-only set has no equivalent pin: assertion D asserts only expect(receiverOnly.length).toBeGreaterThan(0) and that none of them leaked into the catalogue. A hard 33 in customer-facing text would therefore be an unpinned count, free to drift the next time cel-js changes shape. The corrected passage states the rule instead, which cannot go stale.

Token ratchet — under the ceiling, no raise

tokens ceiling headroom
before 5158 6002 844
after 5249 6002 753

Delta +91 tokens (+364 bytes) for the ruled content — the membership rule, the receiver distinction, and the withheld primitives. ⛔ No ceiling raise; the pinned 6002 is untouched.

✓ check-skills-token-ratchet: skills/objectstack-formula/SKILL.md is 5249 tokens (ceiling 6002; headroom 753).
✓ check-skills-token-ratchet: 36 authored bundle file(s) within their ceilings; 10 generator-owned file(s) measured, not ratcheted.

Gate verdicts

Gate family derived from the change set by scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, then reconciled against what was actually run:

✓ dispatch-gates --ran: 21 derived famil(ies) accounted for — 21 run, 0 NOT-MEASURED.
Run reconciliation — 21 derived, 21 run, 0 NOT-MEASURED, 0 UNRUN.

All 21 exit 0, at commit adfe3a48f. One needed a prerequisite first: check:doc-formula-expressions exited 3PREREQUISITE NOT MET — the workspace package @objectstack/formula is not built, which the gate itself states measures nothing. After building @objectstack/formula and @objectstack/lint under the shared verification lock it re-ran at exit 0. Both builds and the gate sweep are recorded as run, not as a failure.

Landing regime, asserted rather than assumed:

⛔ GOVERNED — a human merge is the review record for this PR.
skills/** ×1 — the published skills catalog

scripts/pm/check-governed-merges.mjs --test skills/objectstack-formula/SKILL.md exits 3. So: this stays a draft. Not flipped ready, not enqueued, no auto-merge armed, no approval from the authoring seat.

skip-changeset applies by the rule rather than by the example list — this PR publishes nothing from any package. No package.json in the workspace ships skills/; the catalogue is not a package artifact.

Review notes

Both approvers may want to check the two things a wording change like this can get wrong: that the four names are presented as withheld and not as an invitation (the passage says so and adds "don't reach for them"), and that the corrected text agrees with validate.ts word for word where it matters — bare-callability as the membership rule, and the withholding as an authoring decision rather than an unavailability.

🤖 Generated with Claude Code

https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox


Generated by Claude Code

…bare-callable public subset

`skills/objectstack-formula/SKILL.md` claimed "Only the functions above are
callable" and called `CEL_STDLIB_FUNCTIONS` "the canonical list". Both read as a
complete registry of what resolves. Measurement says otherwise: receiver-only
methods (`s.split(',')`, `list.map(...)`) resolve when called on a value, and
four bare primitives (`bytes`, `dyn`, `type`, `uint`) resolve but are withheld
from the catalogue by an authoring decision.

The correction states the membership rule the engine's own docblock already
carries as load-bearing (`packages/formula/src/validate.ts`), and keeps the
sentence that was true and useful: an unknown name still fails `os build` with a
no-matching-overload type error.

The engine is untouched — no edit to `CEL_STDLIB_FUNCTIONS` or
`packages/formula/**`, and the four withheld primitives are named as withheld,
never added to any list the skill presents as callable.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
@os-zhuang
os-zhuang marked this pull request as ready for review September 5, 2026 01:29
@os-zhuang
os-zhuang enabled auto-merge September 5, 2026 01:29
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 5, 2026
Merged via the queue into main with commit 1183e97 Sep 5, 2026
36 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-13933-formula-skill-callable-wording branch September 5, 2026 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[decision] CEL_STDLIB_FUNCTIONS route: keep 35 as a declared subset, widen to the 39 bare-callables, or rename the symbol

2 participants