Found while measuring #14680 (PR #15343). Recording only, unassigned.
The promise
packages/metadata/src/errors.ts is the leaf subpath @objectstack/metadata/errors, and its header states why it exists:
@objectstack/metadata's root entry pulls the manager, every loader and the YAML/filesystem machinery behind them. A consumer that wants a 40-line predicate should not have to load any of that.
That promise is the precedent #14680 was decided on, so it is worth knowing whether it still holds. Measured, it half holds.
The measurement
Method: build the workspace, load one entry in a fresh Node process, and record every module file Node actually evaluates through a module.registerHooks load hook unioned with require.cache, byte sizes from statSync. Measured at origin/main 6e67b86c0 plus the #15343 branch (the leaf under test is unchanged by that branch).
| entry loaded standalone |
modules |
bytes |
packages/metadata/dist/errors.js |
83 |
2,487,842 |
| its breakdown |
packages/spec 1,883,493 · zod 567,918 · @objectstack/types 36,288 · @objectstack/metadata 143 |
|
So the manager, the loaders, chokidar, glob, js-yaml and readdirp are all correctly absent — that half of the promise holds and is worth keeping. But an out-of-repo consumer that imports the subpath for a 40-line predicate loads 2.4 MB across 83 modules, because since the maintainer's 2026-08-30 ruling the file re-exports from @objectstack/types, @objectstack/types declares @objectstack/spec as its one dependency, and packages/types/src/env.ts imports @objectstack/spec/security at module top.
Why this is a finding and not a bug
- Nothing enforced is crossed. No gate measures any entry point's module-init closure (which is the subject of a sibling finding filed from the same measurement).
- In-repo it costs nothing measurable: every current consumer of the subpath already loads
@objectstack/spec, so its marginal contribution to, for example, @objectstack/objectql/core is 143 bytes.
- The header's own wording is about the manager and the YAML machinery specifically, and that part is accurate. What has drifted is the general claim a reader takes from it.
What could be done, none of it prescribed
- Nothing — record the measurement in the header so the next author is not surprised, and keep the narrow claim.
- Make the type-level seam leaner at the source: if the predicate's home in
@objectstack/types could reach it without @objectstack/spec/security at module top (a lazy or type-only edge), the whole chain would collapse for every consumer of @objectstack/types, not just this one.
- Nothing at all, deliberately, if 2.4 MB for an in-process node consumer is judged uninteresting.
Option 2 touches packages/types and packages/spec and is the domain:spec seat's call, not the engine lane's.
Re-check
node -e "import('@objectstack/metadata/errors')" # from a package that depends on it
with the closure harness quoted in #15343's report.
Generated by Claude Code
Found while measuring #14680 (PR #15343). Recording only, unassigned.
The promise
packages/metadata/src/errors.tsis the leaf subpath@objectstack/metadata/errors, and its header states why it exists:That promise is the precedent #14680 was decided on, so it is worth knowing whether it still holds. Measured, it half holds.
The measurement
Method: build the workspace, load one entry in a fresh Node process, and record every module file Node actually evaluates through a
module.registerHooksload hook unioned withrequire.cache, byte sizes fromstatSync. Measured atorigin/main6e67b86c0plus the #15343 branch (the leaf under test is unchanged by that branch).packages/metadata/dist/errors.jspackages/spec1,883,493 ·zod567,918 ·@objectstack/types36,288 ·@objectstack/metadata143So the manager, the loaders,
chokidar,glob,js-yamlandreaddirpare all correctly absent — that half of the promise holds and is worth keeping. But an out-of-repo consumer that imports the subpath for a 40-line predicate loads 2.4 MB across 83 modules, because since the maintainer's 2026-08-30 ruling the file re-exports from@objectstack/types,@objectstack/typesdeclares@objectstack/specas its one dependency, andpackages/types/src/env.tsimports@objectstack/spec/securityat module top.Why this is a finding and not a bug
@objectstack/spec, so its marginal contribution to, for example,@objectstack/objectql/coreis 143 bytes.What could be done, none of it prescribed
@objectstack/typescould reach it without@objectstack/spec/securityat module top (a lazy or type-only edge), the whole chain would collapse for every consumer of@objectstack/types, not just this one.Option 2 touches
packages/typesandpackages/specand is thedomain:specseat's call, not the engine lane's.Re-check
with the closure harness quoted in #15343's report.
Generated by Claude Code