Spec Harness
AI 프로그래밍 에이전트를 위한 태스크 패키지 워크플로우 도구로, 검증 가능한 범위(scope), 증거(evidence), 그리고 Git 게이트를 사용하여 장기적인 변경 사항을 관리합니다.
CI
Release
License: PolyForm Noncommercial
Python 3.9+
🇬🇧 영어로 읽기
Spec Harness는 세션 간, 테스트 라운드 간의 엔지니어링 작업을 복구 가능한 개발 기록(Development Record)으로 저장합니다. 이 도구는 태스크 패키지, 라우팅, 검증, 아카이빙, 그리고 Git 마무리 기능을 제공하며, 모델을 제공하거나 사용자 대신 제품 결정을 내리지는 않습니다.
원하는 작업에 따라 진입점을 선택하세요: 먼저 이해하고 싶다면 프로젝트 소개를 읽고; 직접 실행해보고 싶다면 장기 태스크 튜토리얼을 참고하세요; 배포하거나 롤백하려면 Git 워크플로우를 확인하세요. 모든 공개 진입점은 문서 인덱스에서 볼 수 있으며, 영어 독자는 English index를 참고하세요.
목차
얻게 되는 것들
- 태스크 패키지:
.spec/specs/YYYY-MM-DD_slug/ 경로에 spec.md와 tasks.md를 저장합니다 (승인 기준은 references/templates.md 참조).
- 검증 가능한 체인:
목표 → 범위 → 태스크 → 검증 → 아카이빙 → 커밋 → 푸시의 흐름을 가지며, 각 태스크는 boundary와 verify를 선언합니다.
- 명확한 진입점:
new, goal, autoplan, autorun, run, check, done, push, update, status, doctor, organize 등의 명령어를 제공합니다.
- 복구 가능한 상태: 보고서, 실패 원인, 완료 요약 및 아카이빙은 모두 디스크 파일에서 가져오므로, 세션을 변경해도 작업을 계속할 수 있습니다.
- 세션 경계 인계: 태스크 패키지는 선택적으로
handoff.md를 포함합니다. 이는 생성적 스냅샷 헤더(generative snapshot header)와 추가 전용 항목 로그(append-only entry log)를 생성하며, 필수 섹션은 협업 모드(단일 사용자/다중 사용자/에이전트/클러스터)에 따라 적응적으로 처리됩니다. spec_handoff.py가 유지 관리하고, 체크 게이트 검증 및 완료 아카이빙 시 동결됩니다.
- 대화형 계획:
autoplan은 목표를 명확히 한 후 프레임워크, 단계 세부 사항, 일관성 재검토 순으로 작업을 완료합니다. 데스크톱 및 IDE 에이전트 플러그인은 현재 세션에서 진행되며, 검증된 CLI는 새로운 세션 체인을 사용할 수 있습니다. 서브 에이전트가 없을 경우 주 세션의 재검토를 명확히 표시하며, 계획 준비가 되면 자동으로 시작하지 않고 멈춥니다.
- 복구 가능한 자동화 체인:
autorun은 계획 기능에 따라 패키지별로 실행 및 검증을 진행하고, 승인된 Git 마무리가 완료되면 다음 라운드로 넘어갑니다. 데스크톱 버전은 PATH에 다른 CLI가 설치되어 있어도 건너뛰지 않습니다. 일시 중지 후에는 동일한 단계에서 복구하며, 기본적으로 최대 5개 라운드(--max-rounds로 변경 가능, --unbounded로 해제 가능)까지 처리합니다. 현재 세션이 클라이언트 종료 후 백그라운드에서 계속 실행된다는 보장은 없습니다.
- 안정적인 태스크 식별자: 태스크는
id:와 depends-on을 사용하여 식별자와 종속성을 선언할 수 있습니다. 프로토콜 마이그레이션 시에도 과거 아카이브가 수정되지 않습니다.
- 제어된 실행 영역: 메인 세션은 라우팅, 통합, 승인 및 완료/푸시 게이트를 유지하며,
workflow-runner와 다른 슬롯들은 경계가 있는 작업 구간만 실행합니다.
- 두 가지 실행 형태: 로컬 스킬(Skill)은 참고 구현이며, 선택적인
server/ 어댑터는 원격 태스크 패키지의 start/result/health 투영만을 담당합니다.
디렉토리 구조
.
├── SKILL.md # 스킬 진입점: 단계 지침 및 런타임 계약
├── install.sh # 로컬 스킬 설치기 (다중 호스트, 아래 표 참조)
...
실행 시 작업 패키지는 기본적으로 대상 프로젝트의 .spec/에 작성됩니다. 소스 코드 저장소 자체에는 사용자 프로젝트 상태가 포함되어 있지 않습니다. 상세 계약은 references/에서, 사용자를 위한 튜토리얼은 docs/에서 확인할 수 있습니다.
환경 요구 사항 (Environment Requirements)
- Python 3.9 이상 버전.
SKILL.md를 로드할 수 있는 에이전트 클라이언트: CLI, IDE 플러그인 또는 데스크톱 애플리케이션; 프로젝트 읽기/쓰기 및 Python/Git 실행 도구를 실제로 보유해야 합니다.
- 보조 스크립트는 Python 표준 라이브러리만 사용합니다; 개발 테스트를 추가하려면
pytest와 ruff가 필요합니다.
- 설치기는 Bash가 필요합니다; 현재 세션 체인은 macOS, Linux/WSL2를 지원합니다. 네이티브 Windows 환경은 WSL2 내에서 실행해야 하며, 플랫폼 시뮬레이션 테스트를 네이티브 지원으로 간주할 수 없습니다.
- 신규 CLI 세션만 추가 백엔드가 필요합니다: macOS Terminal.app 또는 Linux/WSL2의 tmux ≥3.2 및 ps.
current 모드는 tmux, osascript 또는 다른 에이전트 CLI가 필요하지 않습니다. 자세한 내용은 실행 및 세션 백엔드 계약을 참조하십시오.
설치 설명 (Installation Instructions)
설치기 (Installer)
소스 코드 저장소 루트 디렉토리에서 실행합니다:
git clone https://github.com/MicTx/spec-harness.git /tmp/spec-harness
cd /tmp/spec-harness
git checkout v0.24.0
...
install.sh은 로컬 Skill의 유일한 설치 진입점입니다; 선택적인 server/install.sh는 self-hosted server-mode 배포에만 사용됩니다. 업데이트하거나 롤백할 때는 대상 태그로 전환한 후 설치기를 다시 실행하십시오.
소스 트리 설치에는 서명 자격 증명(signing credentials)이 필요하지 않습니다: 로컬에 발급된 자격 증명이 없는 경우, 설치기는 자동으로 --skip-signing으로 내보내고 한 줄의 안내 메시지를 출력합니다; 배포 서명은 릴리스 빌드에서만 강제됩니다(릴리스 압축 파일에는 출고 시 기본적으로 서명이 포함됨). 로컬 서명이 필요한 경우 SPEC_SIGNING_IDENTITY와 SPEC_SIGNING_KEY를 식별자 JSON 및 키 파일이 가리키도록 설정해야 합니다; 명시적으로 건너뛰려면 SPEC_SKIP_SIGNING=1을 사용할 수 있습니다.
지원 호스트 (Supported Hosts)
INSTALL_HOSTS | 호스트 | 기본 디렉토리 | 추가 동작 |
|---|
claude | Claude Code | ~/.claude/skills | /spec 및 단계 명령어 생성 (core 5개, full 12개) |
| ... | | | |
INSTALL_HOSTS를 설정하지 않으면 설치기가 자동으로 감지합니다: PATH 또는 호스트 기본 디렉토리에 이미 존재하는 '호스트 CLI'만 설치하며, 이 설치기는 소유권 마크로 표시된 기존 호스트를 유지합니다; 건너뛴 호스트는 설치 출력에 나열됩니다. INSTALL_HOSTS (all 포함)를 명시적으로 지정하면 감지 과정이 전혀 없습니다.
하나의 호스트만 설치할 때는 토큰을 명시적으로 지정합니다. 예:
INSTALL_HOSTS=codex CODEX_SKILLS_DIR=~/.codex/skills bash install.sh
설치 프로필 (Installation Profile): INSTALL_PROFILE은 구성 요소를 선택하며, 기본값은 core입니다—커널만 설치합니다(핵심 단계 명령어 /spec:new /spec:run /spec:check /spec:done /spec:push, Git 훅 및 스크립트 트리)이며, 확장 구성 요소(slots/, agents/)와 확장 단계 명령어(goal/autoplan/autorun/update/status/doctor/organize)는 설치하지 않습니다; INSTALL_PROFILE=full은 전체 설치(모든 12개 단계 명령어 및 확장 구성 요소, 구 버전 Byte와 동등)를 복원합니다. full로 이미 설치된 장치에서 기본 설치를 다시 실행하면 core로 다운그레이드됩니다: 확장 단계 명령어와 agents는 먼저 백업된 후 제거됩니다. 체인, 계획 체인 또는 확장 기능이 필요할 때는 명시적으로 지정해야 합니다:
INSTALL_PROFILE=full bash install.sh
설치기는 기본적으로 .spec-skill-install 소유권 마크가 없는 동일한 이름의 Skill을 덮어쓰는 것을 거부합니다; 사용자 디렉토리를 확인하고 대체할 때만 FORCE=1을 설정해야 합니다. pi는 이제 Pi agent를 나타내며, 이전의 Claude + Codex 조합은 rpi 또는 desktop을 사용하십시오.
설치 목표를 '파일을 어디에 배치할지'로 선택하고, 실행 전략을 '이 세션은 어떻게 진행될지'로 선택합니다. 이 둘은 동일한 화이트리스트가 아닙니다. 과거의 desktop 토큰은 여전히 Claude Code와 Codex만을 조합하며, 모든 데스크톱 환경에서 사용되는 것은 아닙니다.
| Agent / 실행 형태 | auto 실행 전략 | 조건 및 경계 |
|---|
| Claude Code, Codex, Pi의 명확한 CLI 세션 | fresh | 기존 완전 상호작용 세션 어댑터 유지; 명시적 워커는 다른 검증된 CLI 선택 가능 |
| ... | | |
| 필요한 확장 기능이 있다면 full로 설치해야 합니다. 예를 들면: | | |
INSTALL_HOSTS=devin,cursor,zcode INSTALL_PROFILE=full bash install.sh
Devin/Cursor는 /spec을 사용하여 Skill을 로드한 후 spec:autoplan 또는 spec:autorun을 요청하며, ZCode는 $spec을 사용합니다. 새로 설치한 후에는 호스트 방식에 따라 Skill을 새로 고치거나 새 세션을 시작해야 하며, 모든 호스트가 /spec:<stage>를 등록했다고 가정해서는 안 됩니다. 메인 세션이 능력 검증, 권한 경계 및 복구를 담당하며, 독립적인 창이나 서브 에이전트에 의존하지 않습니다. 서브 에이전트가 없는 경우의 검토는 명시적으로 메인 세션 검토로 표시됩니다.
검증 기준: 자동화 테스트가 클라이언트 프로필, 복구 프로토콜 및 격리 설치를 포괄한다고 해서 해당 제품이 개별적으로 실제 기기에서 승인되었다는 의미는 아닙니다. Cursor/ZCode 데스크톱 버전, Linux/WSL2와 네이티브 Windows에서의 실제 실행 증거는 각각 기록되어야 하며, 미실측된 것은 live verified로 표기할 수 없습니다. 프로토콜은 실행 및 세션 백엔드 계약을 참조하십시오.
능동 활성화 (선택 사항, 일회성)
설치는 파일을 배치하는 것일 뿐, 사용자의 Claude 설정을 변경하지 않으므로 기본적으로 작업별로 자동 평가를 수행하지 않습니다. 여러 기능 수정이나 다중 인력의 실행이 사전에 '작업 기록 필요 여부'를 자동으로 검토하도록 하려면 명시적으로 한 번 활성화해야 합니다:
python3 ~/.claude/skills/spec/scripts/install_activation_hooks.py --mode on
- 판단 기준은 전달되는 형태를 봅니다: 독립적인 승인 면적, 실제 실행자, 복구 가능한 진행 중인 작업입니다. 파일 수, 글자 길이, 방에 있는 여유 팀원 수 등이 개별적으로 결정하는 것은 아닙니다. 사소한 수정, 읽기 전용 조사, 일회성 실험, 명확하게 '작업 패키지 불필요'라고 말하는 경우 모두 바로 처리됩니다.
- 자신이 작성한 항목만 관리하며, 사용자의 다른 hooks,
permissions, 그리고 알 수 없는 필드는 보존합니다. 잘못된 설정은 쓰기를 거부하고, 쓰기 전에 백업하며, 언제든지 --mode off로 되돌릴 수 있습니다.
- 적용 범위는 Edit/Write/MultiEdit/NotebookEdit과 Agent/Task/SendMessage입니다. Bash, MCP 및 사용자 정의 도구는 파싱하지 않으며, 이를 포괄한다고 주장하지도 않습니다. 팀원/서브 에이전트는 패키지를 생성하지 않고, 오직 메인 코디네이터의 할당만 받습니다. 호스트의
agent_id로 식별되며, --agent로 시작된 메인 세션은 여전히 메인 세션으로 검사됩니다. 분할 화면 모드의 팀원은 독립적인 프로세스이며, 실제 테스트에서 그들이 제시하는 이벤트는 agent_id를 포함하지 않으므로 마찬가지로 메인 세션으로 처리됩니다.
- 이것은 협력형 agent에게 보내는 알림일 뿐 안전 경계가 아닙니다: 형태와 역할에 대한 사실은 agent가 스스로 보고하지만, 종료/사소한 수정/읽기 전용과 같은 결론적 사실은 무조건 주입을 거부합니다(주입은 오류를 의미). 사용자가 명시적으로 거부하는 것은 사용자 본인이 호스트 레벨에서 덮어쓸 수만 있습니다(해당 호출 허용 또는 연결 끊기). 기록된
direct는 새로운 사용자 입력이나 2시간 후 만료됩니다. 이것은 '평가 누락'을 방지하며, 의도적으로 수정 면적을 적게 보고하는 것을 막지는 못합니다.
- 이벤트 배선은 현재 Claude Code에만 적용됩니다. 다른 호스트들은 동일한 발견 설명서를 공유하지만, 동등한 수준의 이벤트 보장은 없습니다.
spec:doctor는 '미설치 / 미연결 / 연결됨'을 구분하며, 연결된 경우에도 항상 'live 검증되지 않음'으로 표시합니다. 파일 존재 여부나 훅 종료 코드가 모델이 실제로 능동적으로 채택했음을 증명할 수는 없습니다.
- 작업이 오염된 브랜치에서 진행되었거나 팀원이 작업을 시작했다면,
new를 다시 실행하지 마십시오(이는 깨끗한 트리를 요구합니다). init_spec_package.py --adopt --confirm-adopt를 사용하여 명시적으로 인계받으세요: 현재 브랜치와 모든 수정을 유지하고, 기준선 해시만 기록하며, 브랜치를 전환하거나 stash 하거나 커밋하지 않습니다.
수동 설치
실행 시점의 Skill 패키지만 내보냅니다:
python3 scripts/export_skill_package.py --output /tmp/spec --force
수동으로 직접 호출하는 내보내기는 서명 건너뛰기를 자동으로 수행하지 않습니다: 자격 증명이 없는 환경에서는 --skip-signing을 명시적으로 추가해야 합니다(설치기가 동일한 조건에서 자동으로 첨부하고 알림을 표시합니다). 내보내기 도구는 또한 --profile core|full을 허용합니다(기본값은 full이며, 릴리스 페이로드 바이트와 동등합니다).
추출된 spec/ 디렉터리를 호스트의 Skill 루트 디렉터리에 넣고, Codex/ZCode에서 $spec을 트리거하며, Pi에서는 네이티브 명령어인 /spec, /spec:<stage>를 사용합니다 (매개변수는 $@를 통해 원본 그대로 전달). Claude Code에서는 /spec:goal을 사용하고, Devin/Cursor에서는 /spec을 로드한 후 spec:goal을 요청합니다.
DeepSeek Harness (dsh) 플러그인 모드: python3 scripts/package_agent_plugin.py --format dsh를 실행하여 dsh 번들을 생성합니다 (package.json에 dsh.bundle.patch가 선언되고, index.js는 ctx.skills에 제공자로 등록됩니다). 압축 해제 후 dsh plugin --profile <name> add ./spec-harness를 사용하여 프로필에 추가하고, dsh plugin --profile <name> remove spec-harness로 제거합니다. dsh는 developer preview 상태이며 라이브 검증을 거치지 않았습니다.
빠른 시작
설치를 완료한 후, 가장 간단한 경로는 호스트에서 완전한 목표 문장을 제시하는 것입니다:
$spec
spec:goal add payment recovery with tests
# Claude Code: /spec:goal add payment recovery with tests
호스트는 단계별로 안내합니다: 먼저 목표와 범위를 명확히 하고 (goal), 실행(run)하고, 검토(check)한 다음, 최종적으로 아카이빙 및 제출(done)합니다. 푸시(push)는 명시적으로 요청할 때만 실행됩니다. 호스트를 우회하여 스크립트를 직접 구동하려면 동일한 효과를 얻을 수 있습니다. 목표 프로젝트 내에 작업 패키지를 생성하십시오:
python3 /tmp/spec-harness/scripts/init_spec_package.py \
--root /path/to/project \
--slug 2026-10-03_add-payment-recovery \
...
초기화 후, 순서대로 단계, 상태 및 게이트를 확인합니다:
python3 /tmp/spec-harness/scripts/route_spec_package.py --root /path/to/project --slug 2026-10-03_add-payment-recovery
python3 /tmp/spec-harness/scripts/report_spec_package.py --root /path/to/project --slug 2026-10-03_add-payment-recovery --view status
python3 /tmp/spec-harness/scripts/check_spec_package.py --root /path/to/project --slug 2026-10-03_add-payment-recovery
작업 완료 후에는 /spec:done을 사용하여 검토, 아카이빙 및 Git 커밋을 완료할 수 있습니다. 직접 조작하는 경우 먼저 실행합니다:
python3 /tmp/spec-harness/scripts/complete_spec_package.py \
--root /path/to/project \
--slug 2026-10-03_add-payment-recovery \
...
이 스크립트는 요약 생성 및 아카이빙만 담당합니다. 이후 수동으로 git commit을 실행하고, push_spec_package.py를 사용하여 병합 및 푸시 마무리를 합니다. 폐기된 멤버는 archive/retired에만 아카이빙되며, never delete 원칙을 따릅니다. 각 작업은 반드시 실제로 verify를 실행해야 하며, 체크박스만 선택해서는 안 됩니다. 더 강력한 증거 바인딩이 필요할 경우, spec.md에 evidence: runs를 선언합니다. 기계 작업의 verify 명령어는 scripts/spec_verify.py run을 통해 실제로 실행되며, 실행 기록(exit 코드, 소요 시간, stdout 끝 해시, 워크트리 지문)이 패키지 내 runs.jsonl에 추가됩니다. check/done은 "최근 exit==0이고 지문이 현재 워크트리와 일치하는" 기록만 인정합니다. 실행되지 않은 것은 미검증이며, 증거를 확보한 후 코드를 수정하면 증거가 만료된 것으로 간주됩니다.
런타임 Skill 패키지 내보내기
소스 코드 저장소에는 패키징기(packer), 테스트 및 배포 산출물이 모두 포함되어 있습니다. 런타임 패키지는 scripts/export_skill_package.py의 기계 규칙을 통해 생성됩니다. 이 패키지에는 SKILL.md, 설치기, agents/, hooks/, references/, server/, slots/ 및 런타임 보조 스크립트가 유지되며, 소스 코드 관리 도구, 테스트 파일 및 release/ 디렉토리는 제외됩니다.
내보내기 트리(export tree)는 테스트에 의해 잠겨 있으며, 현재 내용은 다음과 같습니다:
spec/
├── LICENSE
├── NOTICE
...
검증 (Verification)
소스 코드 레벨 검사:
python3 -m compileall -q scripts server hooks slots tests
python3 scripts/slot_registry.py validate
python3 scripts/smoke_test_spec_skill.py
...
변경 문서를 작성할 때는 최소한 다음을 실행해야 합니다:
python3 -m pytest tests/test_public_docs.py tests/test_export_skill_package.py -q
git diff --check
전체 검증 범위는 CONTRIBUTING.md를 따릅니다. 작업 패키지의 package, integration, project 검증 레벨은 spec.md의 ### 5.1 검증 전략 (Verification Strategy) 섹션에 명시되어 있습니다 (기계 키 verification-strategy). 블록은 기계 키로 식별되며, 영어 제목과 키는 앵커(anchor)가 동일합니다 (이는 references/templates.md의 영어 템플릿 변형을 참조하십시오).
효율성 및 읽기 비용 (Efficiency and Reading Cost)
내부 읽기면(Internal Read Surface) (예: route_spec_package.py --format json --brief 작업 슬라이싱과 spec_verify.py show 증거 뷰)은 문서 압축과의 트레이드오프를 위해 네 팔 접대군 비교 테스트(four-arm controlled test)로 측정되었습니다: A 기준선 / B 압축만 적용 / C 내부 도구만 사용 / D 조합. 16개의 고정 시나리오가 다섯 가지 유형의 고정 작업에 분류되었으며, 두 번 연속 실행해도 투영된 일관성을 유지합니다. 바이트 수, 결정론적 호출(deterministic call) 및 실제 사용을 세 단계로 분리하여 계산하지 않습니다.
- 텍스트 압축은 다섯 가지 모든 유형의 작업에서 읽기 바이트를 감소시킵니다 (각 유형별 -23 ~ -2,270 B). 이는 정적 문서면 대비 1,357 B 절감 효과이며, 작업 무결성 손실은 없습니다.
- 내부 도구 스케줄링 설명(scheduling explanation)의 고정 비용은 248 B입니다. 조합 상태는 읽기량이 가장 많은 작업 유형에서도 순수하게 782 B를 절약합니다.
--brief 옵션은 여러 번의 전체 읽기를 한 번의 뷰로 대체하는 형태에서 호출과 바이트 수를 동시에 줄여줍니다 (실측: 재검토 시나리오 -1 호출, -552 B). 작은 패키지 위치 지정 및 단일 파일 정밀 읽기는 스케줄링 결정표에 따라 네이티브 읽기를 유지하며, 실측 결과는 집계된 오버헤드가 직접 읽기보다 크다는 부정적 수익은 그대로 보존됩니다.
spec_verify.py show --history의 전체 재구성(full reassembly)은 완전한 로그가 필요할 때만 사용해야 하며, 페이지네이션을 통해 바이트 단위로 검증 재구성이 가능합니다. 첫 화면 및 짧은 증거에 대한 직접 읽기 시에는 이 과정이 거치지 않습니다.
버전 가져오기 (Getting Version)
안정 버전과 SHA-256 체크섬 파일은 GitHub Releases에서 확인할 수 있습니다. 설치, 업그레이드 및 롤백 방법은 RELEASE.md를 참조하십시오. 개발 참여는 CONTRIBUTING.md와 Git 워크플로우를 참고하십시오.
적용 범위 (Scope)
Spec Harness는 작업 패키지, 워크플로우 명령어, 템플릿, 검증 스크립트 및 선택적인 자체 호스팅 서버 모드 어댑터를 제공합니다. 이 도구는 호스팅 서비스를 운영하거나 모델을 제공하지 않으며, 사용자 대신 제품 결정을 내리거나 PR 생성 또는 원격 CI 오케스트레이션을 담당하지 않습니다.
[!WARNING]
server/는 선택적인 자체 호스팅 HTTP 접속 계층입니다. 공용 네트워크에 배포하기 전에 반드시 SPEC_SERVER_TOKEN과 ALLOWED_ROOTS를 설정하고, 신뢰할 수 있는 리버스 프록시 뒤에서 TLS를 제공해야 합니다. /health 경로는 활성 상태 확인 용도로만 사용되며, /start와 /result는 Bearer 토큰이 필요합니다.
감사의 말 (Acknowledgments)
@h565656445 님께서 #3과 #4에 기여해 주신 점에 감사드립니다. 이 두 PR은 doctor가 이미 렌더링된 gate hook을 프로젝트 자체의 것으로 오판한 문제와, 공개 CI(Continuous Integration)가 테스트 수집 단계에서 중단되는 문제를 해결했습니다. 두 가지 수정 사항 모두 v0.21.1 버전에서 반영되었습니다.
여러분의 @wait4xx가 제안한 #1 (spec.md의 '반증된 경로' 섹션)과 #2 (tasks.md의 경량 claim: 선언) 두 가지 제안 모두 반영되었습니다.
라이선스 계약
본 프로젝트의 소프트웨어 코드는 PolyForm Noncommercial 1.0.0 (PolyForm-Noncommercial-1.0.0)을 채택하고 있습니다. 상업적 사용에는 별도의 서면 승인이 필요하며, 전체 약관은 LICENSE를 참조하십시오.