SKILL.md


name: licensing-with-reuse description: 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. user-invocable: true license: LicenseRef-MutuaL-1.2 metadata: author: Amolith amolith@secluded.site

Use the reuse CLI as the source of truth for file licensing. Prefer a small, verified change over hand-writing SPDX metadata and hoping reuse lint agrees.

First pass

  1. Inspect existing licensing before changing it:
    reuse lint
    find . -maxdepth 1 -type f \( -iname 'license*' -o -iname 'licence*' -o -iname 'copying*' -o -iname 'notice*' \) -print | sort
    find LICENSES -maxdepth 1 -type f -print 2>/dev/null | sort
    rg -n "SPDX-License-Identifier|SPDX-FileCopyrightText|LicenseRef-|\[\[annotations\]\]" .
    
  2. If the project already has a clear pattern, follow it. Do not offer to re-license existing work unless the user asked for that.
  3. If the project has no convention, ask whether they want one. Useful defaults to discuss: docs/examples/config are some CC variant like CC0, while meaningful code may use a copyleft license.
  4. If the user is choosing licenses and wants guidance, point them at https://writefreesoftware.org/.

Everyday commands

Add an SPDX header without a year:

reuse annotate -c "User <user@example.com>" -l 'SPDX-ID' --exclude-year path/to/file.ext # ask the user for name/email

Use more than one copyright holder or license by repeating the flag:

reuse annotate \
  -c "Alice <alice@example.com>" \
  -c "Example Org" \
  -l 'Apache-2.0' \
  -l 'MIT' \
  --exclude-year \
  path/to/file.go

Write a .license sidecar instead of putting a header in the file:

reuse annotate \
  -c "User <user@example.com>" \
  -l 'CC0-1.0' \
  --exclude-year \
  --force-dot-license \
  AGENTS.md .agents/skills/example/SKILL.md

Use --force-dot-license for files whose literal bytes matter, especially text that will be read directly as an LLM prompt or embedded into another prompt. Headers in those files change the prompt; sidecars keep licensing metadata out of the content. Example: if internal/server/silverbullet.md is embedded and sent as part of a prompt, license it with --force-dot-license.

For files where reuse cannot infer the comment style, choose one deliberately:

reuse annotate -c "User <user@example.com>" -l 'CC0-1.0' --exclude-year --style python script
reuse annotate -c "User <user@example.com>" -l 'CC0-1.0' --exclude-year --fallback-dot-license unknown.file
reuse annotate -c "User <user@example.com>" -l 'CC0-1.0' --exclude-year --skip-unrecognised some/path

Bulk annotations belong in REUSE.toml when a whole class of files shares the same metadata and inline headers would be noisy or impossible. Keep those globs tight.

The reuse annotate gotcha agents miss

Re-running reuse annotate on a file that already has a matching header does not mean "edit the header I just added". It means add another copyright line to the existing header. This is correct when a new holder contributed to the file, but wrong when the previous command had a typo or the wrong holder.

If the first command was wrong, inspect the file and edit or replace the bad header directly, then run reuse lint. If you are applying metadata to a mixed tree, use --skip-existing so already-covered files are not changed:

reuse annotate -c "User <user@example.com>" -l 'CC0-1.0' --exclude-year --skip-existing -r docs

When in doubt, test the exact command on a temporary copy first:

tmp=$(mktemp -d)
cp path/to/file.ext "$tmp/"
reuse annotate -c "User <user@example.com>" -l 'CC0-1.0' --exclude-year "$tmp/file.ext"
sed -n '1,20p' "$tmp/file.ext"
rm -rf "$tmp"

License files and custom identifiers

Use SPDX identifiers where possible, like MIT, Apache-2.0, and CC0-1.0, so reuse download --all pickes them up.

Custom licenses must use a LicenseRef-* identifier and have matching text under LICENSES/. For example, a custom MutuaL license identifier would look like LicenseRef-MutuaL-1.2 in headers, sidecars, or REUSE.toml and could go in LICENSES/LicenseRef-MutuaL-1.2.txt.

If the text already exists locally somewhere else, copy it through reuse download --source or place it at the exact LICENSES/LicenseRef-... path expected by reuse lint:

reuse download --source /path/to/other/LICENSES LicenseRef-ID

Do not invent an ID without the user's agreement. The identifier becomes part of the project's public metadata and the user may know its ID even if you don't.

reuse lint in development and CI

Run reuse lint after changing file coverage, headers, sidecars, LICENSES/, or REUSE.toml. In CI, pre-commit hooks, or task runners, keep it boring:

reuse lint
# or
reuse lint --lines

reuse lint failures are usually one of:

  • a file has no licensing metadata;
  • an ephemeral build artifact needing rm-ing;
  • a header names a license missing from LICENSES/;
  • a LicenseRef-... identifier does not match a license text file;
  • a generated, binary, vendored, or prompt file needs a sidecar or REUSE.toml annotation;
  • an old or broad annotation no longer matches the actual tree.