Skip to content

fix(packaging): ship the LICENSE @loopover/miner declares, and assert it everywhere - #9787

Merged
JSONbored merged 3 commits into
mainfrom
fix/miner-license
Jul 29, 2026
Merged

fix(packaging): ship the LICENSE @loopover/miner declares, and assert it everywhere#9787
JSONbored merged 3 commits into
mainfrom
fix/miner-license

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

packages/loopover-miner declares "license": "AGPL-3.0-only" and is published — and ships no LICENSE file. Every published sibling carries one. Distributing a copyleft package without its license text is a licensing defect, not packaging tidiness.

(discovery-index has none either, but it is private: true and declares no license — correctly excluded, not a gap.)

Closes #9786

Why it was missing

It could not simply be added. check-miner-package.ts's ALLOWED list had no /^LICENSE$/ entry, so dropping the file in would have failed test:miner-pack with "Unexpected file in miner package: LICENSE". The omission was actively enforced.

The wider class

No published package's checker ever asserted the file. engine and ui-kit allowed it without requiring it; check-mcp-package.ts had no required-files concept at all, only an allowlist. LICENSE could therefore drop silently out of any of them — miner is simply where it happened.

So this requires it in all four, and gives the MCP checker the required-files assertion it lacked. package.json is asserted alongside LICENSE there, so a pathologically empty file list cannot pass every other check by vacuous truth.

Same discipline check-miner-package.ts already applies to DEPLOYMENT.md and the Dockerfile"asserted present so they can never silently drop out of the package again" — and more warranted here: a missing operational doc is an inconvenience, a missing license is a distribution defect.

Validation

Verified non-vacuous rather than assumed. Removing the file makes the real check fail:

$ npm run test:miner-pack
Miner package is missing required file: LICENSE
Check Result
test:mcp-pack · test:miner-pack · test:engine-pack · test:ui-kit-pack (real npm pack dry-runs) all PASS
Four checker suites 46 tests (4 new negative tests, one per checker, pinning the exact message)
typecheck · validate:no-hand-written-js · coverage-boltons:check · release-linked-versions:check · git diff --check clean

Three existing fixtures were made faithful rather than the assertion relaxed. They modelled a valid published package without a LICENSE, which is no longer valid. Two of them assert other failures — ui-kit's "no dist/components/*.js artifacts" and miner's "at least one docs/*.md" — and were masked because the new check fired first and changed which error surfaced. Adding LICENSE to those fixtures restores each test to failing for its own reason.

