Skip to content

docs(objectql): query-syntax §9 states the all-unknown projection refusal, not the retired every-column fallback - #27586

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-27565-query-syntax-projection
Oct 29, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-27565-query-syntax-projection

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

domain:devx#2 · os-justin · session_01QSeKYp3oFeDem8Tbh8pzWA

Fixes #27565

Clause-②: no
Metadata-protocol: none
Skills-docs: updated here — content/docs/protocol/objectql/query-syntax.mdx §9 (heading, lead sentence, example and callout): the all-unknown projection is refused 400 VALIDATION_ERROR by engine.find() / findOne(), a mix still drops the unknown columns, expand sub-reads are unaffected, the REST ingress answers 400 INVALID_FIELD. Prose only; skills/** needs no change.

维护者速读

  • 改了什么:协议文档 query-syntax.mdx 第 9 节改写:投影里混有已知列时未知列才会被丢弃;全部是未知列时 find() / findOne() 答 400 VALIDATION_ERROR(与 fields: [] 同一拒绝);expand 子查询不受影响;REST 入口对任何未知列答 400 INVALID_FIELD。
  • 为什么改:PR fix(objectql)!: refuse a projection whose every column is unknown, as an empty one is refused #27541 已让引擎拒绝全未知投影,但这页还写着"回退为读全部列",会把钩子和流程作者引向引擎现在拒绝的写法。
  • 风险与回滚:极低,纯文档,不动代码、不发布;回滚即 revert。
  • 先看:content/docs/protocol/objectql/query-syntax.mdx 第 9 节"Unknown Projection Fields"(唯一改动文件)。
  • 两分钟验证:git grep -n "falls all the way back" content/docs,预期无输出(退出码 1)。
  • 需要你做的:无,席位落地。

What changes

content/docs/protocol/objectql/query-syntax.mdx §9. The heading "Unknown Fields Are Tolerated" became "Unknown Projection Fields", because the old one now misleads. The lead sentence, the example and the callout were rewritten, and the "falls all the way back to every field" clause is removed. git grep -n "falls all the way back" content/docs returns nothing (exit 1). No other page linked the old anchor (git grep unknown-fields-are-tolerated has no hits).

Each clause was checked against the code and a test at head 6535c19c:

Clause on the page Code Test
An unknown plain column is dropped only while one requested column is known; id / created_at / updated_at always count as known packages/objectql/src/engine.ts:13635-13641 (find), :13943-13946 (findOne); packages/objectql/src/declared-read-columns.ts:79 packages/objectql/src/engine-empty-projection-refusal.test.ts:257; packages/objectql/src/query-expression-conformance.test.ts:1776
An all-unknown projection is refused by find() / findOne() with 400 VALIDATION_ERROR, naming the requested columns, before any driver read engine.ts:13641, :13946 call refuseProjectionOfUnknownColumns; packages/objectql/src/empty-projection-door.ts:61-78 (status, code, got [...] in the message) engine-empty-projection-refusal.test.ts:241, :249 (reads stays empty); query-expression-conformance.test.ts:1786
The same refusal as fields: [] empty-projection-door.ts:111 and :125 both go through refuseEmptyProjection the same file's fields: [] block, earlier in engine-empty-projection-refusal.test.ts
expand sub-reads are unaffected, because the engine always adds id and strips it back off engine.ts:12797, :12806 (adds id), :12845 (strips it); id is never dropped (declared-read-columns.ts:79) packages/objectql/src/engine.test.ts:1942, :2010
The REST ingress answers 400 INVALID_FIELD for any unknown name, alone or mixed packages/metadata-protocol/src/protocol-query-validation.ts:716-727 (unknown.length > 0) query-expression-conformance.test.ts:1431 (alone), :1441 (mixed); packages/rest/src/data-record-read-malformed-query-door.test.ts:73

Tests

The cited suites on the merged head 6535c19

bash scripts/pm/os-verify-lock.sh -c "pnpm --filter @objectstack/objectql exec vitest run --maxWorkers=2 src/engine-empty-projection-refusal.test.ts src/query-expression-conformance.test.ts"

 Test Files  2 passed (2)
      Tests  209 passed (209)
os-verify-lock: VERDICT command-exit 0

Acceptance notes

  • Prose only, no code; skip-changeset: nothing in any package's files[] changes.
  • The old callout listed "registry-less hosts" among the callers the tolerance protects. That is dropped: an unregistered object is now refused 404 OBJECT_NOT_FOUND by the engine first (query-expression-conformance.test.ts, the registry-less guard after :1786). The new lead sentence says "on a registered object".

Verification

Derived gates, local subset (head 6535c19)

node scripts/docs-audit/affected-docs.mjs: exit 0, "0 docs name something this change touched".

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived the same 43 commands before and after the origin/main merge. On the merged head all 43 exit 0. Some first answered exit 3 (PREREQUISITE NOT MET, nothing measured), or exit 1 from a stale json-schema, until the build closures of @objectstack/lint... and @objectstack/client-react... (spec included) were rebuilt on that head. After the rebuild they exit 0: check:doc-formula-expressions, check:doc-security-posture, check:skill-examples, check:docs-transcript-drift, check:docs.

--ran with every exit recorded: "43 derived famil(ies) accounted for — 43 run, 0 NOT-MEASURED (a DERIVED zero — all 43 recorded an exit code and none of them is 3)".

NOT MEASURED locally: Build Docs and Check Documentation Links. These are CI-only jobs, and this PR's check-runs answer them.


Generated by Claude Code

…usal, not the retired every-column fallback

An unknown plain column is dropped only while one requested column is
known; a projection whose every entry is unknown is refused by find() /
findOne() with 400 VALIDATION_ERROR, the fields: [] refusal; expand
sub-reads always name id; the REST ingress answers 400 INVALID_FIELD.

Claude-Session: https://claude.ai/code/session_01QSeKYp3oFeDem8Tbh8pzWA
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 29, 2026
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Oct 29, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:devx#2 · os-justin · session_01QSeKYmTYfaPbLQD4BJfomW

席位核对 — ACCEPT · domain:devx#2 · head 6535c19c0c · 2026-10-29T14:10Z

维护者速读

  • 改了什么:ObjectQL 协议文档 query-syntax.mdx 的 §9 改写。旧版说「投影里不认识的字段一律静默丢掉,全不认识就退回成读所有列」,这已经和引擎行为不符。新版写的是现在的真实行为:混合投影里不认识的列照样丢掉;一列都不认识时,find() / findOne() 直接拒绝,返回 400 VALIDATION_ERROR;expand 子读取不受影响;REST 入口对任何未知列都返回 400 INVALID_FIELD。
  • 为什么改:fix(objectql)!: refuse a projection whose every column is unknown, as an empty one is refused #27541 已经收紧了引擎行为,这一页却还在教旧写法。写钩子或流程的人、以及照文档写代码的 AI,都会被它误导。
  • 风险与回滚:只改一页文档,+20/−10,不碰代码。回滚即还原本 PR。
  • 先看:§9「Unknown Projection Fields」整节。
  • 两分钟验证:git grep -n "falls all the way back" content/docs 不再有结果。
  • 需要你做的:无,席位落地。

席位意见:合入。每一句都能在代码和测试里找到依据,不是照抄卡片的措辞。

Shape: draft → main, Fixes #27565. 1 file, +20/−10. Label skip-changeset, with no assignees (#27385). Not governed. Claim 6497660661, report 6498636440.

Seat's own read (at TIER_DEFAULT, against origin/main):

  • The all-unknown refusal is pinned by packages/objectql/src/engine-empty-projection-refusal.test.ts L241 ("find with only unknown columns is refused 400 VALIDATION_ERROR, naming them, before any driver read").
  • fields: [] → VALIDATION_ERROR is pinned at L136–L154, and the REST door at L181.
  • Removing the "falls all the way back" clause leaves 0 hits in content/docs. The dev's suites, 209/209, pin every cited clause.

Gates: on head 6535c19c0c, 49 check-runs: 30 success, 19 skipped, 0 failure. That includes Build Docs and Check Documentation Links. check-expected-skips --pr 27586: OK. check-governed-merges: NOT governed, 30 lines.

Open question → A, kept: the "registered object only" precision and the id/created_at/updated_at precision both follow the code (404 OBJECT_NOT_FOUND first; system columns always count as known).

Out of scope: the REST INVALID_FIELD message's past-tense history sentence (protocol-query-validation.ts:716–727) is accurate history. No carrier needed. Skills-docs: content/docs/protocol/objectql/query-syntax.mdx.

Landing: the seat readies the PR and arms auto-merge in this act. On merge it posts the landing note on #27565 and archives the cloud session.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 29, 2026 14:11
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 29, 2026 14:11
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 492703e Oct 29, 2026
50 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-27565-query-syntax-projection branch October 29, 2026 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation 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.

docs(objectql): query-syntax.mdx §9 still declares the all-unknown projection fallback that #27165 / PR #27541 refused

1 participant