The defect
packages/loopover-miner/package.json declares "license": "AGPL-3.0-only" and is published (no private: true). It ships no LICENSE file.
Every one of its published siblings does — @loopover/engine, @loopover/mcp, @loopover/ui-kit, @loopover/contract. packages/discovery-index also has none, but it is private: true and declares no license, so it is correctly excluded.
Distributing a copyleft package without its license text is a licensing problem, not a packaging tidiness one.
Why it could not simply be added
scripts/check-miner-package.ts's ALLOWED list has no /^LICENSE$/ entry. Dropping the file in would have failed npm run test:miner-pack with "Unexpected file in miner package: LICENSE" — so the omission was actively enforced.
The wider class
No published package's checker ever asserted LICENSE. check-engine-package.ts and check-ui-kit-package.ts allow it but leave it out of REQUIRED; check-mcp-package.ts has no required-files concept at all, only an allowlist. So the file could silently drop out of any of them and nothing would notice — miner is simply where it actually happened.
That is the same shape as the DEPLOYMENT.md / Dockerfile regression check-miner-package.ts already guards against, and its comment states the principle: "asserted present so they can never silently drop out of the package again." LICENSE deserves the same treatment, more so — a missing operational doc is an inconvenience, a missing license is a distribution defect.
Scope
- Ship
packages/loopover-miner/LICENSE (AGPL-3.0, matching what the package declares and what its siblings carry).
- Add
LICENSE to miner's ALLOWED, since that omission is what blocked it.
- Require
LICENSE in every published package's pack check — including giving check-mcp-package.ts a required-files assertion, which it lacks entirely.
@loopover/contract needs no change here: it has a LICENSE, and publish-contract.yml already validates its tarball inline with an allowlist that includes it.
Note npm pack includes LICENSE automatically regardless of the files array, so no package.json change is needed — which is precisely why the checker, not files, is where this has to be enforced.
The defect
packages/loopover-miner/package.jsondeclares"license": "AGPL-3.0-only"and is published (noprivate: true). It ships no LICENSE file.Every one of its published siblings does —
@loopover/engine,@loopover/mcp,@loopover/ui-kit,@loopover/contract.packages/discovery-indexalso has none, but it isprivate: trueand declares no license, so it is correctly excluded.Distributing a copyleft package without its license text is a licensing problem, not a packaging tidiness one.
Why it could not simply be added
scripts/check-miner-package.ts'sALLOWEDlist has no/^LICENSE$/entry. Dropping the file in would have failednpm run test:miner-packwith "Unexpected file in miner package: LICENSE" — so the omission was actively enforced.The wider class
No published package's checker ever asserted LICENSE.
check-engine-package.tsandcheck-ui-kit-package.tsallow it but leave it out ofREQUIRED;check-mcp-package.tshas no required-files concept at all, only an allowlist. So the file could silently drop out of any of them and nothing would notice — miner is simply where it actually happened.That is the same shape as the
DEPLOYMENT.md/Dockerfileregressioncheck-miner-package.tsalready guards against, and its comment states the principle: "asserted present so they can never silently drop out of the package again." LICENSE deserves the same treatment, more so — a missing operational doc is an inconvenience, a missing license is a distribution defect.Scope
packages/loopover-miner/LICENSE(AGPL-3.0, matching what the package declares and what its siblings carry).LICENSEto miner'sALLOWED, since that omission is what blocked it.LICENSEin every published package's pack check — including givingcheck-mcp-package.tsa required-files assertion, which it lacks entirely.@loopover/contractneeds no change here: it has a LICENSE, andpublish-contract.ymlalready validates its tarball inline with an allowlist that includes it.Note
npm packincludes LICENSE automatically regardless of thefilesarray, so nopackage.jsonchange is needed — which is precisely why the checker, notfiles, is where this has to be enforced.