Repository navigation
refactor(objectql): move three query-lowering bodies out of engine.ts into engine-query-lowering.ts (#25522 cut 20) - #27851
Conversation
…25522 cut 20) resolveWhereTokens, lowerRelationConditions and resolveSearchQueryableFields move unedited into engine-query-lowering.ts behind QueryLoweringHost; the class keeps each method as a stub. resolveThenLowerWhere and relationSitesOf are exported in place and imported back. Move-only. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgWZYhVkTy8Yp9oDD11
📓 Docs Drift CheckThis PR changes 1 package(s): ⛔ 1 release-owned page(s) name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 19 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 8470d7bbbeb9592939cb53c38e3310eec19b0fce && git checkout 8470d7bbbeb9592939cb53c38e3310eec19b0fce
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 637cfc67362933c7c04b8784247e2b39d4e68acf 0014e73327f5c6e6ccd57dec7bc5d71f94c57316 && git checkout -B drift-repro 637cfc67362933c7c04b8784247e2b39d4e68acf && git merge --no-ff 0014e73327f5c6e6ccd57dec7bc5d71f94c57316
node scripts/docs-audit/affected-docs.mjs --json 637cfc67362933c7c04b8784247e2b39d4e68acf
|
|
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F 维护者速读(席位终稿)
席位意见: ACCEPT。Shape B 搬移,系列 d.ts 关卡满足;新出现的 symbol 键 getter 宿主形状在使用时读槽,保留「从不缓存」语义。 席位核对ACCEPT · head
|
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F
Requested by Sales · project thread
Part of #25522
Clause-②: no
Metadata-protocol: none
Skills-docs: none — a move-only split of a private engine body; no skill or docs page names these members
Ruling-ref: 6348891160 + 6441032442
维护者速读
engine.ts「查询条件下沉」区里 3 个方法体(where/having令牌解析resolveWhereTokens、跨对象关系条件改写成$in的lowerRelationConditions、搜索可查询字段的取得resolveSearchQueryableFields)原样搬进新文件engine-query-lowering.ts;类上的方法签名、注释、位置不变,方法体换成转交。与留下代码共用的 2 个顶层 helper(resolveThenLowerWhere、relationSitesOf)原地加export、由新文件导入(不复制)。engine.ts22,170 → 22,131 行。src/engine.ts(23,903 lines, +7,501 in 30 days) along itsObjectQLseams, one move-only slice per PR #25522 按缝拆分engine.ts的第 20 刀。在最新main上把类的 268 个成员全部重新测价:大块方法体几乎都被系列限制锁住(私有静态、推断的公开返回类型、engine.ts#X外部指针、写入普查、查询选项擦除基线),能整块搬、付得起 −30 行以上的只剩这一区,净 −39 行。.d.ts六个文件里四个逐字节相同;index.d.ts/.d.mts因两个 helper 原地export引起顶层声明重排(裁决6441032442B 情形),经语句级归一化后完全相等(语句多重集、声明面摘要、导入导出名集合都相等,附阳性对照)。运行期导出名单与函数名相同,外部包加载顺序不变,晚绑定探针新旧逐行一致。回滚 = revert 本 PR。packages/objectql/src/engine-query-lowering.ts(3 个函数与QueryLoweringHost,其中用 symbol 键 getter 传安全服务槽是本系列新出现的宿主形状)、packages/objectql/src/engine.ts里 3 个转交桩、新导入行与 2 处原地export。pnpm --filter @objectstack/objectql exec vitest run --project local --maxWorkers=2 src/engine-nested-relation-lowering.test.ts src/relation-condition-prescription-cap.test.ts src/engine-search-queryable-fields.test.ts,应见 3 个文件、38 个测试全部通过。Cut 20 of the
packages/objectql/src/engine.tssplit (#24586 ruling A, recorded in6270097840), under the claim6512318712(branch amendment6512348857). Three bodies of the query-lowering area move unedited into a new module,packages/objectql/src/engine-query-lowering.ts, behindQueryLoweringHost. No behaviour changes. #25522 stays open.Branch
claude/project-thread-n9w3bf(the card thread's harness-pinned branch), cut fromorigin/mainatfec60e00, withorigin/main0a4b0fb223merged in (clean).origin/mainhas since moved to637cfc6736; that range touchesregistry.ts, two ADRs andliveness/datasource.*, none of this diff's paths, none of them names a moved body, andgit merge-treeof this head with it is clean.What changes
Why this area
Re-priced on fresh
origin/main(engine.ts22,170 lines, blob543fe0beb94c): every one of the class's 268 members was screened for the series limits and priced by the net-line rule (body lines removed less the stub and host the move costs). What is left that is both free and large is little:resolveWhereTokens,lowerRelationConditions,resolveSearchQueryableFields)staticReadonlyCreateStripand neighbours)dispatchUnscopedMultiWriteHooks)The large bodies are locked: private statics (
expandRelatedRecords,walkReferencingRelations), an inferred public return (registerApp),engine.ts#Xliveness pointers (registerMetadataCollections,buildSummaryIndex,expandSearchOnAst),docs/adrpointers (applyFieldDefaults,executeWithMiddleware,transaction), query-options erasure sites (find,findOne,seedAutonumber) andthis.updatewrite sites under the tenant-audit census (recordObservedDeviation,retractCreationAttestation,recomputeSummaries).Inside the chosen area:
resolveWhereTokensresolveRelateThenLowerWherelowerRelationConditionswithResolvedWhereexpandSearchOnAstdocs/qaandpackages/spec/livenessnameengine.ts#expandSearchOnAstresolveSearchQueryableFieldsexpandSearchOnOptionsfillQueryAstDefaultspackages/spec/livenesspointer names itThe three bodies price at −43 in all; the module's import line and the import-list edits in
engine.tsbring the file to −39. The two-body variant (withoutresolveSearchQueryableFields) measured −29 to −31, so the third body was added to clear −30.The shape
ThisParameterType<typeof fn>with exactly theQueryLoweringHostmembers it reads, plus a.call, marked[#25522 cut 20], as cuts 8 and 10 to 19 did; the genericlowerRelationConditions<W>is called as(lowerRelationConditions<W>).call(host, …)._registry,relatedSchemaOf); methods as late-bound closures (resolveRelateThenLowerWhere,find), so a double set on the engine after construction is still the one a call reaches.resolveSearchQueryableFieldsreads the engine's security-service source through the module-level symbolSECURITY_SERVICE_SOURCE_SLOT. The host carries it asget [SECURITY_SERVICE_SOURCE_SLOT](), typedunknownonQueryLoweringHost(the body already narrows it), and the stub reads it as(this as unknown as Record<symbol, unknown>)[SECURITY_SERVICE_SOURCE_SLOT]. No moved body assigns a field, so there is no setter..d.tsline staysprivate NAME;. No moved body reads a private static, has athis.FIELD.delete/insert/update(site, callsthis.insert/this.update/this.delete, is a query-options erasure site, carries anengine.ts#NAMEpointer, or holds a system-context census row or a reader-testviasite.6432376812.resolveThenLowerWhereandrelationSitesOfare read by moved and staying bodies alike; each gainsexportin place, byte for byte otherwise, and the module imports them (andSECURITY_SERVICE_SOURCE_SLOT, already exported) from./engine.js. Nothing re-exports any of them from the package entry.assertHavingResolvedTemporalTokensInRange,relationFilterCapErrorand theRelationReplacementtype were read inengine.tsonly by moved bodies, so they leaveengine.ts's import lists (both modules are still imported there for other names).RELATION_FILTER_ID_CAPbecomes a type-only specifier inengine.ts, since its only remaining reader there is a{@link}in a docblock that stays.engine.tsimports the module right after./having-filter.js, after every module the new one imports, so no module is evaluated earlier than before. On the head bundles the// src/...region order equals the base's with one line added,// src/engine-query-lowering.ts, afterengine-validate.ts(index.mjs121 to 122 regions,index.js122 to 123,core.mjs110 to 111,core.js111 to 112). The externalimportstatements (158 inindex.mjs, 140 incore.mjs) andrequire(calls are identical and in the same order at base and head.Net lines
engine.tsgoes from 22,170 to 22,131 lines, net −39 (28 added, 67 removed). The module is 178 lines. The diff againstorigin/mainis 273 changed lines over 2 files (+206 / −67).Readers of the moved lines
engine.ts#resolveWhereTokens|lowerRelationConditions|resolveSearchQueryableFields|resolveThenLowerWhere|relationSitesOfpointer exists anywhere outsidepackages/objectql/src(git greponorigin/main637cfc6736: 0 hits), so no reader moves.federated-injected-column-readers.test.tskeys name none of the moved bodies; the test passes.check-system-context-census: OK, register unchanged.check-tenant-audit-census: census JSON equal at base and head.check-durability-degradation-log-level --listat base and head: identical once line numbers are masked (167 lines).check-adr-anchors: 1,921 decision-letter citations at base and at head. The moved bodies carry no[ADR-NNNN Dn]letter.Why
#25522 splits
engine.tsone seam at a time so that a change to one area reads, reviews and conflicts as that area alone. This is the largest free, contiguous seam left under the current series limits. Nothing about what the engine does changes.Tests
No test is added and none is edited: the move is proved by identity, not by new behaviour.
Public
.d.ts: ruling6441032442letter B (top-level reorder), with a positive controlBuilt
@objectstack/objectqlat base0a4b0fb223and at the merged head0014e7332. Four declaration files are raw byte-identical;index.d.tsandindex.d.mtsdiffer by 180 raw-diff lines each. Measured per variant: exporting eitherresolveThenLowerWhereorrelationSitesOfalone moves theAggregatedColumnClassandRELATION_FILTER_ID_CAPdeclarations and reorders one import's specifiers, which is the case letter B allows when the statement-level normaliser closes it.core.d.ts61512fd9…=3a827f7f…EQUAL0224b74e351a(1) EQUALcore.d.mts1753655e…=9c348846…EQUAL0224b74e351a(1) EQUALindex.d.ts1f93ea9f…→17310099…8369d957…EQUAL5ad12aeac594(118) EQUALindex.d.mtsb28038a7…→576cb7ad…aa35d3ef…EQUAL5ad12aeac594(118) EQUALutil-BMx8ShtN.d.ts75d16412…=17b34879…EQUAL38c72db70306(175) EQUALutil-BMx8ShtN.d.mts75d16412…=17b34879…EQUAL38c72db70306(175) EQUALutil-BMx8ShtNat both).dtsnorm.mjslives in another project's files and was not available in this container, sodtsnorm-cut20.mjsre-implements ruling6441032442item 1(b) from the ruling's text (statement multiset, declared-surface digest sorted per top-level entry, import/export specifier sets). Its sha256 is2dd168976943dd62df853a20dd2e06fc41afea76aef34cb2d4e7fb54af8fa5c0; the positive control below shows it does see a surface change.66d694e25(whose declaration files are byte-identical to the merged head's),node scripts/ablation-replace.mjsdroppedprivatefrom thelowerRelationConditionsstub and rebuilt. The chunk is renamedutil-ljRTZG5W; its normalised sha256 reads4ca41d40…against17b34879…and its declared surface21b34ba6d9a8against38c72db70306. The restore leg put theengine.tsblob back tofd1d10a8237a(equal toHEAD), and the rebuild that followed compared equal to the head build.index194 names andcore54, ESM and CJS, and a digest over every export's name and function.nameisc5c2f41286d9at base and head, so no bundler same-name rename happened.turbo run build(116 of 116 tasks, the dependents' DTS builds included) and the@objectstack/coreand@objectstack/objectqltypechecks ran: exit 0 each. (P2)packages/objectql/package.jsonexportsnames./dist/index.*and./dist/core.*only; (P3)git grep -n -E 'objectql/dist' -- scripts package.json: 0 hits.AST compare (move-only)
A one-off script (TypeScript compiler API; leaf tokens) on base
engine.tsagainst headengine.tsplus the module:async, body tokens, and every body line equal after one level of indent):resolveWhereTokens173 tokens / 20 lines,lowerRelationConditions282 / 27,resolveSearchQueryableFields135 / 14. Negative controls: one changed token in a module copy reads DIFF, and a comment-only edit fails the line rule.class ObjectQL: 333 of 333 members kept, in the same order; 330 byte-identical including leading trivia, and the 3 stubs keep docblock, modifiers and signature identical.resolveThenLowerWhereandrelationSitesOfeach withexportadded and otherwise byte-identical, and the class. The head adds one statement: the module import.Late-binding probe (base and head
dist)zz-probe-cut20.mjs(a one-off, not committed) loads the builtObjectQLfrom eachdist/and drives the three bodies with doubles set on the instance after construction:lowerRelationConditionson a nested relation condition,null, a plain condition, the 1,000-id cap (it throwsINVALID_FILTER) and withfindreplaced a second time;resolveWhereTokensonwhere, withresolveRelateThenLowerWherereplaced (the spy sees the call), onhaving, and on an empty AST;resolveSearchQueryableFieldswith no context, with no slot, with the security-service slot set after construction, replaced, throwing, and set to a non-function. The 27 output lines are identical on base and head (the construction log lines, which carry timestamps, set aside); stderr is empty on both.Suites
Under
scripts/pm/os-verify-lock.sh:turbo run build: 116 of 116 tasks, exit 0.typecheckof@objectstack/objectqland@objectstack/core: exit 0 each.@objectstack/objectqlvitest--project localon the merged head: 491 files, 9,252 tests passed, exit 0 (engine-nested-relation-lowering.test.ts,relation-condition-prescription-cap.test.ts,engine-search-queryable-fields.test.ts,engine-nested-object-door.test.ts,query-expression-conformance.test.tsandfederated-injected-column-readers.test.tsamong them). The three files in the two-minute check: 38 passed.test:repoprojects forobjectql(1 of 5) andcore(6 of 94) that read this package ran green locally;Test Coreruns the rest in CI.Verification
The gate list is
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackon0014e7332, each run with its exit code captured before any pipe, then reconciled with--ran(each lineCMD :: exit N).--ran: 48 derived, 48 run, 0 NOT-MEASURED, 0 UNRUN ("a DERIVED zero — all 48 recorded an exit code and none of them is 3").check:dual-build-cjs-loadsran after the full build.pnpm check:authz-resolver,check:error-code-casing,check:filter-alias-parity,check:engine-double-contract,check:tenant-chokepoint,check:adr-anchors,check:query-options-erasure;@objectstack/speccheck:api-surface,check:generated,check:liveness;node scripts/check-tenant-audit-census.mjs,check-adr-symbol-anchors.mjs,check-platform-checklist.mjs --changed-from origin/main,check-commit-card-trailers.mjs --range origin/main..HEAD,check-system-context-census.mjs,check-nul-bytes.mjs; and eslint aspnpm lintruns it (--no-inline-config) onpackages/objectql.Acceptance notes
6512318712and its amendment6512348857named this branch.git diff --name-only origin/main...pr/N): none touchespackages/objectql/src/engine*.git merge-treeof this head withorigin/main637cfc6736is clean.SECURITY_SERVICE_SOURCE_SLOTis the first host member in the series keyed by a symbol rather than a name; it is the one place this cut goes beyond cuts 8 to 19's shape.expandSearchOnAst(84 body lines) andfillQueryAstDefaultsstay for their liveness pointers;resolveRelateThenLowerWhere,withResolvedWhereandexpandSearchOnOptionsdo not pay for a stub. After this cut, no free contiguous area inengine.tspays more than −30 under the current series limits.engine.tsstill says{@link RELATION_FILTER_ID_CAP}; it is kept byte-identical with the specifier type-only. The moved bodies keep their indentation minus one level, as moved, not re-formatted.Human Minimum
packages/specholds no runtime logic. (Not touched.)QueryLoweringHost,engine-query-lowering.ts).pnpm lintpasses on the touched package.main, one pull request.skip-changeset(ruling6441032442item 4: no changeset for a reorder); both declaration lines are filled in above.packages/specnot touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.skip-changeset: move-only inside@objectstack/objectql, with the published declarations equal under the ruling's normaliser and no behaviour change, so there is nothing for a release note to say.🤖 Generated with Claude Code
https://claude.ai/code/session_01L6bhgWZYhVkTy8Yp9oDD11
Generated by Claude Code