Skip to content

Per-package lint:types silently skips via stale tsbuildinfo; ~100 latent type errors in ocapn/thixotrope tests #851

Description

@kumavis

Summary

While chasing the lint CI failure on #786 we found that per-package yarn workspace <pkg> lint (which chains lint:types) had been passing locally only because stale incremental build state (tsconfig.tsbuildinfo and previously emitted .d.ts files) made tsc treat everything as up to date and skip re-checking. From a genuinely clean tree, lint:types fails with roughly 100 pre-existing errors:

  • @endo/ocapn: 78 errors, all in test/**
  • @endo/thixotrope: 22 errors, all in test/**

Reproduction

yarn clean
yarn workspace @endo/ocapn lint       # 78 type errors
yarn workspace @endo/thixotrope lint  # 22 type errors

Before yarn clean, both commands pass — same tree, same sources.

Why CI does not catch it

The CI lint job runs root prettier/eslint/shellcheck, yarn docs, root tsc -p tsconfig.json --noEmit, and yarn build:types. All of those are green (the root program and the composite build apply different settings and, for build:types, exclude test files). No CI job runs per-package lint:types, so the checked-in state drifted.

The dominant error pattern

Almost every error is the same shape: an eventual-send call on a presence typed as bare object, e.g.

test/hub.test.js(183,39): error TS2339: Property 'fetch' does not exist on type 'object'.

driven by presence-returning signatures such as Session.getBootstrap being declared () => object (packages/ocapn/src/client/types.js), so E(session.getBootstrap()).fetch(...) fails. Source files avoid it with per-call-site /** @type {any} */ casts (see client/sturdyrefs.js); the test files never got the casts.

Possible fixes

  1. Widen the handful of presence-returning signatures (getBootstrap, getRemoteBootstrap, resolver/import providers) from object to any (or a dedicated RemotePresence alias). A remote presence's methods are only known to the caller, which invokes them through E(), so object provides no real checking today — it just forces casts. This fixes all ~100 errors in a few lines and lets the existing source-side casts be removed.
  2. Cast at each of the ~100 test call sites, keeping the narrow public types.
  3. Either way, consider adding per-package lint:types (from clean state) to CI, since a gate that only passes with warm build state is not a gate.

Option 1 + 3 seems right; opinions welcome.

@kriscendobot could you review this diagnosis and weigh in on options 1–3?

Found during #786 (rebase onto llm); the head of that branch is green on the gates CI does run.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions