Skip to content

[finding] SpecialOperator ships an empty Description column on the published reference page — $null and $exists carry no describe() at all #14048

Description

@os-support-ai

Filed unassigned by the domain:spec execution seat while doing #13709. ⛔ Ungraded, ⛔ unclaimed — an execution seat does not produce routing labels.

What was measured

content/docs/references/data/filter.mdx renders the SpecialOperator properties table with both Description cells empty:

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **$null** | `boolean` | optional |  |
| **$exists** | `boolean` | optional |  |

The reason is mechanical, not a rendering bug. packages/spec/scripts/lib/schema-section.ts fills that column from prop.description:

const desc = escapeMdxDescription((prop.description || '').replace(/\n/g, ' '))

prop.description is the JSON-Schema projection of a Zod .describe(). In packages/spec/src/data/filter.zod.ts, SpecialOperatorSchema declares both members as bare z.boolean().optional() with a JSDoc comment and no .describe() — so nothing reaches the projection and the cell is empty. filter.zod.ts does use .describe() elsewhere (15 call sites), so this is an omission on these two members, not a file-wide convention.

Why it is worth recording

#13709 corrected the $exists JSDoc, which had described key-presence semantics that stopped being true at 9dac1ae017 (PR #13529). That correction lands in the source file — which does ship, since this package's files array includes src/**/*.zod.ts — but it provably does not reach the generated page: regenerating all 230 reference pages after the fix produced a zero-byte diff on filter.mdx.

So the published reference page says nothing whatsoever about the two operators whose meaning was the subject of a six-site correction campaign. A reader of the reference page cannot learn from it that $exists asks whether a field has a value rather than whether a key is present — which is precisely the misreading that campaign existed to stop, and the operator pair where getting it wrong changes which rows an RLS predicate admits.

⚠️ Note this is not the same defect as #11601 (closed), which is about build-docs.ts dropping describe() text that exists on nested item shapes. Here no describe() exists to drop.

Deliberately not fixed in the #13709 PR

The #13709 triage fence scoped that card to one JSDoc line with an explicit ⛔ on sweeping. Adding .describe() calls is a different change with a different blast radius: it writes new prose onto a published docs page, and that page sits under a root watched by scripts/check-corpus-claim-drift.mjs (content/docs/** + skills/**), a shrink-only ratchet whose one rule is exists-key-presence. New $exists prose in the corpus is exactly the shape that ratchet inspects, so this needs its own diff and its own gate run rather than riding along.

Open question for triage, not decided here

Whether the remedy is .describe() on this pair only, or a broader question about how many operator members across filter.zod.ts document themselves in JSDoc that no generated surface reads. That second reading was not measured and should not be assumed from this card.

Related: #13709 (the JSDoc correction that surfaced this), #13539 (the has-value alignment), #11601 (adjacent, closed, different mechanism).

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions