Skip to content
Apothem
Справочник

Заголовок авторства — пофайловая SPDX-строка лицензии

Определение и применение пофайловых маркеров SPDX-идентификатора лицензии с помощью канонических однострочных заголовков в подходящем синтаксисе комментариев для каждого типа файла.

Каноническая нормативная справка для нижестоящих участников. Этот документ отражает разделы спецификации проекта «Авторство и заголовки файлов» (Спецификация §0.5 + §4.6); это самостоятельная справка, которая поставляется вместе с опубликованным репозиторием. Архитектурное обоснование зафиксировано в ADR-0002.


1. Каноническая строка заголовка

Каждый применимый файл в экосистеме ДОЛЖЕН начинаться с одной канонической строки SPDX-идентификатора лицензии в синтаксисе комментариев своего семейства типов файлов; перед ней могут стоять только shebang или, в файлах Markdown, YAML-фронтматтер (§5). Эта строка — машиночитаемый маркер лицензии файла; её наличие не подлежит обсуждению для файлов, не подпадающих под исключения, а её содержимое определяется единым источником истины и не придумывается заново для каждого файла. Полный правовой документ об авторских правах находится один раз в корневом файле LICENSE репозитория — он не дублируется в каждый исходный файл.

1.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. Механизмы самоприменения

Эта дисциплина должна пережить каждую будущую сессию и каждого будущего участника. Обязательные поверхности принудительного применения:

  1. src/apothem/schemas/authorship-header.txt — байт-точная каноническая фикстура; единый источник истины.
  2. scripts/inject-header.{sh,py} — механический инжектор (§7).
  3. Валидатор file-header (§8) — сообщает о расхождении как о блокирующем замечании, которое проваливает прогон с --strict.
  4. Хук pre-commit — хук conformity-corpus-perwrite запускает каждый сопоставитель для записи, включая валидатор file-header (§8), по отслеживаемому дереву с --strict. Сопоставитель file-header является блокирующим, поэтому его замечание блокирует коммит. Хук только проверяет. У него нет режима исправления, и он никогда не запускает инжектор (§7), который работает через make headers-fix.
  5. Блок обязательного поведения в CLAUDE.md — предписывает ассистенту вставлять каноническую строку SPDX при создании каждого применимого файла.
  6. Файл инструкций GitHub Copilot по пути .github/copilot-instructions.md — предписывает Copilot делать то же при генерации файлов.
  7. Хуки 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 — соглашение этого репозитория, а не умолчание для каждого проекта, который открывает плагин.
  8. Флажок в шаблоне PR — заявление участника о том, что каждый новый файл содержит каноническую строку SPDX.
  9. Этот документ (site/content/docs/reference/authorship-header.mdx) — каноническое нормативное пояснение.

См. также

On this page