License Headers
The DispatchAtlas license-header registry — the single-line SPDX header every commentable source file carries, plus blanket coverage for generated and data files.
Every commentable source file in DispatchAtlas carries one single-line
SPDX-License-Identifier: MIT header; everything else is covered by the
annotation blocks in REUSE.toml and the project LICENSE. This page is the
ratified policy; the machine projection the gate consumes is
tools/license_header.toml, and tools/license_header.py enforces it
(check fails closed in pre-commit and CI, inject adds a missing header at
the correct position idempotently).
Inline header forms
| File class | Header line | Position |
|---|---|---|
.py .toml .yml .yaml .sh .ps1 .cff .editorconfig .gitattributes .gitignore CODEOWNERS | # SPDX-License-Identifier: MIT | First line; after the shebang when one is present |
.ts .tsx .mjs | // SPDX-License-Identifier: MIT | First line |
.js | // SPDX-License-Identifier: MIT (the block form /* SPDX-License-Identifier: MIT */ is also accepted) | First line |
.css | /* SPDX-License-Identifier: MIT */ | First line |
.md | <!-- SPDX-License-Identifier: MIT --> | First line, or first non-blank line after the closing YAML frontmatter fence |
.mdx | {/* SPDX-License-Identifier: MIT */} | First non-blank line after the closing frontmatter fence (HTML comments are invalid in MDX bodies) |
.xml | <!-- SPDX-License-Identifier: MIT --> | First line, or directly after the <?xml …?> declaration |
Blanket-covered classes
Non-commentable, data, asset, lockfile, and marker classes carry no inline
header; REUSE.toml asserts their license and copyright centrally:
.json .svg .csv .gz .whl .ttf .woff2 .pdf .png .ico
.log .hash .map .tsbuildinfo .txt .html .lock .typed and the pagefind index
classes, plus the basenames LICENSE, CNAME, .nojekyll, py.typed, and
.gitkeep.
Generated-output trees
Every file under a generated-output tree is machine-emitted evidence or build
output and is blanket-covered regardless of extension: site/out/ and each
package's dist/, plus the local layers of the experiments workspace. The
gate never requires or injects inline headers there.
Exemptions and scope
License texts under LICENSES/ are the licenses themselves and carry no
header. Dependency and cache trees (.venv/, node_modules/, byte-code and
tool caches) are outside the policy: they are not DispatchAtlas files. A file
class absent from this registry is reported by the gate as unregistered and
fails the check — new classes are ratified here before they ship.
Running the gate
uv run python tools/license_header.py check
uv run python tools/license_header.py injectcheck walks every tree — tracked, private, and generated — and exits
non-zero on any missing or unregistered finding. inject writes the canonical
header for the file's class at the correct position and changes nothing on a
second run.