The Drift Log · Software inventory you can trust
Identify Unexecutable Registry Entries with a Simple CI Check
21 September 2026 · 3 min read · 638 words · established

Prevent phantom registry entries by verifying that registered components dynamically import and export runnable symbols in CI.
You query your internal package index or shared component registry and find 450 items listed. You pick entry number 214 to handle a standard token transformation. When you import it, the build fails: the file is an interface stub, a file containing throw new Error("TODO: implement"), or a package whose build artifact was never generated into dist/.
The registry counter went up when someone opened a pull request six months ago, but your usable surface area stayed flat. Cataloging metadata is trivial. What makes an inventory real is whether each row can be read, executed, and graded.
When unexecutable rows sit in your registry, developers waste time debugging missing implementations, and leadership reports phantom capabilities. The fix is not a company-wide refactor. It is a simple executable check that runs on every pull request.
The Anatomy of an Empty Row
Unexecutable registry entries persist because registration is decoupled from execution. Most teams validate only structural metadata in CI:
- Does the entry exist in the manifest?
- Does it have a valid semver tag?
- Does the markdown documentation parse?
None of these checks determine whether the entry contains runnable code. Common failure modes that pass superficial linting include:
- Type-only stubs: Exporting TypeScript types or interfaces without concrete runtime values.
- Missing build targets: The
package.jsonpoints to./dist/index.js, but the build pipeline never compiled it. - Broken internal dependencies: Unresolved local imports or environment assumptions that crash the runtime at initial load.
An honest inventory audit treats an entry as non-existent until the runtime can evaluate it without throwing an unhandled exception.
A Lightweight CI Verification Step
You do not need an end-to-end test suite for every single utility just to verify its basic viability. You need a fast registry validation pass that loads the entry point and verifies that expected symbols exist.
Below is a minimal Node.js script suitable for a CI step. It iterates over your catalog manifest, dynamically loads each entry point, and fails the build if an entry lacks an executable export.
import { resolve } from 'node:path';
import { pathToFileURL } from 'node:url';
export async function validateRegistry(manifest) {
const failures = [];
for (const entry of manifest.entries) {
const targetPath = resolve(process.cwd(), entry.path);
try {
const module = await import(pathToFileURL(targetPath).href);
const exportedSymbols = Object.keys(module);
if (exportedSymbols.length === 0) {
failures.push(`${entry.id}: Module imported successfully but exports no symbols.`);
continue;
}
const hasExecutable = exportedSymbols.some(
(key) => typeof module[key] === 'function' || typeof module[key] === 'object'
);
if (!hasExecutable) {
failures.push(`${entry.id}: No executable functions or objects found in exports.`);
}
} catch (err) {
failures.push(`${entry.id}: Execution failed at load time: ${err.message}`);
}
}
return failures;
}
This step catches missing compilation artifacts, syntax errors, missing peer dependencies, and empty stubs before a merge happens. It runs in seconds across hundreds of entries.
What a Load Check Cannot Prove
Be clear about what this test achieves and where its boundary lies.
Importing a module proves that the file exists, its dependencies resolve, its syntax is valid, and its top-level code evaluates. It does not prove algorithmic correctness, handle deep edge cases, or verify that the component meets its input contracts under load.
For full verification, components require isolated execution harnesses. But catching import-level dead weight is the baseline requirement. If an entry cannot be loaded into memory, running functional tests against it is impossible.
How SHPBL Enforces Inventory Reality
SHPBL handles inventory trust by reporting counts strictly apart. We never sum our numbers into a single headline metric.
The engineered catalog, the unpromoted discovery-engine vault, and the standalone Crown Jewels are distinct tiers. When artifacts enter our pipeline, our certification harness executes them and records an explicit verdict: CERTIFIED, PROVISIONAL (reproducible, correctness not yet asserted), INCONCLUSIVE (a harness limitation, not an artifact defect), or FAILED.
Unexecutable stubs never reach the catalog. You can inspect the library using our typed client at @shpbl/sdk or run a free repository evaluation to see how your own tree grades under execution checks.
What to Do on Monday
Do not write a massive testing framework this week. Add a 20-line verification script to your repository's primary CI workflow:
- Read your component or package manifest.
- Attempt a dynamic import of every registered entry point.
- Assert that at least one callable symbol is exported.
- Fail the CI run if any entry throws an exception or exports zero runnable values.
This post supports the longer argument in A Component Count Is Not an Inventory.
Keep reading
Next in the log
- A Component Count Is Not an Inventory
Why internal component registries decay into unverified technical debt and how to calculate the true yield of reusable code.
- Embedding Certification Harnesses to Verify SHPBL Catalog Entries
Embedding SHPBL’s certification harness in CI ensures each catalog entry is verified with a reproducible verdict.
- Mapping Load-Bearing Code Across Deep Dependency Trees
Separate quiet, invariant-enforcing logic from loud transport scaffolding to find the computational code that actually carries production risk.
The Strategic Master Library · written and reviewed under the house's own epistemic rules: nothing claimed that we cannot show.