Skip to content

[finding] aggregate() IS on the IDataDriver contract and is masked as Promise[any] on both SQL drivers — #15267's census and its dispatch order both say it is not #17277

Description

@claude

Filed by the domain:engine execution PM seat, from the #15267 round (PR #17258).

⛔ Filed unassigned and unlabelled, as an observation for triage. Grade deliberately not asserted.

The defect

aggregate() is declared on the IDataDriver contract and is masked as Promise<any> on both SQL driver classes — the same defect class #15267 just repaired for five sibling doors, on the same two files.

Measured on origin/main, packages/spec/src/contracts/data-driver.ts:

:250   aggregate?(object: string, query: DriverQuery, options?: DriverOptions): Promise<Record<string, unknown>[]>;

Optional, but declared — with its own documented calling convention at :220-249, including the note that the engine dispatches on typeof driver.aggregate === 'function'. Positive control on the same file: findOne at :181.

Both SqlDriver.aggregate and TursoDriver.aggregate publish Promise<any> over that declaration.

Why it was excluded from #15267, and why that exclusion needs revisiting

#15267's census states aggregate() is not on the contract ("its own comment says so, #6212"), and the dispatch order for that card repeated the claim as a ruling: 「analyzeQuery() and aggregate() are NOT on IDataDriver」. The implementer followed the instruction exactly and left the method alone — correctly, since a narrow diff was what the order asked for.

The instruction was right; its stated reason was false. The card's census and the dispatch order inherited the same error from each other. The implementer measured it and refused to let the false premise stand silently, which is the only reason it is recorded here rather than lost.

⚠️ analyzeQuery is a different matter and is not part of this card: it has no hit anywhere in data-driver.ts, so that half of the original claim survives. It is a public helper behind explain(), not a door.

What needs deciding

  1. Is the ? optionality material? aggregate is declared optional while the five doors [finding] driver-sql / driver-turso still publish Promise[any] on five IDataDriver doors after #14438 — findOne, create, bulkCreate, execute, explain on SqlDriver, and TursoDriver.create()'s own override #15267 moved are required. Whether an optional contract member carries the same "publish what you declared" obligation is a real question, not a foregone conclusion, and it is why this is filed rather than folded into [finding] driver-sql / driver-turso still publish Promise[any] on five IDataDriver doors after #14438 — findOne, create, bulkCreate, execute, explain on SqlDriver, and TursoDriver.create()'s own override #15267.
  2. Does TursoDriver.aggregate override, or inherit? [finding] driver-sql / driver-turso still publish Promise[any] on five IDataDriver doors after #14438 — findOne, create, bulkCreate, execute, explain on SqlDriver, and TursoDriver.create()'s own override #15267 measured four turso overrides among the five doors it moved; whether aggregate is a fifth override or inherited from SqlDriver decides whether this is one site or two.
  3. Same grade question as [finding] driver-sql / driver-turso still publish Promise[any] on five IDataDriver doors after #14438 — findOne, create, bulkCreate, execute, explain on SqlDriver, and TursoDriver.create()'s own override #15267? That card landed minor + BREAKING with a type-surface-only ADR-0087 marker, on landed precedent PR feat(driver-sql,driver-turso): update() publishes its honest type — the contract's Record[string, unknown] | null, not any (#14438) #15280. If this one moves, it is presumably the same rung — but the optionality in (1) may change the consumer-breakage argument, since a consumer reading an optional member already guards it.

Adjacent, deliberately not conflated

These three are the same neighbourhood and were each explicitly out of scope for #15267. Whether they belong on this card or their own is triage's call.


Generated by Claude Code

Activity

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions