Skip to content

docs(licenses): record initial dependency license review - #2113

Merged
josecelano merged 7 commits into
torrust:developfrom
josecelano:269-first-dependency-license-review
Sep 15, 2026
Merged

josecelano merged 7 commits into
torrust:developfrom
josecelano:269-first-dependency-license-review

Conversation

@josecelano

@josecelano josecelano commented Aug 28, 2026

Copy link
Copy Markdown
Member

Records the first evidence-grounded technical dependency-license review for #269.

The review retains compact inventories for the complete locked graph at its initial review snapshot (575 packages) and a runtime-oriented view (510 packages), with reproducible commands, checksums, and published-source records for non-routine declarations. It also adds the missing workspace license inheritance for workspace-coupling.

The direct runtime bloom GPL-2.0 finding is technically resolved: Issue #2114 and merged PR #2119 removed bloom and its transitive bit-vec dependency after a focused Criterion comparison found the exact-map path faster for the measured operations. The report retains the original bloom evidence for any review of releases that included it; it makes no conclusion about those releases.

No license-enforcement policy is introduced. The five LGPL-3.0 declarations and other non-routine expressions remain pending maintainer classification and qualified legal review where required.

Pending Maintainer Actions

  1. For each remaining pending finding, record the package/version/license evidence, dependency kind and reachability, and which distributed artifacts include or depend on it.
  2. Read the linked license and notice files, recording plainly stated notice or text-retention requirements without inferring legal compatibility from SPDX metadata.
  3. Record one disposition per finding: escalate for qualified legal review, create remediation work, or propose an approval rationale after the required review is complete.
  4. Obtain an explicit approval or objection from every active maintainer. A missing response remains pending; approval records the project decision and is not an individual legal opinion.
  5. Create focused remediation issues for every finding that cannot be approved. Do not add automated license enforcement until an approved SPDX policy and exception process exist.

Related to #269.

Copilot AI lite review requested due to automatic review settings August 28, 2026 17:10
@josecelano josecelano self-assigned this Aug 28, 2026
@josecelano
josecelano requested a review from da2ce7 August 28, 2026 17:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR records the initial, evidence-grounded technical dependency-license review for issue #269 by adding reproducible inventories (locked graph + runtime-oriented view) and accompanying review/evidence documentation, plus closing a missing workspace license inheritance gap for the workspace-coupling crate.

Changes:

  • Add initial review report (initial-review.md) and evidence ledger (evidence.md) for dependency license declarations, including reproducible commands and checksums.
  • Add deterministic JSON inventories for the locked dependency graph and a runtime-oriented subset, and exclude those large JSON files from spellchecking noise.
  • Ensure workspace-coupling explicitly inherits the workspace AGPL-3.0-only license via license.workspace = true.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
project-words.txt Adds SPDX/metadata-related terms used in the new license review docs.
docs/issues/open/269-review-dependency-licenses/runtime-license-inventory.json Adds the runtime-oriented dependency license inventory artifact.
docs/issues/open/269-review-dependency-licenses/locked-license-inventory.json Adds the complete locked-graph dependency license inventory artifact.
docs/issues/open/269-review-dependency-licenses/ISSUE.md Updates the issue spec to reference and track the initial review artifacts and current status.
docs/issues/open/269-review-dependency-licenses/initial-review.md Adds the initial technical review report (explicitly non-legal).
docs/issues/open/269-review-dependency-licenses/evidence.md Adds the reproducible evidence ledger backing the report’s findings.
cspell.json Excludes the large JSON inventory files from cspell scanning.
contrib/dev-tools/analysis/workspace-coupling/Cargo.toml Makes workspace-coupling inherit the workspace license (license.workspace = true).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@codecov

codecov Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.49%. Comparing base (efebacf) to head (1edda0e).

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #2113   +/-   ##
========================================
  Coverage    85.48%   85.49%           
========================================
  Files          353      353           
  Lines        31315    31315           
  Branches     31315    31315           
========================================
+ Hits         26771    26774    +3     
+ Misses        4171     4168    -3     
  Partials       373      373           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@josecelano

josecelano commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

Maintainer decision: defer the remaining dependency-license dispositions until the package-overhaul EPIC has defined the final package boundaries, publication status, and distributable artifacts.

