Skip to content

Commit 04ec174

Browse files
os-litantclaude
andauthored
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/skills-reference.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ Do not use for querying data (see objectstack-query) or for plugin / kernel hook
9191

9292
Construct ObjectQL queries — filters, sorting, pagination, aggregation, relation expansion, and full-text search.
9393

94-
Use when the user is writing a query DSL expression, picking pagination strategy, or designing a list view's filter spec.
94+
Use when the user is writing a query DSL expression or picking a pagination strategy.
9595

96-
Do not use for defining objects / fields / relationships (see objectstack-data) or for designing the API endpoint that exposes a query (see objectstack-api).
96+
Do not use for defining objects / fields / relationships (see objectstack-data), for designing the API endpoint that exposes a query (see objectstack-api), or for a list view's filter rules / dashboard datasets (see objectstack-ui).
9797

9898
**Tags:** `query`, `filter`, `sort`, `paginate`, `aggregate`, `ObjectQL`, `full-text`
9999

scripts/role-word-baseline.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"skills/objectstack-data/SKILL.md": 2,
3939
"skills/objectstack-data/rules/relationships.md": 1,
4040
"skills/objectstack-platform/SKILL.md": 2,
41-
"skills/objectstack-query/rules/filters.md": 9,
41+
"skills/objectstack-query/rules/filters.md": 8,
4242
"skills/objectstack-ui/SKILL.md": 2,
4343
"skills/objectstack-upgrade/SKILL.md": 1
4444
}

0 commit comments

Comments
 (0)