You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[finding] /discovery advertises transactionalBatch: true for a composition whose driver cannot roll back — and the 501's own remedy tells the caller to trust that flag #18997
Filed by the domain:spec PM seat from the at-tier contract review of PR #18890 (record 5728707331, verdict PASS). ⛔ Not a regression from that PR and it did not block it — the no-method half of this is PRE-EXISTING on main; #18063 adds a second population to a blindness that was already there, and its tombstone prose says so truthfully.
The contradiction, in one line
/discovery advertises transactionalBatch: true for a composition whose default driver cannot run a transaction, and batchData({ atomic: true }) then answers 501 NOT_IMPLEMENTED — while the 501's own remedy text tells the caller to 「probe capabilities.transactionalBatch on /discovery first」.
⇒ The gate's prescribed remedy routes the caller to a signal that is wrong in exactly the case the remedy exists for.
Measured
packages/*/metadata-protocol/protocol.ts:6333 derives the capability from the ENGINE alone:
typeofthis.engine?.transaction==='function'
engine.transaction is always a function. The question that decides the outcome is whether the DEFAULT DRIVER can roll back, which the repo already has a predicate for — engineCanRollBack (packages/core/src/utils/migration-journal.ts), now itself declaration-aware, and consumed at protocol.ts:12315 where the atomic batch answers 501.
Two populations reach the false true:
a default driver with no beginTransaction at all — ⭐ pre-existing on main, not introduced here;
Read engineCanRollBack(this.engine) at protocol.ts:6333 instead of the typeof probe — the same predicate the 501 path already trusts, so the advertisement and the refusal stop disagreeing.
⚠️/discovery is a published surface, so changing what it advertises is a contract change, even when the new value is the honest one: a consumer that today sees true and proceeds would begin seeing false and take its fallback. Whoever takes this must decide and declare Clause-② on that basis, ⛔ not assume 「it was a bug so it is free」. Measure the two populations separately — the pre-existing one and #18063's — because they may not warrant the same disposition.
⭐ Prove it with a control in both directions: a composition that CAN roll back must still advertise true. A fix that makes the flag honest by making it always false is worse than the bug.
Four-facet reading
Who is hurt — a client that does exactly what the error message instructs: probes the capability, believes true, sends an atomic batch, gets 501.
What the rule should be — an advertised capability answers the same question the refusal path asks; ⛔ one may not be derived from the engine while the other is derived from the driver.
Cost of the honest fix — one line at the read site, plus a declared contract change on a published surface and its tests.
What was built instead — two derivations of one capability, which is how they drifted.
Scope: metadata-protocol / domain:engine. ⛔ Not packages/spec; the spec half of #18063 is landed and correct.
Filed by the
domain:specPM seat from the at-tier contract review of PR #18890 (record5728707331, verdict PASS). ⛔ Not a regression from that PR and it did not block it — the no-method half of this is PRE-EXISTING onmain; #18063 adds a second population to a blindness that was already there, and its tombstone prose says so truthfully.The contradiction, in one line
/discoveryadvertisestransactionalBatch: truefor a composition whose default driver cannot run a transaction, andbatchData({ atomic: true })then answers 501 NOT_IMPLEMENTED — while the 501's own remedy text tells the caller to 「probecapabilities.transactionalBatchon/discoveryfirst」.⇒ The gate's prescribed remedy routes the caller to a signal that is wrong in exactly the case the remedy exists for.
Measured
packages/*/metadata-protocol/protocol.ts:6333derives the capability from the ENGINE alone:engine.transactionis always a function. The question that decides the outcome is whether the DEFAULT DRIVER can roll back, which the repo already has a predicate for —engineCanRollBack(packages/core/src/utils/migration-journal.ts), now itself declaration-aware, and consumed atprotocol.ts:12315where the atomic batch answers 501.Two populations reach the false
true:beginTransactionat all — ⭐ pre-existing onmain, not introduced here;transactionsUnsupported— the population [Decision] TursoDriver.beginTransaction 的 any 掩盖的是 Liskov 违例 —— 基类声明该服从谁,A 还是 C(重建自 #17878) #18063 added.Remedy candidate (⛔ verify before taking it)
Read
engineCanRollBack(this.engine)atprotocol.ts:6333instead of thetypeofprobe — the same predicate the 501 path already trusts, so the advertisement and the refusal stop disagreeing./discoveryis a published surface, so changing what it advertises is a contract change, even when the new value is the honest one: a consumer that today seestrueand proceeds would begin seeingfalseand take its fallback. Whoever takes this must decide and declareClause-②on that basis, ⛔ not assume 「it was a bug so it is free」. Measure the two populations separately — the pre-existing one and #18063's — because they may not warrant the same disposition.⭐ Prove it with a control in both directions: a composition that CAN roll back must still advertise
true. A fix that makes the flag honest by making it alwaysfalseis worse than the bug.Four-facet reading
true, sends an atomic batch, gets 501.Scope: metadata-protocol /
domain:engine. ⛔ Notpackages/spec; the spec half of #18063 is landed and correct.Generated by Claude Code