Repository navigation
refactor(driver-sql): move applyIndexDriftOp and restoreBareIndexAfterFailedTighten into sql-driver-schema-sync.ts (#25521 cut 8) - #26169
Conversation
…estore into sql-driver-schema-sync.ts Move-only. The bodies of the protected SqlDriver#applyIndexDriftOp and SqlDriver#restoreBareIndexAfterFailedTighten move unedited (re-indented one level) into sql-driver-schema-sync.ts beside cut 6's pair. The class keeps both methods as stubs that hand the moved function the SchemaSyncHost members it reads; the host grows by exactly those seven members. The ADR-0120 D4 paragraph of the sql-driver.ts anchor entry follows the apply-side body into a new anchor entry for sql-driver-schema-sync.ts. Claude-Session: https://claude.ai/code/session_0155UnTppT9uLobphwpxhiZu Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 13 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 5150b9b2e0a632e0743f8ce4c607e5291603e101 && git checkout 5150b9b2e0a632e0743f8ce4c607e5291603e101
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 365fe5ecc4a1f7157186d8053cd721d2384e3f56 68fc94704d0833d5b3a6f1395969c2bfd22a0584 && git checkout -B drift-repro 365fe5ecc4a1f7157186d8053cd721d2384e3f56 && git merge --no-ff 68fc94704d0833d5b3a6f1395969c2bfd22a0584
node scripts/docs-audit/affected-docs.mjs --json 365fe5ecc4a1f7157186d8053cd721d2384e3f56
|
席位核对ACCEPT · The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」.
Generated by Claude Code |
Requested by Leehom · project thread
Part of #25521
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6270097840
Ruling-ref: 6348891160
Cut 8 of the
sql-driver.tssplit (#24586 ruling A, recorded in6270097840). The claim is6417688620; this is the slice cuts 6 and 7 both proposed (Release6417590425). The bodies of the protectedSqlDriver#applyIndexDriftOp(one index drift op, every dialect) andSqlDriver#restoreBareIndexAfterFailedTighten(the ADR-0120 restore it runs when a NULL-safe tightening cannot be created after the old index is gone) move unedited intopackages/drivers/driver-sql/src/sql-driver-schema-sync.ts, beside cut 6'sapplyDriftOpInPlaceandrebuildSqliteTablePatched. They reach the class through that module's existing host,SchemaSyncHost, widened by exactly the seven members these two bodies read and nothing else. Both methods keep their name, docblock, signature (lessasync) and position.The ADR-0120 D4 paragraph of the
sql-driver.tsanchor entry follows the apply-side body into a new anchor entry forsql-driver-schema-sync.ts(below). Nodocs/adr/**edit, nopackages/spec/**edit, no new gate.It is move-only, and the card stays open for the later cuts. Branch
claude/project-thread-wbvc9p(platform-assigned to this card thread, as the claim records). One commit,68fc9470, onorigin/maina335f1def.Net line count (the seat's rule from ACCEPT
6385306916).sql-driver.tsgoes from 21,431 lines to 21,334: -97. The two bodies are 122 lines out (105 + 17); the two stubs are 24 lines in (15 + 9); the schema-sync import comment gains one line (+1). The module grows 227 to 372 lines.Serial with the file's in-flight PRs. Re-measured at my start: 32 open PRs, each file list read in full (the two over 100 files paged to the end: #26138, 343 files, none under
packages/drivers/**; #25640, the Version Packages PR, onlyCHANGELOG.mdandpackage.jsonfor the driver packages). None touchessql-driver.ts,sql-driver-schema-sync.tsor the driver-sql anchor entries.The area, measured on
a335f1defapplyIndexDriftOpis lines 14776-14882 ofsql-driver.ts(105 body lines);restoreBareIndexAfterFailedTightenis lines 14893-14914 (17 body lines). Callers:applyMigrationEntries(class) and cut 6'sapplyDriftOpInPlacebody (module, through its host closure) callapplyIndexDriftOp; onlyapplyIndexDriftOp's body calls the restore.getBuilder(the only knex use isthis.knex(op.table).columnInfo()), socheck:tenant-chokepointrule 1 is untouched, and neither has a.raw(/.where(site, so rule 2 visits exactly what it visited.thisread. Thethisreads areknex,logger,syncDeclaredIndexes,getExistingIndexNames,dropIndexIfExists,dropOrphanedHashShadowColumn,probeNullSafeUniqueDuplicates,logDurabilityFailureandrestoreBareIndexAfterFailedTighten(the restore reads four of those). Nothis.FIELD.delete/insert/update(site, soUNTYPED_RECEIVERSdoes not move.TursoDriverandSqliteWasmDriveroverride neither (turso-driver.tsnamesapplyIndexDriftOponce, in a comment). One test subclass callsapplyIndexDriftOpthroughthis(sql-driver-13056-orphan-shadow-column-cleanup.test.ts), which still reaches the class method. No script, doc or ADR names either method by path.The shape (#23050 shape B, as cuts 1-7 apply it)
async. Its body is one host literal plusNAME.call(host, ...), marked[#25521 cut 8], and it returns the moved function's own promise.knexandloggergo as GETTERS that read the driver at call time; the seven methods go as closures that call the method on the driver at call time. So a subclass override, an instance spy, or aknex/loggerreplaced after construction is still the one the body reaches (probe below).thisas thePickofSchemaSyncHostover the members it reads, and each stub annotates its literal as theThisParameterTypeof the moved function. No cast, and no member becomes public.SchemaSyncHostgainsdropIndexIfExists,dropOrphanedHashShadowColumn,getExistingIndexNames,logDurabilityFailure,probeNullSafeUniqueDuplicates,restoreBareIndexAfterFailedTightenandsyncDeclaredIndexes, each typed as the class member's indexed access, in the interface's alphabetical order.knex,loggerandapplyIndexDriftOpwere already there.DriftOptype, which the module already imports fromschema-drift.ts. No declaration gains anexport;index.tsre-exports nothing from the module, andsql-driver.tsdrops no import.[#25521 cut 8]paragraph; thesql-driver.tsimport comment names cut 8.The ADR anchor follows the body
check:adr-anchorscounts decision-letter citations on the anchored surface (each anchor'sinvariantplus the full text of each anchored file). The moved bodies carry threeADR-0120 D4citations (the ceremony comment and the refusal text inapplyIndexDriftOp, the restore's error text); the restore's docblock citation stays on the class.scripts/adr-anchors/packages__drivers__driver-sql__src__sql-driver.ts.json: theADR-0120 D4: …sentences leave itsinvariantandADR-0120leaves itsadrs. TheADR-0053paragraph is untouched.scripts/adr-anchors/packages__drivers__driver-sql__src__sql-driver-schema-sync.ts.json:adrs: ["ADR-0120"], and itsinvariantis those D4 sentences, byte-identical.a335f1defand at head68fc9470; anchored files 88 to 89; both runs exit 0.sql-driver.ts: the plan-side duplicate pre-flight (applyNullSafeUniquePreflight,probeNullSafeUniqueDuplicates) and theGLOBAL_TENANTkey fold, which that paragraph also describes. The file still citesADR-0120on 29 lines (10 of themADR-0120 D4), but no anchor entry names it for ADR-0120 any more. Raised to the seat in the report as an open question; this PR follows the claim's wording.The published
.d.tsdoes not changeUnder the series bar (ruling
6348891160, letter A). Each end built withpnpm turbo run build --filter=@objectstack/driver-sqlagainst the same dependency tree; the base leg restores the base text of the two source files in this worktree after the commit, under an EXIT/INT/TERM trap that restores HEAD (proved by HEAD blob hashes, an emptygit diff HEADand 0 status entries).dist/index.d.tsanddist/index.d.mts; the two are identical at both ends.5028e040e1501b0bd72b91fafcf4e1cb372393c59baa5bab8b936b240dd2d3f5(cut 7's hash),cmpidentical.index.d.tswithprotecteddropped fromapplyIndexDriftOp(line 5606) hashes toe5e7a31c2fd4231d94f0a95af3c6e7e7b49225b6c1538a86528e7c9bc20fefa7, a 4-line diff,cmpexit 1.requireand ESMimportof the built dist): 56 / 56 names at both ends, identical..call(hostsites inindex.mjs19 at base, 21 at head.Move-only proof
TypeScript compiler AST leaf tokens (JSDoc nodes skipped), base
a335f1defagainst head68fc9470, scratch script, not committed:applyIndexDriftOp: body 502 tokens, 0 differ; 46 comments identical; parameters lessthis3 tokens, 0 differ; return type 4 tokens, 0 differ;asyncon both; 107 body lines, each the base line less two leading spaces.restoreBareIndexAfterFailedTighten: body 132 tokens, 0 differ; 1 comment identical; parameters lessthis15 tokens, 0 differ; return type 4 tokens, 0 differ;asyncon both; 19 body lines, each the base line less two leading spaces.async.sql-driver.tstop level: 207 to 207 statements, 205 byte-identical; the two that differ are the schema-sync import (with its comment) and the class.sql-driver-schema-sync.ts: the 5 base statements become 7; 3 byte-identical, the 2 that differ are the import carrying the module header andSchemaSyncHost; the 2 new ones are the moved functions.PROOF OK, exit 0. Negative control (REFUSING to rebuildtoREFUSING to rebui1din a module copy): 1 token and 1 line differ,PROOF FAILED, exit 1.Tests
Each suite under its own
os-verify-lockhold, vitest JSON compared per test name and status, basea335f1defagainst head68fc9470:@objectstack/driver-sql@objectstack/driver-turso(against that end's built driver-sql dist)@objectstack/driver-sqlite-wasmpnpm exec tsc --noEmitin driver-sql: exit 0.pnpm exec eslint --no-inline-config packages/drivers/driver-sql/src: exit 0, 268 files, 0 errors, 0 warnings.diffempty). It covers theunbuildable_indexearly return with noknexread;create_indexthrough aknexreplaced on the instance after construction;replace_unique_indexboth ways, the skipped create warning on aloggerreplaced after construction;recreate_indexrefused over duplicates through an instance spy onlogDurabilityFailure, applied on clean data, its create throwing (an instance spy on the restore reached with the cause, the restore's error logged, the rejection rethrown) and its create silently absent (a subclass override of the restore reached with an undefined cause); the restore whose own re-create fails (the NOT enforced message, the cause passed as meta);drop_indexrunning the index half before the shadow half; anullop answering aTypeErrorrejection, never a synchronous throw, from both methods; and thedefaultarm.test:reponot run locally (the diff touches no repo-project test; CI's Test Core runs it).Gates
Local, head
68fc9470.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(change set vs merge basea335f1def, 4 paths): 65 commands, each exit captured before any pipe. 62 exit 0 on the first run.check-plugin-teardown-shape.mjs --self-testexit 3 (shallow clone) then exit 0 aftergit fetch origin 621a4876(its positive control).check:lean-entry-closureexit 3 (no objectql dist) then exit 0 afterpnpm turbo run build --filter=@objectstack/objectqlunder the lock.check:dual-build-cjs-loadsexit 3, PREREQUISITE NOT MET (needs every package's dist): NOT MEASURED locally, CI runs it.--ran: "65 derived famil(ies) accounted for — 64 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)", exit 0.a335f1defand head at68fc9470, exit 0 at both ends:check:adr-anchors: 88 to 89 anchored files; 1879 decision-letter citations at base and at head.check:adr-symbol-anchors: 2658 anchors resolve at both.check:tenant-chokepoint: 24getBuilder()bindings across 3 files at both; rule 2 clean at both.check:logger-receiver-detach: 0 detaches at both (3731 non-test TS files walked at base, 3732 at head, where the base worktree lacks the gitignored generated spec registry; theloggergetter keeps the receiver).check:driver-conformance: 55 covered, 0 DEBT, 0 exempt at both.node scripts/check-tenant-audit-census.mjs: 243 write call sites certified, everyUNTYPED_RECEIVERSrow matched, at both.check:nul-bytes,check:commit-card-trailers.check-platform-checklist --changed-fromnot owed (no exported symbol renamed or deleted).origin/mainmoved 9 commits (tod00215f68) while this ran; none touchespackages/drivers/**,scripts/adr-anchors/**orcheck-adr-anchors.mjs,git merge-treeagainst it is clean, anddispatch-gates --commandsderives the same 65-command list there. Not merged: CI tests the merge ref.Acceptance notes
sql-driver.tsis gone with this cut (see above); the residual plan-side mechanism there is named in the report'sopen_questionsfor the seat.SqlDriverareas are the seat's to pick.skip-changeset: move-only, nothing a published package ships changes (the.d.tsis byte-identical; the emitted JS runs the same bodies through the host).Generated by Claude Code