Заголовок авторства — пофайловая SPDX-строка лицензии
Определение и применение пофайловых маркеров SPDX-идентификатора лицензии с помощью канонических однострочных заголовков в подходящем синтаксисе комментариев для каждого типа файла.
Каноническая нормативная справка для нижестоящих участников. Этот документ отражает разделы спецификации проекта «Авторство и заголовки файлов» (Спецификация §0.5 + §4.6); это самостоятельная справка, которая поставляется вместе с опубликованным репозиторием. Архитектурное обоснование зафиксировано в ADR-0002.
1. Каноническая строка заголовка
Каждый применимый файл в экосистеме ДОЛЖЕН начинаться с одной канонической строки SPDX-идентификатора лицензии в синтаксисе комментариев своего семейства типов файлов; перед ней могут стоять только shebang или, в файлах Markdown, YAML-фронтматтер (§5). Эта строка — машиночитаемый маркер лицензии файла; её наличие не подлежит обсуждению для файлов, не подпадающих под исключения, а её содержимое определяется единым источником истины и не придумывается заново для каждого файла. Полный правовой документ об авторских правах находится один раз в корневом файле LICENSE репозитория — он не дублируется в каждый исходный файл.
1.1 Информационное содержимое (инвариант)
Каноническое содержимое — это ровно одна строка:
SPDX-License-Identifier: MIT— машиночитаемый маркер лицензии согласно спецификации REUSE, которую поддерживает FSFE; однозначно разбирается инструментарием SPDX (reuse lint,scancode), инструментами ядра Linux и нижестоящими сканерами лицензий. Он не содержит визуальной рамки и пофайловых строк с копирайтом, веб-сайтом, e-mail или GitHub — по замыслу пофайловое происхождение выражается единственной строкой SPDX (см. §4).
1.2 Эталонная форма (семейство #-комментариев)
Канонический текст — записанный здесь в форме с синтаксисом комментариев # — служит источником истины в src/apothem/schemas/authorship-header.txt:
# SPDX-License-Identifier: MITЭтот текст — единственный авторитетный источник. Валидатор file-header (§8) сверяет файлы с этой байт-точной фикстурой. Любое расхождение между строкой заголовка файла и этой фикстурой (с учётом подстановки синтаксиса по §2) фиксируется как замечание. Валидатор является блокирующим: в режиме --strict, в котором его запускают CI и хук pre-commit, замечание проваливает прогон (§8).
2. Варианты по типам файлов (байт-точные)
Информационное содержимое строки инвариантно; от типа файла зависит только её синтаксис комментариев. Полная таблица вариантов по типам файлов:
| Семейство типов файлов | Синтаксис комментариев | Вид варианта |
|---|---|---|
Семейство # — .sh, .bash, .zsh, .py, .rb, .pl, .ps1, .yml, .yaml, .toml, .cff, .cfg, .gitignore, .gitattributes, .editorconfig, .shellcheckrc, .env.example, Makefile, Dockerfile, Procfile, CODEOWNERS, PKGBUILD, точки входа shell-скриптов без расширения, такие как scripts/apothem | строчный комментарий # | # SPDX-License-Identifier: MIT |
Семейство // — .js, .jsx, .mjs, .cjs, .ts, .tsx, .go, .rs, .java, .kt, .swift, .cs, .scala, .dart, .jsonc | строчный комментарий // | // SPDX-License-Identifier: MIT |
Семейство блочных комментариев — .html, .htm, .md, .markdown, .xml, .vue (область шаблона), .php (область шаблона) | <!-- ... --> | <!-- SPDX-License-Identifier: MIT --> |
MDX (.mdx) | {/* ... */} (комментарий JSX-выражения) | {/* SPDX-License-Identifier: MIT */} |
Семейство C-блоков — .c, .cc, .cpp, .h, .hpp, .css, .scss, .less (/* */) | /* ... */ | /* SPDX-License-Identifier: MIT */ |
Семейство ; — .ini, некоторые .lisp/.scm | строчный комментарий ; | ; SPDX-License-Identifier: MIT |
Семейство -- — .sql, .lua, .hs, .elm, .ada | строчный комментарий -- | -- SPDX-License-Identifier: MIT |
| Lock-файлы / сгенерированные / JSON | нет / неприменимо | Освобождены. См. §3, список исключений. |
Вариант для Markdown (каноническая запись):
<!-- SPDX-License-Identifier: MIT -->Обёртка в виде HTML-комментария (или MDX {/* */}) в отображаемом виде невидима, поэтому отображаемая поверхность остаётся чистой, а лицензионный маркер в исходнике остаётся машиночитаемым для всех типов файлов.
3. Список исключений (категорически освобождены)
Следующие классы освобождены от строки заголовка SPDX. Валидатор file-header пропускает эти файлы, не проверяя их. Классы ниже соответствуют списку glob-шаблонов в header-exceptions.txt:
- Юридические файлы и файлы версий —
LICENSE,LICENSE.md,LICENSE.txt,NOTICEиVERSION.LICENSEсодержит авторитетную строку авторского права, наличие которой подтверждает валидаторlicense-author-consistency. - Каноническая фикстура —
schemas/authorship-header.txt. Внедрение заголовка в фикстуру породило бы заголовок заголовка. - Ассеты
*.svg— XML-комментарии ненадёжны для маркеров строчных комментариев, поэтому происхождение SVG фиксируется в README ассета и в сгенерированных растровых выходах. - Файлы JSON (
.json) — в JSON нет синтаксиса комментариев. Там, где для JSON-конфигурации требуется указание авторства, поместите рядом файл<file>.NOTICE.md. - Lock-файлы — каждый файл
*.lock,package-lock.json,yarn.lock,pnpm-lock.yamlиgo.sum. Эти файлы управляются машиной. - Сгенерированные и минифицированные файлы — любой файл в каталоге
generated/, а также минифицированные сборки (*.min.js,*.min.css). - Вендоренное стороннее содержимое — файлы в
_vendor/,vendor/,third_party/иnode_modules/. Они несут собственную лицензию или уведомление вышестоящего проекта. Внедрение нашего маркера поверх указания авторства вышестоящего проекта — нарушение лицензии. - Состояние аудита, планирования и окружения — всё под
.audit/и.apothem/, где хранятся планы, память, данные обучения и контексты. Такжеprojects/иmemory/в корне рабочего дерева, которыми владеет окружение. Эти деревья либо исключены через gitignore, либо принадлежат оператору и находятся вне области опубликованного дерева. Файлы планов отслеживают происхождение по своему фронтматтеру (см.plans-discipline.md§3). - Тестовые данные-фикстуры — файлы
.yaml,.yml,.txtи.jsonвtests/fixtures/. Исходные файлы тестов в этом дереве по-прежнему несут заголовок. - Входные данные smoke-теста инжектора — файлы в
tests/conformity-scenarios/fixtures/F-13-injector-smoke/. Они остаются без заголовка, поскольку тест инжектора проверяет, что инжектор добавляет в них заголовок. - Упаковочные и пустые маркеры —
.SRCINFO, который парсер упаковки читает строго, и маркеры нулевого размера.keep,.gitkeepиpy.typed. - Бинарные файлы — суффиксы изображений, шрифтов, архивов, медиа и скомпилированных объектов, перечисленные в фикстуре. Суффикс, которого нет в таблице вариантов валидатора, по умолчанию освобождён.
Сам список исключений закодирован как список regex/glob в src/apothem/schemas/header-exceptions.txt и служит входными данными для проверки применимости валидатором. Изменения требуют структурированного запроса и нового ADR.
4. Взаимодействие с лицензией
Строка SPDX объявляет лицензию проекта в машиночитаемом виде; файл LICENSE объявляет её авторитетно:
SPDX-License-Identifier: MIT— машиночитаемый маркер лицензии согласно спецификации REUSE и стандарту SPDX. Автоматические сканеры лицензий разбирают эту строку напрямую; синтаксис выражений SPDX совместим сreuse lint, scancode-toolkit, FOSSology и инструментарием лицензий ядра Linux.
- Корневой
LICENSEрепозитория — авторитетный юридический документ, содержащий полные условия MIT и имя правообладателя. Это единственное место для заявления об авторских правах; пофайловые заголовки ссылаются на него неявно через общий идентификатор SPDX и не повторяют заявление об авторских правах в каждом файле.
Однострочная форма. Пофайловое происхождение — это единственная строка SPDX; правовой документ об авторских правах находится один раз в корневом LICENSE. Многострочные баннеры в рамке (строки с копирайтом, веб-сайтом, e-mail и контактами, заключённые в линованную рамку) отклоняются валидатором: они дублируют в каждом файле контактные метаданные и метаданные об авторских правах, не добавляя ничего, чего машиночитаемый маркер лицензии уже не даёт инструментарию REUSE/SPDX/SBOM. Байт-точная фикстура src/apothem/schemas/authorship-header.txt содержит однострочную форму; валидатор сверяется с этой фикстурой.
Перекрёстные ссылки. Файл LICENSE (MIT) — при конфликте приоритет имеет юридический документ. ADR-0006 документирует обоснование ратификации сужения баннера.
5. Позиция вставки
- Строка SPDX — это первое содержимое файла, за двумя исключениями. Строка shebang (
#!/usr/bin/env bash,#!/usr/bin/env python3и т. д.) всегда остаётся строкой 1, а строка SPDX начинается со строки 2. В файлах Markdown / MDX с YAML-фронтматтером первым идёт фронтматтер (следующий пункт). - Для файлов Markdown / MDX с YAML-фронтматтером фронтматтер остаётся на байте 0, чтобы инструменты могли его разобрать, а комментарий SPDX следует за закрывающим
---, затем идёт тело, которое в файлах, имеющих H1, открывается этим заголовком.scripts/inject-header.pyразмещает комментарий именно так. - Одна пустая строка отделяет строку SPDX от следующего содержимого (H1, тела и т. д.).
6. Политика видимости заголовка
Для файлов Markdown и MDX строка SPDX всегда записывается внутри своей комментарной обёртки (<!-- ... --> или {/* */}). Она видна только в исходном коде и не появляется в отображаемой странице. У инжектора нет видимого отображения и нет переопределения для отдельного файла. Ни один инструмент в репозитории не читает фикстуру src/apothem/schemas/header-visibility.yaml.
7. Инжектор — scripts/inject-header.{sh,py}
Детерминированный CLI, который:
- Принимает один или несколько путей к файлам (или glob-шаблонов).
- Определяет применимость по списку исключений (§3).
- Определяет текущее состояние заголовка (канонический, некорректный или отсутствует), удаляя найденный неканонический блок баннера, чтобы повторные запуски были идемпотентными.
- Формирует корректный вариант SPDX для типа файла (§2).
- Вставляет строку в правильную позицию (§5), учитывая shebang и фронтматтер.
- Добавляет недостающую пустую строку к строке SPDX, которая стоит в месте вставки без неё, вместо того чтобы вставлять вторую копию выше.
- Работает в трёх режимах:
fix-in-place(записывает изменения),emit-patch(печатает унифицированный diff),check(завершается с ненулевым кодом при любом расхождении; ни одно задание CI не запускает его по отслеживаемому дереву). - Идемпотентен: двукратный запуск ничего не меняет.
Инжектор вызывается целью make headers-fix, которая запускает scripts/inject-header.py --mode fix-in-place.
8. Валидатор — file-header
Находится в src/apothem/conformity/file_header_grep.py. Для каждого файла в рабочем дереве валидатор определяет его применимость (по §3) и, если она есть, проверяет, что каноническая строка SPDX присутствует в месте вставки. Для большинства семейств этим местом является начало файла, после необязательной строки shebang. Для файлов Markdown и MDX сначала пропускается блок YAML-фронтматтера, поэтому каноническая строка может следовать за закрывающей строкой фронтматтера, как того требует §5. Файлы MDX приводятся к форме {/* */} (§2) и проверяются по ней. Валидатор и инжектор размещают канонический блок по одному и тому же индексу.
Опирается на байт-точную фикстуру src/apothem/schemas/authorship-header.txt. Прогон по корпусу выводит число замечаний и выборку помеченных файлов для этого сопоставителя. Diff по каждому файлу и процент покрытия не выводятся. Сопоставитель является блокирующим: при --strict, который используют CI и хук pre-commit, замечание проваливает прогон. Без --strict шлюз сообщает о замечании и завершается с кодом 0.
9. Механизмы самоприменения
Эта дисциплина должна пережить каждую будущую сессию и каждого будущего участника. Обязательные поверхности принудительного применения:
src/apothem/schemas/authorship-header.txt— байт-точная каноническая фикстура; единый источник истины.scripts/inject-header.{sh,py}— механический инжектор (§7).- Валидатор
file-header(§8) — сообщает о расхождении как о блокирующем замечании, которое проваливает прогон с--strict. - Хук pre-commit — хук
conformity-corpus-perwriteзапускает каждый сопоставитель для записи, включая валидаторfile-header(§8), по отслеживаемому дереву с--strict. Сопоставительfile-headerявляется блокирующим, поэтому его замечание блокирует коммит. Хук только проверяет. У него нет режима исправления, и он никогда не запускает инжектор (§7), который работает черезmake headers-fix. - Блок обязательного поведения в
CLAUDE.md— предписывает ассистенту вставлять каноническую строку SPDX при создании каждого применимого файла. - Файл инструкций GitHub Copilot по пути
.github/copilot-instructions.md— предписывает Copilot делать то же при генерации файлов. - Хуки PreToolUse в
src/apothem/hooks/messages/pretooluse-{write,edit}-header-guard.md— перехватывают вызовы инструментов Write/Edit для применимых путей, так что строка SPDX вставляется при создании файла, а не обнаруживается позже как замечание валидатора. Проверяющий модуль защиты,src/apothem/hooks/lib/header_check.py, использует только стандартную библиотеку и читает фикстуру и список исключений из каталогаschemas/рядом сhooks/, поэтому он работает и под плагином Claude Code, где пакетapothemне импортируется. Он применяет таблицы вариантов и правила места вставки инжектора к файлам внутри проекта, и только в git-проекте, который содержит фикстуру заголовка (src/apothem/schemas/authorship-header.txt), поскольку строка SPDX — соглашение этого репозитория, а не умолчание для каждого проекта, который открывает плагин. - Флажок в шаблоне PR — заявление участника о том, что каждый новый файл содержит каноническую строку SPDX.
- Этот документ (
site/content/docs/reference/authorship-header.mdx) — каноническое нормативное пояснение.
См. также
- ADR-0002 — архитектурное обоснование, рассмотренные альтернативы.
- ADR-0006 — ратификация сужения баннера.
src/apothem/schemas/authorship-header.txt— байт-точная каноническая фикстура.src/apothem/schemas/header-exceptions.txt— список исключений (в форме regex/glob).scripts/inject-header.pyиscripts/inject-header.sh— инжектор.src/apothem/conformity/file_header_grep.py— валидатор.- Спецификация проекта §0.5 + §4.6 — канонический текст, отражённый здесь.
Соглашения для многоповерхностных окружений
Каноническая нормативная справка по конфигурации многоповерхностных окружений и их согласованности в средах выполнения чата, автодополнения в IDE и ревью PR.
Манифест закрепления зависимостей
Политика объявления зависимостей, охватывающая диапазоны среды выполнения Python, инструменты разработки, lock-файлы инструментов релиза и утверждённые нижние границы версий для каждой поверхности сборки.