Commit 04ec174
skills(query): optimization flight — seven twice-stated rules merged into rules/, removed-key history collapsed to one table, search/flow-filter/compareTo pointed at their anchors, context and the calling convention taught (net −2,139 tokens) (#14443)
* docs(skills): collapse removed-key history in the query rules files
QRY-D-01 — delete the per-key "why it was removed" narration from
rules/aggregation.md (`distinct: true`, `array_agg`/`string_agg`,
`windowFunctions`) and rules/pagination.md (`cursor`, `distinct`, and the
`cursor` Common-Mistakes pair). The keys are tombstoned: `tsc` types them
`never` and a query carrying one fails to parse with the prescription, so the
only decision-changing half is the replacement — now one table in SKILL.md.
QRY-D-02 — delete the alias/push-down bug-history parenthesis at
rules/aggregation.md; the behaviour it describes no longer exists.
QRY-E-04 — the group-by example is shown in the real `engine.aggregate(obj, …)`
shape with legal keys only; `fields` is not in ENGINE_AGGREGATE_OPTION_KEYS and
is rejected by name, which the old "readability convention" note did not say.
QRY-C-05 — `compareTo` is objectstack-ui's surface; the copy here becomes a
pointer.
aggregation.md 2226 -> 1846 tok, pagination.md 1381 -> 1158 tok.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
* docs(skills): filters.md keeps the token vocabulary, drops the flow rule
QRY-C-04 — the "a flow filter that loses a condition refuses to run" rule is a
flow-node authoring rule, and objectstack-automation already states it. Deleted
here; one pointer line stays. (Two things the automation anchor does NOT carry
are listed in the PR body as a follow-up for that package.)
QRY-F-03 — the string-operator table listed four operators and omitted three
that exist: `$icontains`, `$like`, `$ilike`. Added, together with the case rule
`packages/spec/src/data/filter.zod.ts` states outright ("`$contains` /
`$notContains` / `$startsWith` / `$endsWith` compare CASE-SENSITIVELY.
`$icontains` is the case-INSENSITIVE twin"), the ASCII-only folding domain, and
the faces that refuse `$like`/`$ilike` rather than approximating them.
Funded additions from the delivered objectstack-ui flight, each verified at
source before porting — this package is the anchor for the token vocabulary and
ui now points here: both `{token}` and `${token}` parse (DATE_MACRO_WRAPPED_RE,
shared by the context tokens); `{user_id}` and `{organization_id}` join the
near-miss list (CONTEXT_TOKEN_SUGGESTIONS); a token embedded in a larger string
is left untouched; `isDateMacroToken` / `isContextToken` from
`@objectstack/spec/data` are the author-time check; the build rule is named
(`filter-token-unknown`) along with why it exists.
Paid in-file by C-04 plus two schema-enforced Common-Mistakes blocks.
2144 -> 2100 tok.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
* docs(skills): SKILL.md teaches the calling convention it never named
QRY-E-03 / QRY-B-04 — the package used two incompatible calling conventions and
named neither, and its most-copied example shape (`{ object: 'account', … }`
passed as an option bag) is not accepted by any engine method:
ENGINE_FIND_OPTION_KEYS and ENGINE_AGGREGATE_OPTION_KEYS are closed sets and an
unlisted key is refused by name. The file now opens with the convention —
object is the FIRST ARGUMENT, the legal key set per method, and where a bare
`{ object, … }` literal IS correct (findData's `query`, an `expand` value).
QRY-B-01 — the seven rules stated twice are merged into rules/*: field
references, keyset pagination, the OData alias, the aggregation functions
table, HAVING, filtered aggregation and window functions. SKILL.md keeps
one-line pointers.
QRY-D-01 — the four removal-history spans become one 6-row "removed key ->
live replacement" table.
QRY-C-01 — the search-mirror prescription is objectstack-data's (this file
already named data as the anchor); reduced to the rule plus that pointer.
QRY-C-03 / QRY-C-05 — the CRM Analytics Query Blueprint and `compareTo` are
objectstack-ui's dataset/widget surface; one routing line replaces them.
QRY-B-02 / QRY-B-03 / QRY-D-03 / QRY-D-04 — "When to Use This Skill", "Skill
Boundaries", the opening blurb, the callout legend and the positioning prose
restate the frontmatter or the catalog and change no decision.
QRY-E-02 (incidental falsehood 1) — the canonical `expand` example expanded
nothing: it projected `fields: ['title','status']` while expanding `assignee`
and `project`, dropping both foreign-key columns, and the engine skips a
relation whose FK is absent. The example keeps the FK columns and the
requirement is now the first Rules bullet.
QRY-F-01 — `context` had zero coverage; it is the RLS / system-read escape
hatch, and a read without it silently returns fewer rows. Added with the
`{ isSystem: true }` example and the query-bag vs trailing-argument rule.
QRY-F-02 / QRY-G-03 — the bare-string `search` plus sibling `searchFields` is
the canonical Tier-1 form; the three spellings of that one knob are named.
QRY-F-03 / QRY-A-01 / QRY-G-02 — the three missing string operators and the
case rule; a "which filter dialect" table; one spelling for the version fact.
QRY-A-01 also edits the frontmatter description: the list-view filter spec is
objectstack-ui's vocabulary, not this package's.
5443 -> 3784 tok.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
* docs(skills): regenerate the skills reference after the query description edit
Generator output only — `pnpm --filter @objectstack/spec gen:skill-docs`.
`skills/README.md` is byte-unchanged: it renders only the description's FIRST
sentence, which QRY-A-01 did not touch.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
* docs(skills): contract review round 1 — the passthrough keys, and the $like faces
Two spans, both re-measured at source before touching them.
1. The calling-convention table listed nine keys for engine `find`/`findOne` and
called the set closed. `packages/objectql/src/engine.ts:396-400` spreads
`ENGINE_DRIVER_PASSTHROUGH_KEYS` (`:368-370`: `transaction`, `tenantId`,
`tenantIds`, `timezone`, `bypassTenantAudit`, `preserveAudit`) into it, so as
written the table said an explicit `tenantId` is refused, which is false. The
row now names all fifteen, and the prose carries the reason the source gives
at `:360-366`: on find/findOne (and update/delete) the option bag IS the base
of the driver options, while `count`/`aggregate` never forward the bag, so
those keys are deliberately illegal there. `count` and `aggregate` rows
unchanged — both were already exact.
2. Review asked me to verify the `$like`/`$ilike` face list at source or drop
it. Verified; all three refusals hold, and each is an ALLOWLIST MISS, which
is why grepping the drivers for `$like` does not find them:
- driver-mongodb — `mongodb-filter.ts:1071` throws `Unsupported filter
operator "$like" …`; its `unsupportedFilterError` (`:366-371`) sets
`INVALID_FILTER` / 400. Pinned at
`mongodb-operator-key-clobber.test.ts:158-161`.
- objectql `having` — `having-filter.ts:136-141` `CONDITION_OPERATORS` is
sixteen operators without `$like`/`$ilike`; anything else reaches
`unknownOperator` (`:174-205`) and `invalidFilterError`, `INVALID_FILTER`
/ 400 (the table at `:157-158` names the faces sharing that envelope).
- service-analytics — `strategies/filter-normalizer.ts:418-435`
`MONGO_TO_CUBE_OP` omits them; the miss branch at `:1032-1046` throws
`invalidFilterError` (`:403-406`, `INVALID_FILTER` / 400) with
`Unsupported filter operator "$like" …`.
The review's own two readings were the ones that did not survive measurement,
so the sentence is corrected rather than weakened: `driver-memory` ANSWERS
these operators (`memory-driver.ts:58,1522`, `memory-matcher.ts:458`), and
`filter-refusal.ts:720-726` refuses only a DANGLING ESCAPE in the pattern via
the spec's shared `hasDanglingLikeEscape`. The prose now states which faces
answer, which refuse, and the escape rule that binds all of them.
Paid in-file: `rules/filters.md` 2100 -> 2136 (ceiling 2149, and still under the
2144 it started at) by collapsing two Common-Mistakes blocks that restated the
Logical Operators and `$null` sections above them.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
* chore(gates): ratchet the role-word baseline down for rules/filters.md
`check:role-word` reds on IMPROVEMENT as well as regression: round 2's deletion
of two Common-Mistakes blocks in `skills/objectstack-query/rules/filters.md`
removed one baselined occurrence, so the gate reported
role-word count improved 9 -> 8 — ratchet DOWN: run
`node scripts/check-role-word.mjs --update` and commit the baseline.
This is that commit, and nothing else: `node scripts/check-role-word.mjs
--update` moved exactly one row (9 -> 8) and no other, verified by `git diff`
before committing. The gate is green after it.
Why it reached CI rather than my machine: round 2 re-ran only the five
card-named gates instead of re-deriving the union, and this family is pulled in
by the prose paths, not by the card's list. Round 3 runs the whole re-derived
list — which this baseline file itself widens.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 3e5ad08 commit 04ec174
6 files changed
Lines changed: 227 additions & 575 deletions
File tree
- content/docs/ai
- scripts
- skills/objectstack-query
- rules
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | | - | |
| 94 | + | |
95 | 95 | | |
96 | | - | |
| 96 | + | |
97 | 97 | | |
98 | 98 | | |
99 | 99 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
0 commit comments