Repository navigation
refactor(objectql): move the migration-flag and attestation bodies out of engine.ts into engine-migration-flags.ts (#25522 cut 13) - #26403
Conversation
…t of engine.ts into engine-migration-flags.ts Eight ObjectQL method bodies of the "Migration flags and attestations" section move unedited into a new module behind one named host, MigrationFlagsHost: supplyTenantKeyCertifiedResolver, isOrganizationOwnershipCertified, readFileReferencesFlagRow, isValueShapesMigrationVerified, readMigrationFlagVerified, noteAdmittedValueShapeViolation, announceOpenMigrationGates and wasDatastoreCreatedFromEmpty. The class keeps each method's name, modifiers, signature, docblock and position; fields go as getters, the one field a moved body assigns (migrationGatesAnnounced) as a getter and setter pair over the instance, methods as late-bound closures. MigrationFlagRead gains `export` in place so the module can name it as a type. No behaviour changes. Two stale path readers of cut 12 are corrected: the header of engine-realtime-publish.ts (accessibleOrganizationsOf now lives in engine-driver-options.ts), and the engine-execute-transactions.ts ADR anchor entry, which drops the buildDriverOptions half of the transaction-seam paragraph that engine-driver-options.ts's entry now carries. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wzm9du2KfnvCibhjZZYgyq
📓 Docs Drift CheckThis PR changes 1 package(s): 14 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 7 release-owned page(s) also 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 feb7e55d91a0addf0ffb9a508ab9c6d52d668c54 && git checkout feb7e55d91a0addf0ffb9a508ab9c6d52d668c54
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 7c70f91ce1910553ae1be4b19297011ae6ad04c0 c7df09f8803159f75fec54fbfea8fdbdd5e76379 && git checkout -B drift-repro 7c70f91ce1910553ae1be4b19297011ae6ad04c0 && git merge --no-ff c7df09f8803159f75fec54fbfea8fdbdd5e76379
node scripts/docs-audit/affected-docs.mjs --json 7c70f91ce1910553ae1be4b19297011ae6ad04c0
|
席位核对ACCEPT · The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」.
Generated by Claude Code |
Requested by Leehom · project thread
Part of #25522
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6348891160
维护者速读
engine.ts里「迁移标志与证明」一段的 8 个方法体原样搬进新文件engine-migration-flags.ts,类上方法签名与注释不变,只把方法体换成转交;顺手改正第 12 刀留下的两处过时说明(一行文件头注释、一个 ADR 锚条目)。engine.ts22,517 → 22,423 行。src/engine.ts(23,903 lines, +7,501 in 30 days) along itsObjectQLseams, one move-only slice per PR #25522 按缝拆分engine.ts的第 13 刀;本段在刀前重测的缝表里净减行最多,且不与在途 PR 重叠。席位为本刀裁定了「宿主 setter」:被搬方法体写入的类字段,经宿主上的一对 get/set 访问器写回实例。.d.ts六个文件逐字节不变;setter 的读写回实例由一次性探针在新旧两版上逐行对照证明。回滚 = revert 本 PR。packages/objectql/src/engine.ts里announceOpenMigrationGates的转交桩(唯一带 setter 的一处)、packages/objectql/src/engine-migration-flags.ts(搬入的方法体与MigrationFlagsHost)、scripts/adr-anchors/packages__objectql__src__engine-execute-transactions.ts.json(锚段落去掉重复的一半)。pnpm --filter @objectstack/objectql exec vitest run --project local --maxWorkers=2,应见 472 个测试文件全部通过。Cut 13 of the
packages/objectql/src/engine.tssplit (#24586 ruling A, recorded in6270097840). The claim is6430872749, which carries the seat's host-setter ruling for this cut. Eight bodies of the "Migration flags and attestations" section move unedited into a new module,packages/objectql/src/engine-migration-flags.ts:supplyTenantKeyCertifiedResolver(hand a driver the "is this database certified" question),isOrganizationOwnershipCertified(its answer),readFileReferencesFlagRowandisValueShapesMigrationVerified(the two memoized flag readers),readMigrationFlagVerified(the onesys_migrationrow read behind them),noteAdmittedValueShapeViolation(tally a violation this boot admitted),announceOpenMigrationGates(the once-per-boot open-gate advisory) andwasDatastoreCreatedFromEmpty. Two stale path readers of cut 12 are corrected in the same PR. No behaviour changes. #25522 stays open for the later cuts.Branch
claude/project-thread-9q75rj(the card thread's harness-pinned branch), cut fromorigin/mainat756220c4a, which contains cut 12's merge (2e7127bc3a, #26371). Nothing was edited before that merge landed: the move was dry-run on #26371's head while it was in the queue, and the four files committed here are byte-identical to that dry run (git hash-object, 4 of 4;engine.tsat756220c4ais the same blob,a17c9e9b93e6, as at #26371's head).What changes
Why this area
Re-measured on
756220c4awith cut 11's scripts, unchanged (both screens: query-options erasure sites and module-helper closure).engine.tsis 22,517 lines, 7,134 of them from the last 30 days (git blame --since=2026-09-27T01:21Z).scripts/pm/git-history.mjs count: 131 commits in 30 days, 35 in 7.class ObjectQLholds 318 members, 255 methods and accessors.Seam table at 756220c (41 sections)
txStore…constructorgetStatus…registryregisterHook…triggerHookshasHooksFor…assertBulkPerRowHookBudgetregisterAction…setActionActive_heldFileResolver…registerInsertRecomputeListenerreadableIdsSecurityReported…resolveDefaultPermissionswriteEpoch…hasObjectMiddlewareexecuteWithMiddleware…buildUserbuildDriverOptions…resolveEnginePostureprobeInstallOrganizations…transactionCoversDriverForresolveNowDefault…defaultFieldEntriesapplyAutonumbers…seedAutonumberregistrationConversionWarned…registerDriversupplyFileColumnsMovedResolver…listUnavailableDatasourcesassertWriteAllowed…publishBulkDataEventsetI18nService…objectDisplayLabelassertReferencesResolve…masterDeclaredFieldsinspectDanglingReferences…inspectCascadeDeletesetCryptoProvider…setTenancyPostureProviderencryptSecretFields…resolveInternalFieldgetSchema…judgeFilterLIFECYCLE_DATASOURCE…setDatasourceMappinginit…resolvePrimaryDatasourceobjectHasMediaField…valueShapeStrictForisFileReferencesMigrationVerified…wasDatastoreCreatedFromEmptydestroy…destroyMAX_EXPAND_DEPTH…MAX_BULK_PER_ROW_HOOK_ROWSautonumberCounters…recomputeSummariesexpandRelatedRecords…expandRelatedRecordsresolveFileReferences…readParentDerivedFilesresolveWhereTokens…requireFindOnePredicatefind…staticReadonlyCreateStripvalidate…validatereadUpdatePriorRow…insertManyupdate…updateplanCascadeAtomicity…organizationOwnedRowCountsdelete…deletecount…aggregateexecute…enforceTransactionOriginregisterObject…createThe full per-method screen and price list are in the project file
pm-orders/server/25522-cut13-seam-table.md; the move script ispm-orders/server/evidence/25522/move-cut13.mjs.Nine members of the section stay:
isFileReferencesMigrationVerified(ADR-0104 names it by path),recordObservedDeviationandretractCreationAttestation(each writes throughthis.update, a self-call the screen keeps in the class), and six bodies too short to pay for a host (haveFileColumnsMoved,readMigrationFlagMemoized,readMigrationFlagRowMemoized,valueShapeViolationsAdmitted,admittedViolationSink,invalidateDataMigrationFlags). Every field of the section stays declared where it was.The shape
MigrationFlagsHostmembers it reads, plus a.call, marked[#25522 cut 13], as cuts 8, 10, 11 and 12 did. Fields go as getters over areadXclosure (logger,_registry,admittedValueShapeViolations,drivers); methods go as late-bound closures (isOrganizationOwnershipCertified,findOne,readMigrationFlagRowMemoized,readMigrationFlagMemoized,recordObservedDeviation,retractCreationAttestation,objectHasMediaField,objectHasCoveredValueField,readMigrationFlagVerified), so a spy or double set on the engine is still the one a call reaches.announceOpenMigrationGatesis the one moved body that ASSIGNS a field (this.migrationGatesAnnounced = true). Its host carries the accessor pairget migrationGatesAnnounced() { return readMigrationGatesAnnounced(); }, set migrationGatesAnnounced(v) { writeMigrationGatesAnnounced(v); }, wherewriteMigrationGatesAnnounced = (v: ObjectQL['migrationGatesAnnounced']) => { this.migrationGatesAnnounced = v; }closes over the instance as the getters'readXdo. The field stays declared on the class with its initialiser and modifiers untouched;MigrationFlagsHosttypes itmigrationGatesAnnounced: ObjectQL['migrationGatesAnnounced'], notreadonly. No other moved body assigns a field, so no other setter exists (noteAdmittedValueShapeViolationcalls.seton theadmittedValueShapeViolationsmap it reads; that is a read of the field).MigrationFlagsHosttypes each member as the class member (ObjectQL['logger']and so on); each function'sthisis thePickof what it reads. The module imports the engine only as a type.export.MigrationFlagRead(the shape of onesys_migrationflag read) is the return type of two moved bodies and of members that stay. It stays declared inengine.ts, byte for byte, and gainsexportin place so the module can name it withimport type; no second copy, and no runtime import ofengine.ts.index.tsnames its exports singly, so the published.d.tsdoes not move (below).DATA_MIGRATION_FLAG_OBJECT, the three migration ids,ORGANIZATION_OWNERSHIP_SHAPE_GENERATION,organizationOwnershipShapeGenerationOf,isDataMigrationFlagVerifiedandhasMovedFileColumns(@objectstack/spec/system),ExecutionContext(type),IDataDriver(type,@objectstack/core),isMissingTableError,valueShapePostureSetByEnv,mediaPostureSetByEnvand the typeAdmittedValueShapeViolation.engine.tsdropsVALUE_SHAPES_MIGRATION_ID,ORGANIZATION_OWNERSHIP_MIGRATION_ID,ORGANIZATION_OWNERSHIP_SHAPE_GENERATION,organizationOwnershipShapeGenerationOf,hasMovedFileColumns,valueShapePostureSetByEnvandmediaPostureSetByEnv, whose last code readers moved (hasMovedFileColumnsis still named in a docblock that stays), and gains the module import with a three-line comment.Net lines (the seat's rule)
engine.tsgoes from 22,517 to 22,423 lines, net -94 (66 added, 160 removed). The module is 295 lines. With the two path readers below, the diff againstorigin/mainis 527 changed lines over 4 files (+364 / -163).Readers of the moved lines
objectql/src/engine.ts#NAMEpointer underpackages/spec/**,docs/adr/**,docs/qa/**,content/**orscripts/**names a moved member (ADR-0104's pointer namesisFileReferencesMigrationVerified, which stays). The prose that names them (check-durability-degradation-log-level.mjscomments, test headers,sql-driver.ts,seed-tenancy-backfill.ts,packages/spec/src/contracts/objectql-engine.ts) still resolves, because the methods stay on the class. No ADR anchor paragraph describes a moved body. No moved body readsisSystem(the two{ isSystem: true }literals are context construction, not reads;check-system-context-censuspasses unchanged at 153 read sites), holds aquery-options/no-any-erasuresite (8 at base and head), a tenant-audit untyped receiver, a.canReadObject(orreferenceTargetOf(call (the two core census pins), or anew Error(.isMissingTableErrorkeeps its two-argument form (driver-error-classification.callers.test.ts).check-adr-anchorsat base756220c4a(clean detached worktree): 91 anchored files, 1,877 decision-letter citations, 59,318 resolving citations across 8,374 files. At headc7df09f88: 91, 1,877, 59,321 across 8,375. No moved body comment cites a decision letter, and the module is not anchored, so the count is equal.Fold-ins (stale path readers of cut 12)
engine-realtime-publish.ts's header saidaccessibleOrganizationsOfstays inengine.ts; cut 12 moved it toengine-driver-options.ts. The sentence now says so (two comment lines).scripts/adr-anchors/packages__objectql__src__engine-execute-transactions.ts.json(cut 7) still carried the transaction-seam paragraph'sbuildDriverOptionshalf, whichengine-driver-options.ts's entry has carried since cut 12. That half now has one home, withbuildDriverOptions' body: this entry's invariant is now theengine.tsentry's text exactly (the opening sentence, theenforceTransactionOriginsentences and the "Never add a companion transaction" clause), with its file and three ids unchanged. The count above includes this edit.Tests
Published .d.ts identical (ruling 6348891160), with a positive control
Base:
@objectstack/objectqlbuilt withengine.tsrestored to756220c4a(bloba17c9e9b93e6checked) and the module removed; head built atc7df09f88; the tree restored and checked (git diff HEADempty, both blobs equal to HEAD).announceOpenMigrationGates.call(hostoccurs 0 times in the basedist/index.mjsand once in the head's. All six declaration files are byte-identical, and equal to the hashes cuts 7 to 12 recorded:core.d.mtsef178bf0725eccc2f358f082ce13dc5122a6d5a53c19ef630017256f67de03b4core.d.ts1d20303a455a909e4b55fd0802fb0b0bcb59ec51784daf27d5ef4c0659410953index.d.mtsccf900240aa137abe72f82b8abfc872d42c5645467400134c580285f2a3b3090index.d.ts0454d5e70b156d8effbf27b8915587c7cbee241dcd7d698013c0a4c369a02aa5util-CVzOGxAn.d.mts85ef1cbec2b016d5f7afabaa21689c86c6dffc573076fdfdeb8ea0f1a1b1ad53util-CVzOGxAn.d.ts85ef1cbec2b016d5f7afabaa21689c86c6dffc573076fdfdeb8ea0f1a1b1ad53Positive control:
scripts/ablation-replace.mjsdroppedprivatefrom thereadFileReferencesFlagRowstub (anchor hit once, 1 to 0; blob4e64ab23e37ato93b9d017a031) and rebuilt: all six hashes and the chunk name changed (util-BnUvXrEZ.d.ts8939a58e8fee…,index.d.ts63b9dacdf4c1…,core.d.tsb6d8ba14102d…), and the chunk now printsreadFileReferencesFlagRow()(returning aPromiseofMigrationFlagRead) as a public member. The tool restored the file (blob4e64ab23e37aequal to HEAD,git diff HEADempty); after a rebuild, all six files compared equal to the head build again.Proof of move-only (TypeScript-AST leaf-token compare)
pm-orders/server/evidence/25522/astcmp.mjs(unchanged from cuts 9 to 12), baseengine.tsagainst the head module:async:supplyTenantKeyCertifiedResolver97 tokens / 16 lines,isOrganizationOwnershipCertified166 / 19,readFileReferencesFlagRow19 / 7,isValueShapesMigrationVerified17 / 6,readMigrationFlagVerified232 / 37,noteAdmittedValueShapeViolation96 / 18,announceOpenMigrationGates201 / 40,wasDatastoreCreatedFromEmpty94 / 11.@objectstack/spec/systemimport less the five bindings above; the./validation/record-validator.jsimport lessvalueShapePostureSetByEnvandmediaPostureSetByEnv;interface MigrationFlagRead, nowexport interfacewith the same body. Head adds the module import.Late-binding probe for the setter (one-off, not committed)
pm-orders/server/evidence/25522/zz-probe-cut13.mjsdrives the builtdist/of base and head with instance doubles. Both runs print the same 28 lines (diff empty, apart from the engine's own creation log timestamps). The setter lines:announceOpenMigrationGates()on a fresh engine:engine.migrationGatesAnnouncedreadsfalsebefore andtrueafter (the write through the moved body is read back on the instance); a second call returns before reading the registry.engine.migrationGatesAnnounced = falseon the instance makes the next call run again; setting ittruemakes the next call skip;invalidateDataMigrationFlags()(stays in the class) resets it, and the next call runs.The rest:
announceOpenMigrationGatesreaches instance doubles ofobjectHasMediaField,objectHasCoveredValueFieldandreadMigrationFlagVerifiedand logs the media advisory; the two public flag readers reach an instancefindOnedouble once per memo slot with{ isSystem: true }and log their verified lines; a throwingfindOneand an absent ledger answer inconclusive;isOrganizationOwnershipCertifiedanswersfalseon a missing table and rethrows any other error; the resolversupplyTenantKeyCertifiedResolverhands a driver reaches anisOrganizationOwnershipCertifieddouble set on the instance AFTER the hand-over, and a driver that throws is logged at debug; the admitted-violation tally and its two deviation calls;wasDatastoreCreatedFromEmptyreads adriversmap replaced on the instance.Suites
At
c7df09f88:pnpm --filter @objectstack/objectql typecheck(tsc --noEmit+check:test-typecheck): VERDICT command-exit 0.pnpm exec eslint --no-inline-config packages/objectql: exit 0.pnpm --filter @objectstack/objectql exec vitest run --project local --maxWorkers=2: 472 files, 8,789 tests passed (VERDICT command-exit 0). The suites that drive these bodies (adr0131-tenant-key-certified-supply,value-shape-scan-advisory,sys-migration-single-row-route,adr0104-attestation-evidence,engine-find-missing-table-log-level,engine.test) are among them.vitest run --project repoin every package that has one, after the^...closure builds:core6/6 files (83 tests),objectql1/1 (5),rest5/5 (280 passed, 18 skipped),runtime3/3 (947),spec79/79 (1,279),types1/1 (11), all exit 0..d.tsfiles are byte-identical, so no dependant can see a difference. CI'sTypeScript Type Checkcovers them.Acceptance notes
packages/objectql/**. feat!: ownership queues and assignment rules (ADR-0142 phase 2) #26337 (ADR-0142 phase 2, heade45133760) editsengine.tsin nine hunks (an import near line 245, three declarations above the class, and theinsert/updatebodies); none is in the moved section, on the import lines this cut edits, or onMigrationFlagRead.git merge-tree --write-treeof this head with its head merges cleanly (exit 0). Under the card's rule 4 whichever lands second mergesmain. docs: TypeScript legacy node10 resolution is unsupported for the 15 packages with subpath exports #26378 editspackages/objectql/README.mdonly; feat(spec,cli)!: retire the ≤16.x retirement kits; the strict unknown-key refusal names the protocol upgrade guide #26138 editsvalidation/rule-validator.test.tsonly. No open PR touchesengine-realtime-publish.tsorscripts/adr-anchors/.supplyTenantKeyCertifiedResolverhands the driver() => this.isOrganizationOwnershipCertified();thisis now the host, whose member is a late-bound closure over the engine, so the call still lands on the engine's method (the probe sets a double after the hand-over and the resolver reaches it).this.findOne(...)keeps the engine as its receiver through the closure.this._registry.getObject(...),this.drivers.values(),this.admittedValueShapeViolations.get/set(...)andthis.logger.info(...)keep their own receivers.Verification
At
c7df09f88:dispatch-gates --commandsderived 64 families on the real diff. Every one was run, each exit code captured before any pipe, then reconciled with--ran: 64 accounted for, 63 run green, 1 NOT MEASURED (exit 3, PREREQUISITE NOT MET; CI runs it):check:dual-build-cjs-loads(needs every package'sdist/). Two first answered a shallow-clone prerequisite and were re-run green aftergit fetch --shallow-since=2026-07-22 origin main:check-engine-split-ratio --days 90andcheck-plugin-teardown-shape --self-test. Named readings:check:adr-anchorsOK,check:nul-bytes,check-engine-split-ratio --self-test,check:lean-entry-closure,check-affected-docs, all exit 0.check-adr-anchorsat base and head (above),check-system-context-census(153 read sites),check-tenant-audit-census(244 write sites certified, everyUNTYPED_RECEIVERSrow matched),check-adr-symbol-anchors(2,664 anchors resolve),check-platform-checklist --changed-from origin/main(13 anchors judged, 0 lost),check-commit-card-trailers --range origin/main..HEADandcheck-nul-bytes.engine.tsbytes and the same four files), the derivation named 111 families, because that branch's diff also carried cut 12's files; all 111 ran, 107 green and four answering PREREQUISITE NOT MET exactly as on cut 12 (shallow clone, client builds, every package'sdist/), among themcheck:query-options-erasure,check:engine-double-contract,check:type-check-debt,check:objectql-double-limitandcheck:where-matcher, all exit 0.origin/mainmoved eight commits after the cut (to7c70f91ce); none touchespackages/objectql/src/**,scripts/adr-anchors/**or the census scripts (the nearest is feat(spec,metadata-protocol,service-storage,runtime,cli)!: a seed record can carry a file the package ships, seedFile(path) #26244'spackages/specseed-file addition), so the branch is not merged with it here; CI runs the merge ref.Test Corefarm is CI's.skip-changeset: move-only. The published.d.tsfiles are byte-identical,liveness/and every other published path are untouched, and the module's runtime is the same code under a different file name. The other edits are one source comment and one anchor file.Human Minimum
packages/specholds no runtime logic. (Nopackages/specedit.)pnpm lintpasses (scoped:eslint --no-inline-config packages/objectql, exit 0).main, one pull request.skip-changeset.)packages/spectouched: its generated artifacts are regenerated and committed. (Not touched.)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01Wzm9du2KfnvCibhjZZYgyq
Generated by Claude Code