[finding] MongoDBDriver.update() and RemoteTransport.update() fabricate a record for a missing id — a third posture that becomes a semantic violation once IDataDriver.update() declares null (#13878 ruling item 5) #14428

Description

@os-musk

Filed unassigned by the #13878 dev seat (session session_0112hMx9hjJ9BgB28X97DS68), as the director's ruling on #13878 (comment 5494524403) item 5 directs — verbatim, untranslated:

⚠️Mongo / RemoteTransport 的捏造姿态在 A 落地后成为语义违反者 —— ⛔ 不折进本卡:实施者测完「谁读它们的 update() 结果」后另立卡(行为变更,量了再裁);

Recording + measurement only — no severity asserted, no fix chosen; the posture is the maintainer's decision. Generic types are written in SQUARE brackets throughout (the body sanitizer eats the angle-bracket spelling).

The two sites (measured at 79b6a22a5)

ImplementationWhereWhat it does on a miss
MongoDBDriver.update()packages/drivers/driver-mongodb/src/mongodb-driver.ts:403-424updateOne({ id }), then findOne({ id }); when nothing comes back it returns withoutUndefinedOwnKeys({ id: String(id), ...updateData }) — a row assembled from the caller's payload plus the updated_at it stamped, for an id that names no document
RemoteTransport.update()packages/drivers/driver-turso/src/remote-transport.ts:1517-1534UPDATE ... WHERE "id" = ?, then SELECT * ... WHERE "id" = ?; when no row comes back it returns { id, ...data } — the caller's payload with the id stapled on

Both are declared Promise[Record[string, unknown]] and both honour that declaration by inventing data. After #13878 the contract's not-found arm is null (the shape findOne carries, what InMemoryDriver / SqlDriver / TursoDriver (local) / SqliteWasmDriver return), so "a row for an id that does not exist" is no longer a way of satisfying the declaration — it is a value the declaration now distinguishes from, and these two drivers answer "updated" where every other driver answers "not found".

Who reads their update() results — the measurement the ruling asked for

ReaderPathWhat a fabricated row does there
Engine by-id dispatchpackages/objectql/src/engine.ts:11017result = await driver.update(object, id, data, options)Returned to the engine's caller as the updated record. The only guard downstream is typeof result === 'object' && result && 'id' in result around an id read — a fabricated row passes it, so a REST / SDK / MCP update on a missing id answers 200 with a record that does not exist, on these two drivers only
TursoDriver.update() remote branchpackages/drivers/driver-turso/src/turso-driver.ts:778this.formatRemoteRow(object, await this.remoteTransport!.update(...))Passes the fabricated row through as the driver's own result; the local branch (super.update, SqlDriver) returns null for the same miss — one driver, two postures, chosen by isRemote
RemoteTransport.bulkUpdate()packages/drivers/driver-turso/src/remote-transport.ts:1625-1632if (updated) results.push(updated)The cross-driver skip convention SqlDriver.bulkUpdate follows is dead code on this transport: updated is never falsy, so a batch over N missing ids answers N fabricated rows
In-package bulkUpdate on Mongonone — mongodb-driver.ts has no this.update( call site
Testsmongodb-driver.test.ts:157,171 · turso-driver.test.ts:138,731 · turso-remote-autonumber-refusal.test.ts:369All read update() results over rows that EXIST; no test pins the miss posture on either driver, so changing it breaks nothing landed

What this does NOT claim

Dedup

MCP search_issues, one targeted query (MongoDBDriver update fabricates synthesizes a record for a missing id RemoteTransport returns invented row instead of null not found) → 5 results, none on this posture: #13878 (the parent), #12586 (turso json column types), #11151 (mongo boolean aggregates), #6944 (turso remote autonumber), #5088 (updateMany hooks on a nonexistent id). Control query for #13878's own title → #13878 ranked first ⇒ the channel answers, the zero on this posture is a reading.

Related

#13878 (the ruling, item 5) · #13854 (SqlDriver.bulkUpdate, the live dependent of the null skip — the convention RemoteTransport.bulkUpdate copies but can never take)


Triage — the block is discharged and the premise is now present tense

#13878 closed as completed at 2026-09-02T08:28:30Z via merged PR #14434 ("declare the not-found arm on IDataDriver.update() and un-mask driver-memory's published update/upsert types"). The Blocked-by: #13878 line was therefore exhausted and has been removed from this body — verified by re-reading the card after the write.

That discharge is what makes this card urgent rather than anticipatory. The contract's | null arm is on mainnow, so the sentence "these two drivers answer updated where every other driver answers not found" is a description of today, not of a state after some future landing. Everything the measurement table predicts is live.

The measurement the ruling ordered — 「实施者测完『谁读它们的 update() 结果』后另立卡」 — is done and it is thorough (five readers enumerated, the dead if (updated) in RemoteTransport.bulkUpdate found, and the absence of any test pinning the miss posture established). So this card is ready for the ruling half: 「行为变更,量了再裁」 — the measuring is finished, the ruling is the maintainer's.

<!-- os-decision-facets -->

  • ① 项目长远合理性(权重 ≥50%,领起推荐) —— 契约现在明写「找不到就是 null」,六个实现里四个照做,两个捏造一行数据交差。而那两个之所以捏造,靠的是「声明不允许 null,所以必须返回点什么」这个理由 —— 那个理由已经被 [finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 修掉了,姿态却还留着。长远终态只有一个:一个契约一个答案。①指向姿态 (a) 返回 null,因为那是契约自己声明的那一支,也是另外四个实现的做法;(b) 抛错是第三种姿态,等于在两个答案之上再加一个。
  • ② 实际业务拉动 —— 今天就在发生。[finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 已合并关闭,契约的 null 支已在 main 上。此刻一个客户对着已删除的记录发 update,在 Mongo 或 Turso 远程上拿回的是 200 加一条并不存在的记录。不是「将来会怎样」。
  • ③ 防 AI 犯错 —— 最响的一棱,而且坏在方向上:它在该说「没找到」的地方说了「成功」。捏造的那行还带着调用方自己传进去的字段和一个刚刚戳上的 updated_at,看起来完全合理,没有任何地方不对劲。调用方(人或 agent)据此认定写入落地了 —— 不重试、不告警、不回滚。批量更糟:RemoteTransport.bulkUpdate 里那句跨驱动的 if (updated) 跳过约定在这个传输上是死代码,N 个不存在的 id 换回 N 行假数据。
  • ④ 创业阶段不扩散 —— (a) 不引入任何新概念,只是让这两个实现回到契约已经声明的那一支;(b) 抛错要新增一条错误契约、要 REST 映射、要文档、要迁移指引。对齐优于新增。

推荐:A = 姿态 (a),miss 返回 null 四棱同向。每个驱动配一条与 driver-memoryshould return null on update of missing record in default mode 同形的 pin —— 卡面已经量到当前没有任何测试钉住 miss 姿态,所以这是净增覆盖,不是改基线,风险面比一般行为变更小得多。
回退:B = 姿态 (b) 抛错。 若维护者认为「更新一个不存在的记录」应当是响亮失败而非安静的 null,走这条 —— 但必须同批裁定另外四个实现是否一起改,⛔ 否则就是把两种答案变成三种,而那正是本卡要消灭的东西。
置信缺口(本分析看不见什么): 没有量 Mongo 与 Turso 远程的真实部署面 —— 有多少客户在这两个驱动上跑写路径,决定 (a) 的迁移面是零还是非零。卡面量到的是仓内无测试钉住,仓外未知,而那正是「净增覆盖」这句话唯一可能不成立的地方。

Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
     blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    
    Skip to content

    [finding] MongoDBDriver.update() and RemoteTransport.update() fabricate a record for a missing id — a third posture that becomes a semantic violation once IDataDriver.update() declares null (#13878 ruling item 5) #14428

    Description

    @os-musk

    Filed unassigned by the #13878 dev seat (session session_0112hMx9hjJ9BgB28X97DS68), as the director's ruling on #13878 (comment 5494524403) item 5 directs — verbatim, untranslated:

    ⚠️Mongo / RemoteTransport 的捏造姿态在 A 落地后成为语义违反者 —— ⛔ 不折进本卡:实施者测完「谁读它们的 update() 结果」后另立卡(行为变更,量了再裁);

    Recording + measurement only — no severity asserted, no fix chosen; the posture is the maintainer's decision. Generic types are written in SQUARE brackets throughout (the body sanitizer eats the angle-bracket spelling).

    The two sites (measured at 79b6a22a5)

    ImplementationWhereWhat it does on a miss
    MongoDBDriver.update()packages/drivers/driver-mongodb/src/mongodb-driver.ts:403-424updateOne({ id }), then findOne({ id }); when nothing comes back it returns withoutUndefinedOwnKeys({ id: String(id), ...updateData }) — a row assembled from the caller's payload plus the updated_at it stamped, for an id that names no document
    RemoteTransport.update()packages/drivers/driver-turso/src/remote-transport.ts:1517-1534UPDATE ... WHERE "id" = ?, then SELECT * ... WHERE "id" = ?; when no row comes back it returns { id, ...data } — the caller's payload with the id stapled on

    Both are declared Promise[Record[string, unknown]] and both honour that declaration by inventing data. After #13878 the contract's not-found arm is null (the shape findOne carries, what InMemoryDriver / SqlDriver / TursoDriver (local) / SqliteWasmDriver return), so "a row for an id that does not exist" is no longer a way of satisfying the declaration — it is a value the declaration now distinguishes from, and these two drivers answer "updated" where every other driver answers "not found".

    Who reads their update() results — the measurement the ruling asked for

    ReaderPathWhat a fabricated row does there
    Engine by-id dispatchpackages/objectql/src/engine.ts:11017result = await driver.update(object, id, data, options)Returned to the engine's caller as the updated record. The only guard downstream is typeof result === 'object' && result && 'id' in result around an id read — a fabricated row passes it, so a REST / SDK / MCP update on a missing id answers 200 with a record that does not exist, on these two drivers only
    TursoDriver.update() remote branchpackages/drivers/driver-turso/src/turso-driver.ts:778this.formatRemoteRow(object, await this.remoteTransport!.update(...))Passes the fabricated row through as the driver's own result; the local branch (super.update, SqlDriver) returns null for the same miss — one driver, two postures, chosen by isRemote
    RemoteTransport.bulkUpdate()packages/drivers/driver-turso/src/remote-transport.ts:1625-1632if (updated) results.push(updated)The cross-driver skip convention SqlDriver.bulkUpdate follows is dead code on this transport: updated is never falsy, so a batch over N missing ids answers N fabricated rows
    In-package bulkUpdate on Mongonone — mongodb-driver.ts has no this.update( call site
    Testsmongodb-driver.test.ts:157,171 · turso-driver.test.ts:138,731 · turso-remote-autonumber-refusal.test.ts:369All read update() results over rows that EXIST; no test pins the miss posture on either driver, so changing it breaks nothing landed

    What this does NOT claim

    Dedup

    MCP search_issues, one targeted query (MongoDBDriver update fabricates synthesizes a record for a missing id RemoteTransport returns invented row instead of null not found) → 5 results, none on this posture: #13878 (the parent), #12586 (turso json column types), #11151 (mongo boolean aggregates), #6944 (turso remote autonumber), #5088 (updateMany hooks on a nonexistent id). Control query for #13878's own title → #13878 ranked first ⇒ the channel answers, the zero on this posture is a reading.

    Related

    #13878 (the ruling, item 5) · #13854 (SqlDriver.bulkUpdate, the live dependent of the null skip — the convention RemoteTransport.bulkUpdate copies but can never take)


    Triage — the block is discharged and the premise is now present tense

    #13878 closed as completed at 2026-09-02T08:28:30Z via merged PR #14434 ("declare the not-found arm on IDataDriver.update() and un-mask driver-memory's published update/upsert types"). The Blocked-by: #13878 line was therefore exhausted and has been removed from this body — verified by re-reading the card after the write.

    That discharge is what makes this card urgent rather than anticipatory. The contract's | null arm is on mainnow, so the sentence "these two drivers answer updated where every other driver answers not found" is a description of today, not of a state after some future landing. Everything the measurement table predicts is live.

    The measurement the ruling ordered — 「实施者测完『谁读它们的 update() 结果』后另立卡」 — is done and it is thorough (five readers enumerated, the dead if (updated) in RemoteTransport.bulkUpdate found, and the absence of any test pinning the miss posture established). So this card is ready for the ruling half: 「行为变更,量了再裁」 — the measuring is finished, the ruling is the maintainer's.

    <!-- os-decision-facets -->

    • ① 项目长远合理性(权重 ≥50%,领起推荐) —— 契约现在明写「找不到就是 null」,六个实现里四个照做,两个捏造一行数据交差。而那两个之所以捏造,靠的是「声明不允许 null,所以必须返回点什么」这个理由 —— 那个理由已经被 [finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 修掉了,姿态却还留着。长远终态只有一个:一个契约一个答案。①指向姿态 (a) 返回 null,因为那是契约自己声明的那一支,也是另外四个实现的做法;(b) 抛错是第三种姿态,等于在两个答案之上再加一个。
    • ② 实际业务拉动 —— 今天就在发生。[finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 已合并关闭,契约的 null 支已在 main 上。此刻一个客户对着已删除的记录发 update,在 Mongo 或 Turso 远程上拿回的是 200 加一条并不存在的记录。不是「将来会怎样」。
    • ③ 防 AI 犯错 —— 最响的一棱,而且坏在方向上:它在该说「没找到」的地方说了「成功」。捏造的那行还带着调用方自己传进去的字段和一个刚刚戳上的 updated_at,看起来完全合理,没有任何地方不对劲。调用方(人或 agent)据此认定写入落地了 —— 不重试、不告警、不回滚。批量更糟:RemoteTransport.bulkUpdate 里那句跨驱动的 if (updated) 跳过约定在这个传输上是死代码,N 个不存在的 id 换回 N 行假数据。
    • ④ 创业阶段不扩散 —— (a) 不引入任何新概念,只是让这两个实现回到契约已经声明的那一支;(b) 抛错要新增一条错误契约、要 REST 映射、要文档、要迁移指引。对齐优于新增。

    推荐:A = 姿态 (a),miss 返回 null 四棱同向。每个驱动配一条与 driver-memoryshould return null on update of missing record in default mode 同形的 pin —— 卡面已经量到当前没有任何测试钉住 miss 姿态,所以这是净增覆盖,不是改基线,风险面比一般行为变更小得多。
    回退:B = 姿态 (b) 抛错。 若维护者认为「更新一个不存在的记录」应当是响亮失败而非安静的 null,走这条 —— 但必须同批裁定另外四个实现是否一起改,⛔ 否则就是把两种答案变成三种,而那正是本卡要消灭的东西。
    置信缺口(本分析看不见什么): 没有量 Mongo 与 Turso 远程的真实部署面 —— 有多少客户在这两个驱动上跑写路径,决定 (a) 的迁移面是零还是非零。卡面量到的是仓内无测试钉住,仓外未知,而那正是「净增覆盖」这句话唯一可能不成立的地方。

    Generated by Claude Code

    Activity

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
      Skip to content

      [finding] MongoDBDriver.update() and RemoteTransport.update() fabricate a record for a missing id — a third posture that becomes a semantic violation once IDataDriver.update() declares null (#13878 ruling item 5) #14428

      Description

      @os-musk

      Filed unassigned by the #13878 dev seat (session session_0112hMx9hjJ9BgB28X97DS68), as the director's ruling on #13878 (comment 5494524403) item 5 directs — verbatim, untranslated:

      ⚠️Mongo / RemoteTransport 的捏造姿态在 A 落地后成为语义违反者 —— ⛔ 不折进本卡:实施者测完「谁读它们的 update() 结果」后另立卡(行为变更,量了再裁);

      Recording + measurement only — no severity asserted, no fix chosen; the posture is the maintainer's decision. Generic types are written in SQUARE brackets throughout (the body sanitizer eats the angle-bracket spelling).

      The two sites (measured at 79b6a22a5)

      ImplementationWhereWhat it does on a miss
      MongoDBDriver.update()packages/drivers/driver-mongodb/src/mongodb-driver.ts:403-424updateOne({ id }), then findOne({ id }); when nothing comes back it returns withoutUndefinedOwnKeys({ id: String(id), ...updateData }) — a row assembled from the caller's payload plus the updated_at it stamped, for an id that names no document
      RemoteTransport.update()packages/drivers/driver-turso/src/remote-transport.ts:1517-1534UPDATE ... WHERE "id" = ?, then SELECT * ... WHERE "id" = ?; when no row comes back it returns { id, ...data } — the caller's payload with the id stapled on

      Both are declared Promise[Record[string, unknown]] and both honour that declaration by inventing data. After #13878 the contract's not-found arm is null (the shape findOne carries, what InMemoryDriver / SqlDriver / TursoDriver (local) / SqliteWasmDriver return), so "a row for an id that does not exist" is no longer a way of satisfying the declaration — it is a value the declaration now distinguishes from, and these two drivers answer "updated" where every other driver answers "not found".

      Who reads their update() results — the measurement the ruling asked for

      ReaderPathWhat a fabricated row does there
      Engine by-id dispatchpackages/objectql/src/engine.ts:11017result = await driver.update(object, id, data, options)Returned to the engine's caller as the updated record. The only guard downstream is typeof result === 'object' && result && 'id' in result around an id read — a fabricated row passes it, so a REST / SDK / MCP update on a missing id answers 200 with a record that does not exist, on these two drivers only
      TursoDriver.update() remote branchpackages/drivers/driver-turso/src/turso-driver.ts:778this.formatRemoteRow(object, await this.remoteTransport!.update(...))Passes the fabricated row through as the driver's own result; the local branch (super.update, SqlDriver) returns null for the same miss — one driver, two postures, chosen by isRemote
      RemoteTransport.bulkUpdate()packages/drivers/driver-turso/src/remote-transport.ts:1625-1632if (updated) results.push(updated)The cross-driver skip convention SqlDriver.bulkUpdate follows is dead code on this transport: updated is never falsy, so a batch over N missing ids answers N fabricated rows
      In-package bulkUpdate on Mongonone — mongodb-driver.ts has no this.update( call site
      Testsmongodb-driver.test.ts:157,171 · turso-driver.test.ts:138,731 · turso-remote-autonumber-refusal.test.ts:369All read update() results over rows that EXIST; no test pins the miss posture on either driver, so changing it breaks nothing landed

      What this does NOT claim

      Dedup

      MCP search_issues, one targeted query (MongoDBDriver update fabricates synthesizes a record for a missing id RemoteTransport returns invented row instead of null not found) → 5 results, none on this posture: #13878 (the parent), #12586 (turso json column types), #11151 (mongo boolean aggregates), #6944 (turso remote autonumber), #5088 (updateMany hooks on a nonexistent id). Control query for #13878's own title → #13878 ranked first ⇒ the channel answers, the zero on this posture is a reading.

      Related

      #13878 (the ruling, item 5) · #13854 (SqlDriver.bulkUpdate, the live dependent of the null skip — the convention RemoteTransport.bulkUpdate copies but can never take)


      Triage — the block is discharged and the premise is now present tense

      #13878 closed as completed at 2026-09-02T08:28:30Z via merged PR #14434 ("declare the not-found arm on IDataDriver.update() and un-mask driver-memory's published update/upsert types"). The Blocked-by: #13878 line was therefore exhausted and has been removed from this body — verified by re-reading the card after the write.

      That discharge is what makes this card urgent rather than anticipatory. The contract's | null arm is on mainnow, so the sentence "these two drivers answer updated where every other driver answers not found" is a description of today, not of a state after some future landing. Everything the measurement table predicts is live.

      The measurement the ruling ordered — 「实施者测完『谁读它们的 update() 结果』后另立卡」 — is done and it is thorough (five readers enumerated, the dead if (updated) in RemoteTransport.bulkUpdate found, and the absence of any test pinning the miss posture established). So this card is ready for the ruling half: 「行为变更,量了再裁」 — the measuring is finished, the ruling is the maintainer's.

      <!-- os-decision-facets -->

      • ① 项目长远合理性(权重 ≥50%,领起推荐) —— 契约现在明写「找不到就是 null」,六个实现里四个照做,两个捏造一行数据交差。而那两个之所以捏造,靠的是「声明不允许 null,所以必须返回点什么」这个理由 —— 那个理由已经被 [finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 修掉了,姿态却还留着。长远终态只有一个:一个契约一个答案。①指向姿态 (a) 返回 null,因为那是契约自己声明的那一支,也是另外四个实现的做法;(b) 抛错是第三种姿态,等于在两个答案之上再加一个。
      • ② 实际业务拉动 —— 今天就在发生。[finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 已合并关闭,契约的 null 支已在 main 上。此刻一个客户对着已删除的记录发 update,在 Mongo 或 Turso 远程上拿回的是 200 加一条并不存在的记录。不是「将来会怎样」。
      • ③ 防 AI 犯错 —— 最响的一棱,而且坏在方向上:它在该说「没找到」的地方说了「成功」。捏造的那行还带着调用方自己传进去的字段和一个刚刚戳上的 updated_at,看起来完全合理,没有任何地方不对劲。调用方(人或 agent)据此认定写入落地了 —— 不重试、不告警、不回滚。批量更糟:RemoteTransport.bulkUpdate 里那句跨驱动的 if (updated) 跳过约定在这个传输上是死代码,N 个不存在的 id 换回 N 行假数据。
      • ④ 创业阶段不扩散 —— (a) 不引入任何新概念,只是让这两个实现回到契约已经声明的那一支;(b) 抛错要新增一条错误契约、要 REST 映射、要文档、要迁移指引。对齐优于新增。

      推荐:A = 姿态 (a),miss 返回 null 四棱同向。每个驱动配一条与 driver-memoryshould return null on update of missing record in default mode 同形的 pin —— 卡面已经量到当前没有任何测试钉住 miss 姿态,所以这是净增覆盖,不是改基线,风险面比一般行为变更小得多。
      回退:B = 姿态 (b) 抛错。 若维护者认为「更新一个不存在的记录」应当是响亮失败而非安静的 null,走这条 —— 但必须同批裁定另外四个实现是否一起改,⛔ 否则就是把两种答案变成三种,而那正是本卡要消灭的东西。
      置信缺口(本分析看不见什么): 没有量 Mongo 与 Turso 远程的真实部署面 —— 有多少客户在这两个驱动上跑写路径,决定 (a) 的迁移面是零还是非零。卡面量到的是仓内无测试钉住,仓外未知,而那正是「净增覆盖」这句话唯一可能不成立的地方。

      Generated by Claude Code

      Activity

      Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

      Metadata

      Metadata

      Assignees

      Type

      No type

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
        Skip to content

        [finding] MongoDBDriver.update() and RemoteTransport.update() fabricate a record for a missing id — a third posture that becomes a semantic violation once IDataDriver.update() declares null (#13878 ruling item 5) #14428

        Description

        @os-musk

        Filed unassigned by the #13878 dev seat (session session_0112hMx9hjJ9BgB28X97DS68), as the director's ruling on #13878 (comment 5494524403) item 5 directs — verbatim, untranslated:

        ⚠️Mongo / RemoteTransport 的捏造姿态在 A 落地后成为语义违反者 —— ⛔ 不折进本卡:实施者测完「谁读它们的 update() 结果」后另立卡(行为变更,量了再裁);

        Recording + measurement only — no severity asserted, no fix chosen; the posture is the maintainer's decision. Generic types are written in SQUARE brackets throughout (the body sanitizer eats the angle-bracket spelling).

        The two sites (measured at 79b6a22a5)

        ImplementationWhereWhat it does on a miss
        MongoDBDriver.update()packages/drivers/driver-mongodb/src/mongodb-driver.ts:403-424updateOne({ id }), then findOne({ id }); when nothing comes back it returns withoutUndefinedOwnKeys({ id: String(id), ...updateData }) — a row assembled from the caller's payload plus the updated_at it stamped, for an id that names no document
        RemoteTransport.update()packages/drivers/driver-turso/src/remote-transport.ts:1517-1534UPDATE ... WHERE "id" = ?, then SELECT * ... WHERE "id" = ?; when no row comes back it returns { id, ...data } — the caller's payload with the id stapled on

        Both are declared Promise[Record[string, unknown]] and both honour that declaration by inventing data. After #13878 the contract's not-found arm is null (the shape findOne carries, what InMemoryDriver / SqlDriver / TursoDriver (local) / SqliteWasmDriver return), so "a row for an id that does not exist" is no longer a way of satisfying the declaration — it is a value the declaration now distinguishes from, and these two drivers answer "updated" where every other driver answers "not found".

        Who reads their update() results — the measurement the ruling asked for

        ReaderPathWhat a fabricated row does there
        Engine by-id dispatchpackages/objectql/src/engine.ts:11017result = await driver.update(object, id, data, options)Returned to the engine's caller as the updated record. The only guard downstream is typeof result === 'object' && result && 'id' in result around an id read — a fabricated row passes it, so a REST / SDK / MCP update on a missing id answers 200 with a record that does not exist, on these two drivers only
        TursoDriver.update() remote branchpackages/drivers/driver-turso/src/turso-driver.ts:778this.formatRemoteRow(object, await this.remoteTransport!.update(...))Passes the fabricated row through as the driver's own result; the local branch (super.update, SqlDriver) returns null for the same miss — one driver, two postures, chosen by isRemote
        RemoteTransport.bulkUpdate()packages/drivers/driver-turso/src/remote-transport.ts:1625-1632if (updated) results.push(updated)The cross-driver skip convention SqlDriver.bulkUpdate follows is dead code on this transport: updated is never falsy, so a batch over N missing ids answers N fabricated rows
        In-package bulkUpdate on Mongonone — mongodb-driver.ts has no this.update( call site
        Testsmongodb-driver.test.ts:157,171 · turso-driver.test.ts:138,731 · turso-remote-autonumber-refusal.test.ts:369All read update() results over rows that EXIST; no test pins the miss posture on either driver, so changing it breaks nothing landed

        What this does NOT claim

        Dedup

        MCP search_issues, one targeted query (MongoDBDriver update fabricates synthesizes a record for a missing id RemoteTransport returns invented row instead of null not found) → 5 results, none on this posture: #13878 (the parent), #12586 (turso json column types), #11151 (mongo boolean aggregates), #6944 (turso remote autonumber), #5088 (updateMany hooks on a nonexistent id). Control query for #13878's own title → #13878 ranked first ⇒ the channel answers, the zero on this posture is a reading.

        Related

        #13878 (the ruling, item 5) · #13854 (SqlDriver.bulkUpdate, the live dependent of the null skip — the convention RemoteTransport.bulkUpdate copies but can never take)


        Triage — the block is discharged and the premise is now present tense

        #13878 closed as completed at 2026-09-02T08:28:30Z via merged PR #14434 ("declare the not-found arm on IDataDriver.update() and un-mask driver-memory's published update/upsert types"). The Blocked-by: #13878 line was therefore exhausted and has been removed from this body — verified by re-reading the card after the write.

        That discharge is what makes this card urgent rather than anticipatory. The contract's | null arm is on mainnow, so the sentence "these two drivers answer updated where every other driver answers not found" is a description of today, not of a state after some future landing. Everything the measurement table predicts is live.

        The measurement the ruling ordered — 「实施者测完『谁读它们的 update() 结果』后另立卡」 — is done and it is thorough (five readers enumerated, the dead if (updated) in RemoteTransport.bulkUpdate found, and the absence of any test pinning the miss posture established). So this card is ready for the ruling half: 「行为变更,量了再裁」 — the measuring is finished, the ruling is the maintainer's.

        <!-- os-decision-facets -->

        • ① 项目长远合理性(权重 ≥50%,领起推荐) —— 契约现在明写「找不到就是 null」,六个实现里四个照做,两个捏造一行数据交差。而那两个之所以捏造,靠的是「声明不允许 null,所以必须返回点什么」这个理由 —— 那个理由已经被 [finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 修掉了,姿态却还留着。长远终态只有一个:一个契约一个答案。①指向姿态 (a) 返回 null,因为那是契约自己声明的那一支,也是另外四个实现的做法;(b) 抛错是第三种姿态,等于在两个答案之上再加一个。
        • ② 实际业务拉动 —— 今天就在发生。[finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 已合并关闭,契约的 null 支已在 main 上。此刻一个客户对着已删除的记录发 update,在 Mongo 或 Turso 远程上拿回的是 200 加一条并不存在的记录。不是「将来会怎样」。
        • ③ 防 AI 犯错 —— 最响的一棱,而且坏在方向上:它在该说「没找到」的地方说了「成功」。捏造的那行还带着调用方自己传进去的字段和一个刚刚戳上的 updated_at,看起来完全合理,没有任何地方不对劲。调用方(人或 agent)据此认定写入落地了 —— 不重试、不告警、不回滚。批量更糟:RemoteTransport.bulkUpdate 里那句跨驱动的 if (updated) 跳过约定在这个传输上是死代码,N 个不存在的 id 换回 N 行假数据。
        • ④ 创业阶段不扩散 —— (a) 不引入任何新概念,只是让这两个实现回到契约已经声明的那一支;(b) 抛错要新增一条错误契约、要 REST 映射、要文档、要迁移指引。对齐优于新增。

        推荐:A = 姿态 (a),miss 返回 null 四棱同向。每个驱动配一条与 driver-memoryshould return null on update of missing record in default mode 同形的 pin —— 卡面已经量到当前没有任何测试钉住 miss 姿态,所以这是净增覆盖,不是改基线,风险面比一般行为变更小得多。
        回退:B = 姿态 (b) 抛错。 若维护者认为「更新一个不存在的记录」应当是响亮失败而非安静的 null,走这条 —— 但必须同批裁定另外四个实现是否一起改,⛔ 否则就是把两种答案变成三种,而那正是本卡要消灭的东西。
        置信缺口(本分析看不见什么): 没有量 Mongo 与 Turso 远程的真实部署面 —— 有多少客户在这两个驱动上跑写路径,决定 (a) 的迁移面是零还是非零。卡面量到的是仓内无测试钉住,仓外未知,而那正是「净增覆盖」这句话唯一可能不成立的地方。

        Generated by Claude Code

        Activity

        Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

        Metadata

        Metadata

        Assignees

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
          Skip to content

          [finding] MongoDBDriver.update() and RemoteTransport.update() fabricate a record for a missing id — a third posture that becomes a semantic violation once IDataDriver.update() declares null (#13878 ruling item 5) #14428

          Description

          @os-musk

          Filed unassigned by the #13878 dev seat (session session_0112hMx9hjJ9BgB28X97DS68), as the director's ruling on #13878 (comment 5494524403) item 5 directs — verbatim, untranslated:

          ⚠️Mongo / RemoteTransport 的捏造姿态在 A 落地后成为语义违反者 —— ⛔ 不折进本卡:实施者测完「谁读它们的 update() 结果」后另立卡(行为变更,量了再裁);

          Recording + measurement only — no severity asserted, no fix chosen; the posture is the maintainer's decision. Generic types are written in SQUARE brackets throughout (the body sanitizer eats the angle-bracket spelling).

          The two sites (measured at 79b6a22a5)

          ImplementationWhereWhat it does on a miss
          MongoDBDriver.update()packages/drivers/driver-mongodb/src/mongodb-driver.ts:403-424updateOne({ id }), then findOne({ id }); when nothing comes back it returns withoutUndefinedOwnKeys({ id: String(id), ...updateData }) — a row assembled from the caller's payload plus the updated_at it stamped, for an id that names no document
          RemoteTransport.update()packages/drivers/driver-turso/src/remote-transport.ts:1517-1534UPDATE ... WHERE "id" = ?, then SELECT * ... WHERE "id" = ?; when no row comes back it returns { id, ...data } — the caller's payload with the id stapled on

          Both are declared Promise[Record[string, unknown]] and both honour that declaration by inventing data. After #13878 the contract's not-found arm is null (the shape findOne carries, what InMemoryDriver / SqlDriver / TursoDriver (local) / SqliteWasmDriver return), so "a row for an id that does not exist" is no longer a way of satisfying the declaration — it is a value the declaration now distinguishes from, and these two drivers answer "updated" where every other driver answers "not found".

          Who reads their update() results — the measurement the ruling asked for

          ReaderPathWhat a fabricated row does there
          Engine by-id dispatchpackages/objectql/src/engine.ts:11017result = await driver.update(object, id, data, options)Returned to the engine's caller as the updated record. The only guard downstream is typeof result === 'object' && result && 'id' in result around an id read — a fabricated row passes it, so a REST / SDK / MCP update on a missing id answers 200 with a record that does not exist, on these two drivers only
          TursoDriver.update() remote branchpackages/drivers/driver-turso/src/turso-driver.ts:778this.formatRemoteRow(object, await this.remoteTransport!.update(...))Passes the fabricated row through as the driver's own result; the local branch (super.update, SqlDriver) returns null for the same miss — one driver, two postures, chosen by isRemote
          RemoteTransport.bulkUpdate()packages/drivers/driver-turso/src/remote-transport.ts:1625-1632if (updated) results.push(updated)The cross-driver skip convention SqlDriver.bulkUpdate follows is dead code on this transport: updated is never falsy, so a batch over N missing ids answers N fabricated rows
          In-package bulkUpdate on Mongonone — mongodb-driver.ts has no this.update( call site
          Testsmongodb-driver.test.ts:157,171 · turso-driver.test.ts:138,731 · turso-remote-autonumber-refusal.test.ts:369All read update() results over rows that EXIST; no test pins the miss posture on either driver, so changing it breaks nothing landed

          What this does NOT claim

          Dedup

          MCP search_issues, one targeted query (MongoDBDriver update fabricates synthesizes a record for a missing id RemoteTransport returns invented row instead of null not found) → 5 results, none on this posture: #13878 (the parent), #12586 (turso json column types), #11151 (mongo boolean aggregates), #6944 (turso remote autonumber), #5088 (updateMany hooks on a nonexistent id). Control query for #13878's own title → #13878 ranked first ⇒ the channel answers, the zero on this posture is a reading.

          Related

          #13878 (the ruling, item 5) · #13854 (SqlDriver.bulkUpdate, the live dependent of the null skip — the convention RemoteTransport.bulkUpdate copies but can never take)


          Triage — the block is discharged and the premise is now present tense

          #13878 closed as completed at 2026-09-02T08:28:30Z via merged PR #14434 ("declare the not-found arm on IDataDriver.update() and un-mask driver-memory's published update/upsert types"). The Blocked-by: #13878 line was therefore exhausted and has been removed from this body — verified by re-reading the card after the write.

          That discharge is what makes this card urgent rather than anticipatory. The contract's | null arm is on mainnow, so the sentence "these two drivers answer updated where every other driver answers not found" is a description of today, not of a state after some future landing. Everything the measurement table predicts is live.

          The measurement the ruling ordered — 「实施者测完『谁读它们的 update() 结果』后另立卡」 — is done and it is thorough (five readers enumerated, the dead if (updated) in RemoteTransport.bulkUpdate found, and the absence of any test pinning the miss posture established). So this card is ready for the ruling half: 「行为变更,量了再裁」 — the measuring is finished, the ruling is the maintainer's.

          <!-- os-decision-facets -->

          • ① 项目长远合理性(权重 ≥50%,领起推荐) —— 契约现在明写「找不到就是 null」,六个实现里四个照做,两个捏造一行数据交差。而那两个之所以捏造,靠的是「声明不允许 null,所以必须返回点什么」这个理由 —— 那个理由已经被 [finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 修掉了,姿态却还留着。长远终态只有一个:一个契约一个答案。①指向姿态 (a) 返回 null,因为那是契约自己声明的那一支,也是另外四个实现的做法;(b) 抛错是第三种姿态,等于在两个答案之上再加一个。
          • ② 实际业务拉动 —— 今天就在发生。[finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 已合并关闭,契约的 null 支已在 main 上。此刻一个客户对着已删除的记录发 update,在 Mongo 或 Turso 远程上拿回的是 200 加一条并不存在的记录。不是「将来会怎样」。
          • ③ 防 AI 犯错 —— 最响的一棱,而且坏在方向上:它在该说「没找到」的地方说了「成功」。捏造的那行还带着调用方自己传进去的字段和一个刚刚戳上的 updated_at,看起来完全合理,没有任何地方不对劲。调用方(人或 agent)据此认定写入落地了 —— 不重试、不告警、不回滚。批量更糟:RemoteTransport.bulkUpdate 里那句跨驱动的 if (updated) 跳过约定在这个传输上是死代码,N 个不存在的 id 换回 N 行假数据。
          • ④ 创业阶段不扩散 —— (a) 不引入任何新概念,只是让这两个实现回到契约已经声明的那一支;(b) 抛错要新增一条错误契约、要 REST 映射、要文档、要迁移指引。对齐优于新增。

          推荐:A = 姿态 (a),miss 返回 null 四棱同向。每个驱动配一条与 driver-memoryshould return null on update of missing record in default mode 同形的 pin —— 卡面已经量到当前没有任何测试钉住 miss 姿态,所以这是净增覆盖,不是改基线,风险面比一般行为变更小得多。
          回退:B = 姿态 (b) 抛错。 若维护者认为「更新一个不存在的记录」应当是响亮失败而非安静的 null,走这条 —— 但必须同批裁定另外四个实现是否一起改,⛔ 否则就是把两种答案变成三种,而那正是本卡要消灭的东西。
          置信缺口(本分析看不见什么): 没有量 Mongo 与 Turso 远程的真实部署面 —— 有多少客户在这两个驱动上跑写路径,决定 (a) 的迁移面是零还是非零。卡面量到的是仓内无测试钉住,仓外未知,而那正是「净增覆盖」这句话唯一可能不成立的地方。

          Generated by Claude Code

          Activity

          Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

          Metadata

          Metadata

          Assignees

          Type

          No type

          Projects

          No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
            Skip to content

            [finding] MongoDBDriver.update() and RemoteTransport.update() fabricate a record for a missing id — a third posture that becomes a semantic violation once IDataDriver.update() declares null (#13878 ruling item 5) #14428

            Description

            @os-musk

            Filed unassigned by the #13878 dev seat (session session_0112hMx9hjJ9BgB28X97DS68), as the director's ruling on #13878 (comment 5494524403) item 5 directs — verbatim, untranslated:

            ⚠️Mongo / RemoteTransport 的捏造姿态在 A 落地后成为语义违反者 —— ⛔ 不折进本卡:实施者测完「谁读它们的 update() 结果」后另立卡(行为变更,量了再裁);

            Recording + measurement only — no severity asserted, no fix chosen; the posture is the maintainer's decision. Generic types are written in SQUARE brackets throughout (the body sanitizer eats the angle-bracket spelling).

            The two sites (measured at 79b6a22a5)

            ImplementationWhereWhat it does on a miss
            MongoDBDriver.update()packages/drivers/driver-mongodb/src/mongodb-driver.ts:403-424updateOne({ id }), then findOne({ id }); when nothing comes back it returns withoutUndefinedOwnKeys({ id: String(id), ...updateData }) — a row assembled from the caller's payload plus the updated_at it stamped, for an id that names no document
            RemoteTransport.update()packages/drivers/driver-turso/src/remote-transport.ts:1517-1534UPDATE ... WHERE "id" = ?, then SELECT * ... WHERE "id" = ?; when no row comes back it returns { id, ...data } — the caller's payload with the id stapled on

            Both are declared Promise[Record[string, unknown]] and both honour that declaration by inventing data. After #13878 the contract's not-found arm is null (the shape findOne carries, what InMemoryDriver / SqlDriver / TursoDriver (local) / SqliteWasmDriver return), so "a row for an id that does not exist" is no longer a way of satisfying the declaration — it is a value the declaration now distinguishes from, and these two drivers answer "updated" where every other driver answers "not found".

            Who reads their update() results — the measurement the ruling asked for

            ReaderPathWhat a fabricated row does there
            Engine by-id dispatchpackages/objectql/src/engine.ts:11017result = await driver.update(object, id, data, options)Returned to the engine's caller as the updated record. The only guard downstream is typeof result === 'object' && result && 'id' in result around an id read — a fabricated row passes it, so a REST / SDK / MCP update on a missing id answers 200 with a record that does not exist, on these two drivers only
            TursoDriver.update() remote branchpackages/drivers/driver-turso/src/turso-driver.ts:778this.formatRemoteRow(object, await this.remoteTransport!.update(...))Passes the fabricated row through as the driver's own result; the local branch (super.update, SqlDriver) returns null for the same miss — one driver, two postures, chosen by isRemote
            RemoteTransport.bulkUpdate()packages/drivers/driver-turso/src/remote-transport.ts:1625-1632if (updated) results.push(updated)The cross-driver skip convention SqlDriver.bulkUpdate follows is dead code on this transport: updated is never falsy, so a batch over N missing ids answers N fabricated rows
            In-package bulkUpdate on Mongonone — mongodb-driver.ts has no this.update( call site
            Testsmongodb-driver.test.ts:157,171 · turso-driver.test.ts:138,731 · turso-remote-autonumber-refusal.test.ts:369All read update() results over rows that EXIST; no test pins the miss posture on either driver, so changing it breaks nothing landed

            What this does NOT claim

            Dedup

            MCP search_issues, one targeted query (MongoDBDriver update fabricates synthesizes a record for a missing id RemoteTransport returns invented row instead of null not found) → 5 results, none on this posture: #13878 (the parent), #12586 (turso json column types), #11151 (mongo boolean aggregates), #6944 (turso remote autonumber), #5088 (updateMany hooks on a nonexistent id). Control query for #13878's own title → #13878 ranked first ⇒ the channel answers, the zero on this posture is a reading.

            Related

            #13878 (the ruling, item 5) · #13854 (SqlDriver.bulkUpdate, the live dependent of the null skip — the convention RemoteTransport.bulkUpdate copies but can never take)


            Triage — the block is discharged and the premise is now present tense

            #13878 closed as completed at 2026-09-02T08:28:30Z via merged PR #14434 ("declare the not-found arm on IDataDriver.update() and un-mask driver-memory's published update/upsert types"). The Blocked-by: #13878 line was therefore exhausted and has been removed from this body — verified by re-reading the card after the write.

            That discharge is what makes this card urgent rather than anticipatory. The contract's | null arm is on mainnow, so the sentence "these two drivers answer updated where every other driver answers not found" is a description of today, not of a state after some future landing. Everything the measurement table predicts is live.

            The measurement the ruling ordered — 「实施者测完『谁读它们的 update() 结果』后另立卡」 — is done and it is thorough (five readers enumerated, the dead if (updated) in RemoteTransport.bulkUpdate found, and the absence of any test pinning the miss posture established). So this card is ready for the ruling half: 「行为变更,量了再裁」 — the measuring is finished, the ruling is the maintainer's.

            <!-- os-decision-facets -->

            • ① 项目长远合理性(权重 ≥50%,领起推荐) —— 契约现在明写「找不到就是 null」,六个实现里四个照做,两个捏造一行数据交差。而那两个之所以捏造,靠的是「声明不允许 null,所以必须返回点什么」这个理由 —— 那个理由已经被 [finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 修掉了,姿态却还留着。长远终态只有一个:一个契约一个答案。①指向姿态 (a) 返回 null,因为那是契约自己声明的那一支,也是另外四个实现的做法;(b) 抛错是第三种姿态,等于在两个答案之上再加一个。
            • ② 实际业务拉动 —— 今天就在发生。[finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 已合并关闭,契约的 null 支已在 main 上。此刻一个客户对着已删除的记录发 update,在 Mongo 或 Turso 远程上拿回的是 200 加一条并不存在的记录。不是「将来会怎样」。
            • ③ 防 AI 犯错 —— 最响的一棱,而且坏在方向上:它在该说「没找到」的地方说了「成功」。捏造的那行还带着调用方自己传进去的字段和一个刚刚戳上的 updated_at,看起来完全合理,没有任何地方不对劲。调用方(人或 agent)据此认定写入落地了 —— 不重试、不告警、不回滚。批量更糟:RemoteTransport.bulkUpdate 里那句跨驱动的 if (updated) 跳过约定在这个传输上是死代码,N 个不存在的 id 换回 N 行假数据。
            • ④ 创业阶段不扩散 —— (a) 不引入任何新概念,只是让这两个实现回到契约已经声明的那一支;(b) 抛错要新增一条错误契约、要 REST 映射、要文档、要迁移指引。对齐优于新增。

            推荐:A = 姿态 (a),miss 返回 null 四棱同向。每个驱动配一条与 driver-memoryshould return null on update of missing record in default mode 同形的 pin —— 卡面已经量到当前没有任何测试钉住 miss 姿态,所以这是净增覆盖,不是改基线,风险面比一般行为变更小得多。
            回退:B = 姿态 (b) 抛错。 若维护者认为「更新一个不存在的记录」应当是响亮失败而非安静的 null,走这条 —— 但必须同批裁定另外四个实现是否一起改,⛔ 否则就是把两种答案变成三种,而那正是本卡要消灭的东西。
            置信缺口(本分析看不见什么): 没有量 Mongo 与 Turso 远程的真实部署面 —— 有多少客户在这两个驱动上跑写路径,决定 (a) 的迁移面是零还是非零。卡面量到的是仓内无测试钉住,仓外未知,而那正是「净增覆盖」这句话唯一可能不成立的地方。

            Generated by Claude Code

            Activity

            Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

            Metadata

            Metadata

            Assignees

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              [finding] MongoDBDriver.update() and RemoteTransport.update() fabricate a record for a missing id — a third posture that becomes a semantic violation once IDataDriver.update() declares null (#13878 ruling item 5) #14428

              Description

              @os-musk

              Filed unassigned by the #13878 dev seat (session session_0112hMx9hjJ9BgB28X97DS68), as the director's ruling on #13878 (comment 5494524403) item 5 directs — verbatim, untranslated:

              ⚠️Mongo / RemoteTransport 的捏造姿态在 A 落地后成为语义违反者 —— ⛔ 不折进本卡:实施者测完「谁读它们的 update() 结果」后另立卡(行为变更,量了再裁);

              Recording + measurement only — no severity asserted, no fix chosen; the posture is the maintainer's decision. Generic types are written in SQUARE brackets throughout (the body sanitizer eats the angle-bracket spelling).

              The two sites (measured at 79b6a22a5)

              ImplementationWhereWhat it does on a miss
              MongoDBDriver.update()packages/drivers/driver-mongodb/src/mongodb-driver.ts:403-424updateOne({ id }), then findOne({ id }); when nothing comes back it returns withoutUndefinedOwnKeys({ id: String(id), ...updateData }) — a row assembled from the caller's payload plus the updated_at it stamped, for an id that names no document
              RemoteTransport.update()packages/drivers/driver-turso/src/remote-transport.ts:1517-1534UPDATE ... WHERE "id" = ?, then SELECT * ... WHERE "id" = ?; when no row comes back it returns { id, ...data } — the caller's payload with the id stapled on

              Both are declared Promise[Record[string, unknown]] and both honour that declaration by inventing data. After #13878 the contract's not-found arm is null (the shape findOne carries, what InMemoryDriver / SqlDriver / TursoDriver (local) / SqliteWasmDriver return), so "a row for an id that does not exist" is no longer a way of satisfying the declaration — it is a value the declaration now distinguishes from, and these two drivers answer "updated" where every other driver answers "not found".

              Who reads their update() results — the measurement the ruling asked for

              ReaderPathWhat a fabricated row does there
              Engine by-id dispatchpackages/objectql/src/engine.ts:11017result = await driver.update(object, id, data, options)Returned to the engine's caller as the updated record. The only guard downstream is typeof result === 'object' && result && 'id' in result around an id read — a fabricated row passes it, so a REST / SDK / MCP update on a missing id answers 200 with a record that does not exist, on these two drivers only
              TursoDriver.update() remote branchpackages/drivers/driver-turso/src/turso-driver.ts:778this.formatRemoteRow(object, await this.remoteTransport!.update(...))Passes the fabricated row through as the driver's own result; the local branch (super.update, SqlDriver) returns null for the same miss — one driver, two postures, chosen by isRemote
              RemoteTransport.bulkUpdate()packages/drivers/driver-turso/src/remote-transport.ts:1625-1632if (updated) results.push(updated)The cross-driver skip convention SqlDriver.bulkUpdate follows is dead code on this transport: updated is never falsy, so a batch over N missing ids answers N fabricated rows
              In-package bulkUpdate on Mongonone — mongodb-driver.ts has no this.update( call site
              Testsmongodb-driver.test.ts:157,171 · turso-driver.test.ts:138,731 · turso-remote-autonumber-refusal.test.ts:369All read update() results over rows that EXIST; no test pins the miss posture on either driver, so changing it breaks nothing landed

              What this does NOT claim

              Dedup

              MCP search_issues, one targeted query (MongoDBDriver update fabricates synthesizes a record for a missing id RemoteTransport returns invented row instead of null not found) → 5 results, none on this posture: #13878 (the parent), #12586 (turso json column types), #11151 (mongo boolean aggregates), #6944 (turso remote autonumber), #5088 (updateMany hooks on a nonexistent id). Control query for #13878's own title → #13878 ranked first ⇒ the channel answers, the zero on this posture is a reading.

              Related

              #13878 (the ruling, item 5) · #13854 (SqlDriver.bulkUpdate, the live dependent of the null skip — the convention RemoteTransport.bulkUpdate copies but can never take)


              Triage — the block is discharged and the premise is now present tense

              #13878 closed as completed at 2026-09-02T08:28:30Z via merged PR #14434 ("declare the not-found arm on IDataDriver.update() and un-mask driver-memory's published update/upsert types"). The Blocked-by: #13878 line was therefore exhausted and has been removed from this body — verified by re-reading the card after the write.

              That discharge is what makes this card urgent rather than anticipatory. The contract's | null arm is on mainnow, so the sentence "these two drivers answer updated where every other driver answers not found" is a description of today, not of a state after some future landing. Everything the measurement table predicts is live.

              The measurement the ruling ordered — 「实施者测完『谁读它们的 update() 结果』后另立卡」 — is done and it is thorough (five readers enumerated, the dead if (updated) in RemoteTransport.bulkUpdate found, and the absence of any test pinning the miss posture established). So this card is ready for the ruling half: 「行为变更,量了再裁」 — the measuring is finished, the ruling is the maintainer's.

              <!-- os-decision-facets -->

              • ① 项目长远合理性(权重 ≥50%,领起推荐) —— 契约现在明写「找不到就是 null」,六个实现里四个照做,两个捏造一行数据交差。而那两个之所以捏造,靠的是「声明不允许 null,所以必须返回点什么」这个理由 —— 那个理由已经被 [finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 修掉了,姿态却还留着。长远终态只有一个:一个契约一个答案。①指向姿态 (a) 返回 null,因为那是契约自己声明的那一支,也是另外四个实现的做法;(b) 抛错是第三种姿态,等于在两个答案之上再加一个。
              • ② 实际业务拉动 —— 今天就在发生。[finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 已合并关闭,契约的 null 支已在 main 上。此刻一个客户对着已删除的记录发 update,在 Mongo 或 Turso 远程上拿回的是 200 加一条并不存在的记录。不是「将来会怎样」。
              • ③ 防 AI 犯错 —— 最响的一棱,而且坏在方向上:它在该说「没找到」的地方说了「成功」。捏造的那行还带着调用方自己传进去的字段和一个刚刚戳上的 updated_at,看起来完全合理,没有任何地方不对劲。调用方(人或 agent)据此认定写入落地了 —— 不重试、不告警、不回滚。批量更糟:RemoteTransport.bulkUpdate 里那句跨驱动的 if (updated) 跳过约定在这个传输上是死代码,N 个不存在的 id 换回 N 行假数据。
              • ④ 创业阶段不扩散 —— (a) 不引入任何新概念,只是让这两个实现回到契约已经声明的那一支;(b) 抛错要新增一条错误契约、要 REST 映射、要文档、要迁移指引。对齐优于新增。

              推荐:A = 姿态 (a),miss 返回 null 四棱同向。每个驱动配一条与 driver-memoryshould return null on update of missing record in default mode 同形的 pin —— 卡面已经量到当前没有任何测试钉住 miss 姿态,所以这是净增覆盖,不是改基线,风险面比一般行为变更小得多。
              回退:B = 姿态 (b) 抛错。 若维护者认为「更新一个不存在的记录」应当是响亮失败而非安静的 null,走这条 —— 但必须同批裁定另外四个实现是否一起改,⛔ 否则就是把两种答案变成三种,而那正是本卡要消灭的东西。
              置信缺口(本分析看不见什么): 没有量 Mongo 与 Turso 远程的真实部署面 —— 有多少客户在这两个驱动上跑写路径,决定 (a) 的迁移面是零还是非零。卡面量到的是仓内无测试钉住,仓外未知,而那正是「净增覆盖」这句话唯一可能不成立的地方。

              Generated by Claude Code

              Activity

              Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

              Metadata

              Metadata

              Assignees

              Type

              No type

              Projects

              No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                Skip to content

                [finding] MongoDBDriver.update() and RemoteTransport.update() fabricate a record for a missing id — a third posture that becomes a semantic violation once IDataDriver.update() declares null (#13878 ruling item 5) #14428

                Description

                @os-musk

                Filed unassigned by the #13878 dev seat (session session_0112hMx9hjJ9BgB28X97DS68), as the director's ruling on #13878 (comment 5494524403) item 5 directs — verbatim, untranslated:

                ⚠️Mongo / RemoteTransport 的捏造姿态在 A 落地后成为语义违反者 —— ⛔ 不折进本卡:实施者测完「谁读它们的 update() 结果」后另立卡(行为变更,量了再裁);

                Recording + measurement only — no severity asserted, no fix chosen; the posture is the maintainer's decision. Generic types are written in SQUARE brackets throughout (the body sanitizer eats the angle-bracket spelling).

                The two sites (measured at 79b6a22a5)

                ImplementationWhereWhat it does on a miss
                MongoDBDriver.update()packages/drivers/driver-mongodb/src/mongodb-driver.ts:403-424updateOne({ id }), then findOne({ id }); when nothing comes back it returns withoutUndefinedOwnKeys({ id: String(id), ...updateData }) — a row assembled from the caller's payload plus the updated_at it stamped, for an id that names no document
                RemoteTransport.update()packages/drivers/driver-turso/src/remote-transport.ts:1517-1534UPDATE ... WHERE "id" = ?, then SELECT * ... WHERE "id" = ?; when no row comes back it returns { id, ...data } — the caller's payload with the id stapled on

                Both are declared Promise[Record[string, unknown]] and both honour that declaration by inventing data. After #13878 the contract's not-found arm is null (the shape findOne carries, what InMemoryDriver / SqlDriver / TursoDriver (local) / SqliteWasmDriver return), so "a row for an id that does not exist" is no longer a way of satisfying the declaration — it is a value the declaration now distinguishes from, and these two drivers answer "updated" where every other driver answers "not found".

                Who reads their update() results — the measurement the ruling asked for

                ReaderPathWhat a fabricated row does there
                Engine by-id dispatchpackages/objectql/src/engine.ts:11017result = await driver.update(object, id, data, options)Returned to the engine's caller as the updated record. The only guard downstream is typeof result === 'object' && result && 'id' in result around an id read — a fabricated row passes it, so a REST / SDK / MCP update on a missing id answers 200 with a record that does not exist, on these two drivers only
                TursoDriver.update() remote branchpackages/drivers/driver-turso/src/turso-driver.ts:778this.formatRemoteRow(object, await this.remoteTransport!.update(...))Passes the fabricated row through as the driver's own result; the local branch (super.update, SqlDriver) returns null for the same miss — one driver, two postures, chosen by isRemote
                RemoteTransport.bulkUpdate()packages/drivers/driver-turso/src/remote-transport.ts:1625-1632if (updated) results.push(updated)The cross-driver skip convention SqlDriver.bulkUpdate follows is dead code on this transport: updated is never falsy, so a batch over N missing ids answers N fabricated rows
                In-package bulkUpdate on Mongonone — mongodb-driver.ts has no this.update( call site
                Testsmongodb-driver.test.ts:157,171 · turso-driver.test.ts:138,731 · turso-remote-autonumber-refusal.test.ts:369All read update() results over rows that EXIST; no test pins the miss posture on either driver, so changing it breaks nothing landed

                What this does NOT claim

                Dedup

                MCP search_issues, one targeted query (MongoDBDriver update fabricates synthesizes a record for a missing id RemoteTransport returns invented row instead of null not found) → 5 results, none on this posture: #13878 (the parent), #12586 (turso json column types), #11151 (mongo boolean aggregates), #6944 (turso remote autonumber), #5088 (updateMany hooks on a nonexistent id). Control query for #13878's own title → #13878 ranked first ⇒ the channel answers, the zero on this posture is a reading.

                Related

                #13878 (the ruling, item 5) · #13854 (SqlDriver.bulkUpdate, the live dependent of the null skip — the convention RemoteTransport.bulkUpdate copies but can never take)


                Triage — the block is discharged and the premise is now present tense

                #13878 closed as completed at 2026-09-02T08:28:30Z via merged PR #14434 ("declare the not-found arm on IDataDriver.update() and un-mask driver-memory's published update/upsert types"). The Blocked-by: #13878 line was therefore exhausted and has been removed from this body — verified by re-reading the card after the write.

                That discharge is what makes this card urgent rather than anticipatory. The contract's | null arm is on mainnow, so the sentence "these two drivers answer updated where every other driver answers not found" is a description of today, not of a state after some future landing. Everything the measurement table predicts is live.

                The measurement the ruling ordered — 「实施者测完『谁读它们的 update() 结果』后另立卡」 — is done and it is thorough (five readers enumerated, the dead if (updated) in RemoteTransport.bulkUpdate found, and the absence of any test pinning the miss posture established). So this card is ready for the ruling half: 「行为变更,量了再裁」 — the measuring is finished, the ruling is the maintainer's.

                <!-- os-decision-facets -->

                • ① 项目长远合理性(权重 ≥50%,领起推荐) —— 契约现在明写「找不到就是 null」,六个实现里四个照做,两个捏造一行数据交差。而那两个之所以捏造,靠的是「声明不允许 null,所以必须返回点什么」这个理由 —— 那个理由已经被 [finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 修掉了,姿态却还留着。长远终态只有一个:一个契约一个答案。①指向姿态 (a) 返回 null,因为那是契约自己声明的那一支,也是另外四个实现的做法;(b) 抛错是第三种姿态,等于在两个答案之上再加一个。
                • ② 实际业务拉动 —— 今天就在发生。[finding] InMemoryDriver.update() returns null for a missing id, which IDataDriver.update()'s declared return type forbids — hidden for the life of the code by an inferred any #13878 已合并关闭,契约的 null 支已在 main 上。此刻一个客户对着已删除的记录发 update,在 Mongo 或 Turso 远程上拿回的是 200 加一条并不存在的记录。不是「将来会怎样」。
                • ③ 防 AI 犯错 —— 最响的一棱,而且坏在方向上:它在该说「没找到」的地方说了「成功」。捏造的那行还带着调用方自己传进去的字段和一个刚刚戳上的 updated_at,看起来完全合理,没有任何地方不对劲。调用方(人或 agent)据此认定写入落地了 —— 不重试、不告警、不回滚。批量更糟:RemoteTransport.bulkUpdate 里那句跨驱动的 if (updated) 跳过约定在这个传输上是死代码,N 个不存在的 id 换回 N 行假数据。
                • ④ 创业阶段不扩散 —— (a) 不引入任何新概念,只是让这两个实现回到契约已经声明的那一支;(b) 抛错要新增一条错误契约、要 REST 映射、要文档、要迁移指引。对齐优于新增。

                推荐:A = 姿态 (a),miss 返回 null 四棱同向。每个驱动配一条与 driver-memoryshould return null on update of missing record in default mode 同形的 pin —— 卡面已经量到当前没有任何测试钉住 miss 姿态,所以这是净增覆盖,不是改基线,风险面比一般行为变更小得多。
                回退:B = 姿态 (b) 抛错。 若维护者认为「更新一个不存在的记录」应当是响亮失败而非安静的 null,走这条 —— 但必须同批裁定另外四个实现是否一起改,⛔ 否则就是把两种答案变成三种,而那正是本卡要消灭的东西。
                置信缺口(本分析看不见什么): 没有量 Mongo 与 Turso 远程的真实部署面 —— 有多少客户在这两个驱动上跑写路径,决定 (a) 的迁移面是零还是非零。卡面量到的是仓内无测试钉住,仓外未知,而那正是「净增覆盖」这句话唯一可能不成立的地方。

                Generated by Claude Code

                Activity

                Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

                Metadata

                Metadata

                Assignees

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions