Skip to content

docs(objectql,metadata-protocol): pin why the two __search doors answer differently (#7876) - #8079

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-7876-search-door-divergence-pin
Aug 12, 2026
Merged

docs(objectql,metadata-protocol): pin why the two __search doors answer differently (#7876)#8079
os-zhuang merged 1 commit into
mainfrom
claude/issue-7876-search-door-divergence-pin

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #7876

One column, two doors, two answers: $searchFields=__search is refused with a 400, while ?select=__search returns 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 __search under isSystem) is untouched.

Where the two comments went

door site why here
silent drop ObjectQL.stripSearchCompanionFromReadpackages/objectql/src/engine.ts Named by the ruling. Its docblock already explained why a non-system caller does not keep the column; it did not answer why that is silence rather than a 400.
the 400 assertSearchFieldsAreSearchablepackages/metadata-protocol/src/protocol.ts The refusal located by symbol. It is not in objectql at all: a hidden field is dropped from the searchable set, lands in the unsearchable bucket and throws 400 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:224 already 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.
  • Gates re-derived for the real two-file surface via node scripts/pm/dispatch-gates.mjs (adding protocol.ts pulls in check: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

…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
@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 12, 2026 2:44pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/metadata-protocol, @objectstack/objectql.

16 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/metadata-lifecycle.mdx (via @objectstack/metadata-protocol, @objectstack/objectql)
  • content/docs/data-modeling/formulas.mdx (via packages/objectql)
  • content/docs/deployment/migration-from-objectql.mdx (via @objectstack/objectql)
  • content/docs/deployment/vercel.mdx (via @objectstack/objectql)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/objectql)
  • content/docs/kernel/runtime-services/examples.mdx (via packages/objectql)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/metadata-protocol, @objectstack/objectql)
  • content/docs/kernel/services.mdx (via @objectstack/objectql)
  • content/docs/permissions/authentication.mdx (via @objectstack/objectql)
  • content/docs/permissions/system-context.mdx (via packages/objectql)
  • content/docs/plugins/index.mdx (via @objectstack/objectql)
  • content/docs/plugins/packages.mdx (via @objectstack/objectql)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/metadata-protocol)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/objectql)
  • content/docs/protocol/objectql/query-syntax.mdx (via packages/objectql)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/objectql)

2 release-owned page(s) also reference the affected code. These are read-only:

  • content/docs/releases/implementation-status.mdx (via @objectstack/objectql)
  • content/docs/releases/v9.mdx (via @objectstack/metadata-protocol)

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

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

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Decision] Two doors answer __search differently: the projection door drops it silently, $searchFields refuses it with 400 "is hidden"

2 participants