Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: test

# git-logbook 자체의 개발용 CI(GF-21, decision-8). 컨슈머에 배포하는 verify.yml과
# git-trail 자체의 개발용 CI(GF-21, decision-8). 컨슈머에 배포하는 verify.yml과
# 달리 이건 이 저장소 자신의 훅 코드 품질만 검사한다 — 훅도 테스트도 Python 표준
# 라이브러리만 쓰므로(decision-16, decision-21) 테스트 프레임워크를 따로 설치하는
# 스텝이 없다. 아래 ruff 설치는 이 저장소 자신의 Python 코드를 검사하는 개발 도구다 —
Expand Down
2 changes: 1 addition & 1 deletion .gitmessage
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@
#
# ── 이 템플릿 사용법 ──
# git config commit.template .gitmessage
# (git-logbook install.sh를 사용하면 자동으로 설정됩니다 — GF-8 참고)
# (git-trail install.sh를 사용하면 자동으로 설정됩니다 — GF-8 참고)
29 changes: 18 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div align="center">

# 📒 git-logbook
# 👣 git-trail

**git 이력을 작업 로그로 만드는 도구 — 커밋 형식 · 출처 기록 · 이력 불변**
**git 이력을 감사 추적(audit trail)으로 만드는 도구 — 커밋 형식 · 출처 기록(provenance) · 이력 불변**

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
[![Hooks: Python 3](https://img.shields.io/badge/hooks-Python%203-3776ab.svg)](./hooks/)
Expand Down Expand Up @@ -66,7 +66,7 @@ Signed-off-by: cpu-once <231006716+cpu-once@users.noreply.github.com>
| `Tokens-Used` | 이 커밋에 든 토큰. 작업 비용을 이력에서 읽게 합니다 | `post-commit` · 직전 커밋 이후 세션 구간의 델타(누적 아님) | 서버 발급 사실(Claude Code 한정), **측정 방법론은 실험 단계** |
| `Tool-Calls` | 같은 구간의 도구 호출 수 | `post-commit` · `tool_use` 블록 개수 | 위와 동일 |
| `Co-Authored-By` | 공동저자 귀속 | `post-commit` · `AI-Tool`이 `claude-code`일 때만 | 자동 |
| `Hooks-Commit` | 이 커밋을 검사한 git-logbook 자체의 버전. 훅에 버그가 있었을 때 어느 커밋들이 그 훅을 거쳤는지 역추적합니다 | `post-commit` · 훅 클론의 `rev-parse --short HEAD` | 완전 자동, 모든 커밋 |
| `Hooks-Commit` | 이 커밋을 검사한 git-trail 자체의 버전. 훅에 버그가 있었을 때 어느 커밋들이 그 훅을 거쳤는지 역추적합니다 | `post-commit` · 훅 클론의 `rev-parse --short HEAD` | 완전 자동, 모든 커밋 |
| `Signed-off-by` | 커미터 정보(DCO 관례) | `post-commit` · `git log -1 --format='%cn <%ce>'` | 완전 자동, 모든 커밋 |
| `Verify-Bypassed` | `--no-verify`로 검사를 건너뛴 사실. 우회를 막지는 못하니 대신 기록합니다(decision-3) | `post-commit` · `prepare-commit-msg`가 남긴 검증 마커의 **부재** | 자동 |
| `Fixes` | 이 버그를 만든 커밋 | **사람이 씀**(원인 커밋을 아는 경우만) · `commit-msg`가 해시 실재를 검증 | 검증됨 |
Expand All @@ -78,10 +78,10 @@ Signed-off-by: cpu-once <231006716+cpu-once@users.noreply.github.com>
## 🪝 커밋 한 번에 훅이 도는 순서

> 공식 문서: [githooks(5)](https://git-scm.com/docs/githooks). git이 제공하는 훅은 28개이고,
> git-logbook의 훅은 지금 커밋 단계만 다룹니다. push된 이력의 보호는 원격 설정이 맡습니다
> git-trail의 훅은 지금 커밋 단계만 다룹니다. push된 이력의 보호는 원격 설정이 맡습니다
> ([다루는 범위](#-다루는-범위)).

| 순서 | 훅 | 커밋 객체가 있는가 | `--no-verify`로 건너뛰나 | git-logbook이 하는 일 |
| 순서 | 훅 | 커밋 객체가 있는가 | `--no-verify`로 건너뛰나 | git-trail이 하는 일 |
| --- | --- | --- | --- | --- |
| 1 | [`prepare-commit-msg`](hooks/prepare-commit-msg) | 아직 없음 | **건너뛸 수 없음** | 재생·병합 커밋 면제, 에디터 경로 거부, 검증 마커 기록 |
| 2 | (에디터) | 아직 없음 | — | 사람이 메시지를 씁니다. 훅보다 **뒤**라서 1번은 최종 메시지를 볼 수 없습니다 |
Expand All @@ -104,17 +104,21 @@ git 이력을 작업 로그로 만드는 데 필요한 세 가지입니다(decis
| **출처 기록** | 누가·어떤 도구와 모델로·얼마를 들여 만들었는지 자동으로 남김 | 위 트레일러 전체, `Task-Id` 브랜치 강제, `AI-Model` 게이트 | 측정 재작성(GF-129), 트레일러 집합 재정의(decision-19, `Signed-off-by`는 유지 — decision-25) |
| **이력 불변** | 한 번 남긴 기록은 다시 쓰지 않음(append-only, decision-24) | 이 저장소의 GitHub 설정: 머지 커밋만 허용, main의 force push·삭제 금지(doc-20). 컨슈머는 doc-20을 참고해 직접 설정 | 로컬 훅 강제(DRAFT-18 append-only 훅 강제), CI 트레일러 검사(DRAFT-19) |

용어로 말하면 trail(감사 추적)이 세 기둥 전체이고, provenance(출처 기록)가 두 번째 기둥입니다.
attestation(서명된 증명)은 아직 없고, audit(사후 검사)은 커밋 시점 검사까지만 있습니다 —
자세한 구현 위치는 [개념 지도(doc-21)](<backlog/docs/doc-21 - 개념-지도-—-trail·provenance·attestation·audit이-어디에-구현돼-있나.md>)를 보세요.

세 기둥은 서로를 필요로 합니다. 이력이 다시 쓰이면 트레일러가 자기 커밋에 대해 거짓이
되고, 기록할 내용이 정형화돼 있지 않으면 지킬 가치가 줄어듭니다. 로컬 훅은
`--no-verify`를 막지 못합니다. 그렇게 다시 쓴 이력이 main에 force push되는 것은 원격
설정이 거부합니다. 웹 UI 커밋과 트레일러 검사는 CI로 할 계획입니다(DRAFT-19).

**언어별 lint는 다루지 않습니다**(decision-23) — 세 기둥 어디에도 속하지 않고, 컨슈머에게
npm/ruff/clang-format 같은 도구를 전제하게 만듭니다. 언어 검사가 필요하면 CI에서 돌리시기
바랍니다. git-logbook이 `core.hooksPath`를 점유하므로 그 저장소의 `.git/hooks/*`는
바랍니다. git-trail이 `core.hooksPath`를 점유하므로 그 저장소의 `.git/hooks/*`는
무시되고, 자기 훅과 함께 쓰는 방법은 아직 정하지 않았습니다.

> 이름을 git-format에서 git-logbook으로 바꿨습니다(decision-25). 설정 키와 파일명
> 이름은 git-format → git-logbook → git-trail 순으로 바뀌었습니다(decision-25, decision-26). 설정 키와 파일명
> (`gitformat.*`, `gitformat.conf`, `.gitformat-*`)은 기존 설치를 깨지 않도록 아직 예전 이름입니다(GF-133).

구성은 Python 훅 + 설정 파일 하나(`hooks/gitformat.conf`) + POSIX sh 설치
Expand Down Expand Up @@ -151,17 +155,17 @@ python3는 이런 환경에서 보이지 않을 수 있습니다.
### 기존 저장소에 적용하는 방법입니다

```sh
git clone https://github.com/coralstay/git-logbook.git ~/git-logbook # 원하는 위치에 한 번만 클론
git clone https://github.com/coralstay/git-trail.git ~/git-trail # 원하는 위치에 한 번만 클론
cd ~/my-project
~/git-logbook/install.sh
~/git-trail/install.sh
```

대상 디렉터리를 인자로 주셔도 됩니다: `~/git-logbook/install.sh ~/my-project`.
대상 디렉터리를 인자로 주셔도 됩니다: `~/git-trail/install.sh ~/my-project`.

### 앞으로 만들 모든 새 저장소에 자동 적용하는 방법입니다

```sh
~/git-logbook/install.sh --global
~/git-trail/install.sh --global
```

`git init`/`git clone`을 실행할 때마다 훅과 커밋 템플릿이 자동으로 심어집니다
Expand All @@ -170,6 +174,9 @@ cd ~/my-project

## 📚 더 자세한 내용이 궁금하시다면

- **trail·provenance·attestation·audit이 각각 어느 훅·함수·설정에 구현돼 있고 어디가
비어 있는지**는 [개념 지도(doc-21)](<backlog/docs/doc-21 - 개념-지도-—-trail·provenance·attestation·audit이-어디에-구현돼-있나.md>)에
정리했습니다.
- **설치 상세, 커밋 메시지 규칙 전문, AI 귀속 트레일러 표, 커스터마이즈, 저장소 구조,
주의점·한계**는 `backlog doc list`에서 확인하실 수 있습니다.
- **설계 배경과 각 결정 이유**는 `backlog decision list`에서
Expand Down
2 changes: 1 addition & 1 deletion backlog/config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
project_name: "git-logbook"
project_name: "git-trail"
default_status: "To Do"
statuses: ["To Do", "In Progress", "Done"]
labels: []
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
id: decision-26
title: 이름을 git-trail로 바꾼다 (decision-25의 이름 조항 대체)
date: '2026-10-03 03:43'
status: accepted
---
## Context

decision-25가 목적을 세 기둥(형식·출처 기록·이력 불변)으로 정하면서 이름을 git-logbook으로
바꿨다. 같은 날(2026-10-03) 유저가 이름을 다시 정했다 — 개발자들이 이런 도구를 부를 때 실제로
쓰는 말에서 고르기로 했다.

| 용어 | 뜻 | 이 프로젝트에서 |
| --- | --- | --- |
| trail (audit trail) | 누가·언제·무엇을 했는지 고칠 수 없게 남긴 기록 | 세 기둥 전체 |
| provenance | 결과물이 어디서 어떻게 만들어졌는지 (SLSA 용어) | 출처 기록 트레일러 |
| attestation | provenance를 기계가 검증할 수 있게 남긴 증명 (in-toto, Sigstore) | 아직 서명 없음 |
| audit | 기록을 사후에 대조·검사하는 일 | Fixes 검증, CI 검사 계획 |

유저 판단: 저장소 이름은 하나로 짧게 하고, 네 용어는 설명과 문서에 모두 적는다.

## Decision

**이름을 git-trail로 바꾼다.** audit trail에서 왔고, 이 도구가 남기는 git trailer와 소리도
겹친다. decision-25의 이름 조항(git-logbook)만 대체하고, 목적 세 기둥과 decision-11·12·19
대체 조항은 그대로 유효하다.

네 용어가 이 저장소의 어느 훅·함수·파일·원격 설정에 구현돼 있는지, 어디가 비어 있는지는
개념 지도 문서(GF-140)에 적는다. 이름에 용어를 다 넣는 대신 문서로 연결한다.

GitHub 저장소는 다시 rename한다(coralstay/git-logbook → coralstay/git-trail). 예전 이름
두 개(git-format, git-logbook)는 GitHub이 리다이렉트한다.

## Consequences

- 표시 이름만 바뀐다. 설정 키·파일명(`gitformat.*`)은 GF-133, 태스크 접두어 GF와 지난 기록
본문은 decision-25와 같은 이유로 그대로 둔다. decision-25 본문의 "git-logbook"도 당시
기록이라 고치지 않는다.
- attestation이라는 말을 쓰는 이상, 지금은 서명된 증명이 없다는 점을 개념 지도에 분명히
적어야 한다. 기대와 실제가 어긋나지 않게 하기 위해서다.
20 changes: 10 additions & 10 deletions backlog/docs/doc-1 - 설치-가이드.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@ id: doc-1
title: 설치 가이드
type: guide
created_date: '2026-09-19 05:27'
updated_date: '2026-10-03 03:40'
updated_date: '2026-10-03 03:44'
---
## 🚀 설치

### 기존 저장소에 적용

```sh
git clone https://github.com/coralstay/git-logbook.git ~/git-logbook # 원하는 위치에 한 번만 클론
git clone https://github.com/coralstay/git-trail.git ~/git-trail # 원하는 위치에 한 번만 클론
cd ~/my-project
~/git-logbook/install.sh
~/git-trail/install.sh
```

대상 디렉터리를 인자로 줘도 됩니다: `~/git-logbook/install.sh ~/my-project`.
대상 디렉터리를 인자로 줘도 됩니다: `~/git-trail/install.sh ~/my-project`.

### 앞으로 만들 모든 새 저장소에 자동 적용

```sh
~/git-logbook/install.sh --global
~/git-trail/install.sh --global
```

`git init`/`git clone`을 실행할 때마다 훅과 커밋 템플릿이 자동으로 심어집니다
Expand All @@ -35,18 +35,18 @@ cd ~/my-project

| 대상 | 명령 | 효과 |
| ----------------- | -------------------------------------------------------------- | ------------------------------------------ |
| 로컬(대상 저장소) | `git config core.hooksPath <git-logbook>/hooks` | `.git/hooks/`의 기존 로컬 훅을 완전히 대체 |
| 로컬(대상 저장소) | `git config commit.template <git-logbook>/.gitmessage` | 커밋 에디터에 스켈레톤 표시 |
| 전역(`--global`) | `git config --global init.templateDir <git-logbook>/template` | 이후 모든 신규 저장소에 자동 적용 |
| 전역(`--global`) | `git config --global commit.template <git-logbook>/.gitmessage` | 위와 동일, 전역 기본값 |
| 로컬(대상 저장소) | `git config core.hooksPath <git-trail>/hooks` | `.git/hooks/`의 기존 로컬 훅을 완전히 대체 |
| 로컬(대상 저장소) | `git config commit.template <git-trail>/.gitmessage` | 커밋 에디터에 스켈레톤 표시 |
| 전역(`--global`) | `git config --global init.templateDir <git-trail>/template` | 이후 모든 신규 저장소에 자동 적용 |
| 전역(`--global`) | `git config --global commit.template <git-trail>/.gitmessage` | 위와 동일, 전역 기본값 |

**실행 중 새로 생기는 파일**

| 파일/디렉터리 | 위치 | 언제 | 비고 |
| ------------------------- | ---------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------- |
| `.gitformat-verified` | `<대상 저장소>/.git/` | `pre-commit` 통과 시 생성, `post-commit`이 곧 삭제 | 커밋 사이에 남지 않는 임시 마커 |
| `.gitformat-token-cursor` | `<대상 저장소>/.git/` | Claude Code 실측 성공 시에만 `post-commit`이 갱신(`unavailable`일 때는 갱신 안 함) | `Tokens-Used`/`Tool-Calls` 델타 계산용 커서(`<세션 ID> <줄 수>`, 세션이 바뀌면 0줄부터, GF-139), 커밋 간 유지됨 |
| `template/hooks/*` | 이 git-logbook 클론 자신의 `template/` 안 | `install.sh --global` 실행 시 | 클론 위치를 가리키는 심볼릭 링크, 커밋 안 됨(`.gitignore`) |
| `template/hooks/*` | 이 git-trail 클론 자신의 `template/` 안 | `install.sh --global` 실행 시 | 클론 위치를 가리키는 심볼릭 링크, 커밋 안 됨(`.gitignore`) |

**커밋 자체가 바뀌는 경우**: `post-commit`이 조건에 따라 `git commit --amend`로
방금 만든 커밋의 footer에 트레일러를 추가합니다(README의 "훅 생애주기" 섹션과
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ id: doc-20
title: GitHub 원격 강제 설정 관리 — rulesets와 저장소 설정
type: guide
created_date: '2026-09-26 12:54'
updated_date: '2026-10-03 03:16'
updated_date: '2026-10-03 03:44'
---
# GitHub 원격 강제 설정 관리

Expand Down Expand Up @@ -66,27 +66,27 @@ decision-24(append-only)는 **로컬 훅만으로 달성할 수 없다.** `--no-

```sh
# 병합 방식
gh api repos/coralstay/git-logbook \
gh api repos/coralstay/git-trail \
--jq '{allow_merge_commit, allow_rebase_merge, allow_squash_merge}'

# ruleset 목록
gh api repos/coralstay/git-logbook/rulesets \
gh api repos/coralstay/git-trail/rulesets \
--jq '.[] | "\(.name) | \(.enforcement) | id=\(.id)"'

# 특정 ruleset 상세
gh api repos/coralstay/git-logbook/rulesets/23313297 \
gh api repos/coralstay/git-trail/rulesets/23313297 \
--jq '{name, enforcement, include: .conditions.ref_name.include, rules: [.rules[].type]}'
```

## 변경 방법

```sh
# 병합 방식 변경
gh api -X PATCH repos/coralstay/git-logbook \
gh api -X PATCH repos/coralstay/git-trail \
-f allow_merge_commit=true -F allow_rebase_merge=false -F allow_squash_merge=false

# ruleset 갱신 (PUT은 전체 교체다 - 기존 규칙을 빠뜨리면 사라진다)
gh api -X PUT repos/coralstay/git-logbook/rulesets/23313297 --input ruleset.json
gh api -X PUT repos/coralstay/git-trail/rulesets/23313297 --input ruleset.json
```

## 함정
Expand Down
Loading
Loading