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 blamearcheology. 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 reservedand 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:
- No banner. Rely on LICENSE alone for attribution.
- Per-file ad-hoc attribution. Each contributor adds whatever banner they prefer; consistency is a contributor concern, not a mechanical one.
- 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; modesfix-in-place,emit-patch,check; idempotent on re-run. - Validator at
src/apothem/conformity/file-header-grep.py— applicability check viasrc/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
--fixmode 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 --quickflow) 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-verbatimframing. Thedocs/authorship-header.mdmirror 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.