Skip to content
Apothem
레퍼런스

작성자 헤더 — 파일별 SPDX 라이선스 줄

각 파일 타입에 맞는 주석 구문의 정식 한 줄 헤더로 파일별 SPDX 라이선스 식별자 마커를 정의하고 강제합니다.

다운스트림 기여자를 위한 정식 규범 참조. 이 문서는 프로젝트 명세의 작성자 및 파일 헤더 섹션(명세 §0.5 + §4.6)을 미러링합니다. 게시된 저장소와 함께 배포되는 독립형 참조입니다. 아키텍처 근거는 ADR-0002에 기록되어 있습니다.


1. 정식 헤더 줄

생태계의 해당되는 모든 파일은 그 파일 타입 계열의 주석 구문으로 작성된 정식 SPDX 라이선스 식별자 한 줄로 시작해야 합니다(MUST). 그 앞에 올 수 있는 것은 셔뱅, 그리고 Markdown 파일에서는 YAML 프런트매터뿐입니다(§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에 따른 구문 치환을 적용한 뒤)는 발견 사항으로 보고됩니다. 검증기는 차단 수준이며, CI와 pre-commit 훅이 실행할 때처럼 --strict를 지정하면 발견 사항이 실행을 실패시킵니다(§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 같은 확장자 없는 셸 진입점# 줄 주석# 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의 glob 목록과 일치합니다:

  • 법적 및 버전 파일 — 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).
  • 벤더링된 서드파티 콘텐츠 — _vendor/, vendor/, third_party/, node_modules/ 아래의 파일. 이들은 업스트림 자체의 라이선스 또는 고지를 담고 있습니다. 업스트림의 저작자 표기 위에 우리 마커를 주입하는 것은 라이선스 위반입니다.
  • 감사, 계획, 하니스 상태 — .audit/와 .apothem/ 아래의 모든 것. 여기에는 플랜, 메모리, 학습 데이터, 컨텍스트가 들어 있습니다. 또한 작업 트리 루트의 projects/와 memory/도 포함되며, 이들은 하니스가 소유합니다. 이 트리들은 gitignore되었거나 운영자가 소유하며, 게시되는 트리의 범위 밖입니다. 플랜 파일은 프런트매터로 출처가 추적됩니다(plans-discipline.md §3 참조).
  • 테스트 데이터 픽스처 — tests/fixtures/ 아래의 .yaml, .yml, .txt, .json 파일. 해당 트리의 테스트 소스 파일에는 여전히 헤더가 있습니다.
  • 인젝터 스모크 테스트 입력 — tests/conformity-scenarios/fixtures/F-13-injector-smoke/ 아래의 파일. 인젝터 테스트는 인젝터가 이 파일들에 헤더를 추가하는지 확인하므로, 이 파일들은 헤더 없이 남아 있습니다.
  • 패키징 및 빈 마커 — 패키징 파서가 엄격하게 읽는 .SRCINFO, 그리고 0바이트 마커 .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 줄은 파일의 첫 번째 콘텐츠이며, 예외는 두 가지입니다. 셔뱅 줄(#!/usr/bin/env bash, #!/usr/bin/env python3 등)은 항상 1번째 줄에 남고, SPDX 줄은 2번째 줄에서 시작합니다. YAML 프런트매터가 있는 Markdown / MDX 파일에서는 프런트매터가 먼저 옵니다(다음 항목).
  • YAML 프런트매터가 있는 Markdown / MDX 파일에서는 도구가 파싱할 수 있도록 프런트매터가 바이트 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)에 삽입합니다.
  • 삽입 위치에 있으면서 빈 줄이 없는 SPDX 줄에는, 그 위에 두 번째 사본을 넣는 대신 빈 줄을 추가합니다.
  • 세 가지 모드로 동작합니다: fix-in-place(쓰기), emit-patch(통합 diff 출력), check(차이가 있으면 0이 아닌 코드로 종료. 추적 중인 트리에 대해 실행하는 CI 작업은 없습니다).
  • 멱등: 두 번 실행해도 아무 작업도 일어나지 않습니다.

인젝터는 make headers-fix 타깃이 호출하며, 이 타깃은 scripts/inject-header.py --mode fix-in-place를 실행합니다.


8. 검증기 — file-header

src/apothem/conformity/file_header_grep.py에 있습니다. 작업 트리의 모든 파일에 대해 검증기는 적용 가능 여부를(§3에 따라) 조회하고, 적용 대상이면 정식 SPDX 줄이 삽입 위치에 있는지 단언합니다. 대부분의 파일 계열에서 이 위치는 셔뱅(있는 경우) 다음의 파일 머리입니다. Markdown과 MDX 파일은 YAML 프런트매터 블록을 먼저 건너뛰므로, §5가 요구하는 대로 정식 줄이 닫는 펜스 뒤에 올 수 있습니다. MDX 파일은 {/* */} 형식으로 해석되며(§2) 그 형식에 따라 검사됩니다. 검증기와 주입기는 정식 블록을 같은 인덱스에 둡니다.

이 매처는 src/apothem/schemas/authorship-header.txt에 있는 바이트 단위로 정확한 픽스처가 뒷받침합니다. 코퍼스 실행은 이 매처에 대해 발견 사항 수와 플래그된 파일의 샘플을 보고합니다. 파일별 diff나 커버리지 비율은 출력하지 않습니다. 이 매처는 차단 수준입니다. 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로 추적 중인 트리 전체에 대해, file-header 검증기(§8)를 포함한 모든 Write별 매처를 실행합니다. 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/ 디렉터리에서 픽스처와 면제 목록을 읽으므로, apothem 패키지를 임포트할 수 없는 Claude Code 플러그인에서도 작동합니다. 이 검사기는 프로젝트 내부의 파일에 인젝터의 변형 표와 삽입 위치 규칙을 적용하며, 헤더 픽스처(src/apothem/schemas/authorship-header.txt)를 담은 git 프로젝트에서만 그렇게 합니다. SPDX 줄은 이 저장소의 규약이지 플러그인이 여는 모든 프로젝트의 기본값이 아니기 때문입니다.
  8. PR 템플릿 체크박스 — 모든 새 파일이 정식 SPDX 줄을 담고 있다는 기여자 대상 확인 항목입니다.
  9. 이 문서(site/content/docs/reference/authorship-header.mdx) — 정식 규범 설명서입니다.

함께 보기

On this page