docs(objectql,metadata-protocol): pin why the two __search doors answer differently (#7876) - #8079
Conversation
…swer differently (#7876) `$searchFields=__search` is a 400; `select=__search` is a 200 without the key. The maintainer ruled on 2026-08-12 that the divergence is intended (direction C) and asked for the reasoning to be written at both doors so the question is not reopened. Two comments, zero behaviour change: - `ObjectQL.stripSearchCompanionFromRead` — why this door is silent, with the option-B refusal explicitly declined and the condition that would reopen it. - `assertSearchFieldsAreSearchable` — the actual `$searchFields` refusal, which sits in the same file as the projection gate it diverges from. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014C8pAprWdmtecFsEprZax4
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 2 package(s): 16 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also reference the affected code. These are read-only:
|
Fixes #7876
One column, two doors, two answers:
$searchFields=__searchis refused with a 400, while?select=__searchreturns 200 with the key absent. The maintainer ruled on 2026-08-12 that this divergence is intended (direction C) and asked for the reasoning to be pinned at both doors so the next reader is stopped instead of re-opening it.Zero behaviour change. Comments only — 54 added lines, all of them continuation lines inside existing block comments, zero deletions. No status code, refusal, assertion or test moved, and the system-caller carve-out (
plugin-pinyin-search's backfill projecting__searchunderisSystem) is untouched.Where the two comments went
ObjectQL.stripSearchCompanionFromRead—packages/objectql/src/engine.tsassertSearchFieldsAreSearchable—packages/metadata-protocol/src/protocol.tsobjectqlat all: a hidden field is dropped from the searchable set, lands in theunsearchablebucket and throws400 INVALID_FIELD("is hidden" is the auto-default branch's reason). Decisive detail:assertProjectionFieldsExist— the projection door's own gate — is 220 lines above it in the same file, so a reader comparing the two axes is standing exactly where the question forms.Each comment states the ruling's reasoning (authoring input vs. read projection), cites the ruling and #7876, declines option B explicitly, and names the one thing that would re-open it: a real caller measured as burned by the silent drop.
Deliberately NOT changed
packages/objectql/src/search-companion.ts:224already narrates both doors in one sentence ("...which refuse it with a 400 'is hidden'. None of them is a PROJECTION rule, though"). A third copy of the same explanation is the drift this card exists to prevent, so it was left alone.Verification
pnpm --filter @objectstack/objectql test— 189 files / 3356 tests passed (unchanged; the diff is structurally incapable of moving a number).pnpm --filter @objectstack/metadata-protocol test— 75 files / 1094 tests passed.pnpm --filter @objectstack/objectql typecheck— clean. ESLint on both changed files — clean.node scripts/pm/dispatch-gates.mjs(addingprotocol.tspulls incheck:cross-package-test-inputs):check:adr-anchors,check:durability-log-level,check:engine-double-contract,check:stack-collection-maps,check:cross-package-test-inputs,check:nul-bytes,node scripts/check-engine-split-ratio.mjs— all green.No changeset: comments only, nothing user-visible ships. Labelled
skip-changeset.Generated by Claude Code