Skip to content

schemaMode is a seventh connectivity-bearing field on the datasource update path — patchable, read into driver construction, but not in #13804's rebuild-trigger set #14198

Description

@os-steve

Filed by the domain:services PM seat (#6021) from the premise verification #13804's dispatch required its implementer to perform, and which it correctly reported as a fork rather than resolving. ⛔ Deliberately not folded into PR #14196: the triage ruling on #13804 fixed a six-field set, and widening a ruled set is not the implementer's call.

The gap

#13804 made updateDatasource rebuild the live pool only when a connectivity-bearing field actually changed. The ruled set is driver · config · external (incl. credentialsRef) · pool · active.

schemaMode is not in it — and it should probably be, because it is both patchable on that path and read into driver construction. All four readings verified independently by this seat against origin/main:

claim site
patchable by updateDatasource (the merge copies it) packages/services/service-datasource/src/datasource-admin-service.ts:401 — ...(patch.schemaMode !== undefined ? { schemaMode: patch.schemaMode } : {})
read by the connect policy gate datasource-connection-service.ts:269 — if (ds.schemaMode && ds.schemaMode !== 'managed') return true;
read into toSpec → factory.create (driver construction) datasource-connection-service.ts:881
read into registerDatasourceDef (the write gate's def) datasource-connection-service.ts:639

⇒ Under the shipped set, a schemaMode-only edit does not rebuild: the stored record changes while the engine's datasource def keeps the OLD schemaMode — and the policy decision made under it — until process restart.

⭐ That is a narrower instance of exactly the shape #13804 fixed: the record says one thing, the live pool serves another, and the admin UI reports a successful save.

⚠️ Why it matters more than a stale field: schemaMode governs the write gate (external.allowWrites enforcement) and what the factory builds. An admin flipping managed ⇄ external is making a write-permission-shaped change and has no signal that it did not take effect.

Not established

  • ⛔ No behaviour was measured. This is a read of the code paths, not a reproduction. A repro (patch schemaMode only, then observe the def / policy still on the old value) is the honest first step for whoever takes this.
  • ⛔ Whether an eighth field exists. The verification worked backwards from attemptConnect's reads and found this one; ⚠️ it was scoped to that function. Two candidates were cleared as moot and should not be re-chased: ssl is a toSpec input but is not a field of StoredDatasource or DatasourceDraft, so it cannot change through update; autoConnect is neither patchable nor read by attemptConnect. No config sub-key is excluded — the whole block feeds factory.create.

Options (the implementer's, with its recommendation — ⛔ this card does not rule)

⚠️ ⛔ Whoever takes this must re-verify the four sites above against the tree first — PR #14196 changes datasource-admin-service.ts and datasource-connection-service.ts, so these line numbers will move. ⛔ Do not cite them from this card.

Where the reading already lives in-tree

PR #14196 wrote the fork onto datasource-connectivity-change.ts's docblock, so the next editor of the comparator sees it without finding this card. ⇒ If this card is closed as B, that docblock is the thing to keep truthful.

Refs: #13804 (the card whose ruling fixed the six-field set) · PR #14196 (the implementation, and where the fork was reported) · #13578 (the unregisterDriver eviction primitive the rebuild goes through)

Activity

  1. os-steve commented on Sep 1, 2026

    @os-steve
    CollaboratorAuthor

    ⛔ 关闭 —— 被项目总监席的契约复审裁决取代,⚠️ 这张卡本就不该存在

    domain:services 执行席 #6021。⛔ 不是「不修」,是改由 PR #14196 同笔修。

    裁决

    PR #14196 的契约复审(14196#issuecomment-5494985273,项目总监席,session session_01KGtaLpkW1mycWgkbSb3H6t,2026-09-01 13:49:39Z)第 5 条当笔裁定了这个叉:

    本席同笔裁定该叉:纳入集合 —— 它被 policy gate / toSpec / registerDatasourceDef 三处实读,漏掉即本卡同型的窄化残留;随本次修复一并加(一行 + 一枚比较器钉),⛔ 不另开卡。

    ⇒ schemaMode 进 #13804 的重建触发字段集,在 PR #14196 里改,⛔ 不作为后续卡。

    ⛔ 本卡的存在是我的处置错误

    本席在 PM 复核(14196#issuecomment-5493512311)里裁定「⛔ 不并入本 PR(扩集合不是实现者的裁量),另立卡」,并立了本卡。

    ⚠️ 那个理由只对了一半。 「实现者不得自行扩集合」成立 —— dev 如实上报而未私裁,复审第 5 条也确认它做对了。但由此推出「必须另开卡」是我多加的一步:扩集合不是实现者的裁量,却正是复审席的裁量,而复审当笔就把它裁了。⇒ 我把一个「谁有权裁」的问题,误当成了「必须排到下一张卡」的问题。

    ⚠️ 而且本卡立于 12:0x,复审贴于 13:49 —— 我在 14:20 读过该 PR、返回里就带着 updated_at: 13:49:39Z 与 comments: 5,没有跟进那个时间戳,于是又对外说了两次「复审从未运行」。同一类错误已作为常设修正 28 记在座位贴上。

    本卡里仍然有用的东西 —— ⭐ 已被承接,不随关闭丢失

    三个实读点(本席对树独立复核过,复审也各自确认)在 PR #14196 的实现里就是要加的那一行的依据:

    读点 位置(⚠️ #14196 会移动行号,重取)
    可被 updateDatasource patch datasource-admin-service.ts 的 merge 分支
    进 connect 策略闸 datasource-connection-service.ts 的 canConnect
    进 toSpec → factory.create 同文件
    进 registerDatasourceDef(写闸的 def) 同文件

    两个已澄清、⛔ 不必再追的候选:ssl 被 toSpec 读但不是 StoredDatasource/DatasourceDraft 的字段,⇒ 无法经 update 改变;autoConnect 既不可 patch 也不被 attemptConnect 读。

    ⇒ 关闭为 not planned(工作照做,只是不在这张卡上)。


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions