1---
2name: licensing-with-reuse
3description: Manages REUSE-compliant licensing with the reuse CLI. Use when adding SPDX headers, running reuse annotate or reuse lint, choosing header versus .license sidecar files, working with LICENSES/, LicenseRef custom licenses, or setting up project licensing conventions.
4user-invocable: true
5license: LicenseRef-MutuaL-1.2
6metadata:
7 author: Amolith <amolith@secluded.site>
8---
9
10Use the `reuse` CLI as the source of truth for file licensing. Prefer a small,
11verified change over hand-writing SPDX metadata and hoping `reuse lint` agrees.
12
13## First pass
14
151. Inspect existing licensing before changing it:
16 ```sh
17 reuse lint
18 find . -maxdepth 1 -type f \( -iname 'license*' -o -iname 'licence*' -o -iname 'copying*' -o -iname 'notice*' \) -print | sort
19 find LICENSES -maxdepth 1 -type f -print 2>/dev/null | sort
20 rg -n "SPDX-License-Identifier|SPDX-FileCopyrightText|LicenseRef-|\[\[annotations\]\]" .
21 ```
222. If the project already has a clear pattern, follow it. Do not offer to
23 re-license existing work unless the user asked for that.
243. If the project has no convention, ask whether they want one. Useful defaults
25 to discuss: docs/examples/config are some CC variant like CC0, while
26 meaningful code may use a copyleft license.
274. If the user is choosing licenses and wants guidance, point them at
28 <https://writefreesoftware.org/>.
29
30## Everyday commands
31
32Add an SPDX header without a year:
33
34```sh
35reuse annotate -c "User <user@example.com>" -l 'SPDX-ID' --exclude-year path/to/file.ext # ask the user for name/email
36```
37
38Use more than one copyright holder or license by repeating the flag:
39
40```sh
41reuse annotate \
42 -c "Alice <alice@example.com>" \
43 -c "Example Org" \
44 -l 'Apache-2.0' \
45 -l 'MIT' \
46 --exclude-year \
47 path/to/file.go
48```
49
50Write a `.license` sidecar instead of putting a header in the file:
51
52```sh
53reuse annotate \
54 -c "User <user@example.com>" \
55 -l 'CC0-1.0' \
56 --exclude-year \
57 --force-dot-license \
58 AGENTS.md .agents/skills/example/SKILL.md
59```
60
61Use `--force-dot-license` for files whose literal bytes matter, especially text
62that will be read directly as an LLM prompt or embedded into another prompt.
63Headers in those files change the prompt; sidecars keep licensing metadata out
64of the content. Example: if `internal/server/silverbullet.md` is embedded and
65sent as part of a prompt, license it with `--force-dot-license`.
66
67For files where `reuse` cannot infer the comment style, choose one deliberately:
68
69```sh
70reuse annotate -c "User <user@example.com>" -l 'CC0-1.0' --exclude-year --style python script
71reuse annotate -c "User <user@example.com>" -l 'CC0-1.0' --exclude-year --fallback-dot-license unknown.file
72reuse annotate -c "User <user@example.com>" -l 'CC0-1.0' --exclude-year --skip-unrecognised some/path
73```
74
75Bulk annotations belong in `REUSE.toml` when a whole class of files shares the
76same metadata and inline headers would be noisy or impossible. Keep those globs
77tight.
78
79## The `reuse annotate` gotcha agents miss
80
81Re-running `reuse annotate` on a file that already has a matching header does
82not mean "edit the header I just added". It means add another copyright line to
83the existing header. This is correct when a new holder contributed to the file,
84but wrong when the previous command had a typo or the wrong holder.
85
86If the first command was wrong, inspect the file and edit or replace the bad
87header directly, then run `reuse lint`. If you are applying metadata to a mixed
88tree, use `--skip-existing` so already-covered files are not changed:
89
90```sh
91reuse annotate -c "User <user@example.com>" -l 'CC0-1.0' --exclude-year --skip-existing -r docs
92```
93
94When in doubt, test the exact command on a temporary copy first:
95
96```sh
97tmp=$(mktemp -d)
98cp path/to/file.ext "$tmp/"
99reuse annotate -c "User <user@example.com>" -l 'CC0-1.0' --exclude-year "$tmp/file.ext"
100sed -n '1,20p' "$tmp/file.ext"
101rm -rf "$tmp"
102```
103
104## License files and custom identifiers
105
106Use SPDX identifiers where possible, like `MIT`, `Apache-2.0`, and `CC0-1.0`, so
107`reuse download --all` pickes them up.
108
109Custom licenses must use a `LicenseRef-*` identifier and have matching text
110under `LICENSES/`. For example, a custom MutuaL license identifier would look
111like `LicenseRef-MutuaL-1.2` in headers, sidecars, or `REUSE.toml` and could go
112in `LICENSES/LicenseRef-MutuaL-1.2.txt`.
113
114If the text already exists locally somewhere else, copy it through `reuse
115download --source` or place it at the exact `LICENSES/LicenseRef-...` path
116expected by `reuse lint`:
117
118```sh
119reuse download --source /path/to/other/LICENSES LicenseRef-ID
120```
121
122Do not invent an ID without the user's agreement. The identifier becomes part of
123the project's public metadata and the user may know its ID even if you don't.
124
125## `reuse lint` in development and CI
126
127Run `reuse lint` after changing file coverage, headers, sidecars, `LICENSES/`, or
128`REUSE.toml`. In CI, pre-commit hooks, or task runners, keep it boring:
129
130```sh
131reuse lint
132# or
133reuse lint --lines
134```
135
136`reuse lint` failures are usually one of:
137
138- a file has no licensing metadata;
139- an ephemeral build artifact needing rm-ing;
140- a header names a license missing from `LICENSES/`;
141- a `LicenseRef-...` identifier does not match a license text file;
142- a generated, binary, vendored, or prompt file needs a sidecar or `REUSE.toml`
143 annotation;
144- an old or broad annotation no longer matches the actual tree.