Skip to content

lint: no gate resolves a documented @objectstack/* import SPECIFIER against the target package's exports map — check:published-readme-exports asks a different question #16207

Description

@claude

Split out of #15931 (delivered by PR #16205), where the dispatch ruled the gate itself out of scope. That card's "Acceptance" section proposes it and the triage seat seconded it; this is the row.

The gap, stated as the difference between two questions

check:published-readme-exports asks "is this documented SYMBOL in the target package's built types?". The defect on #15931 was a documented SPECIFIER that the target package's exports map cannot resolve — a different question, which no gate in the tree asks today. The two are independent: on #15931 the symbols were real and exported, and only the path was wrong, so a symbol-vs-types gate is structurally incapable of seeing it. That is not a coverage shortfall in the existing gate; it is a question nobody asks.

Measured on origin/main while delivering #15931

The failure is a hard resolution refusal, not a soft typing gap:

REFUSED: ERR_PACKAGE_PATH_NOT_EXPORTED - Package subpath './security' is not defined
         by "exports" in packages/core/package.json
CONTROL: import('@objectstack/core/logger') -> RESOLVED, exports: ObjectLogger,createLogger

The proposed gate would read every documented @objectstack/* import specifier in the tree and resolve it against the named workspace package's own exports map.

What a population count would have to settle first, and why this is its own card

  1. Which documents? PHASE2_IMPLEMENTATION.md was invisible to check:published-readme-exports precisely because packages/core does not publish it: npm pack --dry-run over that package lists 16 files and no PHASE2_IMPLEMENTATION.md, only CHANGELOG.md and README.md. A specifier gate that reads only published documents inherits the same blind spot; one that reads every tracked markdown file has to be sized before it is written.
  2. How many false positives? Measured while delivering core: PHASE2_IMPLEMENTATION.md teaches @objectstack/core/security, a subpath the package exports in no entry #15931, the string @objectstack/core/security appears in 16 tracked files, but only 3 of them carry it in an import-statement shape and only 2 were real instructions to a reader. The rest are prose, changelog history, a @module tag, and a pin test's own commentary about the subpath. A naive matcher reddens on all 16.
  3. Whose exports map? Resolution has to follow the workspace member, not the installed tarball, and has to handle wildcard exports keys — packages/core has none today, but the gate cannot assume that of every package.
  4. The existing green. check:published-readme-exports currently reports 60 published documents across 79 workspace packages, 215 import statements, 200/200 @objectstack/ specifiers naming a workspace member. That 200/200 is a membership count, not a resolution count — it is the natural place to look for either a home for this check or a reason it should not live there.

Unassigned and ungraded on purpose: the sizing above is the work, and the answer decides whether this is a new gate or a second limb on the existing one.


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

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions