Skip to content

ADR-0002: Authorship Header — Per-File Provenance Banner

Status

Accepted

Context

Provenance — who authored which file, under what license, with what contact and identity surface — is a permanent, machine-checkable contract. Three forces motivate first-class treatment:

  • Supply-chain attestation surface. Modern supply-chain hygiene (SLSA-grade attestation, signed releases, SBOM provenance) treats per-file authorship metadata as a first-class signal. A repo whose files do not declare their provenance loses an attestation hook that downstream consumers rely on.
  • Deterrent against attribution drift. Files acquire silent rewrites over their lifetime — a contributor edits a file, the original author's attribution slowly fades, the file's lineage becomes unrecoverable except by git blame archeology. A canonical, byte-exact banner pins the original authorship at the file's head, where it cannot quietly vanish.
  • License interaction surface. A repo's LICENSE is the legal instrument; per-file banners interact with it (either preserving the LICENSE's authority by saying All rights reserved and letting LICENSE govern, or amending per-file under permissive licenses by naming the SPDX identifier inline). The interaction is a deliberate ratification, not an accident.

Three plausible postures were available:

  1. No banner. Rely on LICENSE alone for attribution.
  2. Per-file ad-hoc attribution. Each contributor adds whatever banner they prefer; consistency is a contributor concern, not a mechanical one.
  3. Canonical, mechanically-enforced banner. A single byte-exact fixture is the source of truth; an injector adds it to applicable files; a validator fails CI on any divergence; documentation, hooks, and contributor surfaces all converge on the same authority.

Decision

Every applicable file in the ecosystem MUST begin with the canonical 5-line authorship banner per Spec §0.5. The banner's information content is invariant; only the comment syntax varies per filetype family per Spec §4.6.2. The byte-exact fixture lives at src/apothem/schemas/authorship-header.txt — the #-comment-family reference form, against which every per-filetype variant is generated by syntax substitution.

Mechanical enforcement layers:

  • Injector at scripts/inject-header.{sh,py} — deterministic CLI; modes fix-in-place, emit-patch, check; idempotent on re-run.
  • Validator at src/apothem/conformity/file-header-grep.py — applicability check via src/apothem/schemas/header-exceptions.txt; canonical-vs-malformed-vs-absent verdict per file; aggregate coverage % in CI summary.
  • PreToolUse hooks at src/apothem/hooks/messages/pretooluse-{write,edit}-header-guard.md — intercept Write/Edit tool calls on applicable paths; ensure the banner is injected at file creation rather than discovered as a CI failure later.
  • Pre-commit hook — local mirror of the validator with --fix mode wired to the injector.
  • CLAUDE.md mandatory-behavior block — instructs the agent to inject the banner on every new applicable file.
  • .github/copilot-instructions.md §3 File Headers — instructs Copilot to do the same on file generation.
  • Default output-style — when an agent or command writes a new file, it routes through the injector.
  • Pull-request template checkbox — contributor-facing assertion that the banner is present.
  • docs/authorship-header.md — canonical, normative explainer for downstream contributors.

The license-banner interaction is governed by ADR-0006, which ratifies the policy at Phase 09A enactment. The Phase 03B interim keep-verbatim policy is superseded by ADR-0006's amend-per-license with SPDX top decision: the banner is now 6 lines, with SPDX-License-Identifier: MIT at line 1 and Licensed under MIT; see LICENSE for terms at line 6. The historical keep-verbatim framing is preserved in this ADR for context. The interaction is fully described at Spec §0.5.3 and docs/authorship-header.md §4 License Interaction.

The exception list at src/apothem/schemas/header-exceptions.txt enumerates categorically-exempt classes — LICENSE itself, JSON files (no comment syntax), lockfiles, generated files, vendored third-party content, .audit/ ephemera, plan files, empty markers, binary files. Amendments to the exception list require an AskUserQuestion and a new ADR.

Consequences

  • Byte-exact provenance across the ecosystem. Every applicable file declares the same authorship surface, in the variant the filetype's tooling expects. The aggregate coverage % is a continuously-measured CI signal.
  • CI gate on header drift. A file with a malformed or absent banner fails CI; no quiet drift accumulates between releases.
  • New contributors guided by injector + scaffolders. A contributor adding a new file via make new-agent / make new-skill / make new-command (or via the /plan-spec --quick flow) gets the banner pre-inserted; the contributor never has to remember the banner text.
  • License-banner interaction is resolved deliberately. Ratified at ADR-0006 (Phase 09A enactment): the banner uses the amend-per-license with SPDX top form, superseding the Phase 03B interim keep-verbatim framing. The docs/authorship-header.md mirror documents the executed swap and the rationale.
  • The exception list is itself a discoverable contract. A contributor wondering whether a new file class needs a banner consults src/apothem/schemas/header-exceptions.txt; the question is mechanically answerable, not folklore.
  • Maintenance surface is small. Banner text lives in one place (the fixture); per-filetype variants are derived mechanically; updates flow through the fixture and the injector regenerates everywhere.

Alternatives Considered

  • No banner — rely on LICENSE alone. Rejected: provenance is per-file, LICENSE is per-repo; the resolution gap leaves attestation hooks unanchored and permits silent attribution drift over the file's lifetime.
  • Per-file ad-hoc attribution. Rejected: drift is the deterministic outcome of "do whatever feels right per-file"; the banner's job is to be invariant against contributor preference.
  • LICENSE-only attribution at repo root with no per-file metadata. Rejected: insufficient at file granularity; downstream consumers (SBOM tools, supply-chain attestation surfaces, file-level provenance auditors) cannot reach a per-file signal.
  • Per-author free-form banners (each contributor declares their own). Rejected: defeats mechanical enforcement; the validator cannot verify a fixture that has no canonical form.

Cross-references: docs/authorship-header.md, src/apothem/schemas/authorship-header.txt, src/apothem/schemas/header-exceptions.txt, Spec §0.5, Spec §4.6.