Skip to content
Apothem
Referência

Cabeçalho de autoria — Linha de licença SPDX por arquivo

Define e aplica marcadores de identificador de licença SPDX por arquivo usando cabeçalhos canônicos de uma única linha na sintaxe de comentário adequada para cada tipo de arquivo.

Referência normativa canônica para colaboradores downstream. Este documento espelha as seções de Autoria e Cabeçalho de arquivo da especificação do projeto (Especificação §0.5 + §4.6); é a referência independente distribuída com o repositório publicado. A justificativa arquitetural está registrada no ADR-0002.


1. A linha de cabeçalho canônica

Todo arquivo aplicável do ecossistema DEVE começar com uma única linha canônica de identificador de licença SPDX, na sintaxe de comentário de sua família de tipo de arquivo; somente um shebang ou, em arquivos Markdown, o frontmatter YAML pode precedê-la (§5). A linha é o marcador de licença legível por máquina do arquivo; sua presença é inegociável para arquivos não isentos, e seu conteúdo é regido por uma única fonte de verdade, não improvisado arquivo a arquivo. O instrumento de copyright completo vive uma única vez no arquivo LICENSE da raiz do repositório — não é duplicado em cada arquivo-fonte.

1.1 Conteúdo de informação (invariante)

O conteúdo canônico é exatamente uma linha:

  1. SPDX-License-Identifier: MIT — o marcador de licença legível por máquina conforme a especificação REUSE mantida pela FSFE; analisado sem ambiguidade pela cadeia de ferramentas SPDX (reuse lint, scancode), pelas ferramentas do kernel do Linux e pelos scanners de licença a jusante. Ele não carrega borda visual nem linhas de copyright, site, e-mail ou GitHub por arquivo — a procedência por arquivo é a única linha SPDX por design (ver §4).

1.2 A forma de referência (família de comentário #)

O texto canônico — escrito aqui em sua forma de sintaxe de comentário # — é a fonte de verdade em src/apothem/schemas/authorship-header.txt:

# SPDX-License-Identifier: MIT

Este texto é a única fonte autoritativa. O validador file-header (§8) verifica os arquivos contra esta fixture exata, byte a byte. Qualquer divergência entre a linha de cabeçalho de um arquivo e esta fixture (sob a substituição de sintaxe conforme §2) é relatada como um achado. O validador é bloqueante: sob --strict, como o CI e o hook de pre-commit o executam, um achado faz a execução falhar (§8).


2. Variantes por tipo de arquivo (exatas byte a byte)

O conteúdo de informação da linha é invariante; apenas sua sintaxe de comentário varia por tipo de arquivo. A tabela completa de variantes por tipo de arquivo:

Família de tipo de arquivoSintaxe de comentárioRenderização da variante
Família # — .sh, .bash, .zsh, .py, .rb, .pl, .ps1, .yml, .yaml, .toml, .cff, .cfg, .gitignore, .gitattributes, .editorconfig, .shellcheckrc, .env.example, Makefile, Dockerfile, Procfile, CODEOWNERS, PKGBUILD, pontos de entrada de shell sem extensão, como scripts/apothemcomentário de linha ## SPDX-License-Identifier: MIT
Família // — .js, .jsx, .mjs, .cjs, .ts, .tsx, .go, .rs, .java, .kt, .swift, .cs, .scala, .dart, .jsonccomentário de linha //// SPDX-License-Identifier: MIT
Família de comentário de bloco — .html, .htm, .md, .markdown, .xml, .vue (região de template), .php (região de template)<!-- ... --><!-- SPDX-License-Identifier: MIT -->
MDX (.mdx){/* ... */} (comentário de expressão JSX){/* SPDX-License-Identifier: MIT */}
Família de bloco C — .c, .cc, .cpp, .h, .hpp, .css, .scss, .less (/* */)/* ... *//* SPDX-License-Identifier: MIT */
Família ; — .ini, alguns .lisp/.scmcomentário de linha ;; SPDX-License-Identifier: MIT
Família -- — .sql, .lua, .hs, .elm, .adacomentário de linha ---- SPDX-License-Identifier: MIT
Lockfile / gerado / JSONnenhum / não aplicávelIsento. Ver §3 Lista de exceções.

Variante Markdown (renderização canônica):

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

O invólucro de comentário HTML (ou MDX {/* */}) é renderizado de forma invisível, então a superfície renderizada permanece limpa enquanto o marcador de licença no código-fonte continua legível por máquina em todos os tipos de arquivo.


3. Lista de exceções (categoricamente isentas)

As classes a seguir estão isentas da linha de cabeçalho SPDX. O validador file-header aprova estes arquivos sem verificá-los. As classes abaixo correspondem à lista de globs em header-exceptions.txt:

  • Arquivos de licença e de versão — LICENSE, LICENSE.md, LICENSE.txt, NOTICE e VERSION. LICENSE carrega a linha de copyright autoritativa, cuja presença o validador license-author-consistency confirma.
  • A fixture canônica — schemas/authorship-header.txt. Injetar o cabeçalho na fixture produziria um cabeçalho do cabeçalho.
  • Ativos *.svg — comentários XML são frágeis para marcadores de comentário de linha, por isso a procedência do SVG é carregada pelo README do ativo e pelas saídas raster geradas.
  • Arquivos JSON (.json) — JSON não tem sintaxe de comentário. Quando a atribuição for exigida em uma configuração JSON, coloque um <file>.NOTICE.md irmão.
  • Lockfiles — todo arquivo *.lock, package-lock.json, yarn.lock, pnpm-lock.yaml e go.sum. Esses arquivos são gerenciados por máquina.
  • Arquivos gerados e minificados — qualquer arquivo em um diretório generated/ e os pacotes minificados (*.min.js, *.min.css).
  • Conteúdo de terceiros incorporado — arquivos em _vendor/, vendor/, third_party/ e node_modules/. Eles carregam a própria licença ou aviso do upstream. Injetar nosso marcador sobre a atribuição do upstream é uma violação de licença.
  • Estado de auditoria, de planejamento e de harness — tudo em .audit/ e .apothem/, que guarda planos, memória, dados de aprendizado e contextos. Também projects/ e memory/ na raiz da árvore de trabalho, que o harness gerencia. Essas árvores são ignoradas pelo git ou são de propriedade do operador, e estão fora do escopo da árvore publicada. Os arquivos de plano têm procedência rastreada pelo frontmatter deles (consulte plans-discipline.md §3).
  • Fixtures de dados de teste — arquivos .yaml, .yml, .txt e .json em tests/fixtures/. Os arquivos de código-fonte de teste nessa árvore continuam levando o cabeçalho.
  • Entradas de smoke test do injetor — os arquivos em tests/conformity-scenarios/fixtures/F-13-injector-smoke/. Eles permanecem sem cabeçalho porque o teste do injetor verifica se o injetor adiciona o cabeçalho a eles.
  • Empacotamento e marcadores vazios — .SRCINFO, que um parser de empacotamento lê de forma estrita, e os marcadores de zero byte .keep, .gitkeep e py.typed.
  • Arquivos binários — os sufixos de imagem, fonte, arquivo, mídia e objeto compilado listados na fixture. Um sufixo que a tabela de variantes do validador não mapeia fica isento por padrão.

A lista de exceções é, ela própria, codificada como uma lista de regex/glob em src/apothem/schemas/header-exceptions.txt e é a entrada da verificação de aplicabilidade do validador. As emendas exigem uma indagação estruturada e um novo ADR.


4. Interação com a licença

A linha SPDX declara a licença do projeto de forma legível por máquina; o arquivo LICENSE a declara de forma autoritativa:

  • SPDX-License-Identifier: MIT — o marcador de licença legível por máquina conforme a especificação REUSE e o padrão SPDX. Scanners de licença automatizados analisam esta linha diretamente; a sintaxe de expressão SPDX é compatível de forma cruzada com reuse lint, scancode-toolkit, FOSSology e as ferramentas de licença do kernel do Linux.
  • LICENSE na raiz do repositório — o instrumento legal autoritativo que carrega os termos completos do MIT e o detentor do copyright. É o único lar da declaração de copyright; os cabeçalhos por arquivo o referenciam implicitamente por meio do identificador SPDX compartilhado, em vez de reafirmar o copyright em cada arquivo.

Forma de linha única. A procedência por arquivo é a única linha SPDX; o instrumento de copyright vive uma única vez no LICENSE da raiz. Caixas de banner multilinha com borda (copyright, site, e-mail, linhas de contato envolvidas em um quadro riscado) são rejeitadas pelo validador: elas duplicam os metadados de contato e copyright em cada arquivo sem acrescentar nada que o marcador de licença legível por máquina já não forneça às ferramentas REUSE/SPDX/SBOM. A fixture exata byte a byte em src/apothem/schemas/authorship-header.txt carrega a forma de linha única; o validador é executado contra esta fixture.

Referências cruzadas. Arquivo LICENSE (MIT) — o instrumento legal prevalece em caso de conflito. ADR-0006 documenta a justificativa da ratificação do estreitamento do banner.


5. Posição de inserção

  • A linha SPDX é o primeiro conteúdo do arquivo, com duas exceções. Uma linha shebang (#!/usr/bin/env bash, #!/usr/bin/env python3, etc.) permanece sempre na linha 1, e a linha SPDX começa na linha 2. Em arquivos Markdown / MDX com frontmatter YAML, o frontmatter vem primeiro (próximo item).
  • Para arquivos Markdown / MDX com frontmatter YAML, o frontmatter permanece no byte 0 para que as ferramentas possam analisá-lo, e o comentário SPDX vem depois do --- de fechamento, seguido do corpo, que abre com o H1 nos arquivos que têm um. scripts/inject-header.py posiciona o comentário dessa maneira.
  • Uma única linha em branco separa a linha SPDX do conteúdo seguinte (o H1, o corpo, etc.).

6. Política de visibilidade do cabeçalho

Nos arquivos Markdown e MDX, a linha SPDX é sempre escrita dentro do seu invólucro de comentário (<!-- ... --> ou {/* */}). Ela fica visível apenas no código-fonte e não aparece na página renderizada. O injetor não tem renderização visível nem substituição por arquivo. Nenhuma ferramenta do repositório lê a fixture src/apothem/schemas/header-visibility.yaml.


7. O injetor — scripts/inject-header.{sh,py}

Uma CLI determinística que:

  • Recebe um ou mais caminhos de arquivo (ou globs).
  • Determina a aplicabilidade pela lista de exceções (§3).
  • Detecta o estado do cabeçalho existente (canônico / malformado / ausente), removendo qualquer bloco de banner não canônico que encontrar, para que as reexecuções sejam idempotentes.
  • Renderiza a variante SPDX correta por tipo de arquivo (§2).
  • Insere na posição correta (§5), respeitando shebangs e frontmatter.
  • Acrescenta a linha em branco ausente a uma linha SPDX que esteja no ponto de inserção sem ela, em vez de inserir uma segunda cópia acima dela.
  • Opera em três modos: fix-in-place (grava), emit-patch (imprime um diff unificado), check (sai com código diferente de zero em qualquer divergência; nenhum job de CI o executa sobre a árvore rastreada).
  • Idempotente: executar duas vezes é uma não-operação.

O injetor é invocado pelo alvo make headers-fix, que executa scripts/inject-header.py --mode fix-in-place.


8. O validador — file-header

Fica em src/apothem/conformity/file_header_grep.py. Para cada arquivo da árvore de trabalho, o validador consulta sua aplicabilidade (conforme §3) e, se ela se aplicar, afirma que a linha SPDX canônica está presente no ponto de inserção. Para a maioria das famílias, esse ponto é o início do arquivo, depois de um shebang opcional. Para arquivos Markdown e MDX, um bloco de frontmatter YAML é ignorado primeiro, de modo que a linha canônica pode vir depois da cerca de fechamento, como exige §5. Arquivos MDX resolvem para a forma {/* */} (§2) e são verificados contra ela. O validador e o injetor colocam o bloco canônico no mesmo índice.

Respaldado pela fixture exata, byte a byte, em src/apothem/schemas/authorship-header.txt. A execução sobre o corpus informa a contagem de achados e uma amostra dos arquivos sinalizados por este matcher. Não imprime diff por arquivo nem porcentagem de cobertura. O matcher é bloqueante: sob --strict, que o CI e o hook de pre-commit usam, um achado faz a execução falhar. Sem --strict, o portão relata o achado e encerra com código 0.


9. Mecanismos de autoaplicação

A disciplina precisa sobreviver a toda sessão futura e a todo colaborador futuro. Superfícies de aplicação obrigatórias:

  1. src/apothem/schemas/authorship-header.txt — a fixture canônica, byte a byte; uma única fonte de verdade.
  2. scripts/inject-header.{sh,py} — o injetor mecânico (§7).
  3. Validador file-header (§8) — relata divergências como achado bloqueante, que faz uma execução com --strict falhar.
  4. Hook de pre-commit — o hook conformity-corpus-perwrite executa todos os matchers por Write, incluindo o validador file-header (§8), sobre a árvore rastreada com --strict. O matcher file-header é bloqueante, por isso um achado bloqueia o commit. O hook apenas verifica. Ele não tem modo de correção e nunca executa o injetor (§7), que roda por meio de make headers-fix.
  5. Bloco de comportamento obrigatório do CLAUDE.md — instrui o assistente a injetar a linha SPDX canônica sempre que criar um arquivo aplicável.
  6. O arquivo de instruções do GitHub Copilot em .github/copilot-instructions.md — instrui o Copilot a fazer o mesmo na geração de arquivos.
  7. Hooks PreToolUse em src/apothem/hooks/messages/pretooluse-{write,edit}-header-guard.md — interceptam chamadas das ferramentas Write/Edit em caminhos aplicáveis, para que a linha SPDX seja injetada na criação do arquivo, em vez de ser descoberta depois como achado do validador. O verificador do guard, src/apothem/hooks/lib/header_check.py, usa apenas a biblioteca padrão e lê a fixture e a lista de exceções do diretório schemas/ ao lado de hooks/, de modo que também funciona sob o plugin do Claude Code, onde o pacote apothem não é importável. Ele aplica as tabelas de variantes e as regras de posição de inserção do injetor a arquivos dentro do projeto, e somente em um projeto git que traga a fixture do cabeçalho (src/apothem/schemas/authorship-header.txt), já que a linha SPDX é a convenção deste repositório e não um padrão para todo projeto que o plugin abre.
  8. Caixa de seleção do template de PR — afirmação voltada ao colaborador de que todo arquivo novo traz a linha SPDX canônica.
  9. Este documento (site/content/docs/reference/authorship-header.mdx) — explicação canônica e normativa.

Veja também

On this page