The completed bloom remediation remains recorded separately. Retain the inventories and source evidence in this PR as the baseline, but do not infer approval, legal compatibility, or an enforcement policy for the remaining findings yet.

Resume the review when the extraction and distribution decisions are complete, or earlier if a package becomes externally published. At that point, regenerate the locked and runtime inventories, compare them with this snapshot, and classify the final distributed artifacts.

da2ce7
da2ce7 previously approved these changes Sep 10, 2026

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 493d35d9856aa304015ef9b479be8ba7828e270c. Recomputed from a clean checkout at that commit; every statement below is backed by a command that was run.

Recomputation of the central data claim

Regenerating the inventory with the pipeline documented in E1, against c30fbff4's tree plus this PR's workspace-coupling license line, produced a file byte-identical to locked-license-inventory.json (sha256 d61456809c69d4dbd6ada3771d39469f1491ac5cb99498068714a67418d43f3e, 575 packages). The other two recorded checksums verify as well: runtime-license-inventory.json 40b63b6192d529032ad0dec68f2463356459608f8dd0cac2cea898fd2cf1fd4c (510 packages) and Cargo.lock at c30fbff4 4fc7f17ed1d348a4500ef3772c661cda43799f5ef44fb51514386d7b408156d4. Both artifacts are sorted as documented, hold no duplicate name+version entries, and every runtime-inventory package is present in the locked inventory (0 extras).

Against the graph at this PR head the locked artifact differs by exactly two packages, bloom 0.3.2 and bit-vec 0.4.4 — the historical snapshot E8 documents. No other mismatch.

cargo deny check bans passes. cargo deny check licenses fails with 475 rejected errors, reproducing E3's observation that no allowlist is configured, which is consistent with the report's decision not to introduce enforcement here.

Staleness

git merge-tree --write-tree against develop 89d45145 merges cleanly. Of the eight touched paths only project-words.txt has develop commits since this head (12), and it merges without conflict; cspell.json, the issue folder and the workspace-coupling manifest have none. workspace-coupling still declares no license at develop, so the E6 fix is still needed and still applies: a cargo metadata run at 89d45145 reports it as the only package missing a declaration.

Recomputing the inventory at 89d45145: 575 packages, 26 entries differ from the snapshot — bloom/bit-vec removed, ten version bumps, plus nix 0.31.3 (MIT) and zlib-rs 0.6.7 (Zlib). The set of copyleft, CDLA and conjunctive declarations at develop is identical to the snapshot minus bloom; no new non-routine declaration has appeared. The findings still hold.

CI and linters

The five workflow runs at 493d35d9856aa304015ef9b479be8ba7828e270c are all completed success and all have jobs, so no run is a silent startup_failure; Docker E2E and the publish jobs are skipping.

linter all exits 1 locally on 195 local Markdown link errors, but the merge base 576f3668 produces the same 195 errors and none of them is in this PR's files — lychee goes from 1976 to 2031 checked links with the error count unchanged. Pre-existing, not introduced here.

Non-blocking follow-ups

Four inline notes: one gap in the conjunctive-expression finding, and three precision points. One further item has no line in this diff to attach to: cargo deny emits three parse-error warnings for the deprecated SPDX identifier LGPL-3.0openmetrics-parser 0.4.4, and the workspace's own packages/tracker-client/Cargo.toml and packages/rest-api-client/Cargo.toml. The deprecated identifier is ambiguous between LGPL-3.0-only and LGPL-3.0-or-later; the two in-repo declarations are the project's own to disambiguate, and that fact belongs in the LGPL findings.

None of this blocks the record. The inventories reproduce exactly, the technical conclusions still hold against current develop, merging fixes the only package missing a license declaration, and the deferral recorded on this PR treats the inventories as the baseline to compare against later.

Comment thread docs/issues/open/269-review-dependency-licenses/initial-review.md Outdated
Comment thread docs/issues/open/269-review-dependency-licenses/initial-review.md
Comment thread docs/issues/open/269-review-dependency-licenses/evidence.md
Comment thread docs/issues/open/269-review-dependency-licenses/ISSUE.md Outdated
@da2ce7

da2ce7 commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

ACK 493d35d — docs-only license baseline: all three recorded checksums reproduce (the locked inventory byte-identically), the PR merges cleanly with develop 89d4514, and its findings still hold there.

@josecelano

Copy link
Copy Markdown
Member Author

