Uh oh!
There was an error while loading. Please reload this page.
[rest] record the #8039 ruling in DATA_RECORD_READ_PARAMS's docblock - #8510
Conversation
The docblock above DATA_RECORD_READ_PARAMS (GET /data/:object/:id's closed query-parameter set) described the fields/populate alias-table spellings as an open question tracked by #8039. Maintainer ruling, 2026-08-12, settled it: option 2 - keep the narrow select/expand set, refuse the alias spellings loudly instead of folding them. Option 1 (folding RPC_QUERY_ALIAS_SLOTS onto this one route) was explicitly rejected as surface expansion with no measured pull, and would leave other data routes' ingress inconsistent in the opposite direction. No code change. refuseUnknownQueryParams(req, res, DATA_RECORD_READ_PARAMS) already refuses `?fields=` / `?populate=` with a located 400 VALIDATION_ERROR - measured directly against origin/main before this commit by running rest-server-closed-query-params.test.ts (27/27 passing), including the two cases that drive both spellings through the real by-id handler and assert the refusal plus that getData is never called. The behavioural half of the ruling was already shipped; this commit is the prose half the ruling asked for. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P7vaLs7bhBPi9m3JyzkhDj
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 1 package(s): 9 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 3 release-owned page(s) also reference the affected code. These are read-only:
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#8039
What changed
Prose only. The docblock above
DATA_RECORD_READ_PARAMSinpackages/rest/src/rest-server.tsdescribed thefields/populatealias-tablespellings on
GET {basePath}/data/:object/:idas an open question ("Tracked as #8039 …rather than widened here"). It has been settled by maintainer ruling on 2026-08-12:
option 2 — keep the narrow
select/expandaccepted set, refuse the alias-tablespellings loudly instead of folding them. The comment now records that ruling instead of
pointing at a decided question:
select/expand)fields/populaterefused by name viarefuseUnknownQueryParams, not silentlydropped
RPC_QUERY_ALIAS_SLOTSonto this one route) explicitly rejected,and why — surface expansion on a public route with no measured pull, and doing it for
this route alone would leave every other data route's ingress inconsistent in the
opposite direction
all data routes, landed as one card, never a quiet per-route widening here
No route logic changed.
Why this is the correct delivery, not a thin one
The assignment explicitly warned against inheriting a previous round's measurement that
"the code half is already done." I re-verified it myself rather than trusting that
comment, per the instructions:
refuseUnknownQueryParams(packages/rest/src/query-allowlist.ts)builds
Set(allowed)fromDATA_RECORD_READ_PARAMS = ['select', 'expand']and rejectsany query key outside it with a
400 VALIDATION_ERRORbefore the handler everdestructures
{ select, expand }— sofields/populatecannot reachgetDatasilently.
pinned suite
rest-server-closed-query-params.test.ts(see Tests below), which boots areal
RestServer, drivesGET /data/:object/:idthrough its actual registered routehandler with
{ fields: 'title' }and{ populate: 'owner' }, and asserts:status === 400, nestedbody.error.code === 'VALIDATION_ERROR'select/expandas what the route acceptsgetDatawas never called (the defect this whole policy exists to prevent —"still 200" is exactly what silent widening looks like)
Both spellings are refused today, exactly as option 2 requires. No ablation applies
here — there is no behavioural change to reverse-verify, so instead of a predict/run
ablation pair this PR shows the direct measurement above, taken against
origin/mainbefore this change, proving the behaviour already holds. This makes shipping the prose-only
change the correct delivery, per the task's own instruction: "If it is genuinely complete,
then shipping only the prose change is the correct delivery, not a thin result."
Symbol drift note
Every line number on this card was stale (ruling:
:1779-1780; a later round measured:1515/:6834; PR #8487 moved both again). Located everything by symbol instead:DATA_RECORD_READ_PARAMSis now atrest-server.ts:1539, and the by-id handler'srefuseUnknownQueryParams(req, res, DATA_RECORD_READ_PARAMS)call is atrest-server.ts:7007.Tests
Build closure for the package first (per lane convention):
Typecheck, clean:
Targeted suite, before AND after the docblock edit (comment-only change, so identical
either way — confirms the rewrite didn't alter behaviour):
including, specifically:
Whole-package sanity pass (pre-edit, unaffected by a comment-only diff):
Local gate families run
Derived via
node scripts/pm/dispatch-gates.mjs packages/rest/src/rest-server.ts .changeset/data-record-read-alias-ruling-comment.md(one extra family the dispatch prompt didn't name:
check:authz-resolver, matched becauseit globs the whole
rest-server.tsfile — included below since the diff touches that file).All green:
pnpm check:authz-resolverpnpm check:route-envelopepnpm check:meta-type-normalizedpnpm check:filter-alias-paritypnpm check:changeset-gate-self-testspnpm check:objectui-changesetpnpm check:cross-package-test-inputsnode scripts/check-empty-changeset.mjs --base origin/mainnode scripts/check-changeset-no-major.mjs --base origin/mainnode scripts/check-adr-0087-registration.mjs --base origin/mainnode scripts/check-nul-bytes.mjsOne derived family (
check:objectui-pin-fresh) reports the objectui pin as stale — thisis pre-existing on
origin/main, unrelated to this diff (nothing here touches.objectui-shaor console files; the matcher fired only because this PR adds a file under.changeset/), and that gate is release.yml-scoped / advisory on ordinary code PRs per itsown message ("advisory mode does not block on a stale pin").
Changeset
packages/restgets apatchchangeset (non-empty frontmatter, following thecomment-gate-own-depth-contract.mdprecedent for doc-only contract clarifications —check-empty-changeset.mjsrejects a newly-introduced empty-frontmatter changeset, so theempty-frontmatter pattern some older comment-only PRs used is not available for a new
file).
Note on scope
packages/rest/src/rest-server.tsis a named hot-file serial queue for this lane; this PRtouches only the
DATA_RECORD_READ_PARAMSdocblock, nothing else in the file.Generated by Claude Code