@loopover/contract needs nothing: it has a LICENSE, and publish-contract.yml already validates its tarball inline against an allowlist that includes it.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves (e.g. Closes #123) — a linked open issue is required for every contributor PR.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests.
  • API/OpenAPI/MCP behavior is updated and tested where needed.
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks.
  • Visible UI changes include a UI Evidence section below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

No runtime code, no src/** change, no UI output — packaging checks and one license file, hence no coverage obligation and no UI Evidence table. The change only ever adds a required artifact; every existing forbidden-path and secret-content check is untouched and still passes. npm pack includes LICENSE automatically regardless of the files array, which is exactly why the checker — not files — is where this has to be enforced.

… it everywhere

packages/loopover-miner declares "license": "AGPL-3.0-only" and is published,
yet ships no LICENSE file. Every published sibling carries one. Distributing a
copyleft package without its license text is a licensing defect, not packaging
tidiness. (discovery-index has none either, but it is private: true and declares
no license -- correctly excluded, not a gap.)

It could not simply be added: check-miner-package.ts's ALLOWED list had no
/^LICENSE$/ entry, so dropping the file in would have failed test:miner-pack
with "Unexpected file in miner package: LICENSE". The omission was actively
enforced.

The wider class is that NO published package's checker ever asserted the file.
engine and ui-kit allowed it without requiring it; check-mcp-package.ts had no
required-files concept at all, only an allowlist. LICENSE could therefore drop
silently out of any of them -- miner is simply where it happened. So this
requires it in all four, and gives the MCP checker the required-files assertion
it was missing (package.json is asserted alongside LICENSE there, so a
pathologically empty file list cannot pass every other check by vacuous truth).

Same discipline check-miner-package.ts already applies to DEPLOYMENT.md and the
Dockerfile -- "asserted present so they can never silently drop out of the
package again" -- and more warranted here: a missing operational doc is an
inconvenience, a missing license is a distribution defect.

Verified non-vacuous rather than assumed: removing the file makes test:miner-pack
fail with "Miner package is missing required file: LICENSE", and each checker
gains a negative test pinning that message. Three existing fixtures modelled a
valid package without a LICENSE and were made faithful instead of the assertion
being relaxed -- two of them assert OTHER failures (missing docs/*.md, missing
dist/components), and were masked by the new check firing first.

@loopover/contract needs nothing: it has a LICENSE, and publish-contract.yml
already validates its tarball inline against an allowlist that includes it.

Closes #9786
@loopover-orb

loopover-orb Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-29 10:08:58 UTC

10 files · 1 AI reviewer · no blockers · CI green · unknown

⏸️ Suggested Action - Manual Review

Review summary
This PR adds the missing LICENSE file to packages/loopover-miner (which declares AGPL-3.0-only) and closes the enforcement gap by adding a REQUIRED-file assertion to all four package checkers (miner, engine, ui-kit, mcp), plus regression tests for each. The core fix is correct and directly traceable: check-miner-package.ts's ALLOWED list previously had no LICENSE entry, so the file could not have been silently added before this change, and the new REQUIRED entries make the checkers fail when LICENSE is absent, which the diff demonstrates via new regression tests pinning the exact error message. The change closes issue #9786, is narrowly scoped to packaging/license enforcement, and does not bundle unrelated work.

Nits — 7 non-blocking
  • test/unit/check-miner-package.test.ts:42-44 has a duplicated `"LICENSE",` entry in the CHECK_MINER_PACK_TEST_FILES array — harmless since the checker dedupes via `.includes`, but it's stray copy-paste noise worth cleaning up.
  • test/unit/check-mcp-package.test.ts's FULL_PACKAGE array (around line 25) also lists `"LICENSE"` twice — same cosmetic duplication, consider removing the extra entry.
  • The new `REQUIRED` comment blocks in check-engine-package.ts and check-ui-kit-package.ts repeat nearly identical wording about @loopover/miner is published under AGPL-3.0-only and ships no LICENSE file #9786 — consider a shared comment or trimming the duplication across the two files.
  • Dedupe the repeated `"LICENSE"` list entries in the two test files noted above for cleanliness.
  • Since check-mcp-package.ts now has its own REQUIRED array while the sibling checkers reuse the same `[package.json, LICENSE]` fixed pattern, consider whether a small shared helper (e.g. a `requireFiles(paths, required)` utility) would reduce duplication across the four scripts — optional, not blocking.
  • PR author also opened the linked issue — Link an issue that was opened by a different contributor, or provide a rationale for why this self-authored issue represents genuine discovery work.
  • Diff looks like trivial or whitespace-only churn — Reduce whitespace-only or formatting-only churn and keep the diff focused on substantive changes.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #9786
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 14 registered-repo PR(s), 13 merged, 361 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 14 PR(s), 361 issue(s).
Improvement ✅ Minor risk: low · value: minor
Linked issue satisfaction

Addressed
The PR ships packages/loopover-miner/LICENSE (AGPL-3.0), adds LICENSE to the miner's ALLOWED list, and adds LICENSE to REQUIRED in the miner, engine, and ui-kit checkers, plus gives check-mcp-package.ts a new required-files assertion including LICENSE, matching all three scope items in the issue.

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is registered but has no active allocation in the current snapshot.
  • Public profile languages: not available
  • Official Gittensor activity: 14 PR(s), 361 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • Then work through the remaining 2 steps in the Signals table above.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Decision record
  • action: merge · clause: success
  • config: 14775ac9624429adb93f0ccb0db90916b72ce66d6efe01f98dd8a5170672881f · pack: oss-anti-slop · ci: passed
  • record: 81536e14a112b37547984c5701ebf0ea854b77bb95bb275d5ea55deb5bd02845 (schema v5, head 1771e5e)

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@JSONbored JSONbored self-assigned this Jul 29, 2026
@loopover-orb loopover-orb Bot added the manual-review Gittensor contributor context label Jul 29, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 29, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
loopover-ui 86de616 Commit Preview URL

Branch Preview URL
Jul 29 2026, 09:24 AM

@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.57%. Comparing base (7df6148) to head (1771e5e).
⚠️ Report is 3 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9787      +/-   ##
==========================================
+ Coverage   90.33%   95.57%   +5.24%     
==========================================
  Files         917      814     -103     
  Lines      113904    62930   -50974     
  Branches    26966    21930    -5036     
==========================================
- Hits       102894    60145   -42749     
+ Misses       9681     1474    -8207     
+ Partials     1329     1311      -18     
Flag Coverage Δ
backend 95.57% <ø> (ø)
control-plane ?
engine ?
rees ?

Flags with carried forward coverage won't be shown. Click here to find out more.
see 280 files with indirect coverage changes

…eckers now require

The clean-content case in forbidden-content.test.ts exits 1 on "Missing
required file in MCP package: LICENSE" instead of reaching the content read,
because this change gave the MCP checker a required-file guard it never had.

REACHABLE_FILES documents itself as "a minimal file list that passes each
checker's path/allowlist/required-file guards, so the run reaches the shared
secret-content read" -- LICENSE now belongs in it. Added to the miner list too,
so the list stays honest about the guards it claims to satisfy rather than
depending on that checker reading content before it checks required files.
@JSONbored
JSONbored merged commit 122a283 into main Jul 29, 2026
7 checks passed
@JSONbored
JSONbored deleted the fix/miner-license branch July 29, 2026 10:08
JSONbored added a commit that referenced this pull request Jul 29, 2026
… it is (#9799)

* fix(ci): normalize committed CRLF to LF and name the failure for what it is

Twenty files were committed with CRLF and the repo had no .gitattributes. The `changes` job runs
`git diff --check`, and git's default core.whitespace is `blank-at-eol` with `cr-at-eol` off, so a
carriage return at end-of-line counts as trailing whitespace. Any PR adding a line to one of those
files failed CI pointing at lines whose visible content is spotless, with nothing in the log saying
"CRLF" — it hit #9787 (run 30436384202) on two lines of inline-suggestion-anchor.ts.

Convert all twenty to LF via `git add --renormalize`, byte-identical otherwise (`git diff -w` reports
only the two new files below), and pin the repo with `* text=auto eol=lf`. `text=auto` rather than a
bare `text` is load-bearing: five .ts files embed NUL bytes as untrusted-text and sanitizer fixtures,
and auto-detection classifies them binary and passes them through untouched.

The whitespace step now names CRLF before falling through to the generic check. .gitattributes stops
CRLF entering through `git add`, but checkin filters don't run on blobs written directly (web editor,
Contents API) or on a merge of a branch cut earlier, so the diagnostic still has a job. It is scoped
to added lines, so it fires on exactly what `git diff --check` already flagged — a relabel, not a new
failure mode.

Closes #9798

* test(engine): cover the package-local buildIssueQualityReport in the engine suite

`buildIssueQualityReport` is re-exported from the engine barrel (src/index.ts) but this package's own
node:test suite never called it. `npm run engine:coverage` therefore saw the module load — top-level
constants only — and reported it LF:313 LH:96 with BRF:0, i.e. no function-level data at all, while
the root vitest suite covered the same file 87/87 lines and 143/143 branches.

Two uploads disagreeing about the same file is invisible while patch coverage only reads changed
lines, because nothing changes all 313 at once. Renormalizing the file's line endings did, and the
merged report capped at ~57%: of the 217 lines the engine flag called uncovered, 84 were rescued by
vitest and 133 were function-signature and closing-brace lines v8 never lists as statements, so
nothing could rescue them.

Cover it where this package is actually graded rather than leaning on the vitest duplicate — the
outcome scripts/engine-coverage.ts (#9064) was written to encourage. The file now reports
313/313 lines and 163/163 branches under the engine model.

17 cases covering the lane arms (issue_discovery / direct_pr / split / unknown), every bounty
lifecycle, duplicate and invalid labelling, self-solved loops, maintainer-authored vs maintainer-WIP,
linkedPrs back-references for both open and merged PRs, collision risk tiers, sort order, the
lifecycle and report caps, and the null-repo / unparseable-date degradation paths.

---------

Co-authored-by: JSONbored <aetherealdev@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

manual-review Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@loopover/miner is published under AGPL-3.0-only and ships no LICENSE file

1 participant