0008: Third-party licenses page

Status

Accepted (2026-10-06)

Context

The Web UI ships minified bundles of its dependencies. MIT, ISC and BSD require their copyright and license text to accompany copies, and the minifier strips the comments that carried them; the footer linked only morg's own license. The site needs a page listing what it is built from, with the license texts, kept current by the build.

Vite 8's build.license writes exactly the bundled packages, but misses two things: the conversion worker, a separate build its license plugin does not run on, and CSS, where Pico CSS is bundled through an @import. license-checker reads package.json instead, so it sees every dependency, but splits them by scope, not by what is bundled: Pico is a development dependency, and moving it to dependencies would install a CSS framework with the CLI.

Decision

scripts/write-licenses.mjs runs license-checker-rseidelsohn before every Web UI build and dev server start, and writes two lists into web/public/, one per scope, production and development; web/licenses.html shows them as two tables, linked from the footer of every page that has one (the Embed Page is chrome-less, ADR 0003). The two lists split the installed packages between them: production what dependencies reach, development what only development dependencies reach, Pico among them. Together they cannot miss a bundled package, whichever scope it is declared in. morg itself is left off, and so is the README license-checker substitutes for a missing license file: such a package shows its license identifier and copyright line only.

CI separately fails on a production dependency whose license is not GPL-3.0-compatible (npm run licenses:check). Development dependencies are not checked: they do not ship, Pico (MIT) and DejaVu Sans's arrows (Bitstream Vera, public domain changes) aside, and several are MPL-2.0, BlueOak or Python-2.0.

Consequences