Skip to content

[finding] check:published-readme-exports' namespace-import branch can never fire — namespaceSymbol is hardcoded null at the only call site #10367

Description

@os-zhuang

Observation found while widening the call-site half for #9870 (PR #10365). Not fixed there — different defect, and it has no live consequence today.

The branch

analyzeDocument binds a namespace import so the call-site half can check its members against the module's export set:

if (imp.namespaceLocal) {
  const ns = target.namespaceSymbol;
  if (ns) {
    bound.set(imp.namespaceLocal, { symbol: ns, /* … */ imported: '*' });
  }
}

resolveTarget in run() is the only production caller, and it returns:

return {
  declared: true,
  exports,
  namespaceSymbol: null,   // ← always
  hasMember: ,
};

So ns is always falsy and the branch never binds anything. hasMember already has the matching SymbolFlags.Module arm (checker.getExportsOfModule(s).some(…)), so the machinery on the answering side exists — only the symbol is never supplied.

Why it is a finding and not a bug report

The population is zero twice over, measured with the gate's own publishedDocs():

  • 5 namespace imports exist across the 60 published documents;
  • all 5 are relative specifiers (import * as objects from './src/objects'), in packages/cli/README.md, packages/mcp/README.md and packages/spec/prompts/create-new-project.md;
  • splitSpecifier returns null for a relative specifier, so those imports are skipped before the branch is reached regardless.

⇒ Wiring namespaceSymbol today would change no verdict. Nothing is currently mis-measured.

Why it is still worth recording

This is a branch that reads as coverage and cannot fire — in a gate whose own header raises "zero is a broken scan, not a clean repo" (#4690) to a hard error. The day a published README namespace-imports a workspace package (import * as spec from '@objectstack/spec'), the call-site half will silently not read it, and the green line will not say so. The NOT read: clause added by PR #10365 would count those call sites, so the blind spot would at least be visible — but it would be attributed to "no type this gate can reach", which is not the reason.

Two honest resolutions, both cheap; picking between them is a maintainer call:

  1. Wire it — supply the module symbol from surface (the exportsOf cache already holds it) and pin the shape in --self-test, so the branch is exercised by a fixture even while the tree's population is 0.
  2. Delete it — remove the branch and the imported: '*' path, and say in the header that namespace imports are out of scope, the way CHANGELOG.md and bash fences are.

⛔ What it must not stay is what it is now: present, unreachable, and reading like coverage.

Refs: #9870 / PR #10365 (where it was found) · #9911 (the other no-population shape in this file) · #4690 (empty-population failure).

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions