Skip to content
Apothem
参考

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

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

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


1. 规范头部行

生态系统中每个适用文件都必须以单行规范 SPDX 许可标识符行开头,并采用其文件类型族的注释语法。该行是文件的机器可读许可标记;对于非豁免文件,其存在是不可协商的,其内容由单一事实来源治理,而非逐文件即兴编写。完整的版权法律文书在仓库根目录的 LICENSE 文件中只保留一份——它不会复制到每个源文件中。

1.1 信息内容(不变量)

规范内容正好是一行:

  1. SPDX-License-Identifier: MIT — 按 FSFE 维护的 REUSE 规范定义的机器可读许可标记;可被 SPDX 工具链(reuse lintscancode)、Linux 内核工具以及下游许可扫描器无歧义地解析。它不携带任何可视边框,也不携带逐文件的版权、网站、邮箱或 GitHub 行——逐文件溯源就是这一行 SPDX,这是有意为之的设计(见 §4)。

1.2 参考形式(# 注释族)

规范文本——此处以其 # 注释语法形式书写——其事实来源在 src/apothem/schemas/authorship-header.txt

# SPDX-License-Identifier: MIT

此文本是唯一权威来源。file-header 验证器(§7)针对此字节精确的固定样本运行。文件头行与此固定样本之间的任何漂移(在 §2 的语法替换之下)都是 CI 失败。


2. 逐文件类型变体(字节精确)

该行的信息内容是不变的;只有其注释语法随文件类型而变化。完整的逐文件类型变体表:

文件类型族注释语法变体渲染
# 族 — .sh.bash.zsh.py.rb.pl.ps1.yml.yaml.toml.cff.gitignore.gitattributes.editorconfig.shellcheckrc.env.exampleMakefileDockerfileProcfileCODEOWNERSPKGBUILD,以及诸如 scripts/apothem 的无扩展名 shell 入口点# 行注释# SPDX-License-Identifier: MIT
// 族 — .js.jsx.mjs.cjs.ts.tsx.go.rs.java.kt.swift.c.cc.cpp.h.hpp.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 块族 — .css.scss.less.sql/* *//* ... *//* SPDX-License-Identifier: MIT */
; 族 — .ini.cfg、部分 .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 验证器的适用性检查对这些返回 not-applicable

  • LICENSE — 它本身就是法律文书;携带权威版权行,license-author-consistency 验证器会确认其存在。
  • *.svg 资源 — XML 注释对行注释标记而言脆弱,因此 SVG 溯源由资源 README 和生成的栅格输出承载。
  • CHANGELOG.md — 格式受约束的发行说明文档;SPDX 行作为单条 HTML 注释出现在变更日志标题之上,而不是交织进格式中。
  • JSON 文件(.json — JSON 没有注释语法。当 JSON 配置需要署名时,放置一个同级 <file>.NOTICE.md
  • 锁文件package-lock.jsonyarn.lockpnpm-lock.yamlCargo.lockPipfile.lockpoetry.lockgo.sum 等(机器管理)。
  • 生成文件 — 任何带有 # Generated by ...// Generated by ... 标记的文件,或任何匹配 .gitattributes linguist-generated=true 的文件。
  • 供应(vendored)的第三方内容vendor/third_party/node_modules/ 下的文件。它们携带上游自身的许可/声明;在上游署名之上注入我们的标记是许可违规。
  • .audit/ 文件 — 被 gitignore 的临时文件;超出发布树范围。
  • 计划文件(<project-root>/.apothem/plans/**,以及旧的 <project-root>/.plans/** — 被 gitignore 的临时文件;溯源是计划的 frontmatter(见 plans-discipline.md §3)。
  • 空标记.keep.gitkeep 等(语义上零字节)。
  • 任何种类的二进制文件

例外清单本身在 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 文件,SPDX 注释位于最顶端,YAML frontmatter 随后,然后是 H1 和正文。渲染后的输出以一条不可见的注释开头,然后由工具解析 frontmatter,再之后是可见内容。
  • 单个空行将 SPDX 行与下一项内容(frontmatter ---、shebang 的后继行、H1 等)分隔开。

6. 头部可见性策略

具体到 Markdown 文件,SPDX 行默认不可见——包裹在 <!-- ... -->(或 MDX 的 {/* */})中,仅在源中可见。这是 README、CONTRIBUTING、CLAUDE.md、受支持的harness指令文件、技能 SKILL.md、命令正文、output-styles 以及文档页的正确策略。可见渲染(SPDX 行作为输出顶部的纯文本或围栏块)对那些受益于即时可读溯源的独立参考文档是允许的;该策略按文件类别在 src/apothem/schemas/header-visibility.yaml 中设置(默认不可见),并允许在该行之后紧接一个文件作用域覆盖标记 <!-- header-visibility: visible -->


7. 注入器——scripts/inject-header.{sh,py}

一个确定性 CLI,它:

  • 接受一个或多个文件路径(或 glob)。
  • 通过例外清单(§3)确定适用性。
  • 检测现有头部状态(规范 / 畸形 / 缺失),剥离它发现的任何非规范横幅块,使重新运行具有幂等性。
  • 按文件类型渲染正确的 SPDX 变体(§2)。
  • 在正确位置插入(§5),尊重 shebang 和 frontmatter。
  • 以三种模式运行:fix-in-place(写入)、emit-patch(打印统一 diff)、check(在任何偏离时以非零退出——供 CI 使用)。
  • 幂等:运行两次是无操作。

注入器由那些以预先插入的 SPDX 行来搭建新文件的 Make 目标(make headers-fixmake new-* 脚手架)以及处于 --fix 模式的预提交钩子调用。


8. 验证器——file-header(CI)

位于 src/apothem/conformity/file_header_grep.py。对于工作树中的每个文件,验证器查找其适用性(按 §3),若适用,则断言规范 SPDX 行存在于文件头部——位于所有其他内容之前,唯一允许的前置内容是 shebang(§5)。

src/apothem/schemas/authorship-header.txt 处的字节精确固定样本支撑。在 CI 摘要中报告逐文件 diff 和聚合覆盖率 %。在任何偏离时使构建失败。


9. 自我强制机制

该纪律必须在每一个未来会话和每一位未来贡献者中存续。强制性的强制执行界面:

  1. src/apothem/schemas/authorship-header.txt — 字节精确的规范固定样本;唯一事实来源。
  2. scripts/inject-header.{sh,py} — 机械注入器(§7)。
  3. file-header CI 验证器(§8)——在任何偏离时使构建失败。
  4. 预提交钩子 — 在暂存文件上以 --fix 运行验证器,接入注入器。
  5. CLAUDE.md 强制行为块 — 指示助手在创建适用文件时注入规范 SPDX 行。
  6. 位于规范 .github/ 路径的受支持的harness指令文件 — 指示harness运行时在文件生成时做同样的事。
  7. PreToolUse 钩子 位于 src/apothem/hooks/messages/pretooluse-{write,edit}-header-guard.md — 拦截对适用路径的 Write/Edit 工具调用,使 SPDX 行在文件创建时注入,而不是稍后作为 CI 失败被发现。
  8. PR 模板复选框 — 面向贡献者的断言,确认每个新文件都携带规范 SPDX 行。
  9. 本文档site/content/docs/reference/authorship-header.mdx)——规范的、规范性的说明文。

另见

On this page