Repository navigation
refactor(driver-sql): move the declared column DEFAULT emission out of sql-driver.ts into sql-driver-schema-sync.ts (#25521 cut 19) - #26960
Conversation
…f sql-driver.ts into sql-driver-schema-sync.ts Cut 19 of the sql-driver.ts split. The bodies of nowColumnDefault and applyDeclaredColumnDefault move unedited into the existing seam module, through SchemaSyncHost, which already listed every member they read. The class keeps both methods as delegating stubs. MYSQL_DATETIME_PRECISION and isNowDefaultValue gain export in place; isRuntimeDefaultToken is now read only by the module. sql-driver.ts: 18,447 -> 18,406 lines. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEkQ5m67V6oBcEqg8yLDKL
📓 Docs Drift Check8 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. 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 c021a963e9d25a0160e2ef2bb7e4040363d01ca7 && git checkout c021a963e9d25a0160e2ef2bb7e4040363d01ca7
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin e269d3b652d9b160b81d37b467f3e5ae2ef919b1 79ca88b71ba1fec17bbf0f736ced9325b90de705 && git checkout -B drift-repro e269d3b652d9b160b81d37b467f3e5ae2ef919b1 && git merge --no-ff 79ca88b71ba1fec17bbf0f736ced9325b90de705
node scripts/docs-audit/affected-docs.mjs --json e269d3b652d9b160b81d37b467f3e5ae2ef919b1 |
Seat note: CI red on
|
席位核对ACCEPT · The maintainer's standing authorisation for landing reviewed PRs, verbatim: 「按照 pm-dispatch 规则复核过的都授权」.
Generated by Claude Code |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40607197983 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
Seat note: the merge-queue timeout is #26930's cost, not this PR's; re-queued2026-10-28T01:00Z ·
Generated by Claude Code |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 40613497338 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 分类: 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
Seat note: held for #27004 after a second queue timeout2026-10-28T01:35Z ·
Generated by Claude Code |
…ix for #27037) The case seeds RELATION_FILTER_ID_CAP (1,000) rows and deletes 1,001: 2.3 s alone, past the default 5 s on a loaded full-suite queue shard, which ejected #26960, #27011 and #27020 (#27037). The slowdown itself is #27004's (since #26930 a 1,001-row predicate delete is about 18x slower); this only budgets for it. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QUs3Bshfmr8srPY21BVS4u
Seat note: re-queued onto the fixed main ·
|
…ix for #27037) The case seeds RELATION_FILTER_ID_CAP (1,000) rows and deletes 1,001: 2.3 s alone, past the default 5 s on a loaded full-suite queue shard, which ejected #26960, #27011 and #27020 (#27037). The slowdown itself is #27004's (since #26930 a 1,001-row predicate delete is about 18x slower); this only budgets for it. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QUs3Bshfmr8srPY21BVS4u (cherry picked from commit 6674ba8)
Requested by Leehom · project thread
Part of #25521
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6270097840
Ruling-ref: 6348891160
维护者速读
sql-driver.ts里「字段默认值在建表语句里写成什么」这一个机制的两个方法体(nowColumnDefault:defaultValue: 'NOW()'在各数据库方言下的列默认值;applyDeclaredColumnDefault:判断一个字段的defaultValue该不该、以什么形式成为列默认值)原样搬进已有的sql-driver-schema-sync.ts;类上两个方法全部保留,只把方法体转交过去,SchemaSyncHost一个成员都不用加。src/sql-driver.ts(22,096 lines, +2,533 in 30 days) along itsSqlDriverseams, one move-only slice per PR #25521 拆分超大文件的第 19 刀;第 18 刀合入后重新测量,这是仍成「一个机制」、收益最大且不碰任何系列限制的区域,sql-driver.ts减少 41 行。sql-driver-schema-sync.ts头注释新增的第 19 刀段落与文件末尾两个函数;sql-driver.ts中两个方法的转交桩;sql-driver.ts里MYSQL_DATETIME_PRECISION、isNowDefaultValue两处就地加export。pnpm --filter @objectstack/driver-sql exec vitest run src/sql-driver-user-datetime-default-format.test.ts src/sql-driver-option-default-ddl.test.ts src/sql-driver-21241-mysql-now-default-precision.test.ts src/sql-driver-11550-dialect-client-spellings.test.ts,预期全部通过。What changes
Cut 19 of the
sql-driver.tssplit (#24586 ruling A, recorded in6270097840). The claim is6454724955. Cut 18 (#26894) merged first, as452325eed9; this cut opens with a fresh seam table taken onorigin/main4049efa345(below) and takes the largest area that is one mechanism and moves cleanly: the declared column DEFAULT emission, from the class'sInternal helpers › Column creation helpersub-banner. Its two bodies move unedited into the existing seam modulepackages/drivers/driver-sql/src/sql-driver-schema-sync.ts, through its hostSchemaSyncHost:nowColumnDefault, the driver-native column DEFAULT for adefaultValue: 'NOW()'field, per dialect and perdate/time/datetimetype (the UTC expression defaults of Field.time repeats the #3912 pattern: writes unnormalised, repaired only on read — window filters and ORDER BY are silently wrong on SQLite #3994 and Field.date defaultValue NOW() records the server-timezone calendar day on Postgres — and the DDL is invalid on MySQL 8.0 #4022, the MySQLDATETIME(3)precision of driver-sql on MySQL: a declared datetime field defaulting to NOW() gets a precision-less CURRENT_TIMESTAMP default on its datetime(3) column, so MySQL 8.0 refuses the table: sys_activity is never created and its data door answers 500 #21241, the canonical SQLitestrftimeforms);applyDeclaredColumnDefault, the one place that decides what a field'sdefaultValuebecomes in DDL (NOW()throughnowColumnDefault; a runtime token such ascurrent_useremits nothing, data: the SQL driver emits thecurrent_userframework token as a literal column DEFAULT, so the database itself writes a non-id into alookup('sys_user')#4560; an expression envelope emits nothing; a literal is emitted verbatim).The SQLite table rebuild that cut 6 moved into this module (
rebuildSqliteTablePatched) already reaches both throughSchemaSyncHost, which already lists both members and every member their bodies read, so the host does not grow.createColumn(pinned in place) andcreateAuditTimestampColumn, the other callers, stay in the class and still call the two methods on the driver.Module-level declarations. None moves. The bodies read three:
MYSQL_DATETIME_PRECISIONandisNowDefaultValueare declared insql-driver.ts, which still reads both (createAuditTimestampColumn,createColumn, the MySQL widenings). Each gainsexportin place, and the module imports them from./sql-driver.jsthrough its existing import line.index.tsnames its re-exports one by one and names neither, so the published surface does not move (measured below).isRuntimeDefaultTokencomes from@objectstack/spec/data. Its only reader insql-driver.tsmoved, so it leaves that import line (isNowDefaultTokenstays there), and the module adds it to its existing@objectstack/spec/dataimport.Knex.RawandKnex.ColumnBuilder, so the module gainsimport type { Knex } from 'knex';(erased;sql-driver-autonumber.tshas the same line).The change is move-only, and the card stays open for later cuts. There is no
docs/adr/**edit, nopackages/spec/**edit, no anchor entry change, no gate edit, no test edit and no new gate. Branchclaude/project-thread-1nvx81(the platform assigned it to this card thread, as the claim records). The move is one commit,fe7fb7ec5, on4049efa345, followed by one merge oforigin/main(aa00362fe5, 12 commits, none inpackages/drivers/**); the head is79ca88b71b.Net line count (the seat's rule).
sql-driver.tsgoes from 18,447 lines to 18,406: -41.sql-driver-schema-sync.jsimport, whose one line gains the two names. The@objectstack/spec/datatoken import and the twoexportadditions change lines in place.sql-driver-schema-sync.tsgoes from 2,066 to 2,148 lines (+82): the two functions with their one-line docblocks, a 13-line header paragraph and theknextype import.SchemaSyncHostis unchanged (80 members).Path readers. No test, script, doc, ADR or anchor entry reads either body by path, so none is migrated (screen below).
Serial with the file's in-flight PRs. I read the file list of every open PR on
objectstack-ai/objectstackat the start (39) and again before opening this one (30). None touchessql-driver.ts,sql-driver-schema-sync.ts,turso-driver.ts,sqlite-wasm-driver.ts,check-tenant-chokepoint.mjsor a driver-sql anchor entry; #26556 (dependabot) touches only the three drivers'package.json.Seam table, fresh, on
4049efa345sql-driver.tsis 18,447 lines. The 30-day column countsgit blamelines from commits on or after 2026-09-27T21:44:05Z, 30 days before the base commit.scripts/pm/git-history.mjs countproves 32 commits on the file in 30 days and 4 in the last 7 (first-parentorigin/main, history deepened to cover the window). In all, 3,412 lines (18.5%) are from the last 30 days.SqlDriverspans lines 4245-18372 with 350 members: 243 instance methods, 13 accessors and 32 statics, all 32 private or protected.!andsatisfiesbefore it readsthis. Sections are the class's own banner comments.name…assertDialectEmitsconnect…disconnectfind…deletebulkCreate…countrawStatementFault…noteRuntimeIndexDdlbeginTransaction…rollbackTransactionaggregate…unresolvableAggregateColumnRefusaldistinct…unresolvableDistinctColumnRefusalfindWithWindowFunctions…findWithWindowFunctionsexplain…analyzeQuerysyncSchema…reclaimSpacerotationStateByTable…migrateMysqlTimeColumnssetDeferredDdl…flushDeferredSchemaDdldialectName…createNullSafeUniqueIndexlistPhysicalColumns…introspectSchemagetKnex…auditMissingTenanttableNameForBuilder…applyFalseConstantmapSortField…mapAggregateFuncbuildWindowFunction…buildWindowFunctionnowColumnDefault…applyDeclaredColumnDefaultsqliteFilename…isJsonFieldformatInput…formatOutputintrospectColumnOrder…introspectUniqueConstraintsPricing the areas
Eligibility is as cuts 11-18 defined it: an annotated return type or not public; no
getBuilder,this.FIELD.delete/insert/update(, private-static,super, bare-thisorthis-write site; notinsertOnlyUpsertColumns; not a member pinned in place (createColumn,applyFilterCondition,formatInput/formatOutput,initObjects,ensureShardTable,computeTenantField,migrateMysqlDatetimeColumns/migrateMysqlTimeColumns,compileFilters). Each area is priced as its stubs minus its bodies, then net of the module-level declarations only it reads and of its import edits. The two leading rows were measured by running the move script on a scratch copy of the base file; the rest are the stub estimate (a stub costs 4 lines, +2 per field read, +1 per method read).Cut 18 priced the largest clean single area at about -62, naming two candidates: the class head's date-bucket/query-timing pair and the column-creation remainder. Re-measured, neither is one mechanism: each -62 is the sum of a sub-banner's movable members, the same kind of sum as the filter-helper remainder this series does not stitch. So I priced mechanism by mechanism.
nowColumnDefault-39,applyDeclaredColumnDefault-4)exportin place); +2 for the import commentbuildDateBucketExpr)dateGranularityCapabilitiesaccessor andsqliteTemporalArg/temporalFieldKind, all of which stay.updateWithPresumedTimestamp-31,resolveUpdatedAtColumnPresence-6)attemptWithoutPoisoningis shared with the autonumber module and is a separate mechanism.schemaBytesPerChar-9,rethrowWithRowSizeExplanation-2,decorateHashShadowDuplicate-8)buildDateBucketExpr-42,installQueryTiming-20)presentReadValue-29)compileFilters(-75) is refused (inferred return type).Internal helperstenant members (auditMissingTenant-26,applyTenantScope-25,getBuilder-5,injectTenantOnInsert-2)applyTenantScopeholds 2 of the file's 4 D8 predicates andgetBuilderis the builder itself, whichcheck:tenant-chokepointreads only insql-driver.ts(series limit).buildWindowFunction), field mapping (orderKeysFor), database helpers (ensureDatabaseExists,sqliteFilename)Why
Why this area, as one area
defaultValuebecome in the DDL of a fresh or rebuilt column", andapplyDeclaredColumnDefaultis how a declared field'sNOW()reachesnowColumnDefault. They go beside the SQLite rebuild that already calls both through the host. The other callers ofnowColumnDefault(the audit-column DDL, the MySQL datetime widening, the rebuild's audit columns) still call the method on the driver.createAuditTimestampColumn(its stub would cost more than its body) and the rest of theColumn creation helpersub-banner: the hash-shadow and varchar-width members read private statics,createColumnis pinned, and the row-size and hash-shadow explanations are other mechanisms.getBuilder, reads a static, has athis.FIELD.delete/insert/update(site, usessuperor a barethis, or assigns tothis. Both are protected with annotated returns (Knex.Raw,void).check:tenant-chokepoint's D8 predicates, measured with its ownnullArmsOf: 4 at base and 4 at head, all insql-driver.ts, 0 in the moved bodies.tryor callslogDurabilityFailure.check:durability-log-level --listprints 164 lines at both ends, identical except that tworunWideningAltersseams insql-driver.tsmove 2 lines down (the import comment).TursoDriverandSqliteWasmDriveroverride neither method;remote-transport.tsnamesapplyDeclaredColumnDefaultin prose, which is still true. Tests that widen the class (the CLI'sgenerate-declared-column-default.pin.test.tsoracle and four driver-sql suites) callthis.nowColumnDefault(type)on a subclass instance, which still reaches the same body.sql-driver.ts#…pointer or asql-driver.ts::…key, and noscripts/adr-anchors/**record names them. ADR-0053 namesnowColumnDefaultin prose, still true.The shape (#23050 shape B, as cuts 1-18 apply it)
NAME.call(host, ...), marked[#25521 cut 19]. Both methods are synchronous at both ends, so a failure is still a synchronous throw (probe reading 7).nowColumnDefaultreads (isMysql,isPostgres,isSqlite,knex) go as GETTERS that read the driver at call time. The methodapplyDeclaredColumnDefaultcalls (nowColumnDefault) goes as a closure that calls the method on the driver at call time. So a subclass override, an instance spy, or a field replaced after construction is still the one the body reaches (probe readings 2, 5, 6).[#25521 cut 19]paragraph saying what moved, what stayed and where each read declaration comes from. Thesql-driver.tsimport comment names cut 19 in 2 lines. Neither cites anADR-NNNNletter. Both stubs keep their docblocks (which mention ADR-0074 and data: the SQL driver emits thecurrent_userframework token as a literal column DEFAULT, so the database itself writes a non-id into alookup('sys_user')#4560/[finding]SelectOption.defaultis an authorable key that nothing on the insert path ever reads — the select idiom is inert #7246) insql-driver.ts.Verification
ADR anchors
check:adr-anchorscounts 1897 decision-letter citations at base4049efa345(a clean detached worktree) and 1897 at the move commit, over 91 anchored files at both ends; the two outputs are byte-identical. Both runs exit 0.check:adr-symbol-anchors: 2687 resolve at both ends (output byte-identical).mainmoved under the cut, and its own commits changed the count, so I measured its tipaa00362fe5(a clean detached worktree) against the merge head79ca88b71b: 1896 letters at both, exit 0 both, and 2687 symbol anchors resolve at both.The published
.d.tsdoes not changeThis is measured under the series bar (ruling
6348891160, item 1).pnpm turbo run build --filter=@objectstack/driver-sql --forceat each end, against the same dependency tree. The base leg writes basesql-driver.tsand basesql-driver-schema-sync.tsinto this worktree under an EXIT/INT/TERM trap that restores HEAD. The restore is proved by the HEAD blob hashes, an emptygit diff HEADand 0 status entries (RESTORE-OK 1084637988… 8b345d7a5c…).dist/index.d.tsanddist/index.d.mtsis the same at base, at the move commit and at the merge head:0f33bf3febaac3c7aa96f68a4226d752766b8203ab7acade523b69f9aaa44d74(unchanged since cut 8). These two are the dist's only declaration files (no chunk), so the declaration-reorder bar of ruling6441032442does not come into play.protectedfromnowColumnDefaultin a copy of the headindex.d.ts(1 hit, then 0). The copy hashes toae5be4b2d6abbda6d50b0c513af286406f61d5d9e9a97a53c8da4d4d0a7b3359, withcmpexit 1.requireof each dist gives 59 names (sha105757ce5aeat both ends); the ESM namespace ofindex.mjsgives the same 59 at both ends (sha105757ce5ae). Neither moved function, neither newly exported declaration and notSchemaSyncHostis among them..call(hostsites inindex.mjsgo from 67 at base to 69 at head (the two stubs).Move-only proof
The proof compares TypeScript compiler AST leaf tokens (JSDoc nodes skipped), base
4049efa345against the move commitfe7fb7ec5. It is a scratch script and is not committed.thisnowColumnDefaultapplyDeclaredColumnDefaultasyncat either end.sql-driver.ts. 175 of 180 base statements are byte-identical; the other five are the class, the two edited imports (the spec token import losesisRuntimeDefaultToken; the schema-sync import gains two names and its 2-line comment), andMYSQL_DATETIME_PRECISIONandisNowDefaultValue, each checked to gain a leadingexportand nothing else.@objectstack/spec/dataimport (isRuntimeDefaultTokenadded) and the./sql-driver.jsimport (isNowDefaultValueandMYSQL_DATETIME_PRECISIONadded). The head adds theknextype import and the two functions.SchemaSyncHostis byte-identical.PROOF OK, exit 0; on the merge head its output is byte-identical.scripts/ablation-replace.mjs, I changed(cast(utc_timestamp() as date))to(cast(utc_timestamp() as datez))in the module'snowColumnDefault(anchor 1 hit, then 0, checked on disk). The proof then reportsnowColumnDefaultas differing, printsPROOF FAILED, and exits 1. The restore was proved (blob8b345d7a5cequals HEAD, emptygit diff HEAD).Tests
Each end ran under one
os-verify-lockhold, after building that end's driver-sql dist. I compared the vitest JSON per test name and status, base4049efa345against the move commitfe7fb7ec5, and then the merge head79ca88b71bagainst the same base. Every part's exit code was captured on its own (build, probe, three suites: all 0 at every leg).@objectstack/driver-sql@objectstack/driver-turso, against that end's built driver-sql dist@objectstack/driver-sqlite-wasmOn the merge head (it brings in
mainup toaa00362fe5: 12 commits, none inpackages/drivers/**), the three suites give the same totals and the same per-test statuses as base, 0 / 0 / 0 in each. Since thenmainhas moved 11 more commits to40264beec4, none inpackages/drivers/**;git merge-tree --write-treeof the head with it exits 0, so the tree is not stale.tsc --noEmit -p .in driver-sql exits 0 on the move commit and on the merge head.pnpm exec eslint --no-inline-config packages/drivers/driver-sqlexits 0 (driver-sql has nolintscript of its own).nowColumnDefaulton SQLite, PostgreSQL and MySQL drivers (never connected) fordate,time,datetimeand two non-temporal types;isSqliteandisPostgresgetters (the overrides are the ones read);knexreplaced on the instance after construction, then restored;applyDeclaredColumnDefaulton all three dialects over 13defaultValueshapes (absent,null, twoNOW()spellings and a barenow,current_userin two cases, an expression envelope, a string,0,false, a decimal, an array) for three types, with a recording column builder, and with no field at all;nowColumnDefault(it is the oneapplyDeclaredColumnDefaultreaches);nowColumnDefault(likewise);knexunset): a synchronousTypeError;initObjects: the stored column defaults (PRAGMA table_info) and a defaulted row's shapes for declaredNOW()datetime/date/time fields, literals,current_user,false, an option-leveldefault, and the audit columns;rebuildSqliteTablePatched) after a re-initObjectsthat adds a literal default and aNOW()column;_SqlDriver.nowColumnDefaultat base andObject.nowColumnDefaultat head. That is shape B's receiver, the same at every earlier cut, and no test or consumer reads it. On the merge head the probe output is byte-identical to the move commit's.test:repo. Not run locally; it is CI's run on this PR.Gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderives 48 families for this diff, the same list on the move commit and on the merge head (and the same 48 cuts 17 and 18 derived). I ran each one on its own and captured its exit code before any pipe, after a fullpnpm buildof that tree (116 of 116 tasks).fe7fb7ec5: 48 run, all 48 exit 0.--ranreconciles:48 derived famil(ies) accounted for — 48 run, 0 NOT-MEASURED, exit 0. (I fetched the pinned fixture commit ofcheck-plugin-teardown-shape.mjs --self-testinto this shallow clone first.)79ca88b71b: 48 run, all 48 exit 0 (after a second fullpnpm build, 116 of 116).--ranreconciles the same way, exit 0.check-adr-anchors,check-adr-symbol-anchors,check-tenant-audit-census(244 write call sites),check-platform-checklist --changed-from origin/main,check-commit-card-trailers --range origin/main..HEAD,eslint --no-inline-config packages/drivers/driver-sql,check-durability-degradation-log-level --list. In a clean detached worktree at base4049efa345and on the move commit,check-adr-anchors,check-adr-symbol-anchors,check-tenant-audit-censusandcheck-object-def-param-keysprint byte-identical output, andcheck-durability-degradation-log-level --listprints the same seams, line numbers aside.check:object-def-param-keyscompares 7 override parameter positions over 3375 files with every control firing;check:tenant-chokepointreads 24getBuilder()bindings across 3 files;check:durability-log-levelreads 48 durability-critical catch seams and 88 read seams;check:dual-build-cjs-loadsloads 112 entry points across 69 packages;check:driver-conformancescores 55 covered cells).The 48 derived commands:
node scripts/check-closing-keyword-parity.mjs,node scripts/check-closing-keyword-parity.mjs --self-test,node scripts/check-comment-mask-adoption.mjs,node scripts/check-comment-mask-adoption.mjs --self-test,node scripts/check-comment-mask-corpus.mjs,node scripts/check-dts-emitted.mjs --self-test,node scripts/check-issue-citations.mjs,node scripts/check-plugin-teardown-shape.mjs,node scripts/check-plugin-teardown-shape.mjs --self-test,node scripts/ci/assert-turbo-remote-cache.mjs --self-test,node scripts/ci/plan-test-core-shards.mjs --self-test,node scripts/ci/prune-turbo-cache.mjs --self-test,node scripts/docs-audit/check-affected-docs.mjs,node scripts/docs-audit/check-drift-comment.mjs,pnpm --filter @objectstack/spec run check:duration-unit-keys,pnpm check:ci-filter-parity,pnpm check:closed-ceremony-text,pnpm check:cross-package-test-inputs,pnpm check:dispatcher-error-vocabulary,pnpm check:doc-authoring,pnpm check:driver-conformance,pnpm check:driver-memory-census,pnpm check:dts-closure,pnpm check:dual-build-cjs-loads,pnpm check:durability-log-level,pnpm check:error-status-conformance,pnpm check:gitlink-declared,pnpm check:issue-citations,pnpm check:keyed-text-bounds,pnpm check:lean-entry-closure,pnpm check:logger-receiver-detach,pnpm check:nul-bytes,pnpm check:object-def-param-keys,pnpm check:org-identifier,pnpm check:page-declaration-shape,pnpm check:platform-object-tenancy-census,pnpm check:published-files,pnpm check:refd-timer-probe,pnpm check:registry-log-declared,pnpm check:rest-log-spy-declared,pnpm check:slot-lookup,pnpm check:sourcemap-no-sources-content,pnpm check:system-context-census,pnpm check:tenant-chokepoint,pnpm check:test-source-alias,pnpm check:tier-file-adoption,pnpm check:undeclared-dep-imports,pnpm check:watch-hint-literal.Acceptance notes
check:tenant-chokepoint'sSCAN_FILESdoes not listsql-driver-schema-sync.ts. The moved bodies hold 0 of the file's 4 tenant predicates and build no query (they return aknex.raw/knex.fn.now()expression or calldefaultToon a column builder). Noted, not filed: wideningSCAN_FILESwould be a gate change.sql-driver.tshas the same 30{@link X}sites (21 names) that are neither a top-level binding nor aSqlDrivermember at base and at head (the name set is identical). One moved line comment innowColumnDefaultsays{@link canonicalTimeOfDay}; in the module that name is not a binding, so the module's own count of such sites goes from 10 to 11. It is a//comment, which no tool resolves, and it moved byte-identical.buildDateBucketExpr, about -39 with a new module's import) and the presumed-timestamp update (updateWithPresumedTimestampwithresolveUpdatedAtColumnPresence, about -35). Everything else is -28 or less per mechanism (window function builder -28,orderKeysFor-27, database helpers -27, the four filter-helper mechanisms -29 or less), or blocked by a series limit (the tenant members).Human Minimum
packages/specchange.SchemaSyncHostis unchanged, and two module-level constants gainexport(not re-exported byindex.ts).eslint --no-inline-configpasses (repo-widepnpm lintis CI's run).main, one pull request.skip-changeset; both declaration lines above.packages/specnot touched.Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_01FEkQ5m67V6oBcEqg8yLDKL