You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A comment asserts the SEARCH-axis remedy is worded identically to SORT/FILTER, the pin does not cover SEARCH, and the emitted message does not match — declared-≠-enforced on the refusal vocabulary #8648
A comment asserts an invariant, the test does not cover it, and the code does not honour it. That is this repo's recurring declared-≠-enforced family, landing here on the refusal vocabulary rather than on a metadata key. The wording difference alone would be a nit; the unenforced claim about it is the defect.
What was measured
Captured from the running doors — a real ObjectQL plus the protocol, each refusal triggered and its emitted message recorded verbatim (base 259f211f0). Not read out of the source strings: a literal in the tree can be dead or shadowed, and what the door emits is what a caller sees.
axis
door
envelope
remedy sentence, as emitted
SORT
ingress + engine.find()
400 INVALID_SORT
Denormalise the value onto 'showcase_task' (a stored field, written when the source changes) and sort by that.
FILTER
ingress + engine.find()
400 INVALID_FIELD
Denormalise the value onto 'showcase_task' (a stored field, written when the source changes) and filter that.
SEARCH
ingress
400 INVALID_FIELD
Mirror the computed value onto a stored text field on 'showcase_task' and search that instead.
SORT and FILTER are byte-identical apart from the closing verb. SEARCH differs in verb (Mirror / Denormalise), in noun phrase, and it narrows the target to a text field. All three agree in substance — put the value on a stored column of the queried object and query that instead.
The claim, quoted
Three comments state the SEARCH agreement as a fact about wording:
packages/objectql/src/filter-comparand-shape.ts:398 carries the same sentence but names only the ingress door, so it is accurate as written.
The coverage gap
packages/objectql/src/engine.ts:857 also says the pin enforces it: "query-expression-conformance.test.ts pins the three wordings as EQUAL rather than each separately, because separate wordings is exactly how #4256 and #6673 drifted apart in the first place."
The pin — the FILTER refusals agree word-for-word with the SORT refusals on the remedy — asserts the stem Denormalise the value onto 'showcase_task' (a stored field, written when the source changes) and across four doors: filter-ingress, filter-engine, sort-ingress, sort-engine. Verified green in isolation (1 passed, 170 skipped). The SEARCH door is not among them, and its emitted message cannot match that stem — so the claim is unpinned in exactly the place where it is false. An author rewording the SEARCH message will believe a pin protects the agreement, and nothing goes red.
Boundary
⛔ This is not a request to reword SEARCH. Which way the gap should be closed is triage's call, and the routes carry very different weight:
correcting the comments to describe substance-agreement rather than word-identity — comment-only;
extending the pin to the SEARCH door, against whatever agreement is decided — test-only;
aligning the SEARCH wording onto the shared stem — this changes a shipped, user-visible error message on an axis that already landed, a different weight class from the other two, and the text narrowing (correct for an axis that scans text-like columns) would need somewhere to live.
No route is recommended here.
Not addressed in PR #8647: that card is docs-only and its scope explicitly excludes error messages and rules.
Filed out of #8372's docs work (session
session_01Jqe56GnYFddggeAyfkZFVz). Unassigned and unlabeled — recording only, for triage.Backlink: #8372 · PR #8647 · related: #8296, #6673, #6994.
The shape
A comment asserts an invariant, the test does not cover it, and the code does not honour it. That is this repo's recurring declared-≠-enforced family, landing here on the refusal vocabulary rather than on a metadata key. The wording difference alone would be a nit; the unenforced claim about it is the defect.
What was measured
Captured from the running doors — a real
ObjectQLplus the protocol, each refusal triggered and its emittedmessagerecorded verbatim (base259f211f0). Not read out of the source strings: a literal in the tree can be dead or shadowed, and what the door emits is what a caller sees.engine.find()400 INVALID_SORTDenormalise the value onto 'showcase_task' (a stored field, written when the source changes) and sort by that.engine.find()400 INVALID_FIELDDenormalise the value onto 'showcase_task' (a stored field, written when the source changes) and filter that.400 INVALID_FIELDMirror the computed value onto a stored text field on 'showcase_task' and search that instead.SORT and FILTER are byte-identical apart from the closing verb. SEARCH differs in verb (
Mirror/Denormalise), in noun phrase, and it narrows the target to a text field. All three agree in substance — put the value on a stored column of the queried object and query that instead.The claim, quoted
Three comments state the SEARCH agreement as a fact about wording:
packages/objectql/src/engine.ts:853— "Deliberately the SAME remedy, in the same words, as the ingress door's formula and dotted refusals (A non-dottedorderBynaming aformulafield answers 200 in arbitrary order — the sort is silently dropped (measured on driver-sql + driver-memory) #6994, assertSortFieldsExist's dotted-path SORT hint also prescribes an unmaterializable "formula or rollup" denormalization — same defect class as #6673, different axis #6924) and The searchable-fields hints prescribe a "text/formula" mirror — the formula half never works, so the tool output now contradicts the docs that quote it #6673's SEARCH-axis correction."packages/metadata-protocol/src/protocol.ts:6481— "Deliberately the same remedy, in the same words, as the SORT axis' formula refusal (A non-dottedorderBynaming aformulafield answers 200 in arbitrary order — the sort is silently dropped (measured on driver-sql + driver-memory) #6994) and The searchable-fields hints prescribe a "text/formula" mirror — the formula half never works, so the tool output now contradicts the docs that quote it #6673's SEARCH-axis correction, with only the verb changed to name this axis."packages/metadata-protocol/src/protocol.ts:6693— "Deliberately the same remedy, in the same words, as the dotted refusal above and as The searchable-fields hints prescribe a "text/formula" mirror — the formula half never works, so the tool output now contradicts the docs that quote it #6673's SEARCH-axis correction."packages/objectql/src/filter-comparand-shape.ts:398carries the same sentence but names only the ingress door, so it is accurate as written.The coverage gap
packages/objectql/src/engine.ts:857also says the pin enforces it: "query-expression-conformance.test.tspins the three wordings as EQUAL rather than each separately, because separate wordings is exactly how #4256 and #6673 drifted apart in the first place."The pin —
the FILTER refusals agree word-for-word with the SORT refusals on the remedy— asserts the stemDenormalise the value onto 'showcase_task' (a stored field, written when the source changes) andacross four doors: filter-ingress, filter-engine, sort-ingress, sort-engine. Verified green in isolation (1 passed, 170 skipped). The SEARCH door is not among them, and its emitted message cannot match that stem — so the claim is unpinned in exactly the place where it is false. An author rewording the SEARCH message will believe a pin protects the agreement, and nothing goes red.Boundary
⛔ This is not a request to reword SEARCH. Which way the gap should be closed is triage's call, and the routes carry very different weight:
textnarrowing (correct for an axis that scans text-like columns) would need somewhere to live.No route is recommended here.
Not addressed in PR #8647: that card is docs-only and its scope explicitly excludes error messages and rules.
Generated by Claude Code