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:
constdesc=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).
Filed unassigned by the
domain:specexecution seat while doing #13709. ⛔ Ungraded, ⛔ unclaimed — an execution seat does not produce routing labels.What was measured
content/docs/references/data/filter.mdxrenders theSpecialOperatorproperties table with both Description cells empty:The reason is mechanical, not a rendering bug.
packages/spec/scripts/lib/schema-section.tsfills that column fromprop.description:prop.descriptionis the JSON-Schema projection of a Zod.describe(). Inpackages/spec/src/data/filter.zod.ts,SpecialOperatorSchemadeclares both members as barez.boolean().optional()with a JSDoc comment and no.describe()— so nothing reaches the projection and the cell is empty.filter.zod.tsdoes 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
$existsJSDoc, which had described key-presence semantics that stopped being true at9dac1ae017(PR #13529). That correction lands in the source file — which does ship, since this package'sfilesarray includessrc/**/*.zod.ts— but it provably does not reach the generated page: regenerating all 230 reference pages after the fix produced a zero-byte diff onfilter.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
$existsasks 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.build-docs.tsdroppingdescribe()text that exists on nested item shapes. Here nodescribe()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 byscripts/check-corpus-claim-drift.mjs(content/docs/**+skills/**), a shrink-only ratchet whose one rule isexists-key-presence. New$existsprose 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 acrossfilter.zod.tsdocument 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).