Rebased PR #2113 onto the current develop at 492cc897, addressed all four maintainer review comments in signed commit ea3569b8, and reran the full pre-commit quality gate successfully. Fresh GitHub checks and maintainer confirmation remain required before merging.

@josecelano
josecelano requested a review from da2ce7 September 15, 2026 10:47
@josecelano

Copy link
Copy Markdown
Member Author

ACK ea3569b

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at ea3569b828b277e2be2de81c0974b2f25b6c1dae. Every statement below was recomputed from the bytes at this head; nothing is carried over from the round-one review.

The inventories reproduce exactly

Regenerating the locked inventory with the pipeline documented in E1 — c30fbff4's tree plus the one-line license.workspace = true addition to contrib/dev-tools/analysis/workspace-coupling/Cargo.toml — produces a file byte-identical to locked-license-inventory.json: sha256 d61456809c69d4dbd6ada3771d39469f1491ac5cb99498068714a67418d43f3e, 575 packages. Cargo.lock at c30fbff4 hashes to 4fc7f17ed1d348a4500ef3772c661cda43799f5ef44fb51514386d7b408156d4, matching the frontmatter. runtime-license-inventory.json matches its recorded sha256 40b63b6192d529032ad0dec68f2463356459608f8dd0cac2cea898fd2cf1fd4c at 510 packages, and its E2 tallies hold exactly: one GPL-2.0 (bloom 0.3.2), three LGPL-3.0, one CDLA-Permissive-2.0. Every runtime-inventory package is present in the locked inventory, with no extras. Where the two artifacts print different strings for the same package they are the same expression in different notation — cargo-license sorts and normalises SPDX where cargo metadata returns the raw manifest text — not a data conflict.

cargo-license is not installed on the machine used for this review, so the runtime artifact was verified against its recorded checksum, its internal tallies and the locked inventory rather than regenerated. That check is weaker than the byte-level one performed on the locked artifact, and is stated as such.

The rebase is pure and the base is current

git range-diff against the previous head reports commits one through five identical and commit six appended. Commit six touches only the three documents and project-words.txt; neither inventory JSON is in its diff, so the byte-identical result above holds at this head. git merge-tree --write-tree against develop 492cc897 is clean. Both dependency refreshes merged since the first review — #2218 and #2213 — are ancestors of that base.

The snapshot framing survives the new base. The locked graph has moved from 575 to 580 packages with roughly seventy version bumps, but each artifact is explicitly a record at c30fbff4, so that drift dates the snapshot rather than invalidating it. The claims the report makes in the present tense were re-checked at this head and all hold: E8's bloom and bit-vec query still returns zero; E7's openmetrics-parser 0.4.4 and bencode2json 0.1.0 are both still resolved at those versions declaring LGPL-3.0; the five LGPL-3.0 declarations the description counts are exactly the five in the locked graph, at the snapshot and at this head alike. workspace-coupling still carries no license declaration at 492cc897, so the E6 change is still needed and still applies.

Two license facts have changed at the new base and are worth knowing at the next scheduled review, though neither is this pull request's to fix: the zstd family moved from MIT/MIT OR Apache-2.0 to BSD-3-Clause, and zlib-rs 0.6.7 (Zlib) entered the graph. No new copyleft or CDLA declaration has appeared.

The four earlier review points are resolved

All four are addressed by commit six, and each was checked against the bytes rather than taken on the description. The conjunctive finding now lists all seven packages, which is exactly the set of AND expressions in the locked inventory — aws-lc-rs, aws-lc-sys, brotli, encoding_rs, matchit, ring, unicode-ident — and brotli 8.0.4 and matchit 0.8.4 are both in the runtime inventory, so describing them as runtime-reachable is correct, as is describing both as combining only BSD-3-Clause and MIT terms. E5 now forwards to E8, which was one of the two options offered. The progress entry has gained its HH:MM UTC component, last-updated-utc is synchronised, and related-pr now records this pull request.

One blocking point

The new reproducibility anchor names a commit that will not exist in the merged repository. Detail is in the inline comment; the fix is a one-line edit.

All five workflow runs at this head are accounted for, with no startup_failure: three completed successfully and two were still in progress when checked. Docs Lint passes, so brotli needs no project-words.txt entry.

Comment thread docs/issues/open/269-review-dependency-licenses/initial-review.md Outdated
Comment thread docs/issues/open/269-review-dependency-licenses/initial-review.md

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 600e29388a1b92f173cb7acebcb372600d78f246. Recomputed from the bytes at this head.

The blocking point is fixed, and fixed exactly

Commit seven is a single-file change to initial-review.md, three insertions and five deletions. It removes the initial-review-record-commit frontmatter key and rewrites the Scope-and-Method sentence to read: the inventory input is commit c30fbff4, the lockfile checksum in the frontmatter, plus the workspace-coupling license.workspace = true change recorded in E6.

That is precisely the reproduction that produces the recorded checksums, and precisely the one I ran. No commit sha is cited, so nothing here depends on an object that merging or a future rebase could orphan. git grep 1daf4e2d 600e2938 returns no match anywhere in the tree — not only under docs/. The change introduces no new claim: the delta is the removal plus the rewording, and every surrounding statement is unchanged.

The document's own metadata is consistent. ISSUE.md is untouched by this commit, and within this pull request the established pattern is that last-updated-utc and the progress log move when the issue spec itself changes — commits two through five likewise left both alone. The episode this commit belongs to is already recorded by the 2026-09-15 10:16 UTC entry, which describes clarifying the reproducibility input; that entry remains accurate. Every progress-log line still carries its HH:MM UTC component.

Both inventories now reproduce byte-for-byte

cargo-license is available on the review machine this round, so the runtime artifact could be regenerated rather than only checksum-checked. Both artifacts were rebuilt from c30fbff4's tree plus the E6 change, using the commands the evidence ledger documents:

  • locked-license-inventory.json — reproduced sha256 d61456809c69d4dbd6ada3771d39469f1491ac5cb99498068714a67418d43f3e, 575 packages, byte-identical.
  • runtime-license-inventory.json — reproduced sha256 40b63b6192d529032ad0dec68f2463356459608f8dd0cac2cea898fd2cf1fd4c, 510 packages, byte-identical.

Both committed files are unchanged at this head, and both match the checksums recorded in E1 and E2. That closes the one gap in the previous round, where the runtime artifact could only be verified against its recorded checksum and cross-checked against the locked inventory. The byte-level match also confirms the generating tool behaves identically to the cargo-license 0.7.0 that E3 records, since any difference in SPDX normalisation would change the output.

Everything else re-checked

git range-diff reports commits one through six identical and commit seven appended. git merge-tree --write-tree against develop 492cc897 is clean. All five workflow runs at this head are accounted for with a startup_failure count of zero; Docs Lint has completed successfully and the other four were still in progress when checked, with no failure recorded.

The clippy-allow-reasons metadata gap remains non-blocking and stays where it was left: it post-dates the c30fbff4 snapshot, so it is correctly outside a record of that snapshot, and the twice-yearly cadence is the right place for it.

The record reproduces exactly, its stated inputs are durable, and its technical conclusions hold at the current base.

@da2ce7

da2ce7 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

ACK 600e293 — both license inventories reproduce byte-identically from the documented input, the branch-local commit anchor is gone from the tree, and merge-tree against develop 492cc89 is clean.

@josecelano

Copy link
Copy Markdown
Member Author

ACK 600e293

@josecelano
josecelano force-pushed the 269-first-dependency-license-review branch from 600e293 to e6ac268 Compare September 15, 2026 12:54
@josecelano
josecelano force-pushed the 269-first-dependency-license-review branch from e6ac268 to 15f1504 Compare September 15, 2026 13:00
@josecelano
josecelano force-pushed the 269-first-dependency-license-review branch from 15f1504 to 1edda0e Compare September 15, 2026 13:15

@da2ce7 da2ce7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 1edda0eaba11bbce1e3c71e38857b736dafea369. Recomputed from the bytes at this head.

This head is the content approved in review 5209621922 (600e2938), rebased onto develop efebacfb. The trees and the commit messages are unchanged, so that review's argument carries over and is not restated here; what follows is what was recomputed at this head.

Range-diff: seven of seven identical

git range-diff 492cc897..600e2938 efebacfb..1edda0ea

1:  969e86d5 = 1:  484efbd7 docs(licenses): record initial dependency license review
2:  b68ad28f = 2:  8506e82b docs(licenses): clarify maintainer review actions
3:  cb4414ae = 3:  0dd5ae95 docs(licenses): add bloom legal review brief
4:  cbb38623 = 4:  2d4baead docs(licenses): link bloom remediation issue
5:  b460c32b = 5:  7ad91f31 docs(licenses): record bloom removal
6:  ea3569b8 = 6:  5a7cc85a docs(licenses): address dependency review feedback
7:  600e2938 = 7:  1edda0ea docs(licenses): correct review inventory provenance

Every pairing is = — no !, > or <. Two independent checks agree. The two range patches are byte-identical: git diff 492cc897 600e2938 and git diff efebacfb 1edda0ea are the same 169,483 bytes. And git diff 600e2938 1edda0ea restricted to the eight touched paths prints nothing, so the blobs are the same objects, not merely equivalent text.

Base, shape, messages

git merge-base efebacfb 1edda0ea returns efebacfb1f1e52a4324807518887c980d8c05270 exactly, and efebacfb is an ancestor of the head, so develop fast-forwards. Seven commits, eight changed files — the same eight paths as the approved range. Their intersection with develop's own 492cc897..efebacfb delta (24 paths) is empty, which is why the rebase had nothing to resolve and the trees came through untouched.

git log --format=%B over both ranges is byte-identical (sha256 1d0dc96ab472470f5133df0c4d173b71ba6e1398f63b080dbe7a2e2541acd039). The seven messages carry no trailers at all — no co-author line and no tool-attribution line. Author dates are preserved; only the committer timestamps moved, to 13:14:53–13:14:55 UTC.

Metadata still conforms: conventional-commit title, base branch develop, #269 referenced. The change set is documentation-only — zero Rust source files — so the checklist's test and Rust-specific items have nothing to bind to beyond the one-line license.workspace = true addition to workspace-coupling/Cargo.toml, which is unchanged from the approved range.

Inventory checksums

The committed artifacts at this head hash to exactly the values recorded when they were byte-reproduced in round 3:

d61456809c69d4dbd6ada3771d39469f1491ac5cb99498068714a67418d43f3e  locked-license-inventory.json
40b63b6192d529032ad0dec68f2463356459608f8dd0cac2cea898fd2cf1fd4c  runtime-license-inventory.json

Because the commits are byte-identical, the reproduction from the documented input still holds and was not repeated. The round-3 blocking point remains fixed at this head: git grep 1daf4e2d 1edda0ea returns nothing anywhere in the tree, and initial-review.md's frontmatter carries input-revision: c30fbff4 with input-lockfile-sha256: 4fc7f17e… and no record-commit key.

CI at this head

All nineteen checks on the pull request are terminal and none is red: sixteen success, three skipped (Docker E2E, Publish (Release), Publish (Development)).

check result
Unit (stable), Unit (nightly) success
Build on ubuntu / windows / macos, stable and nightly (6) success
Test (Docker) (release) success (13:43 UTC)
Docs Lint, Layer Boundary Bans, Documented Clippy Allows, Context success
Generate Coverage Report, codecov/patch, codecov/project success
Docker E2E, Publish (Release), Publish (Development) skipped

Coverage and the clippy-allow-reasons check, both of which have been intermittently noisy on other heads, are green here.

Nit, outside this pull request. The push-event run on the source fork is red, and it is worth a moment because the cause is environmental rather than anything in these commits. testing.yaml sets BASE_REF: ${{ github.base_ref || 'develop' }}, so on a push event it falls back to origin/develop — the fork's develop, which sits at 7af5a52a (2026-08-21), 875 commits behind upstream. clippy-allow-reasons therefore diffs against a 25-day-old base, sees 255 changed Rust files that belong to upstream history, and reports missing reason = … on pre-existing attributes in packages/configuration/src/lib.rs, packages/udp-protocol/src/lib.rs, src/main.rs and others — none of which this pull request touches. The same run's Docker E2E failure is the already-tracked feature-branch-push shape (#2179). Fast-forwarding the fork's develop, or binding the check to the merge base rather than a branch name, would clear it.

Verdict

Approve. Same content, same verdict as review 5209621922, now recomputed on base efebacfb.

@da2ce7

da2ce7 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

ACK 1edda0e — r3-approved content rebased onto develop efebacf, range-diff identity and inventory checksums recomputed from the bytes at this head.

@josecelano

Copy link
Copy Markdown
Member Author

ACK 1edda0e

@josecelano
josecelano merged commit fa084e3 into torrust:develop Sep 15, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants