Found while carrying out #11833 (the two-site DataEngineLike sweep). Filed unassigned as an observation. Measured at de81acf547, against origin/main = 497ded7801.
The observation
#11833 names two consumer-local structural engine types. There is a third, and it is the one that actually matters: ConnectionEngineLike in packages/services/service-datasource/src/datasource-connection-service.ts (~:89). Unlike the other two it is exported, and it is what datasource-admin-plugin.ts casts its engine handle to for hot pool (de)registration.
It declares seven engine members. Checked member-by-member against packages/spec/src/contracts/:
| member | declared contract equivalent |
|---|
getDriverByName? | IDataEngine.getDriverByName? |
getDefaultDriverName? | IDataEngine.getDefaultDriverName? |
syncObjectSchema? | has a spec mention — not verified as a contract member |
registerDriver? | IObjectQLEngine.registerDriver — signature mismatch, see below |
registerDatasourceDef? | NONE — fork |
markDatasourceUnavailable? | NONE — fork |
clearDatasourceUnavailable? | NONE — fork |
The three forks are all real methods on the ObjectQL class (packages/objectql/src/engine.ts: registerDatasourceDef :4953, markDatasourceUnavailable, clearDatasourceUnavailable) — implemented, called across a package boundary, and declared by no contract. That is the #4251 B3 shape exactly: the producer side meets no compiler, so drift lands silently in the consumer.
The measured mismatch
registerDriver?: (driver: unknown, isDefault?: boolean) => void is wider than the engine it shadows. The contract is registerDriver(driver: IDataDriver, isDefault?: boolean): void. Under this repo's strict: true, the real engine is therefore not assignable to this local view:
Type 'IObjectQLEngine' is not assignable to type 'ConnectionEngineLike'.
Types of property 'registerDriver' are incompatible.
Type '(driver: IDataDriver, isDefault?: boolean) => void' is not assignable to
type '(driver: unknown, isDefault?: boolean) => void'.
Types of parameters 'driver' and 'driver' are incompatible.
Type 'unknown' is not assignable to type 'IDataDriver'.
(Measured on the identical registerDriver? declaration in datasource-admin-plugin.ts during #11833; the declaration in this file is byte-identical.) The practical effect is that this seam's type promises the engine accepts any value as a driver, which it does not — so a mis-shaped driver reaching registerDriver is a runtime problem the compiler is currently structured not to see.
Why this is filed rather than fixed
Closing it means deciding whether the three forked members get declared on a contract, and that is a public-surface widening — a maintainer call, not a consumer-side one. #11833's ruling is explicit that a member with no declared equivalent is a fork to report, never to widen from the consumer side.
Refs: #11833 (the two-site sweep this was found under) · #11493 (the ruling) · #4251 (B3, the declared-contract sweep this pattern escaped).
Found while carrying out #11833 (the two-site
DataEngineLikesweep). Filed unassigned as an observation. Measured atde81acf547, againstorigin/main=497ded7801.The observation
#11833 names two consumer-local structural engine types. There is a third, and it is the one that actually matters:
ConnectionEngineLikeinpackages/services/service-datasource/src/datasource-connection-service.ts(~:89). Unlike the other two it is exported, and it is whatdatasource-admin-plugin.tscasts its engine handle to for hot pool (de)registration.It declares seven engine members. Checked member-by-member against
packages/spec/src/contracts/:getDriverByName?IDataEngine.getDriverByName?getDefaultDriverName?IDataEngine.getDefaultDriverName?syncObjectSchema?registerDriver?IObjectQLEngine.registerDriver— signature mismatch, see belowregisterDatasourceDef?markDatasourceUnavailable?clearDatasourceUnavailable?The three forks are all real methods on the
ObjectQLclass (packages/objectql/src/engine.ts:registerDatasourceDef:4953,markDatasourceUnavailable,clearDatasourceUnavailable) — implemented, called across a package boundary, and declared by no contract. That is the #4251 B3 shape exactly: the producer side meets no compiler, so drift lands silently in the consumer.The measured mismatch
registerDriver?: (driver: unknown, isDefault?: boolean) => voidis wider than the engine it shadows. The contract isregisterDriver(driver: IDataDriver, isDefault?: boolean): void. Under this repo'sstrict: true, the real engine is therefore not assignable to this local view:(Measured on the identical
registerDriver?declaration indatasource-admin-plugin.tsduring #11833; the declaration in this file is byte-identical.) The practical effect is that this seam's type promises the engine accepts any value as a driver, which it does not — so a mis-shaped driver reachingregisterDriveris a runtime problem the compiler is currently structured not to see.Why this is filed rather than fixed
Closing it means deciding whether the three forked members get declared on a contract, and that is a public-surface widening — a maintainer call, not a consumer-side one. #11833's ruling is explicit that a member with no declared equivalent is a fork to report, never to widen from the consumer side.
Refs: #11833 (the two-site sweep this was found under) · #11493 (the ruling) · #4251 (B3, the declared-contract sweep this pattern escaped).