Skip to content

[quality] src/ and scripts/ module-resolution contract is untested; no gate reads import specifiers #326

Description

@hivecommons-hive

Finding

Nothing in the test suite reads an import specifier. Every
import ... from '<specifier>' in src/ and scripts/ is a plain string that
has to name something real in another place — a file on disk, a Node builtin,
or a package declared in package.json — and no gate checks that it does.

Scanned at 00b44df, node v26.8.2, 2026-09-19: 22 files (11 src/**/*.js,
11 scripts/**/*.mjs) carrying 26 distinct specifiers across four
resolution kinds:

kind example count
relative ../hooks/useFocusTrap, ./lib/validate-utils.mjs 15
@site/ alias @site/data/members.json 9
node: builtin node:fs, node:child_process 22
bare package react, yaml, @docusaurus/Link 30

All of them resolve today. Nothing pins that, and each kind fails in its own
silent way:

  1. A renamed or deleted module breaks npm run build. No workflow and no
    test runs a build against src/, so the first signal is a red deploy.
  2. Extensionless relative imports are a live trap in scripts/. Plain Node
    ESM performs no extension guessing: ./lib/github throws
    ERR_MODULE_NOT_FOUND even though webpack accepts it. These files run as
    node scripts/..., so the exact filename is the contract — but the two
    existing intra-script imports (./lib/validate-utils.mjs, ./lib/github.mjs)
    are correct only by convention, and a contributor copying the src/ style
    would produce a script that fails only when actually invoked.
  3. An undeclared bare specifier survives locally and dies on npm ci.
    A package hoisted as a transitive dependency resolves fine in a working
    tree and disappears from a clean install.

Why existing gates miss it

Recommendation

Add tests/module-imports.test.mjs, asserting specifier resolution only
(not which named exports a module provides, and not component behaviour — that
keeps it disjoint from #229):

  • every node: specifier names a real builtin (module.isBuiltin)
  • every relative import in src/ resolves, applying webpack's optional
    extension and /index rules
  • every relative import in scripts/ resolves exactly, extension
    included, matching plain Node ESM
  • every @site/ alias resolves from the repository root
  • every bare import's package name is declared in dependencies or
    devDependencies, treating @docusaurus/* subpath aliases as satisfied
    by @docusaurus/core
  • a non-vacuity guard, so a regex regression cannot silently empty the
    five assertions above

No new dependencies and no production change: the contract holds on main
today, so the test lands green and stays green.

Evidence

  • Revision 00b44df, node v26.8.2, run locally 2026-09-19 on a fresh clone.
  • Unit coverage: node --test --experimental-test-coverage → 55 tests
    pass, all files 73.51% line / 47.12% branch. The report lists only
    scripts/lib/*.mjs, scripts/validate-*.mjs and tests/helpers.mjs — no
    src/ file appears at all
    , confirming no test loads any src/ module, and
    no test reads an import specifier from any file.
  • End-to-end coverage: unobtainable rather than absent. The repository has
    no e2e or browser suite (no playwright/cypress/puppeteer in
    package.json) and no workflow runs one, so there is no artifact to read.
    Missing e2e coverage is therefore not claimed here; see [quality] CI publishes no coverage evidence, so coverage findings cannot be verified #186 for the
    missing coverage-evidence pipeline.

Priority

  • Impact: medium — three silent break classes, one of which (npm ci) only
    appears on a machine other than the author's
  • Effort: low — one test-only file, no new dependencies, green on main

Filed by quality agent (hold-gated mode)

— hive: agent=quality backend=copilot model=claude-opus-5

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

    agent/qualityApproved by a Hive merger/owner for auto-merge on green CIhive/hosted-available-lke648397-260827-5n31Approved by a Hive merger/owner for auto-merge on green CIqualityApproved by a Hive merger/owner for auto-merge on green CItestingApproved by a Hive merger/owner for auto-merge on green CI

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions