Skip to content

AI legal review — SPDX, registries, scanners & OSD/DFSG ecosystem impact (Sonnet cluster) #5

Description

@zackees

Note

AI-generated first-pass legal review — not legal advice. Produced by Claude (Fable 5 coordinator; Opus agents for hard legal-analysis clusters, Sonnet agents for drafting/ecosystem clusters and prior-art research) against the repo at HEAD of main on 2026-08-24. This is input material for the human attorney review gated by LEGAL-REVIEW.md. Severity ratings: CRITICAL / HIGH / MEDIUM / LOW.

Q1 — SPDX LicenseRef syntax and text resolution

Rating: MEDIUM

Findings:
LicenseRef-FastLED-Reciprocal-1.0 is syntactically valid — the SPDX spec permits LicenseRef-[idstring] for licenses not on the SPDX License List (SPDX Annex E). Using it in a // SPDX-License-Identifier: header line follows the documented convention.

The gap is text resolution in SBOMs. A bare LicenseRef- tag has no inherent meaning outside the document that defines it — SPDX 2.x requires an accompanying ExtractedLicensingInfo element (with licenseId + full extractedText) in the same SPDX document, or a DocumentRef-<name>:LicenseRef-<id> composite reference (SPDX Clause 10). Most automated SBOM generators (syft, cdx-gen, reuse-tool, FOSSA) only synthesize ExtractedLicensingInfo inconsistently; downstream consumers of transitively-generated SBOMs will very often get a dangling LicenseRef-FastLED-Reciprocal-1.0 with no extractedText, because cross-repo DocumentRef resolution is rarely populated automatically.

Namespace-collision risk: LicenseRef- ids are only unique within one SPDX document. Nothing stops an unrelated project from independently minting LicenseRef-FastLED-Reciprocal-1.0 with different text; without a canonical, versioned, permanently-hosted copy of the text, SBOM consumers have no authoritative way to verify a match.

Precedent for the stronger path: HashiCorp's Business Source License was accepted onto the official SPDX List as BUSL-1.1 despite being non-OSI-approved (SPDX BUSL-1.1, request issue #995). SPDX List inclusion is not gated on OSI approval.

Recommendation: (1) Host the canonical LICENSE text at a permanent, versioned URL and reference it near the SPDX tag. (2) File a new-license request with SPDX (spdx/license-list-XML, Submit New License tool) once v1.0.0 is legally finalized — following the BUSL-1.1 precedent. (3) In the interim, ship a machine-readable .spdx.json at repo root with a populated hasExtractedLicensingInfos entry.


Q2 — Arduino Library Manager and PlatformIO registry license requirements

Rating: LOW

Findings:
Arduino: the current library.properties spec has no dedicated license metadata field at all — license is not machine-checked at manifest level. The library-registry FAQ contains no mention of "license" or "OSI" as an inclusion gate. Adafruit's 2021 post "Closed Source Libraries in the Arduino Library Manager" corroborates that Library Manager already lists non-OSI, even closed-source, libraries as long as freely redistributable. (A web-search claim that "must include a valid OSI-approved license" could not be corroborated against the primary FAQ text — treat as unverified.) FastLED's Reciprocal License permits unrestricted free redistribution of Covered Software, so it would very likely still qualify — a soft, discretionary editorial review, not an automated OSI gate.

PlatformIO: library.json docs show license as a free-text/SPDX-string field with no visible enforcement; SPDX expressions accepted, OSI-approved is a preference, not a requirement.

Recommendation: Verify directly with Arduino (test PR against library-registry or their issue tracker) — the editorial reviewers make the actual call and the novel clause could still draw pushback. For PlatformIO, set license to the SPDX-syntax string LicenseRef-FastLED-Reciprocal-1.0 (not "custom" or a misleading "MIT").


Q3 — Automated scanner classification and corporate default-deny consequences

Rating: HIGH

Findings:

  • GitHub Licensee: fuzzy-matches (Sørensen–Dice) the LICENSE file against a fixed corpus. MPL 2.0 text plus a large appended rider will almost certainly fall below the similarity threshold and classify as "Other". GitHub's own docs: "if your repository uses an unlisted license, it won't display clearly at the top of the repository page" — and GitHub's recommended fix is to simplify the LICENSE file (GitHub Docs — Licensing a repository), which cuts directly against the MPL-plus-rider structure.
  • FOSSA: unrecognized licenses land in an "Uncategorized" bucket; default-Deny policies hard-flag them (FOSSA — Configuring Default Policy Rules).
  • Black Duck: "Unknown License" is the literal default when no KB match (community article).
  • ScanCode/Debian: will detect embedded MPL-2.0 and flag the custom terms as unmatched — a compound "mpl-2.0" + "unknown-license-reference" result most CI license gates treat as failure.

Consequences: Most enterprise compliance programs run default-deny pipelines: unknown license → blocked until manual legal review (often multi-week), and some orgs categorically reject anything off their pre-approved list. Because FastLED is presently plain MIT — the most permissively pre-approved license class there is — this relicense converts FastLED from "always auto-approved" to "always manually queued" for every corporate consumer, for every future release. First-order adoption friction independent of whether the terms are acceptable once reviewed.

Recommendation: Proactively submit the license to FOSSA's and Black Duck's known-license databases (both accept submissions), and open a ScanCode LicenseDB PR (aboutcode-org/scancode-licensedb) with the canonical text — the only way to escape default Unknown bucketing.


Q4 — OSD / FSF / DFSG failure analysis and Linux distro consequences

Rating: CRITICAL

Findings:
Tested against the OSD's ten criteria:

  • Plain file-level reciprocity is not the problem — MPL-2.0 is OSI-approved, and §2.2's Larger Work carve-out keeps this narrower than SSPL (which OSI rejected for service-stack overreach).
  • The novel, higher-risk element is the trigger + timing: disclosure required on or before a private commercial transaction with no grace period — materially stricter than any OSI-approved analogue (GPL/AGPL require source to accompany or follow distribution, never precede a sale). A precondition that must be satisfied before a sale can lawfully close functions as a procedural gate on commercial redistribution — the strongest candidate for an OSD feat: publish reciprocal license and compliance toolchain #1 (Free Redistribution) problem. OSI's worked history (SSPL, Commons Clause) shows the Board rejects licenses making commercial redistribution contingent on extra affirmative acts.
  • OSD Prior art survey — commercial-trigger/reciprocity licenses & ethical-source lineage #6 (fields of endeavor) is likely not violated — the obligation is uniform across industries.
  • OSD Strategy: project-agnostic GPL/free-software compatibility exception #10 (technology neutrality): minor risk — §2.3(a) prefers "the same source-hosting platform" (implicitly GitHub); "any publicly accessible version control system" drafting would remove the question.
  • FSF: has accepted trigger-based strong copyleft (AGPL), so a sale-trigger alone isn't disqualifying by FSF precedent — but "no grace period, must precede the transaction" is the kind of extra procedural condition FSF treats as an "additional restriction"; endorsement unlikely without a reasonable cure window.
  • Debian DFSG: the most concrete exposure. Debian itself commercially redistributes (CD vendors, paid cloud images) — any Debian derivative that patches FastLED and is sold would trigger §2.3 onto the redistributor. Practical outcome: package maintainers avoid the relicensed FastLED, vendoring a frozen pre-relicense MIT snapshot (permitted per §2.4) or replacing it.
  • Real-world signal already exists: WLED already fully removed its FastLED dependency (WLED PR #4615), noting license-provenance sensitivity even under the current MIT license. A stricter license gives other large consumers (xLights etc.) concrete incentive to freeze on the last MIT tag.

Recommendation: If broad ecosystem compatibility matters, replace "on or before First Sale, no grace period" with a bounded post-sale cure window (e.g., "within 30 days of first sale," mirroring GPLv3's written-offer mechanics) — this single change removes most OSD #1 and DFSG friction while preserving the reciprocal intent. Flag prominently to reviewing counsel that the timing mechanic, not the copyleft mechanic, is the primary legal/ecosystem risk surface.


Q5 — Migration mechanics vs. comparable relicenses, and the NOTICE-TEMPLATE header approach

Rating: MEDIUM

Findings:
Comparable relicense playbooks (MongoDB→SSPL 2018, Elastic→SSPL 2021, HashiCorp MPL-2.0→BUSL 2023, Sentry BSL→FSL 2023; see Goodwin Law overview, HashiCorp announcement, Sentry FSL post) share: (1) a public rationale announcement well before the change; (2) a hard version boundary — old releases stay under the old license (FastLED §2.4 mirrors this correctly); (3) header/SPDX rewrite as one atomic, reviewable commit; (4) a built-in reversion/sunset for the new terms (BUSL/FSL auto-convert to Apache-2.0/MIT after a change date) — the single feature that made BUSL/FSL more palatable than SSPL, and absent from the FastLED license.

FastLED's header-policy.toml + fail-closed, fingerprinted tooling is more rigorous than most precedents.

NOTICE-TEMPLATE.txt problems: Lines 2–4 (the "AI LICENSE" block) are non-standard conventions injected into every source file: (a) scanner confusion — an unrecognized second "LICENSE" keyword adjacent to the SPDX line increases odds of per-file multi-license/ambiguous flags, compounding the Q3 problem; (b) header bloat — 4 lines × hundreds of files is real diff noise and merge-conflict surface; (c) legal ambiguity — the "legally non-remedial" caveat lives in LICENSE §3, not the header, so a bare header reader can't know "AI agents must read that file" isn't binding; the disclaimer needs to be co-located; (d) files with pre-existing third-party notices — vendored platform code will need manual exclusion-with-reason, ongoing maintenance burden.

Recommendation: Move the 3 AI-instruction lines out of per-file headers into a single repo-root AGENTS.md-equivalent (the convention modern coding agents already auto-discover) plus a .reuse/dep5-style manifest entry; keep per-file headers to the one SPDX line. Also consider a sunset/reversion clause (à la BUSL/FSL) — the biggest community-trust lever available and currently missing.


Q6 — GitHub "View license" display and contribution/fork impact

Rating: LOW

Findings:
An undetected/custom LICENSE renders as a plain "View license" link instead of the recognized-license badge (GitHub Docs). Practical impact is reputational/frictional, not functional — no Git operation is gated. The real cost is drive-by-contributor trust: an unrecognized license reads to casual visitors as "no clear license / possibly proprietary," which suppresses first-time PR/star activity.

Recommendation: (1) Keep the LICENSE file's first lines dominated by unmodified MPL-2.0-recognizable text with the rider clearly demarcated (may improve Licensee's partial match — not guaranteed); (2) compensate with a prominent README license summary + static badge image and a CONTRIBUTING.md that states terms plainly.


Additional issues spotted

  • "FastLED" trademark/naming ambiguity in §2.1: the copyright-license definition does double duty as an implicit brand/provenance claim with no trademark policy referenced. Compliance forks will by definition be named/branded "FastLED," creating the ecosystem confusion Redis/Elastic handled via separate trademark policies.
  • "First Sale" definition breadth: sweeps in contract manufacturers and white-label OEM sellers who may not know they ship a FastLED fork — unwitting-noncompliance exposure disproportionate to embedded supply-chain awareness.
  • No exception list for security/CI infrastructure: no carve-out for e.g. selling dev kits/eval boards preloaded with modified test firmware — likely oversight, worth a line-item in the attorney review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions