Skip to content

refactor(drivers)!: 五个驱动的 query 参数跟进 DriverQuery,休眠的类型谎言没有藏身处 (#6075) - #6210

Merged
os-zhuang merged 3 commits into
mainfrom
claude/issue-6075-driver-query-signatures
Aug 7, 2026
Merged

os-zhuang merged 3 commits into
mainfrom
claude/issue-6075-driver-query-signatures

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #6075

这单是什么

#5181(PR #6076)把 IDataDriver 的六个 query 方法收窄为 DriverQuery(Omit< QueryAST, 'object' >)。那条 changeset 自己写明了收尾未做:「把驱动签名一并迁到 DriverQuery 是后续的机械收尾」。这就是那次收尾。

前提复核(实测 origin/main @ 80f7dc6,行号以实测为准)

issue 正文的行号已漂移,以下为实测:

  • 契约侧成立:packages/spec/src/contracts/data-driver.ts:40 导出 DriverQuery,:141 :167 :195 :211 :214 :345 六个方法都已声明它。
  • 驱动侧成立:memory 5 处、mongodb 6 处(另 2 处私有辅助)、sql 6 处(其中 explain 是 any)、turso 5 处 any;sqlite-wasm 自身 0 处 —— SqliteWasmDriver extends SqlDriver,签名随基类走,本 PR 不需要动它的源码。
  • 休眠性成立:git grep 'query\.object' origin/main -- 'packages/drivers/*/src' 零命中。issue 要求复核的这一条仍然成立 ⇒ 今天没有人踩,这是休眠的类型谎言,不是活体缺陷。

反向验证 —— 方向预判:红(预判写在动手之前)

本单的全部价值就是让「驱动读 query.object」变成编译错误,所以预判是标准的「把删掉的肢体装回去 ⇒ 变红」。两个方向都真跑了:

after(收窄后),在 SqlDriver.find 里临时写一行 query.object:

src/sql-driver.ts(2297,54): error TS2339: Property 'object' does not exist on type 'DriverQuery'.

before(对照:把同一个签名改回 QueryAST,探针保留),TS2339 消失——谎言在收窄前编译得干干净净。该轮剩下的 134 条全部是 TS2345,来自已重拼的 fixture 被改回去的宽签名拒绝,与探针无关。

探针已删除(git diff 中零残留)。

新增的 pin 文件 sql-driver-query-signature.test.ts 也做了同样的非幻影验证:把 find 改回 QueryAST 后它四条断言全红,且第一条按方法逐个报名:

src/sql-driver-query-signature.test.ts(53,10): error TS2322: Type 'string' is not assignable to type 'never'.
src/sql-driver-query-signature.test.ts(63,7): error TS2578: Unused '@ts-expect-error' directive.
src/sql-driver-query-signature.test.ts(72,5): error TS2578: Unused '@ts-expect-error' directive.
src/sql-driver-query-signature.test.ts(79,11): error TS2322: Type 'DriverQuery' is not assignable to type 'QueryAST'.

改了什么

非测试改动 100% 是类型注解,无逻辑、无行为、无 emit 差异(git diff 里 4 个源文件共 33 增 32 删,逐行都是签名)。

六个契约方法:find / findOne / count / updateMany / deleteMany / explain。turso 的 query: any 一并收紧。

跟着必须动的私有辅助方法(都只转发或读 where / orderBy / groupBy,本来就不读 object;不动它们则公有方法传参处直接类型不通):

包 辅助方法 说明
mongodb buildFindOptions / buildSortSpec 只读 fields / orderBy
sql findRows / orderKeysFor 只读 orderBy / limit / offset
turso toRemoteQuery / toRemoteReadQuery 只重写 where、拼 orderBy
memory performAggregation 见下

sql-driver.ts 的 QueryAST import 收窄后已无使用者(余下两处是散文里的 QueryASTSchema),一并删除。

收窄不只是消除谎言:实测降了一批类型债

check:type-check-debt 的全仓 re-measure 在本分支报出一批下降项。门禁明说下降不必付记账代价(「an improvement must not have to pay a bookkeeping toll to land」),所以台账未动;但这是本单的实际收益,值得记一笔:

ℹ @objectstack/driver-mongodb: TEST_DEBT records 43, tsc now reports 10 (-33)
ℹ @objectstack/objectql:       TEST_DEBT records 355, tsc now reports 344 (-11)
ℹ @objectstack/rest:           TEST_DEBT records 163, tsc now reports 153 (-10)
ℹ @objectstack/mcp:            TEST_DEBT records 63,  tsc now reports 53  (-10)
ℹ @objectstack/lint:           TEST_DEBT records 42,  tsc now reports 32  (-10)
ℹ @objectstack/service-storage: DEBT records 52,      tsc now reports 42  (-10)
ℹ @objectstack/runtime:        TEST_DEBT records 227, tsc now reports 223 (-4)

只有 driver-mongodb 的 −33 做了归因验证,其余未归因(它们可能早于本分支就已下降,我没有度量,不替它们邀功)。mongodb 这一条是掀掉 tsconfig 的测试排除后直接对照量的:

状态 测试层原始错误数
origin/main 的 mongodb-driver.ts(query: QueryAST) 43
本 PR 的 mongodb-driver.ts(query: DriverQuery) 10

原因很直接:mongodb 的测试里本来就有一批只递 where / fields 的 query 字面量,在 QueryAST 必填 object 的年代它们全是错误、被冻在 TEST_DEBT 里;收窄之后它们本来就该编译通过了。

冻结面口径与一处需要维护者过目的判断

按认领评论的第三档口径,memory / mongodb 一并收紧,且硬约束是只允许改签名类型。全程遵守,但有一处值得单独说明,请复核:

memory-driver.ts 的私有 performAggregation(records, query: QueryInput) 只解构 { groupBy, aggregations }、从不读 object,但 QueryInput 把 object 列为必填,于是 find 收窄后传参报 TS2345。处理方式是把它改成 Omit< QueryInput, 'object' > —— 镜像掉同一个键,不改其余任何松紧度,因此它仍是纯签名类型改动,没有动逻辑、没有动行为、没有动断言,符合硬约束。之所以不写成 DriverQuery:那会连带收紧 groupBy 的元素类型(输入形 vs 输出形),超出「只搬走 object 这一个键」的范围。若维护者认为冻结面连这一处都不该动,我可以把 memory 半边整体拆出。

Fixture 三类处置(不是一把批量重拼)

收窄触发 399 处 TS2353,逐处按其守的是什么来判:

  1. 重拼(绝大多数):driver.find(X, { object: X, where }) 里的 object 就是 [spec] IDataDriver 的 query 参数要求 QueryAST.object 与第一实参重复 —— 下游被迫 as any(20 处实测),提议 Omit/optional 化 #5181 说的冗余——第一个实参已经是对象名。删键。每一处都核对过删掉的值与第一个实参相等(脚本比对,零处不等),所以不存在「测试原本靠 AST 的 object 覆盖实参」的情况。
  2. 恢复(误伤,已修回):blanket 改写误删了 turso-driver.ts 测试里 syncSchemasBatch([{ object, schema }]) 的 object,以及 memory-driver.test.ts 里 distinct(obj, field, query: QueryInput) 的 object。这两个不是被收窄的六个方法,其中 syncSchemasBatch 的 object 是被真实读取的必填键。已逐处放回。
  3. 换承载类型:turso-local-remote-null-parity.test.ts 整份用 as QueryAST 拓宽字面量喂 find / count,删键后该 cast 自相矛盾(TS2352)。cast 目标改为 as DriverQuery,与形参对齐。remote-transport-text-predicates.test.ts 的局部 helper where: unknown 同理收成 DriverQuery['where']。

expand 条目里的 object 命名的是关联对象、不是冗余,tsc 也不会标它(expand 值仍是 QueryAST)——已确认驱动测试里没有这类站点,未被波及。

⚠️ 方法论订正:消费半径要用前缀省略号,别抄第一版

本 PR 第一版把消费半径扫反了方向,CI 因此真红过一次(@objectstack/dogfood#typecheck)。记在这里,免得后来者照抄错命令。

pnpm 的省略号是有方向的:

写法 含义 用途
--filter 'pkg...'(后缀) 该包 + 它依赖的包(上游闭包) ❌ 第一版误用了这个
--filter '...pkg'(前缀) 该包 + 依赖它的包(下游消费者) ✅ 签名收窄要的是这个

签名收窄打到的是下游——那些拿具体驱动类、写内联 { object, where } 字面量的调用方。所以第一版报告里「25 个包全绿」扫的全是上游依赖,真正的消费者(@objectstack/dogfood 等)一个都没进扫描面,结论完全不成立。

正确做法,且以全仓为准(CI 跑的就是全仓,别再用局部闭包下结论):

pnpm typecheck --concurrency=2        # turbo,125 个任务,与 CI 同面
# 或按下游闭包定位:
pnpm --workspace-concurrency=2 --no-bail \
  --filter '...@objectstack/driver-memory' --filter '...@objectstack/driver-mongodb' \
  --filter '...@objectstack/driver-sql'    --filter '...@objectstack/driver-sqlite-wasm' \
  --filter '...@objectstack/driver-turso'  typecheck

(注意 typecheck 在 turbo 里 dependsOn: ["^build"],走 turbo 会自己把依赖建好;直接用 pnpm 递归则不会,新 worktree 里容易撞上 AGENTS.md §9 的陈旧产物陷阱。)

⚠️ 而且全仓 pnpm typecheck 仍然不够 —— 排除了测试的包要靠台账闸门才量得到

修完 dogfood 之后全仓 pnpm typecheck 是 125/125 绿的,CI 却仍红在 check:type-check-debt:

• @objectstack/plugin-auth: TEST_DEBT records 131 raw tsc error(s), `tsc --noEmit` now reports 132 (+1).

原因是 plugin-auth 的 tsconfig 把 **/*.test.ts 排除掉了,per-package tsc --noEmit 根本看不见它的测试层;只有台账闸门的全仓 re-measure 会把排除掀掉重量。所以「驱动签名收窄」这类会波及测试字面量的改动,验证面必须是 pnpm typecheck + pnpm check:type-check-debt 两条,缺一条就会像这次一样漏。

定位到的就是一处,改法照上面第 3 类:

src/auth-where-operator-coverage.test.ts(383,7): error TS2353:
  Object literal may only specify known properties, and 'object' does not exist in type 'DriverQuery'.
// FROM
const left = await driver.find('sys_user', { object: 'sys_user', fields: ['id'] } satisfies QueryAST);
// TO —— 删掉的值与第一个实参逐字相同
const left = await driver.find('sys_user', { fields: ['id'] } satisfies DriverQuery);

保留 satisfies 而不是改成 as any,是尊重该处原有的意图:它上方的注释写明「这里不能用 as any,否则会被 check:query-options-erasure(#4674/#4918)记一笔」。只换承载类型,意图不变。

⛔ 未抬台账数字。 门禁原话是「the ledger is a ratchet and may only shrink」(#5278),而这 +1 是本单自己引入的、属可约。改完复测回到 131,与台账记录一致,check:type-check-debt EXIT=0。

下游实际改了什么

文件 站点数 编译强制?
packages/qa/dogfood/test/storage-growth.dogfood.test.ts 8 1 处是(:260,cold 是真实 SqlDriver),7 处走 DriverLike
packages/qa/dogfood/test/group-key-read-shape-parity.test.ts 1 否
packages/qa/dogfood/test/empty-group-bucket-parity.test.ts 1 否
packages/plugins/plugin-auth/src/auth-where-operator-coverage.test.ts 1 是(仅台账闸门可见)

dogfood 那 9 处非强制的走本地结构替身 DriverLike.count(object, query?: Record< string, unknown >),任何键都收、类型层看不见;一并按同一规矩删掉,避免同一个文件里两种写法并存、诱导后人「修回去」。

每处删键的相等性核对结论:11/11 全部相等,零处不等。 dogfood 那 10 处不是靠肉眼——用的是带反向引用的模式,只有 query 里的值与第一个实参逐字相同时才匹配:

s/(\.(count|find)\((['A-Za-z_]['A-Za-z_0-9]*), )\{ object: \3 \}/\1{}/g

等价性由模式本身保证,不相等的站点根本不会被匹配到。dogfood 包里其余的 { object: ... }——权限授予(publicFormGrant)、端点策略入参(objectParams)、report.swept 条目、以及 interface 里的类型声明——因此一处未被波及。plugin-auth 那处是单点,肉眼核对 'sys_user' vs 'sys_user'。

⛔ 未为了让下游过而放松任何驱动侧签名。

顺带记一条反面教材(本 PR 未触,属其他包):packages/objectql/src/engine-unknown-option.test.ts:183 的 engine.find('task', { object: 'person' } as any) 是故意让两者不相等的拒绝测试。任何按「见 object: 就删」的批量清扫都会毁掉它——这正是必须逐处核对相等性、而不是无脑 sweep 的原因。

验证

typecheck   全仓 pnpm typecheck --concurrency=2
              → Tasks: 125 successful, 125 total(EXIT=0)
debt ratchet pnpm check:type-check-debt
              → --re-measure: OK — 34 ledger entr(ies) re-measured, 2017 raw tsc error(s) total,
                none above its recorded number(EXIT=0)
              修复前:• @objectstack/plugin-auth … 131 → 132 (+1),EXIT=1
test        memory      17 files, 524 passed
            mongodb     10 passed | 5 skipped, 206 passed | 137 skipped(skip 需真实 MongoDB)
            sql         66 passed | 4 skipped, 910 passed | 46 skipped(含新增 pin 的 4 条)
            sqlite-wasm 18 files, 254 passed
            turso       24 files, 788 passed
            dogfood     86 files: 85 passed | 1 skipped, 520 passed | 3 skipped
            plugin-auth 38 files, 967 passed
gates       check:driver-conformance / check:query-options-erasure /
            check:empty-changeset / check:type-check-coverage /
            check:spec-parsed-alias / check:nul-bytes  → 全 PASS
eslint      改动的源文件零 error/warning

冻结面 memory / mongodb 测试全绿,即是零行为变化的证据。

验收 grep:

$ grep -rn "query: QueryAST" packages/drivers/*/src --include=*.ts
packages/drivers/driver-mongodb/src/mongodb-driver.ts:468:  async aggregate(...)
packages/drivers/driver-sql/src/sql-driver-query-signature.test.ts:15:  (散文引用)

六个方法上归零。aggregate 不在 IDataDriver 里(distinct 同理),不是本单范围。

Changeset

.changeset/driver-query-signatures-follow-through.md,五个驱动包 major,依据与 #5181 同一条:源码级破坏性(调用点内联字面量会 TS2353),运行时行为零变化。sqlite-wasm 自身虽无源码改动,但它继承 SqlDriver,公开类型面同样变了,故一并列入。check:api-surface 只记录导出存在与否、不记录签名,所以这条 changeset 是该变更唯一的下游载体——这一点也是 #5181 的原话。

@objectstack/dogfood 是 private 的 QA 包、不发布,plugin-auth 的改动只在测试文件、无公开面变化,两者都不进 changeset。

顺带记录的发现(均未认领、observation-class)

并行注记

PM 标注 #5907(聚合函数信封)同批在飞,触 sql-driver.ts 的聚合区与 remote-transport.ts。本 PR 的面是签名区与 turso-driver.ts,remote-transport.ts 一个字未动,零重叠;后落地者 rebase。

#5181 (PR #6076) 把 IDataDriver 的六个 query 方法收窄为 DriverQuery
(Omit<QueryAST, 'object'>),但五个驱动的实现仍声明 query: QueryAST
(turso 侧是 query: any)。方法参数按双变比较所以它不红,可调用方现在
有权省略 object —— 实现的类型说 query.object 是 string,运行期却可能
是 undefined。这是休眠的类型谎言,不是活体缺陷:实测五个驱动没有一个
读 query.object。

把六个契约方法 (find/findOne/count/updateMany/deleteMany/explain) 的
query 参数统一为 DriverQuery,并跟进少量只转发 where/orderBy/groupBy
的私有辅助方法。收窄后「驱动读 query.object」成为编译错误 (TS2339)。

零运行时改动:非测试改动 100% 是类型注解,无逻辑、无行为、无 emit 差异。
测试面按 #5181 的迁移说明逐处重拼 —— 删掉调用字面量里冗余的 object 键;
syncSchemasBatch 条目与 distinct 的 QueryInput 不在收窄范围,保持原样。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyvqvKMG6asi9aXjKE6xtx
@vercel

vercel Bot commented Aug 7, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 7, 2026 11:43am

Request Review

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/driver-memory, @objectstack/driver-mongodb, @objectstack/driver-sql, @objectstack/driver-turso.

15 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/data-modeling/drivers.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb, @objectstack/driver-sql, @objectstack/driver-turso)
  • content/docs/deployment/cli.mdx (via @objectstack/driver-turso)
  • content/docs/deployment/environment-variables.mdx (via @objectstack/driver-turso)
  • content/docs/deployment/self-hosting.mdx (via @objectstack/driver-turso)
  • content/docs/deployment/vercel.mdx (via @objectstack/driver-memory)
  • content/docs/getting-started/glossary.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb, @objectstack/driver-sql, @objectstack/driver-turso)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb, @objectstack/driver-sql)
  • content/docs/permissions/authentication.mdx (via @objectstack/driver-memory)
  • content/docs/plugins/anatomy.mdx (via @objectstack/driver-sql)
  • content/docs/plugins/index.mdx (via @objectstack/driver-memory)
  • content/docs/plugins/packages.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb, @objectstack/driver-sql, @objectstack/driver-turso)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/driver-sql)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/driver-sql)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb, @objectstack/driver-sql)
  • content/docs/releases/implementation-status.mdx (via @objectstack/driver-memory, @objectstack/driver-mongodb, @objectstack/driver-sql)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

上一版的消费半径扫描用了 `--filter 'pkg...'`(后缀省略号 = 该包 + 它
依赖的包,上游闭包),方向扫反了:签名收窄打到的是**下游**消费者。
真正该用的是前缀形 `--filter '...pkg'`,或者直接以全仓 `pnpm typecheck`
为准(CI 跑的就是全仓)。@objectstack/dogfood 因此没进上一轮扫描面。

全仓复扫命中一处真实编译错误:storage-growth.dogfood.test.ts:260 的
`cold.count(...)`,`cold` 是真实的 SqlDriver,内联字面量里的冗余
`object` 被收窄后的 DriverQuery 拒绝。

同包另有 9 处同形调用未被 tsc 标出 —— 它们走本地结构替身
`DriverLike.count(object, query?: Record<string, unknown>)`,任何键都收,
类型层看不见。一并按同一规矩删除,避免同一文件里两种写法并存。

删键用的是带反向引用的模式,只在 query 里的值与第一个实参**逐字相同**
时才匹配,等价性由模式本身保证;dogfood 包里其余 `{ object: ... }`
(权限授予、端点策略入参、report 条目、类型声明)因此一处未被波及。

⛔ 未放松任何驱动侧签名。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyvqvKMG6asi9aXjKE6xtx
check:type-check-debt 的全仓 re-measure 报 plugin-auth 从 131 涨到 132
(+1)。plugin-auth 的 tsconfig 把 **/*.test.ts 排除在外,所以 per-package
`pnpm typecheck` 看不见它,只有把排除掀掉的全仓 re-measure 量得到。

定位到的就是一处:

  src/auth-where-operator-coverage.test.ts(383,7): error TS2353:
    Object literal may only specify known properties, and 'object'
    does not exist in type 'DriverQuery'.

`driver.find('sys_user', { object: 'sys_user', fields: ['id'] } satisfies
QueryAST)` —— 删掉的值与第一个实参逐字相同,属重拼类。承载类型按第三类
处置改为 `satisfies DriverQuery`:该处上方注释明确写了「这里不能用 as any,
否则会被 check:query-options-erasure (#4674/#4918) 记一笔」,所以保留
satisfies、只换目标类型,正是它原本的意图。

⛔ 未抬台账数字:门禁原话「the ledger is a ratchet and may only shrink」
(#5278),本单是自己引入的 +1,属可约。改完复测回到 131,与台账记录一致。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyvqvKMG6asi9aXjKE6xtx
@os-zhuang
os-zhuang marked this pull request as ready for review August 7, 2026 11:57
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit d367f03 Aug 7, 2026
26 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-6075-driver-query-signatures branch August 7, 2026 12:09
os-zhuang pushed a commit that referenced this pull request Aug 7, 2026
- `find()` 调用去掉 `object` 键:#6210 把驱动查询参数收窄为 `DriverQuery`,
  对象名只由第一个实参给出。没有用 `as any` 绕过——拒收类测试一旦用越契约的
  输入构造查询,就不再是在验证调用方真能发出的形状。
- 反向验证计数重测:LIKE 臂停用 → 8 failed / 40 passed;成员臂停用 →
  4 failed / 44 passed(此前记的 32 / 36 是首写时对 40 个测试测的)。失败数
  两次都不变,是承重的那一半;通过数随邻测增删而漂移,已在注释里说明。
- 补记 analytics 侧同法实测:两个门回退到 main 版本 → 17 failed / 41 passed,
  而 `like-metacharacter-escape.test.ts` 在该回退下保持绿——它锁的是两包谓词
  之间的一致,拒收文件锁的是门确实调用了谓词,两者都需要。

Refs #5234

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyvqvKMG6asi9aXjKE6xtx
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Oct 7, 2026
…ts that decided them (stage 10 of objectstack-ai#20595) (objectstack-ai#21546)

Part of objectstack-ai#20595
Clause-②: no

## What changed

Stage 10 of the `domain:engine` lane of the dead-citation sweep:
`packages/drivers/driver-turso/**`, comment and docblock prose only, per
the claim (`5965451347`). Stages 1 to 9 landed as `a7d9768ec`,
`d150c3039`, `4bf4e7e70`, `13a24ece2`, `db0cf2231`, `85986144c`,
`48fa7a381`, `c205b6c35` and `c98a72d69`. objectstack-ai#20595 stays open: the other
half of this lane is the packages this stage does not touch
(`drivers/driver-mongodb` 9, `formula` 4, `metadata-fs` 2 on the census
after this stage, 15 in all), plus the test-string sites the card
carries for a widened stage.

Every comment or docblock site in the package that cited a tracker
number answering 404 is rewritten in ruling C+D's form C (record
`5749154545` on objectstack-ai#19123): the ADR when one records the decision,
otherwise the commit in this repository's history that made it. That is
**50 sites on 49 lines in 12 files, covering 13 numbers**:

- **14 census sites** (13 lines, 2 files under `src/`): the whole
`allocated-but-absent` population of the gate's own census in this
package at the base. `turso-driver.ts:2131` carries two of them (objectstack-ai#6076
and objectstack-ai#6075);
- **36 test-comment sites** (36 lines, 10 test files), which the census
defers. They carry 12 numbers: 7 the census itself reads as dead in this
package's `src` (objectstack-ai#6075, objectstack-ai#12380, objectstack-ai#14428, objectstack-ai#14438, objectstack-ai#16570, objectstack-ai#16711, objectstack-ai#17690),
and 5 that stand only in test files here (objectstack-ai#14434, objectstack-ai#17590, objectstack-ai#17876,
objectstack-ai#17879, objectstack-ai#17970), which the board and a single read each settle;
- **no site outside the census glob**: `vitest.config.ts`,
`tsconfig.json`, `package.json`, `README.md` and `LICENSE` cite no dead
number.

No comment-id citation is dead here: the package's two comment ids,
ruling records `5865693155` and `5861435168` (`remote-transport.ts:38`,
`:4152` to `:4153`, `turso-20444-empty-operator.test.ts:8`), both answer
200 (see Census).

**Anchors: 13 numbers by commit, 0 by ADR, 0 by repository qualifier; 12
distinct shas** (objectstack-ai#17690 and objectstack-ai#17876 share `be5c60291`: the squash of PR
objectstack-ai#17876, whose message opens 「Part of」 objectstack-ai#17690). 12 numbers reuse the
anchor stage 4 (`driver-sql`) measured for them; `ca3fd4b1a` (objectstack-ai#14428) is
measured here.

Only comments changed. Every file keeps its line count (49 lines out, 49
in, plus the changeset), so no line citation into any of them moves. No
code token moves (the guard below). All 98 changed lines open with a
comment marker. **No citation number is added**: on every changed line
the numbers on the new text are a subset of those on the old (the only
numbers on `+` lines are objectstack-ai#5181, objectstack-ai#6210 twice, objectstack-ai#6212, objectstack-ai#13878 and objectstack-ai#20987,
each already on its line and each answering 200).

**A `patch` changeset**: all 13 rewritten non-test lines are in the
published `dist` (the `.d.ts` keeps JSDoc on exported members, and
esbuild keeps these comments in the JavaScript), and `dist` is not
byte-identical with the base text (see Changeset).

## H0: the package and its size

The gate's own `node scripts/check-issue-citations.mjs --census --json`
at base `31d2255f5` (the before run below), `allocated-but-absent` per
remaining `domain:engine` package:

| package | before | after this stage |
|---|---|---|
| `drivers/driver-turso` | **14** | **0** |
| `drivers/driver-mongodb` | 9 | 9 |
| `formula` | 4 | 4 |
| `metadata-fs` | 2 | 2 |
| `metadata-core`, `core`, `metadata-protocol`, `objectql`, `metadata`,
`drivers/driver-sql`, `drivers/driver-memory`,
`drivers/driver-sqlite-wasm`, `plugins/plugin-pinyin-search`,
`platform-objects` | 0 each | 0 each |

The lane total goes 29 to 15. `driver-turso` is the largest remaining
package and reads 14, as at stage 9's head census (`99f2cfdf0`), so the
stage went ahead.

## Census: `driver-turso`, before and after

**Instrument (A1).** The gate's own `node
scripts/check-issue-citations.mjs --census --json`, read-only and
unchanged. The count is its `allocated-but-absent` findings under
`packages/drivers/driver-turso/`.

| reading | tree | board | whole-repo `allocated-but-absent` | sites |
lines | files | numbers |
|---|---|---|---|---|---|---|---|
| before | base `31d2255f5`, run 04:20:17Z to 04:23:32Z | enumerated,
194 pages, frontier objectstack-ai#21537, 19,358 records | 144 | **14** | 13 | 2 | 8 |
| after | `841405134`, run 04:32:36Z to 04:35:47Z | enumerated, 194
pages, frontier objectstack-ai#21539, 19,360 records (newest number read before and
after the run: objectstack-ai#21539) | 130 | **0** | 0 | 0 | 0 |

The whole-repo drop is 14, and the two finding sets differ by exactly
the 14 rows of this package, removed; none was added. `resolves`
(35,495), `resolves-as-pull-request` (2,388) and `cross-repo-unjudged`
(1,247) did not move.

The head's later commits are the changeset and one merge of `main`. The
census was run a third time at the head `e89bd10cd` (04:53:10Z to
04:56:16Z, 194 pages, frontier objectstack-ai#21544, 19,365 records, newest objectstack-ai#21543
before and objectstack-ai#21544 after): whole-repo 130, `driver-turso` 0. Against the
after run, 5 rows moved line (all in `packages/spec`, shifted by the
merged `main` commit `48eb9c193`), and the finding multiset with line
numbers set aside is identical. Its `resolves` reads 35,509, 14 more
than above, from the merged `main` commits outside this package.

**Supplementary instrument, the whole package.** The census reads
neither test files nor strings nor files outside `src`. A second reading
runs the gate's own exported `extractCitations` (whole-file and
comment-prose projections) over every tracked file in the package (102)
and classifies each citation with the gate's `classifyCitation` against
one board enumerated by the gate's `enumerateBoard` (194 pages, frontier
objectstack-ai#21537, 19,358 records, read 04:24:21Z to 04:27:29Z), the same board for
both readings. Every one of the 13 numbers was then read on its own over
the issues endpoint (04:29:27Z): **all 13 answer 404**; the numbers that
stay on changed lines (objectstack-ai#5181, objectstack-ai#6210, objectstack-ai#6212, objectstack-ai#13878, objectstack-ai#20987) and the lit
controls objectstack-ai#15280, objectstack-ai#12585 and objectstack-ai#6402 answer 200.

| reading | citations | dead | src comment | test comment | other files
| test string | changelog |
|---|---|---|---|---|---|---|---|
| before, `31d2255f5` | 1,921 | **83** | 14 | 36 | 0 | 6 | 27 |
| after, `841405134` | 1,871 | **33** | 0 | 0 | 0 | 6 | 27 |

The citation count drops by 50, the 50 rewritten sites; no respelling
stays a citation. The live counts did not move (src comment: 522
resolve, 80 as pull requests, 8 cross-repo; test comment: 609, 75 and
6). A third, raw reading (every `#` followed by 2 to 6 digits, whatever
surrounds it, `CHANGELOG.md` aside) counts 1,558 before and 1,509 after,
and the URL-spelled issue links go 7 to 6: also a drop of 50.

**Comment ids.** Every ten-digit run under
`packages/drivers/driver-turso` (its `CHANGELOG.md` aside) was read:
five lines. `5861435168` (the record of ruling B on objectstack-ai#20311) and
`5865693155` (the record of ruling A on objectstack-ai#20399) answer 200 (the control
`5965451347`, the claim, answers 200 too).
`remote-canonical-backfill.ts:357` is an epoch-seconds example, not a
citation.

## Per-number table

`src` counts census sites, `test` the test-comment sites. Every sha
matches exactly one commit (`git rev-parse --disambiguate`, count 1), is
an ancestor of the base `31d2255f5` and of `origin/main` (`git
merge-base --is-ancestor`, exit 0 for all 12 on both; the clone is not
shallow), and resolves over the commits endpoint. The `+` lines carry
exactly these 12 nine-hex spans as new ones. Each commit names the
number it replaces, in its message, its diff or both: 7 in the message
and the diff (objectstack-ai#6075, objectstack-ai#12380, objectstack-ai#16570, objectstack-ai#17590, objectstack-ai#17690, objectstack-ai#17879, objectstack-ai#17970), 3
in the diff alone (objectstack-ai#14428 for `ca3fd4b1a`, objectstack-ai#14438 for `2200f8ec8`,
objectstack-ai#16711 for `7862fb711`), and 3 only in the subject's squash suffix
(objectstack-ai#6076 for `6513c1749`, objectstack-ai#14434 for `93940d492`, objectstack-ai#17876 for `be5c60291`),
where the dead number was that pull request's own and the commit is its
squash. `git blame` at the base puts 24 of the 49 changed lines on their
anchor; the other 25 were written by a commit that cites the number as
an earlier decision (`242eb0ac1`, `9f4a6d55f`, `9bfbacbf8` and
`6bd3231f6` citing objectstack-ai#12380; `3cbcedb62` and `e35c40a52` citing objectstack-ai#14438;
`fa2d3b737` citing objectstack-ai#6075 and objectstack-ai#6076; `5ba2ec3ca` citing objectstack-ai#17690;
`862f12c0b` citing objectstack-ai#17590; `2200f8ec8` citing objectstack-ai#14428; `ca3fd4b1a` citing
objectstack-ai#14434; `7862fb711` citing objectstack-ai#16570; `eb9334915` citing objectstack-ai#17876), and in
each case the anchor is the commit that made the change the sentence
credits to the number. `source` says whether stage 4 already used this
anchor for this number (`reused`) or it was measured here (`measured`).

| number | src | test | anchor | kind | source | what it decided |
|---|---|---|---|---|---|---|
| `objectstack-ai#6075` | 1 | 1 | `d367f03d6` | commit | reused (stage 4, stage 5) |
five drivers' `query` parameters follow `DriverQuery`; its turso diff
narrows `count`'s `query` and leaves `options?: any`, the half-narrowed
state both sites describe. It is the squash of PR objectstack-ai#6210, the live number
kept beside it |
| `objectstack-ai#6076` | 1 | 0 | `6513c1749` | commit | reused (stage 4) |
`IDataDriver`'s `query` parameter becomes `DriverQuery` (that pull
request's squash) |
| `objectstack-ai#12380` | 2 | 6 | `4045b954d` | commit | reused (stage 4) | make the
SQLite `Field.json` codec injective, one encoding across all three
dialects: the local half's codec every site credits |
| `objectstack-ai#14428` | 2 | 3 | `ca3fd4b1a` | commit | measured | `update()` on a
missing id answers `null` on Turso's remote face; it wrote the
`RemoteTransport.update()` docblock and the
`turso-update-missing-id.test.ts` header the sites carry, and declared
that door's record-or-null return |
| `objectstack-ai#14434` | 0 | 1 | `93940d492` | commit | reused (stage 4, stage 5) |
declare the not-found arm on `IDataDriver.update()` (that pull request's
squash) |
| `objectstack-ai#14438` | 2 | 5 | `2200f8ec8` | commit | reused (stage 4) |
`update()` publishes the contract's record-or-null, not `any`, on
`SqlDriver` and on `TursoDriver`'s override (the squash of PR objectstack-ai#15280) |
| `objectstack-ai#16570` | 1 | 1 | `b72226f48` | commit | reused (stage 4) | declare
the `indexes` key `initObjects` / `registerObjectMetadata` already read
|
| `objectstack-ai#16711` | 1 | 3 | `7862fb711` | commit | reused (stage 4, stage 3) |
object-definition parameters declare the keys they are read for, plus
the gate that sees subclass overrides; it wrote
`TursoDriver.initObjects`'s docblock and
`turso-driver-16711-init-objects-param.test.ts` |
| `objectstack-ai#17590` | 0 | 1 | `e04a0aff2` | commit | reused (stage 4, stage 5,
stage 8) | compile `$contains` on a JSON column as a per-dialect
MEMBERSHIP test |
| `objectstack-ai#17690` | 4 | 4 | `be5c60291` | commit | reused (stage 4) | eight
more `IDataDriver` doors publish their declared return type,
`TursoDriver`'s overrides among them; its message records the
transaction door left un-narrowed because each of the two repairs is
「neither of which is an annotation swap」, with the 「+14 further consumer
sites」 measurement, the sentence `turso-driver.ts:3549` cites |
| `objectstack-ai#17876` | 0 | 3 | `be5c60291` | commit | reused (stage 4) | that pull
request's squash, which installed the `ContainsAny` detector |
| `objectstack-ai#17879` | 0 | 6 | `eb9334915` | commit | reused (stage 4) | measure
the `ContainsAny` phantom-leg sweep across eight door pins; its message
records that both repair candidates were measured |
| `objectstack-ai#17970` | 0 | 2 | `47e6601c5` | commit | reused (stage 4) | collapse
`ContainsAny`'s distributivity so union-shaped doors assert |

No ADR or ruling record names any of the 13 numbers as the place their
decision is recorded; ADR-0104 names objectstack-ai#12380 in passing, and `4045b954d`
is the change these sites describe.

## Wordings to check

Most rewrites swap a tag in place (`[#N]` to `[commit SHA]`, `(#N)` to
`(commit SHA)`, `with #N` to `with commit SHA`, stage 1's form). These
say more than the tag:

- **Squash rewrites, stage 4's spellings**: 「objectstack-ai#5181 (PR objectstack-ai#6076), objectstack-ai#6075 (PR
objectstack-ai#6210)」 became 「objectstack-ai#5181 (commit 6513c17), commit d367f03 (PR objectstack-ai#6210)」
(`turso-driver.ts:2131`): the dead pull-request number gives way to its
squash, and the dead card number to the commit that landed its fix with
the live pull-request number kept beside it as a convenience link, stage
4's 「Commit 2200f8e (PR objectstack-ai#15280)」 form. 「objectstack-ai#6075 (PR objectstack-ai#6210) narrowed」
became 「commit d367f03 (PR objectstack-ai#6210) narrowed」
(`turso-driver-options-door.test.ts:21`). 「Since objectstack-ai#13878 (PR objectstack-ai#14434)」
became 「Since objectstack-ai#13878 (commit 93940d4)」
(`turso-update-missing-id.test.ts:20`). 「`ContainsAny` (objectstack-ai#17876)」 became
「`ContainsAny` (commit be5c602)」 on three test lines.
- **Reports**: 「the two measured repairs are in the objectstack-ai#17879 report」
became 「the two measured repairs are in commit eb93349's message」
(three test files), stage 4's spelling; that message records that both
candidates were measured.
- **`pre-` spellings**: 「restoring the pre-objectstack-ai#12380 SQLite `json` branch」
became 「restoring the SQLite `json` branch from before commit 4045b95」
(`remote-transport.ts:2612`), and 「The pre-objectstack-ai#12380 form of the string
'bare'」 became 「The form of the string 'bare' from before commit
4045b95」 (`turso-local-json-backfill-depth-limit.test.ts:72`), stage
4's 「from before commit」 form.
- **A URL-spelled citation**: 「@see
objectstack-ai#12380 (the
injective local codec)」 became 「@see commit 4045b95 (the injective
local codec)」 (`turso-json-column-type-asymmetry.test.ts:84`), stage 4's
「@see commit e04a0af (the membership construct)」 form. The three
`@see` links beside it (objectstack-ai#12738, objectstack-ai#12586, objectstack-ai#11535) resolve and stay.
- **The acceptance-criteria reference**: 「(objectstack-ai#16711 验收口径 item 4)」 became
「(验收口径 item 4 of the card commit 7862fb7 closed)」
(`turso-driver-16711-init-objects-param.test.ts:105`), stage 4's wording
for the same sentence in `driver-sql`'s twin test, verbatim. Neither the
card nor PR objectstack-ai#16816 resolves any more, so 「closed」 rests on stage 4's
reading and on `7862fb711` itself: its diff names objectstack-ai#16711 32 times and
creates this test file, and its message records the TS2353 negative
control this paragraph introduces.
- **Sentence and bullet starts**: where the number opened a sentence, a
bullet or a header, the new text opens with 「Commit」: 「Commit
4045b95's codec still runs」
(`turso-json-column-type-asymmetry.test.ts:259`), 「- Commit b72226f's
`indexes` fix」 (`turso-driver-16711-init-objects-param.test.ts:17`), 「//
Commit 2200f8e — 」 (`turso-driver-update-declared-null.test.ts:3`) and
「⛔ Commit 7862fb7 — this parameter type must declare every key」
(`turso-driver.ts:3689`). 「* commit 4045b95 had to defeat」
(`turso-json-column-type-asymmetry.test.ts:46`) stays lower-case: it
continues 「the measured … exposure that」 from the line above.
- **A tag over a paragraph that says 「this card」**:
`turso-driver-doors-declared-types.test.ts:117` now opens 「[commit
be5c602]」, and its line 119 still says 「every door on this card had
regressed to」. That line carries no number, so it was not touched; it
now reads as the card behind the commit in the tag (`be5c60291`'s
message opens 「Part of」 that card).
- **The commit that wrote the file**:
`turso-driver-update-declared-null.test.ts:3` and `:11` cite
`2200f8ec8`, the commit that created that test file. Its subject is
「feat(driver-sql,driver-turso): `update()` publishes the contract's …
not `any`」, so it is both the override fix the header names and the
`SqlDriver.update()` narrowing line 11 credits.
- No line was reflowed, so some are longer than their block's wrap
(`eslint.config.mjs` declares no line-length rule, and a reflow would
move neighbouring lines and every line citation into the file).

## Sites left

- **In comments (src, test, outside the glob): none.**
- **String literals: 6 test-string sites, 4 numbers, 4 files**: the
`describe` titles at `turso-driver-16711-init-objects-param.test.ts:67`
(objectstack-ai#16711), `turso-driver-update-declared-null.test.ts:85` (objectstack-ai#14438) and
`turso-update-missing-id.test.ts:141` and `:223` (objectstack-ai#14428), and two
assertion-message strings at
`turso-json-column-type-asymmetry.test.ts:266` and `:291` (objectstack-ai#12380). All
four numbers are in this stage's table. Strings are outside this stage's
surface; non-test strings cite none.
- **Outside `src`:** the release-owned `CHANGELOG.md` names dead numbers
on 27 sites (11 numbers); left.

## Mechanical guard: no code token moves

The guard (stages 2 to 9's, copied verbatim from stage 9) compares base
`31d2255f5` against the tree over all 12 touched files, with TypeScript
6.0.3:

- **Reading 1**: the parser's leaf nodes, from a `forEachChild` walk.
Comments are trivia there, and JSDoc is never visited. A leaf that is
not itself a token is re-scanned with trivia skipped.
- **Reading 2**: the full token stream in parser context, from a
`getChildren` walk, JSDoc nodes skipped. String, template and numeric
literals are compared in full on both readings.

Results, at `841405134` (the later commits touch none of the 12 files):

- Real run: 38,590 base tokens, **0 files with a token change** (exit
0).
- Comment control (「Keep it that way」 to 「KEEP it that way」,
`turso-driver.ts`): 0 files changed (exit 0).
- Positive control, an identifier (`export class RemoteTransport` to
`XRemoteTransport`, `remote-transport.ts`): DIFFER on both readings
(exit 1).
- Positive control, a string literal (the assertion message 「… for an
existing id」 to 「… for an existing iD」,
`turso-update-missing-id.test.ts`): DIFFER on both readings (exit 1).
- Positive control, a template literal (the index name 「uniq_ … _v」 to
「uniq_ … _w」, `turso-driver-16711-init-objects-param.test.ts`): DIFFER
on both readings (exit 1).
- Positive control, a numeric literal (`deepArray(1001)` to `1002`,
`turso-local-json-backfill-depth-limit.test.ts`): DIFFER on both
readings (exit 1).

Each mutation went through `scripts/ablation-replace.mjs` (wrap mode,
anchor hit 1 to 0, blob changed) under a shell trap that restores by
absolute path from `HEAD`. Each restore was proven equal to its `HEAD`
blob (`cc15138aba39`, `8deefdb0598b`, `e36d370cb3ed`, `f9142478172e`,
`7343e92b5c7d`), with `git diff HEAD` empty and a clean tree afterwards.

## Changeset: `patch` (`dist` measured)

`files[]` is `dist`, `README.md` and `CHANGELOG.md`, and the package is
not private. In one script under the shared verify lock (VERDICT
command-exit 0, held 104s), at `841405134`: the dependency closure was
built first (`pnpm --filter '@objectstack/driver-turso^...' build`),
then the package's own `build` (tsup and `check-dts-emitted`) ran three
times:

- **Leg 1**, the head text: 6 `dist` files hashed (`index.js`,
`index.mjs`, their sourcemaps, `index.d.ts`, `index.d.mts`). All 13
rewritten non-test lines appear verbatim in `dist`. The 5 docblock lines
on exported members (`remote-transport.ts:1645`, `:2601`, `:2612`;
`turso-driver.ts:3689`, `:3694`) are in all four of `index.js`,
`index.mjs`, `index.d.ts` and `index.d.mts`; the 8 `//` lines in
`turso-driver.ts` are in `index.js` and `index.mjs`.
- **Leg 2**, the base text put back in the 2 non-test touched files (2
of 2 proven equal to their base blob): 4 of the 6 files differ from leg
1 (`index.d.ts`, `index.d.mts`, `index.js`, `index.mjs`); the two
sourcemaps do not. `scripts/ablation-dist-preflight.mjs` finds the base
marker 「[objectstack-ai#14428] A miss answers」 in those 4 built files (exit 0).
- **Leg 3**, after the proven restore (2 of 2 equal to their `HEAD`
blob, `git diff HEAD` empty, porcelain empty): all 6 files are
byte-identical to leg 1, and the preflight's `--absent` reading exits 0
with a clean tree, so the build is deterministic and the difference is
the rewrite.

So the rewrite ships, and
`.changeset/20595-driver-turso-provenance-anchors.md` declares a `patch`
for `@objectstack/driver-turso`, comment text only, with the claim's
`Clause-②: no` line. Every anchor is a commit, so it names no ADR,
repository qualifier or bracketed substitution; it says which published
files carry the reworded text, as measured above. The changeset commit
touches no file under `packages/drivers/driver-turso`.

## Gates (head `e89bd10cd`)

- **Derived gates:** `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands` at `e89bd10cd` (13 paths against
merge base `49161683f`, 113 changed lines) derived 65 commands. All 65
ran (04:52:21Z to 05:03:07Z, after the workspace build), each exit code
captured before any pipe: 65 exit 0. `--ran` reports 「65 derived, 65
run, 0 NOT-MEASURED, 0 UNRUN」 (a derived zero) and exits 0. The PM's
lead derivation (55 commands, tree `550f4cc2f`) is a subset: the extra
10 are the eight families the `.changeset/` path adds (the ADR-0087
registration and empty-changeset pairs, `check:objectui-changeset`,
`check:pm-changeset-deadline-census` and two release self-tests) and two
gates whose source names
`packages/drivers/driver-turso/src/turso-driver.ts` itself
(`check:object-def-param-keys`, `check:tenant-chokepoint`).
- **Named readings:** `node scripts/check-issue-citations.mjs` exits 0
(「every citation this change adds resolves (or is a declared cross-repo
reference)」: 3 judged across 2 files, the three numbers kept on
`turso-driver.ts:2131`, two of them issues and one a pull request);
`pnpm check:issue-citations` exits 0 (self-test, 173 cases, 9
batteries); `pnpm check:doc-authoring` exits 0 (the sibling-package
prose-id baseline holds, no growth); `pnpm check:nul-bytes` exits 0
(9,888 files, no raw control bytes), and a control-byte grep over the 13
changed files finds none (exit 1). The changeset gates
(`check-changeset-no-major`, `check-adr-0087-registration`,
`check-empty-changeset` with `--base origin/main`, and
`check:changeset-gate-self-tests`) exit 0; `check:object-def-param-keys`
exits 0 (5 override parameter positions compared).

- **Build, tests and typecheck, under the verify lock:** at `e89bd10cd`,
the dependency closure and the package were rebuilt, then `pnpm --filter
@objectstack/driver-turso test`: 88 test files pass (88), 2,365 tests
pass and 33 are skipped (2,398); `pnpm --filter
@objectstack/driver-turso typecheck` (`tsc --noEmit`) exits 0 (VERDICT
command-exit 0, held 151s). `tsc --listFilesOnly` puts all 88 tracked
test files and all 12 changed files in `tsconfig.json`'s program. The
workspace build after the merge (`turbo run build
--filter='./packages/*' --filter='./packages/*/*' --concurrency=2`, 71
of 71 tasks, 1 cached; VERDICT command-exit 0, held 319s) ran before the
gates. No importing package owes a run: the declaration files change
only in comment text.
- **Lint, as a proven narrowing, at `e89bd10cd`:** eslint with inline
config disabled, over the 12 touched `.ts` files plus `dist/index.js` as
the control: 13 results, 0 errors and 1 warning, the control's ignore
notice; none of the 12 is reported ignored. `eslint.config.mjs` never
enables type-aware linting (its lines 327 and 328 say so), so a comment
edit cannot move the verdict on an untouched file. The repo-wide `pnpm
lint` is CI's run.

## Acceptance notes

- **Base and merge.** The dispatch read `origin/main` at `550f4cc2f`; by
the time the worktree was cut, `main` had moved one commit (`31d2255f5`,
`packages/mcp/server.json` only), and the branch was cut there. It
merges `main` once, pinned to `49161683f` (merge `e89bd10cd`, no
conflict). The two commits it brought (`48eb9c193`, `spec`; `49161683f`,
`plugin-sharing` and `plugin-audit`) touch neither
`packages/drivers/driver-turso`, `check-issue-citations.mjs` nor
`dispatch-gates.mjs`; the closure and the workspace were rebuilt after
the merge, before the tests and gates. The net diff against `main` is
the 12 rewritten files (+49/−49) and the changeset (+15).
- **The same dead numbers outside this package**, each left to its own
carrier: `driver-mongodb` (this lane's next stage) names objectstack-ai#14428 in
`src/mongodb-driver.ts` and its tests and objectstack-ai#14434 in
`mongodb-update-missing-id.test.ts`, where `ca3fd4b1a` and `93940d492`
are the anchors; `driver-sqlite-wasm`, which the census reads 0, still
carries objectstack-ai#12380, objectstack-ai#14438, objectstack-ai#16711, objectstack-ai#17690, objectstack-ai#17876 and objectstack-ai#17879 in five test
files (comments and two `describe` titles; the census defers test files,
every anchor is in this table, and the comment sites are the same
sentences this stage rewrote here);
`scripts/check-object-def-param-keys.mjs` and
`.github/workflows/lint.yml` name objectstack-ai#16570 and objectstack-ai#16711 (outside the census
surface); `service-analytics`'s `contains-membership.test.ts` carries
objectstack-ai#17590 in a comment, and `driver-sql`'s test strings carry objectstack-ai#12380 and
objectstack-ai#17590; ADR-0104 names objectstack-ai#12380 (governed); the release pages name objectstack-ai#6075
and objectstack-ai#12380 (release-owned).
- **Wording only:** no line without a number was changed.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01DDZNkDVwPQnevTFcYE47H3)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
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/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants