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)
Filed by the
domain:servicesPM 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
updateDatasourcerebuild the live pool only when a connectivity-bearing field actually changed. The ruled set isdriver·config·external(incl.credentialsRef) ·pool·active.schemaModeis 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 againstorigin/main:updateDatasource(the merge copies it)packages/services/service-datasource/src/datasource-admin-service.ts:401—...(patch.schemaMode !== undefined ? { schemaMode: patch.schemaMode } : {})datasource-connection-service.ts:269—if (ds.schemaMode && ds.schemaMode !== 'managed') return true;toSpec→factory.create(driver construction)datasource-connection-service.ts:881registerDatasourceDef(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 OLDschemaMode— 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.
schemaModegoverns the write gate (external.allowWritesenforcement) and what the factory builds. An admin flippingmanaged⇄externalis making a write-permission-shaped change and has no signal that it did not take effect.Not established
schemaModeonly, then observe the def / policy still on the old value) is the honest first step for whoever takes this.attemptConnect's reads and found this one;sslis atoSpecinput but is not a field ofStoredDatasourceorDatasourceDraft, so it cannot change through update;autoConnectis neither patchable nor read byattemptConnect. Noconfigsub-key is excluded — the whole block feedsfactory.create.Options (the implementer's, with its recommendation — ⛔ this card does not rule)
schemaModeto the trigger set. One comparator entry indatasource-connectivity-change.tsplus one test. The rebuild path now exists, so enforcement is one set-membership. ⇒ Recommended by the datasource update never rebuilds its driver —already-registeredshort-circuits the reconfigure path, so the OLD pool stays live and the admin UI reports success #13804 implementer:schemaModegoverns the write gate, an admin expects a connection edit to take effect like any other, and a field that silently applies only after restart is precisely the trap an AI-authored metadata app walks into.schemaModeedits need a restart.schemaModeat runtime (reject it inupdateDatasource). ⛔ Assessed as the weakest: it removes an already-published editing surface, which is a contract change neither datasource update never rebuilds its driver —already-registeredshort-circuits the reconfigure path, so the OLD pool stays live and the admin UI reports success #13804 nor this card opened.datasource-admin-service.tsanddatasource-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
unregisterDrivereviction primitive the rebuild goes through)