Skip to content

[finding] os explain query's example teaches two keys QuerySchema SILENTLY DROPS — filters/sort are where/orderBy, and the #14811 sweep is green on it #16925

Description

@claude

Found during the verification pass for the #15170#15176 catalog family (PR #16924), while measuring the entries that pass the #14811 sweep. This entry passes it, and that green is false.

os explain query documents two keys that QuerySchema does not have and does not reject. It strips them silently, so an author who copies the example gets a query with no filter and no ordering, and nothing anywhere says so.

This is a different and sharper failure mode than the seven cards just fixed: those all fail LOUDLY at parse, which is how the sweep found them. This one is invisible to the sweep by construction — the sweep asserts safeParse(...).success === true, and stripping keeps that true.

Measured

BaseQuerySchema (packages/spec/src/data/query.zod.ts) is a plain z.object({...}), not strictObject, so unknown keys are dropped rather than refused. Its real keys are where (not filters) and orderBy (not sort).

Parsing the entry's own example against QuerySchema:

parses: true
output keys: object, fields, limit

filters and sort are gone from the parsed output. The example as shipped:

{
  object: 'project_task',
  fields: ['title', 'status', 'assigned_to'],
  filters: [{ field: 'status', operator: 'eq', value: 'open' }],
  sort: [{ field: 'created_at', order: 'desc' }],
  limit: 50,
}

The entry's optional table carries the same two spellings:

  • { name: 'filters', type: 'Filter[]', description: 'Where conditions' }
  • { name: 'sort', type: 'SortConfig[]', description: 'Order by configuration' }

Both are absent from the schema. filters is a real key on OTHER surfaces (a view's filter list, a dataset), which is exactly why the wrong spelling reads as plausible here.

Why it was not fixed in PR #16924

That PR carries the seven cards #15170#15176, and query is not one of them: it is a different entry, its example is not what any card measured, and correcting it is not the same kind of edit. The where / orderBy rewrite also raises a question the seven did not — whether the sweep should gain a key-retention assertion, i.e. that an entry's example parses AND survives the parse with its keys intact. That is a new verification surface, and it is the part that actually closes the class rather than this one instance.

What a fix probably needs

  1. Correct the query entry's example and its two table rows to where / orderBy, reading the real shapes from BaseQuerySchema.
  2. Decide whether the [finding] os explain's 11 other catalog entries are hand-maintained against no schema — the flow entry's sample was unparseable and nothing said so #14811 sweep grows a second assertion for the bound entries: no declared key of an example may be dropped by its schema. Without it, the next non-strict schema in the catalog reproduces this exact defect with the sweep green.

Filed unassigned for triage. Suggested domain: domain:cli. Deduplicated before filing against all 113 domain:cli + finding cards in every state (REST list, full pagination to a short page, positive control hit).

Reproduce

pnpm --filter @objectstack/cli exec vitest run test/commands.test.ts

The sweep is GREEN on this entry — that is the point. To see the loss, parse SCHEMAS.query.example against QuerySchema from @objectstack/spec/data and read the keys of result.data.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationfinding

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions