origin) 사이에 검문소(gate)를 끼워 넣습니다. git push no-mistakes로 밀어 넣으면, 일회용 작업 폴더에서 리뷰 → 테스트 → 문서 → 린트 9단계 파이프라인을 AI가 돌리고, 모든 검사를 통과한 뒤에야 원격으로 푸시하고 깔끔한 PR을 엽니다. 슬로건은 "Kill all the slop. Raise clean PR(허접한 코드는 다 죽이고, 깨끗한 PR만 올린다)". (kunchenguid/no-mistakes · Go 1.25 · MIT · launchd/systemd 백그라운드 데몬 · Claude·Codex·OpenCode 등 에이전트 무관)"AI가 빠르게 쏟아낸 코드 변경을, 원격에 올라가기 직전 일회용 작업 폴더에서 자동으로 리뷰·테스트·린트하고, 전부 통과해야만 진짜 원격으로 푸시하고 깨끗한 PR까지 열어주는 로컬 검문소"입니다. 핵심은 origin을 절대 건드리지 않고, 새 원격(no-mistakes)을 따로 추가해 그쪽으로 푸시하면 검문이 시작된다는 점입니다.
사용법은 셋 중 하나로 압축됩니다. ① 터미널에서 git push no-mistakes <브랜치>, ② 그냥 no-mistakes를 쳐서 뜨는 터미널 UI(TUI)로, ③ AI 에이전트 안에서 /no-mistakes <작업> 스킬로. 어느 길로 들어와도 같은 게이트, 같은 9단계 파이프라인을 통과합니다.
예전에는 작업자(개발자)가 물건(코드)을 만들면 곧장 트럭(원격 저장소)에 실었습니다. AI가 들어오면서 물건은 폭발적으로 빨리 나오지만, 불량품(slop)도 같이 쏟아집니다. no-mistakes는 출하장 정문에 자동 검사 게이트를 세웁니다.
물건을 트럭에 바로 싣지 못하게 막고, 옆 임시 검사실(일회용 worktree)로 보냅니다. 거기서 리뷰·테스트·린트를 차례로 통과한 물건만 정문이 열려 진짜 트럭에 실리고, 송장(PR)까지 자동으로 붙습니다. 검사 중에 작업자의 책상(내 작업 디렉터리)은 전혀 건드리지 않습니다.
~/.no-mistakes/repos/<id>.git에 만들어지며, 여기로 푸시가 들어오면 post-receive 훅이 검사 파이프라인을 깨웁니다. "검문소" 그 자체.프로젝트 문서가 내세우는 한 문장이 핵심입니다. AI는 코드(diff)를 순식간에 써내지만, 비싸진 것은 그걸 '검증'하는 일이라는 것. no-mistakes는 커밋 전에 막는 pre-commit 훅과 푸시가 이미 공개된 뒤 도는 CI 사이의 빈 구간 — "푸시 직전" — 을 정확히 메웁니다.
비슷한 도구들이 흔히 git 훅이나 별칭으로 기존 워크플로를 몰래 가로채는데, no-mistakes는 정반대입니다. no-mistakes라는 별도 원격을 추가하고, 사용자가 그쪽으로 푸시할 때만 작동합니다. "내가 원할 때만, 내가 지정한 통로로만" 검문이 돈다는 opt-in 설계가 신뢰를 얻은 큰 이유입니다.
특정 AI에 묶이지 않습니다. claude·codex·opencode·rovodev·pi, 그리고 ACP 호환 acp:<target>까지 백엔드로 끼울 수 있고, auto로 두면 PATH에서 먼저 발견되는 것을 씁니다. "내가 쓰던 에이전트 그대로" 붙는다는 점이 진입장벽을 낮춥니다.
이 프로젝트의 모든 PR은 no-mistakes 자신을 통과해야 머지됩니다. GitHub Action("Require no-mistakes")이 no-mistakes가 남긴 결정론적 서명이 없는 PR을 떨어뜨립니다. "우리가 만든 게이트를 우리부터 통과한다"는 자기증명이 설득력을 더합니다.
| no-mistakes | pre-commit 훅 | CI (GitHub Actions) | 그냥 수동 리뷰 | |
|---|---|---|---|---|
| 검사 시점 | 푸시 직전(공개 전) | 커밋 시점 | 푸시 후(이미 공개) | PR 올린 뒤 |
| 내 작업 폴더 | 안 건드림(일회용) | 내 트리에서 실행 | 원격에서 | 해당 없음 |
| AI 자동 수정 | 단계별 한도 내 자동 | 없음 | 드묾 | 사람이 직접 |
| PR 생성 | 통과 시 자동 | 없음 | 없음 | 수동 |
| origin 영향 | 전혀 없음(별도 원격) | 없음 | 이미 푸시됨 | 없음 |
no-mistakes는 코드를 생성하는 도구가 아니라, 이미 만들어진 변경을 '검문'하는 게이트입니다. AI가 자동 수정을 시도하긴 하지만 단계마다 한도가 있고, 리뷰 단계는 항상 멈춰 사람의 승인을 기다립니다. 또 ask-user 표시가 붙은 항목은 에이전트가 임의로 처리하지 못하고 사람에게 그대로 올려야 합니다(--yes로 사전 동의한 경우 제외).
no-mistakes는 Go 1.25로 짠 단일 정적 바이너리입니다. CGO_ENABLED=0이라 C 의존성 없이 macOS·Linux·Windows에서 그대로 돕니다. AI 호출은 라이브러리가 아니라 PATH에 깔린 외부 에이전트 CLI에 위임합니다.
| 구성요소 | 역할 |
|---|---|
| Go 1.25 (CGO 끔) | 전체 CLI·데몬·파이프라인. 단일 정적 바이너리로 크로스플랫폼 배포 |
| spf13/cobra | 서브커맨드 트리(init, axi, daemon, doctor …) |
| charmbracelet/bubbletea + bubbles + lipgloss | 터미널 UI(TUI) 프레임워크 — diff 뷰어·findings·로그 박스·테마 |
| modernc.org/sqlite | 순수 Go SQLite(cgo 없음). 상태를 ~/.no-mistakes/state.sqlite에 저장 |
| oklog/ulid/v2 | 실행(run) ID 생성 — 시간순 정렬 가능한 식별자 |
| toon-format/toon-go | TOON 포맷 — 토큰 효율적인 기계 판독 출력(에이전트 인터페이스 axi가 사용) |
| yaml.v3 / x/sys / go-isatty / termenv | 설정 파싱 · OS 연동 · 터미널 감지/색상 |
| 구성요소 | 역할 |
|---|---|
| launchd (macOS) | 데몬을 관리형 서비스로 등록·자동 기동 |
| systemd (Linux) | 동일 — 리눅스용 서비스 파일 제공 |
| schtasks (Windows) | 동일 — 윈도우 작업 스케줄러 등록 |
| Unix 소켓 + JSON-RPC 2.0 | ~/.no-mistakes/socket으로 TUI·axi와 통신(이벤트 구독/요청·응답) |
| 구성요소 | 역할 |
|---|---|
| claude · codex · opencode · rovodev · pi | 끼울 수 있는 에이전트 백엔드. auto가 PATH에서 먼저 찾은 것 선택 |
| acp:<target> (acpx) | ACP 프로토콜 호환 에이전트를 범용으로 연결 |
| SKILL.md (자동 생성) | /no-mistakes 스킬 정의. cmd/genskill이 Go 소스에서 생성 |
| axi 인터페이스 | 에이전트가 호출하는 비대화형 API. stdout에 TOON, stderr에 진행상황 |
| 구성요소 | 역할 |
|---|---|
| Makefile | build(ldflags로 버전 주입)·dist(6타깃 크로스컴파일)·test·e2e·skill·lint·demo |
| go test -race | 레이스 컨디션 검출 테스트(데몬·동시 푸시가 많아 필수) |
| docs/install.sh | curl | sh 설치 — OS/arch 감지 후 릴리스 타르볼 설치 |
| release-please + Umami | 릴리스 자동화(43KB CHANGELOG) · 익명 분석(ldflags로 호스트/ID 주입) |
공장 라인(Go 데몬)과 외부 검사관(에이전트 CLI)의 분업. Go 데몬은 컨베이어벨트·검사실·송장 발행 같은 "설비"를 전부 소유하고 결정론적으로 굴립니다. 정작 "이 코드 괜찮나?"라는 판단은 외부에서 부른 검사관(claude/codex 등)이 합니다. 검사관이 누구든 라인 구조는 똑같이 작동합니다.
git push no-mistakes 한 줄이 어떻게 9단계 검문을 거쳐 진짜 원격에 올라가는지 따라가 봅시다. 왼쪽이 사용자, 가운데가 게이트와 데몬, 오른쪽이 통과 결과입니다.
no-mistakes의 심장은 의외로 단순합니다. 내 저장소와 원격 사이에 작업 폴더 없는 bare git 저장소를 하나 끼우고, 거기에 post-receive 훅을 심는 것. 푸시는 bare 저장소가 즉시 받아주니 git 입장에선 빠르게 끝나고(블로킹 없음), 그 직후 훅이 데몬을 깨워 진짜 검사를 비동기로 시작합니다.
.git 내용물만 있는 저장소. 보통 "서버 쪽 원격"이 이 형태입니다. no-mistakes는 이걸 로컬에 만들어 "가짜 원격"처럼 쓰고, 여기로 푸시가 들어오는 순간을 검문 트리거로 삼습니다. init 시 게이트의 core.hookspath를 --worktree로 격리해, husky 같은 도구가 훅을 못 끄게 막는 디테일도 있습니다(이슈 #122).파이프라인의 순서와 구성은 바꿀 수 없습니다. internal/types/types.go의 StepName 상수로 못박혀 있고 AllSteps()가 정확히 이 9개를 돌려줍니다. "각 단계가 무엇을 실행할지(테스트 명령 등)"는 바꿀 수 있어도, "순서와 집합"은 못 바꿉니다. 덕분에 "게이트를 통과했다"가 모든 저장소에서 똑같은 의미를 갖습니다.
| # | 단계 | 하는 일 | 자동수정 한도 |
|---|---|---|---|
| 1 | intent | --intent 인자 사용, 없으면 로컬 에이전트 대화 기록에서 의도 추론 | — |
| 2 | rebase | 업스트림 fetch 후 리베이스. diff가 사라지면 이후 단계 스킵 | 3 |
| 3 | review | diff에 대한 AI 코드 리뷰 | 0 (항상 승인 대기) |
| 4 | test | 기준 테스트 실행 + 증거(evidence) 수집 | 3 |
| 5 | document | 문서 갱신, 누락 보고 | 초기 패스 |
| 6 | lint | 린트 / 정적 분석 | 3 |
| 7 | push | 검증된 브랜치를 진짜 업스트림으로 푸시 | — |
| 8 | pr | PR(또는 MR) 생성·갱신 | — |
| 9 | ci | CI·머지 가능 여부 감시, 실패·충돌 자동수정 | 3 |
id, severity(error/warning/info), file, line, description, action으로 구성되고, action은 auto-fix·no-op·ask-user 중 하나. 실행기(executor.go)는 "단계 실행 → auto-fix가 있고 한도가 남으면 에이전트에게 되돌려 수정 → 막는 항목이나 ask-user가 남으면 멈추고 사용자 결정(승인/선택수정/스킵/중단)을 기다림"을 반복합니다.검사는 내 작업 폴더가 아니라 ~/.no-mistakes/worktrees/<repoID>/<runID>/의 detached 일회용 worktree에서 돕니다. 에이전트가 자동수정을 하며 파일을 마음껏 바꿔도 내 책상(working tree)은 절대 영향받지 않습니다. 같은 브랜치에 새 푸시가 들어오면 진행 중인 run을 취소하고 새로 시작하는 직렬화도 데몬이 책임집니다.
같은 검문소에 들어오는 길이 셋입니다. (1) git push no-mistakes — 순수 git 경로. (2) 맨손으로 no-mistakes — bubbletea TUI가 뜨고 브랜치→커밋→푸시 마법사가 안내(-y로 자동화). (3) /no-mistakes <작업> — 에이전트 스킬. 이 스킬은 내부적으로 비대화형 axi 인터페이스를 구동합니다.
axi run --intent "..." [--skip=lint] [--yes]로 실행, axi respond --action approve|fix|skip --findings <ids>로 결정 전달, 그 외 axi status·axi logs --step <name> --full·axi abort. stdout으로 TOON(기계 판독), stderr로 진행상황을 분리 출력합니다. 결과는 checks-passed(CI 통과·머지는 사람이) / passed / failed / cancelled.checks-passed ≠ 머지됨CI가 초록불이어도 no-mistakes는 스스로 머지하지 않습니다. checks-passed에서 멈추고 사람에게 머지를 넘깁니다. 또 SKILL.md의 핵심 규칙: ask-user findings는 에이전트가 사람에게 그대로(verbatim) 올려야 하며, --yes로 standing consent(상시 동의)를 받은 경우가 아니면 임의 해결 금지입니다.
1) README.md + docs/.../introduction.md — "병목이 이동했다" 문제의식과 게이트 모델. 2) internal/gate/gate.go — bare 저장소 + post-receive 훅을 어떻게 까는지. 3) internal/types/types.go(단계 순서)와 findings.go(데이터 모델). 4) internal/pipeline/executor.go — 자동수정·승인 루프의 본체. 5) internal/daemon/ — 소켓·동시성·크래시 복구.
cmd/ vs internal/ 분리cmd/는 cobra에 의존하는 얇은 껍데기, internal/은 cobra를 모르는 순수 로직이라 테스트에서 직접 부를 수 있습니다. internal/이라는 이름 자체를 Go가 특별 취급해 외부 모듈의 import를 차단합니다. 게다가 SKILL.md를 internal/skill 소스에서 생성하고 CI에서 drift를 검사하는 "단일 진실원" 패턴까지 갖췄습니다.배울 것: post-receive 훅, push options(git push -o ...), bare 저장소를 "로컬 가짜 원격"으로 쓰는 발상. git을 가로채지 않고 옆에 새 원격을 더해 확장하는 방식은 어떤 git 자동화에도 응용됩니다. core.hookspath 격리로 훅을 보호하는 디테일도 실전 지식입니다.
배울 것: 백그라운드 데몬을 Unix 소켓 + JSON-RPC로 노출하고, 같은 브랜치 푸시를 직렬화(새 푸시가 진행 중 run을 취소)하며, 크래시 후 "멈춘 run을 failed로 표시·고아 worktree 정리"하는 복구 로직. go test -race가 필수인 이유를 코드로 체감할 수 있습니다.
배울 것: 파이프라인·상태·소켓 같은 결정론적 부분은 Go가 소유하고, "판단"만 외부 에이전트에 위임하는 agent-agnostic 경계. auto 해석으로 PATH에서 백엔드를 고르고, 기계 판독 출력(TOON)과 사람용 진행상황(stderr)을 분리하는 인터페이스 설계가 핵심 교본입니다.
배울 것: Elm 아키텍처(Model-Update-View) 기반 bubbletea로 diff 뷰어·findings·실시간 로그를 그리는 법. 데몬이 보내는 이벤트를 소켓 subscribe로 받아 화면을 갱신하는 구조는 "백엔드-프런트 분리"의 터미널판 사례입니다.
배울 것: Makefile의 ldflags 버전 주입, 6타깃 크로스컴파일, release-please 자동 릴리스, 그리고 "모든 PR이 no-mistakes 자신을 통과해야 머지"되는 도그푸딩 CI. 결정론적 서명을 PR에 남기고 GitHub Action으로 강제하는 방식은 품질 게이트의 좋은 본보기입니다.
| 항목 | 요구사항 |
|---|---|
| 설치(간편) | curl -fsSL https://raw.githubusercontent.com/kunchenguid/no-mistakes/main/docs/install.sh | sh — OS/arch 자동 감지 |
| 설치(빌드) | Go 1.25+ · make build(ldflags로 버전 주입) |
| OS | macOS · Linux · Windows (CGO 없는 단일 정적 바이너리) |
| 에이전트 | claude·codex·opencode·rovodev·pi 중 하나가 PATH에. auto가 자동 선택 |
| 데몬 | 백그라운드 데몬이 서비스로 자동 등록(launchd/systemd/schtasks). Unix 소켓 사용 |
| 호스트 연동 | PR/CI 감시는 GitHub·GitLab·Bitbucket 인증 필요(gh 등 토큰) |
| 상태 저장 | 모두 ~/.no-mistakes/ 아래(NM_HOME으로 이전 가능): bin·repos·worktrees·state.sqlite·socket·config.yaml |
agent(에이전트 지정), commands.{test,lint,format}(각 단계가 실제로 돌릴 명령 — sh -c/cmd.exe /c로 실행), ignore_patterns, auto_fix.<step>(단계별 자동수정 한도), intent.{enabled,threshold,...}, test.evidence.{store_in_repo,dir}. 전역 설정은 ~/.no-mistakes/config.yaml, 1회성 스킵은 git push -o no-mistakes.skip=test,lint.아무 토이 저장소에서 no-mistakes init을 돌려 no-mistakes 원격이 추가되는 걸 확인하세요(git remote -v). 작은 커밋을 만들고 git push no-mistakes <브랜치> 후 no-mistakes attach로 파이프라인이 단계별로 도는 모습을 관찰합니다. origin이 전혀 안 변했는지도 확인하세요.
git push -o no-mistakes.skip=lint,document no-mistakes <브랜치>로 일부 단계를 건너뛰어 보고, no-mistakes runs·no-mistakes status로 어떤 단계가 실행/스킵됐는지 비교하세요. "순서는 고정, 무엇을 돌릴지는 설정"이라는 철학을 체감합니다.
no-mistakes 없이 순수 git만으로, 로컬 bare 저장소를 만들고 post-receive 훅에서 받은 ref·old/new SHA를 로그에 적는 미니 게이트를 짜보세요. no-mistakes가 어떤 메커니즘 위에 서 있는지 손으로 이해하는 과제입니다.
.no-mistakes.yaml의 agent를 auto 대신 특정 백엔드로 고정하고, axi run --intent "..."를 직접 호출해 stdout의 TOON 출력과 stderr 진행상황이 어떻게 분리되는지 분석하세요. axi respond로 승인/스킵 결정을 수동으로 넣어봅니다.
internal/pipeline/steps/에 단계 하나(예: 보안 스캔)를 추가하려면 어디를 고쳐야 하는지 추적하세요: StepName 상수 → AllSteps() → executor의 한도/승인 처리 → SKILL.md 재생성(make skill) → make lint drift 통과. "고정 파이프라인이 계약"인 설계에서 무엇이 바뀌고 무엇이 잠겨 있는지를 몸으로 익히는 과제입니다.
bare 저장소, post-receive/pre-receive 훅, push options, core.hookspath를 익힙니다. 목표: 푸시를 가로채 로그를 남기는 미니 게이트 완성. internal/gate/gate.go를 읽으며 비교하세요.
goroutine·channel·context 취소, Unix 소켓 서버, JSON-RPC, go test -race를 익힙니다. 작은 백그라운드 데몬을 만들어 작업 직렬화·취소·크래시 복구를 직접 구현해보세요. internal/daemon/이 교본입니다.
"결정론 코어 + 교체 가능한 두뇌" 패턴을 이해하고, GitHub/GitLab/Bitbucket API로 PR 생성·CI 상태·머지 가능 여부를 다루는 법을 익힙니다. internal/agent/·internal/scm/을 분석하세요.
bubbletea(Elm 아키텍처)로 실시간 UI를 그리고, Makefile ldflags·크로스컴파일·release-please·도그푸딩 CI를 익힙니다. 목표: 내 Go CLI에 TUI 한 화면과 크로스플랫폼 릴리스를 붙이기.
daemon notify-push를 호출해 검사를 비동기로 시작시킨다.run/respond/status/logs/abort를 제공하고, 기계 판독용 TOON을 stdout에 출력한다. /no-mistakes 스킬이 이걸 구동한다.toon-format/toon-go). 에이전트 인터페이스의 출력으로 비용을 아낀다.auto는 PATH에서 먼저 찾은 것을 쓴다.passed·failed·cancelled와 구분).go build -ldflags "-X ...Version=v1.2.3"로 소스 변수에 값을 박는 기법. 코드 수정 없이 바이너리에 버전·커밋·날짜·분석 호스트까지 새긴다(internal/buildinfo).| 링크 | 설명 |
|---|---|
| GitHub 저장소 | 소스 전체. README.md·AGENTS.md·docs/concepts/{gate-model,pipeline}가 핵심 |
| TrendShift 페이지 | 트렌딩 추이(주간 21위, 2026-06-09) |
| Git Hooks 문서 | post-receive 등 git 훅의 동작 원리 |
| git-worktree | 하나의 저장소에 여러 작업 폴더를 두는 기능 |
| spf13/cobra | Go CLI 프레임워크. 서브커맨드 구조의 사실상 표준 |
| charmbracelet/bubbletea | Elm 아키텍처 기반 Go TUI 프레임워크 |
| modernc.org/sqlite | cgo 없는 순수 Go SQLite |
| TOON 포맷 | 토큰 효율적 기계 판독 포맷 |
| Claude Code 스킬 문서 | SKILL.md 작성·동작 원리 공식 문서 |