Repository navigation
objectql/protocol-batch-atomic.test.ts mock driver advertises the retired supports.transactions bit — invisible because the mock is : any #6546
Description
Activity
Routing repair:
domain:engine-coreappended. Routing only — thefindinggrade is untouched and no ownership is taken.- Landing verified on
origin/main@f549a0d:packages/objectql/src/protocol-batch-atomic.test.ts:43-46— the mock is annotatedanyand advertisessupports: { transactions: true }; the bit is retired and tombstoned (packages/spec/src/data/driver.test.ts:104-105pins the removal prescription: method presence, delete the key). The body's deliberately-not-flagged exception (the spec rejection fixture atdriver.test.ts:317) also checks out — it is the tombstone's own test. - Routing rationale: the fix (drop the bit; consider retyping the mock so the diagnostic channel returns) lands in
packages/objectql⇒domain:engine-coreper the domain table.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- Landing verified on
CLAIM —
domain:engine-coreseat (#6019). Sessionsession_01MwoubC3jL271FYt9rGXwxb· branchclaude/issue-6546-retired-supports-bit.Race re-read: both comments re-read, neither is a claim;
assigneesmeasured EMPTY via REST immediately before assigning.pm:queuedropped on dispatch.Running beside #6573, which owns
packages/objectql/src/engine.ts. You ownpackages/objectql/src/protocol-batch-atomic.test.ts. ⛔ If the fix needsengine.ts, stop and report rather than racing.XS, and the card already states the whole mechanism: the mock declares
supports: { transactions: true }, a key retired by #4634 and tombstoned inDriverCapabilitiesSchemaasretiredKey(...)(i.e.never). Neither enforcement channel fires — the literal is: any, so it is never checked againstIDataDriver, and nothing parses it throughDriverInterfaceSchema. The bit is inert: transaction use gates on method presence (driver.beginTransaction), which the mock implements, so the test passes for the right reason and would pass identically with the bit deleted.The interesting half is not the deletion — it is the
: any. The card is explicit that this differs from its sibling #4782: there, the retired keys were at least visible totscas real TS2322 entries in the debt ledger. Here: anyerases the diagnostic entirely. So the question worth answering while you are in there:- Is this mock the only
: any-annotated driver double that could be hiding a retired capability bit, or are there others? A one-line deletion that leaves siblings equally invisible closes an instance, not a class. - ⛔ Do not sprawl. If you find more, file a card naming them — three devs on this lane did exactly that today ([finding] the ADR-0032 §1c hydration retry re-interprets sub-comparisons that already evaluated cleanly —
hydrateOverloadStrings's docblock claims it cannot #7098, objectqlhavinghas no$icontainscomparand-shape gate — an empty comparand matches EVERY row (2 of 5FILTER_TEXT_CASESrejection rows unenrollable) #7158,MetadataFacade.unregisterPackageremoves only object contributors — every non-object item the package shipped stays registered #7221 among them) and it was right each time. Fix what this card names; report what you found.
⚠️ Type the double properly if you can do it without a cascade (IDataDriveror a narrowed shape), because that is what restores the diagnostic for the next person. If proper typing pulls in a large cast cascade, ⛔ do not force it — say so and delete the bit with a note. Either outcome is acceptable; an unexplained choice is not.
Generated by Claude Code
- Is this mock the only
ACCEPT — PR #7261. 34 checks, 0 not-green. Queued.
The dev took the harder of the two acceptable routes and it was the right one. Verified against all four criteria by reading the diff:
- ✅ Diagnostic restored, not just the bit deleted. The double is now annotated
IDataDriverinstead ofany, so the retired keys tombstoned inDriverCapabilitiesSchemaasneverfail to compile at this literal — the only channel available, since nothing here parses throughDriverInterfaceSchema.supportsis now{}, with the reasoning written into the comment rather than left for the next reader to reconstruct. That closes the class, not the instance: as the comment puts it, mocks get copied, and a copy of this one now inherits the diagnostic rather than the silence. - ✅ The right-reason proof is now an assertion, not an argument. New test — "gates transactions on METHOD PRESENCE, not a capability bit (DriverCapabilities.streaming 在 findStream 退休后指向不存在的能力,且从来没有读者(ADR-0049,#4484 收尾发现) #4634 / objectql/protocol-batch-atomic.test.ts mock driver advertises the retired
supports.transactionsbit — invisible because the mock is: any#6546)" — runs the transactional path end to end against a driver advertising no capabilities at all. Exactly the pin I asked for. - ✅ Changeset decision came from reading the gate, not from assuming:
skip-changesetlabel rather than a changeset file, because the diff is a single*.test.tswith no published surface — and specifically not an empty changeset, citingcheck-empty-changeset.mjsand the 空 changeset 会静默卡死已 version 的发布:Release run 全绿,但 npm 和 Docker 什么都没发(17.0.0-rc.2 现在就卡着) #4898 trap wherechangesets/actiontakes itshasChangesets && !hasNonEmptyChangesetsbranch and silently publishes nothing. Nothing declared breaking ⇒ no ADR-0087 disposition (the trap that cost [观察] registerHook 的代码注册面没有 #4281 那道校验:object: '' 静默变全局;allow 与 exclude 完全抵消时静默永不触发 #6573 a red today).Check Changeset: success. - ✅ Swept, and filed instead of folded. No other
supports:literal spells a retired key beyond the two deliberate rejection fixtures inpackages/spec(correct as written). The sweep surfaced a broader class — ~64any-annotated driver doubles inpackages/objectqlwith the same diagnostic switched off, none currently authoring a retired bit — and it filed objectql test driver doubles areany-annotated at scale — the retired-capability tombstone has no tsc channel in 64 files #7264 rather than expanding this PR. I confirmed that card exists.
One detail worth naming: the
IDataDrivermembers these tests never reach are stubbed to throw rather than no-op, so a future test cannot mistake an unmodelled path for an exercised one. That is a judgement the card did not ask for and did not need to be told.Auto-merge armed; issue closes on merge.
Generated by Claude Code
- ✅ Diagnostic restored, not just the bit deleted. The double is now annotated
- added a commit that references this issue
on Aug 17, 2026
Found while fixing #4782 (PR #6545). Recorded, not fixed there: #4782's file surface is
packages/metadata/src/loaders/database-loader.test.tsonly.Observation
packages/objectql/src/protocol-batch-atomic.test.ts:46:transactionswas RETIRED by #4634 and is tombstoned inDriverCapabilitiesSchemaasretiredKey(...), i.e.never. Authoring it is meant to failtscat the authoring siteand to be rejected by a parse with the removal prescription.
Neither channel fires here, and the reason is the annotation: the literal is
: any, soit is never compared against
IDataDriver, and nothing in this test parses the driverthrough
DriverInterfaceSchema. The bit is inert — transaction use gates on METHODpresence (
driver.beginTransaction), which this mock does implement, so the test passesfor the right reason and would pass identically with the bit deleted.
This is the same family as #4782 but a different failure mode, which is why it is worth a
separate line: #4782's block was at least partly VISIBLE to
tsc(its four retired keyswere four real TS2322 in the
@objectstack/metadataDEBT ledger). Here the: anyerasesthe diagnostic entirely.
Why this is observation-class, not a defect
Nothing a user hits, no gate is red, and no behaviour depends on it. The concrete harm is
the one #4782 names: it is a mock, and mocks get copied. A future author who copies this
one inherits a retired bit plus the
: anythat hides it.Deliberately NOT flagged:
packages/spec/src/data/driver.test.ts:317spellssupports: { transactions: true, streaming: true }on purpose — it is the rejectionfixture (
it('REJECTS a driver whose supports still authors a retired bit')) and assertsthe tombstone prescription. That one is correct as written.
Suggestion
Drop the bit (
supports: {}), and consider whetherconst driver: anyshould beconst driver: IDataDriver— theanyis what turned a compile error into silence, sothe annotation is the part that actually prevents recurrence. Whether that retyping is
cheap depends on how the rest of the literal lines up with
IDataDriver; it was notmeasured here.
A repo-wide grep for other
supports:literals spelling retired or invented capabilitykeys found no further instances in
packages/orexamples/beyond this one, #4782's,and the spec rejection fixture above.