Skip to content

[finding] No gate type-checks TSDoc @example blocks in packages/spec/src — the ADR-0033 channel is uncompiled #10924

Description

@os-elon

Found while fixing #10731 (PR #10922). Filed rather than folded — repairing the one stale example is that card's scope; closing the class is a gate change.

The gap

AgentSchema's own docblock @example wrote knowledge: { … }, a key the same file declares as retiredKey() (z.never()). It did not compile. Measured as an A/B against the built dist in PR #10922:

as-written.ts(8,3): error TS2322: Type '{ sources: string[]; indexes: string[]; }'
is not assignable to type 'undefined'. → tsc EXIT=2
as-fixed.ts → tsc EXIT=0

It survived because nothing compiles it:

  • check:skill-examples extracts only fences carrying an os:check marker under skills/ and content/docs. Spec TSDoc is not in its scan surface.
  • check:doc-formula-expressionsdoes walk spec TSDoc @examples — "9 @example(s) judged clean across 977 packages/spec/src files" — but it judges formula expressions with @objectstack/formula, not TypeScript compilation.
  • The example is not published to content/docs/references/ either (support_tier_1 appears nowhere under content/docs), so no docs-side check sees it.

So a spec docblock example can name a retired key, a renamed export, or a tightened union and stay green indefinitely.

Why it matters more here than in prose docs

This is the ADR-0033 channel. A schema's @example is what an AI author copies, and it sits inches from the tombstone written for that same reader — in this case the example and the tombstone contradicted each other, three lines under a bullet stating the opposite rule. retired-key.ts names tsc as one of the two channels an upgrading author is guaranteed to hit; an uncompiled example is the one place that channel is bypassed by our own documentation.

Suggested direction (not a prescription)

Extend the existing check:skill-examples machinery rather than building a second extractor — it already writes blocks to a throwaway dir and type-checks them against the built @objectstack/spec declarations, with the paths map derived from the package's own exports. Adding packages/spec/src/** TSDoc @example blocks as a third surface would reuse all of it.

Two traps its header already documents and that apply here: most blocks are fragments that need a wrapper to compile (hence the opt-in marker convention), and a block omitting imports resolves bare type names against lib.dom. An opt-in marker on self-contained schema examples is likely the right granularity — the AgentSchema example was self-contained and would have been caught.

Worth checking during the work: whether defineX docblock examples elsewhere in packages/spec/src carry the same rot. This sweep found one, but only looked for stale .strict() prose, not uncompilable examples.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions