Skip to content

objectql test driver doubles are any-annotated at scale — the retired-capability tombstone has no tsc channel in 64 files #7264

Description

@os-zhuang

Found while fixing #6546 (PR #7261). Recorded, not fixed there — #6546's file surface is
packages/objectql/src/protocol-batch-atomic.test.ts only, and folding this in would have turned an
XS card into a 64-file sweep.

Observation

#6546 was one driver double authoring a capability key retired by #4634. The deletion was trivial;
the interesting half was why nobody noticed — the literal was annotated const driver: any, so it
was never compared against IDataDriver, and nothing in that file parses it through
DriverInterfaceSchema. With both channels off, the retiredKey(...) tombstone in
DriverCapabilitiesSchema had nothing to fire through.

That annotation is not unusual in this package. Measured on origin/main @ 0caf122:

files
packages/objectql/src/**/*.test.ts with a driver-ish double annotated : any = 64
…of which also spell supports: {} as any 17
test files that reference IDataDriver at all 14

What this is NOT

No retired bit is authored in any of them today, and no gate is red. A repo-wide sweep for
supports: literals spelling retired or invented keys (run as part of #6546) found nothing beyond
#6546's own instance, #4782's, and the two deliberate rejection fixtures
(packages/spec/src/data/driver.test.ts:317, packages/spec/src/data/datasource.test.ts:60), which
are correct as written. Every other literal is either {} or a live bit
(autonumber, batchSchemaSync, queryDateGranularity).

So this is observation-class, exactly like #6546: nothing a user hits, nothing broken.

Why it is still worth a line

The tombstone's stated design is that a retired key is authored-unwritable — "tsc rejects it at
the authoring site" is the first of the two channels driver.zod.ts names for it. Across these 64
files that channel is switched off, so the tombstone's protection currently rests entirely on the
second channel (a parse), which test doubles by definition rarely go through.

The concrete harm is the one #4782 and #6546 both name: mocks get copied. #6546's mock had
carried its retired bit since #4634 without anyone noticing, and it was found by reading, not by a
gate. The cost of the class is that the next such copy is equally invisible.

Measurement from #6546, for sizing

Retyping one double any → IDataDriver cost three stubs for interface members the tests never
reach (upsert, syncSchema, dropTable), and moved @objectstack/objectql's measured
TEST_DEBT count by zero (340 → 340, ceiling 355). One data point, not a trend — that double
was already close to interface-shaped, and the as any in 17 of the files above suggests some are
further away. Anyone picking this up should re-measure per file rather than extrapolate from one.

Note also that a naive sweep will trip TS2790 wherever a test does delete driver.<requiredMember>
to prove a method-presence gate; Reflect.deleteProperty(...) is the cast-free equivalent (#6546
used it).

Suggestion

Not obviously a single sweep. Plausible shapes, in increasing cost:

  1. Leave it, and retype opportunistically whenever a file is touched for another reason.
  2. Retype only the doubles that author a non-empty supports — the ones where a capability key
    could actually be spelled wrong — which is a much smaller set than 64.
  3. A gate that fails a driver double annotated any, ratcheted against a measured baseline in the
    style of check-engine-double-contract.

Filing without a recommendation; the sizing above is what I measured, not a plan.

Activity

  1. claude commented on Aug 10, 2026

    @claude
    Contributor

    Triage: finding appended (domain:engine-core was applied at filing — kept, the face is packages/objectql/src/**/*.test.ts doubles).

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. claude commented on Aug 10, 2026

    @claude
    Contributor

    Findings triage (re-verify @ origin/main c6a4eeb): HOLD — the tsc channel is still off at scale (a broader count of : any = in packages/objectql/src/*.test.ts now hits 101 files, direction unchanged from the filed 64), no retired bit authored anywhere, no gate red. Observation-class stands; a 64-file retyping sweep is real cost with no live defect behind it today. finding stands.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  3. claude commented on Aug 11, 2026

    @claude
    Contributor

    Findings triage (re-verify @ origin/main afdc6ea): HOLD — the tsc channel is still off at scale, and the count moved again: : any = now appears in 102 files under packages/objectql/src/*.test.ts (101 at the 16:20Z check, 64 as filed). Direction unchanged, nothing red, no retired bit authored anywhere. A 100-file retyping sweep remains real cost with no live defect behind it. finding stands.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  4. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    ContributorAuthor

    Findings triage (re-verify @ origin/main 744b8f5): HOLD — : any = still appears in 102 files under packages/objectql/src/**/*.test.ts (unchanged from the 01:28Z check), no retired bit authored, no gate red. Observation-class stands; the copy-a-mock harm channel is real but latent, and none of the three proposed shapes is cheap enough to promote without a live instance. finding stands.

    Cadence note: three consecutive HOLDs with a stable premise — like #6305, this can rotate to the back until the corpus changes direction or a new retired-bit instance surfaces (that instant makes shape 2 — retype only non-empty supports doubles — the promotion candidate).

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  5. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    ContributorAuthor

    Findings triage round, 2026-08-11 (maintainer-directed). Graded: hold — 64-file typing sweep with no live defect; the tombstone channel matters most at the next retirement. Restart: the next driver-capability retirement card — run this sweep first so the tombstone can fire through the doubles it is meant to police.


    Generated by Claude Code

  6. hotlong commented on Aug 12, 2026

    @hotlong
    Contributor

    Findings-round disposition: closed (not planned) — fifth consecutive hold on a stable premise, zero measured pull, and the "do it later" option is getting monotonically worse (the : any = corpus grew 64 → 108 files in two days), which means the sweep this card imagines will realistically never be dispatched in this form.

    What the closure does NOT dispute: the premise is verified live (zero authored retired capability bits today; the tombstone has no tsc channel in those doubles). The harm stays latent until a retirement actually fires.

    Reopen trigger, documented so this is cheap to resurrect: a fourth retiredKey( entry lands in packages/spec/src/data/driver.zod.ts (today: create/read/update), or any authored retired/invented capability key shows up in a supports: literal under packages/objectql/src/**/*.test.ts. At that moment the promotion candidate is shape 2 only — retype the ~21 non-empty supports doubles — not the 108-file sweep.

    Maintainer veto = reopen; listed in this round's 代裁/closure section of the round report.

    本评论来自分诊座位(scheduled session session_01DLzE5XVRASxFotEU1h9cjH),不构成认领。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions