Skip to content
Apothem
参考

作者署名头——逐文件 SPDX 许可行

使用规范的单行头部,以每种文件类型相应的注释语法,定义并强制执行逐文件的 SPDX 许可标识符标记。

面向下游贡献者的规范性权威参考。 本文档镜像项目规范中的作者署名与文件头章节(规范 §0.5 + §4.6);它是随已发布仓库一同提供的独立参考。架构理由记录于 ADR-0002。


1. 规范头部行

生态系统中每个适用文件都必须(MUST)以单行规范 SPDX 许可标识符行开头,并采用其文件类型族的注释语法;只有 shebang 行,或在 Markdown 文件中的 YAML frontmatter,可以位于它之前(§5)。该行是文件的机器可读许可标记;对于非豁免文件,它必须存在,没有商量余地,其内容由单一事实来源管辖,而不是逐文件即兴编写。完整的版权文书只在仓库根目录的 LICENSE 文件中存放一份——它不会复制到每个源文件中。

1.1 信息内容(不变量)

规范内容恰好是一行:

  1. SPDX-License-Identifier: MIT——按由 FSFE 维护的 REUSE 规范定义的机器可读许可标记;SPDX 工具链(reuse lint、scancode)、Linux 内核工具以及下游许可扫描器都能无歧义地解析它。它不带可视边框,也不带逐文件的版权、网站、邮箱或 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,以及诸如 scripts/apothem 的无扩展名 shell 入口点# 行注释# 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
锁文件 / 生成文件 / JSON无 / 不适用豁免。 见 §3 例外清单。

Markdown 变体(规范渲染):

<!-- SPDX-License-Identifier: MIT -->

HTML 注释(或 MDX 的 {/* */})包装器以不可见方式渲染,因此渲染后的界面保持整洁,而源码内的许可标记在各文件类型间始终保持机器可读。


3. 例外清单(按类别豁免)

以下类别豁免于 SPDX 头部行。file-header 校验器会直接放行这些文件而不作检查。下列类别与 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 文件、package-lock.json、yarn.lock、pnpm-lock.yaml 与 go.sum。这些文件由机器管理。
  • 生成与压缩文件——generated/ 目录下的任何文件,以及压缩后的捆绑包(*.min.js、*.min.css)。
  • 内置(vendored)第三方内容——_vendor/、vendor/、third_party/ 与 node_modules/ 下的文件。它们携带上游自身的许可证或声明。在上游署名之上注入我们的标记属于许可违规。
  • 审计、规划与工具状态——.audit/ 与 .apothem/ 下的全部内容,其中保存计划、记忆、学习数据与上下文。另外,工作树根目录下由工具所有的 projects/ 与 memory/ 也在此列。这些目录要么被 gitignore,要么归操作者所有,不在已发布树的范围之内。计划文件的溯源由其 frontmatter 追踪(见 plans-discipline.md §3)。
  • 测试数据夹具——tests/fixtures/ 下的 .yaml、.yml、.txt 与 .json 文件。该树中的测试源文件仍须携带头部。
  • 注入器冒烟测试输入——tests/conformity-scenarios/fixtures/F-13-injector-smoke/ 下的文件。它们保持无头部状态,因为注入器测试会检查注入器是否为它们添加了头部。
  • 打包与空标记——.SRCINFO(打包解析器会严格读取它),以及零字节标记 .keep、.gitkeep 与 py.typed。
  • 二进制文件——夹具中列出的图像、字体、归档、媒体与已编译对象后缀。校验器变体表未映射的后缀默认豁免。

例外清单本身在 src/apothem/schemas/header-exceptions.txt 中被编码为正则/glob 列表,并作为校验器适用性检查的输入。修订需要一次结构化询问和一份新的 ADR。


4. 许可交互

SPDX 行以机器可读方式声明项目的许可;LICENSE 文件以权威方式声明它:

  • SPDX-License-Identifier: MIT——按 REUSE 规范和 SPDX 标准的机器可读许可标记。自动化许可扫描器直接解析此行;SPDX 表达式语法与 reuse lint、scancode-toolkit、FOSSology 和 Linux 内核许可工具相互兼容。
  • 仓库根目录的 LICENSE——权威的法律文书,载有完整的 MIT 条款和版权持有人。它是版权声明唯一的存放处;逐文件头部通过共享的 SPDX 标识符隐式引用它,而不是在每个文件中重述版权。

单行形式。 逐文件溯源就是这一行 SPDX;版权文书在根目录的 LICENSE 中只存放一份。带边框的多行横幅框(版权、网站、邮箱、联系方式各行包在一个划线框架中)会被校验器拒绝:它们在每个文件中重复联系方式和版权元数据,却没有增加任何机器可读许可标记尚未向 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 行开始。在带有 YAML frontmatter 的 Markdown / MDX 文件中,frontmatter 排在最前(见下一条)。
  • 对于带有 YAML frontmatter 的 Markdown / MDX 文件,frontmatter 保持在字节 0 处,以便工具能够解析它,SPDX 注释紧随闭合的 --- 之后,然后是正文;带有 H1 的文件,其正文以该 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 和 frontmatter。
  • 对位于插入位置且缺少空行的 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 frontmatter 块,因此规范行可位于结束围栏之后,如 §5 所要求的那样。MDX 文件解析为 {/* */} 形式(§2),并依其进行检查。校验器与注入器将规范块放在同一索引处。

由字节精确的夹具 src/apothem/schemas/authorship-header.txt 支撑。针对此匹配器,语料库运行会报告发现项的数量,以及被标记文件的样本。它不输出逐文件差异,也不输出覆盖率百分比。该匹配器属于阻断性质:在 CI 与 pre-commit 钩子所使用的 --strict 下,发现项会导致运行失败。若不使用 --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 钩子会以 --strict 对已跟踪的树运行每个逐写入(per-Write)匹配器,包括 file-header 校验器(§8)。file-header 匹配器属于阻断性质,因此其发现项会阻止提交。该钩子只做检查,没有修复模式,也从不运行注入器(§7);注入器通过 make headers-fix 运行。
  5. CLAUDE.md 强制行为块——指示助手在创建适用文件时注入规范 SPDX 行。
  6. 位于 .github/copilot-instructions.md 的 GitHub Copilot 指令文件——指示 Copilot 在生成文件时同样照做。
  7. 位于 src/apothem/hooks/messages/pretooluse-{write,edit}-header-guard.md 的 PreToolUse 钩子——拦截适用路径上的 Write/Edit 工具调用,使 SPDX 行在文件创建时即被注入,而不是之后才以校验器发现项的形式暴露。该守卫的检查器 src/apothem/hooks/lib/header_check.py 仅使用标准库,并从 hooks/ 旁边的 schemas/ 目录读取夹具和豁免列表,因此它在 Claude Code 插件下同样可用,而在插件环境中 apothem 软件包无法导入。它对项目内部的文件应用注入器的变体表和插入位置规则,并且仅在带有头部夹具(src/apothem/schemas/authorship-header.txt)的 git 项目中这样做,因为 SPDX 行是本仓库的约定,而不是插件所打开的每个项目的默认设置。
  8. PR 模板复选框——面向贡献者的断言:每个新文件都带有规范 SPDX 行。
  9. 本文档(site/content/docs/reference/authorship-header.mdx)——规范的、具有规范效力的说明文。

另请参阅

On this page