claude-harness-pjc (자율 루프)
Claude Code가 "계획 없이 추측하고 a 파일 수정하면서 b·c 파일을 빠뜨리고 검증 없이 완료 선언"하는 것을 막기 위한 도구입니다. 모든 코드 변경은 계획 → 구현 → 다층 검증 → 완료의 자율 루프를 거칩니다.
claude-harness-pjc (자율 루프)
Claude Code가 계획하고 검증하며 일하도록 만드는 plugin (Windows 우선 · pwsh 7 또는 내장 PowerShell)
(계획·검증 로직은 OS 무관, 자동 안전망 hook은 pwsh 7 우선·없으면 Windows 내장 PowerShell로 폴백 — Windows 검증·macOS/Linux 실험적, 호환 환경 참고)
버전: 1.300.0
저장소: https://github.com/jongcheol-pak/claude-harness-pjc
Claude Code: 최소 v2.0 · 권장 v2.1.269+ — --filter 이름 검증과 골든 러너 병렬 모드가 안정된 판이다. 그 미만에서도 동작하지만 부분 실행 필터가 조용히 0건을 돌 수 있다.
한눈에 보기
Claude Code에게 코딩을 맡기면 가끔 이렇게 합니다:
- 계획 없이 바로 코드를 쓰고, 있지도 않은 함수를 호출
- A 파일만 고치고 그걸 부르는 B·C 파일은 그대로 둬서 빌드가 깨짐
- 제대로 확인 안 하고 "다 됐습니다"라고 보고
- task마다 "다음 진행할까요?"를 물어 흐름이 끊김
pjc는 이걸 막습니다. 코드를 바꾸기 전에 먼저 계획을 세우게 하고, 바꾼 뒤에는 여러 단계로 검증하게 하며, 한 번 승인하면 끝까지 자동으로 진행합니다. "꼼꼼한 시니어 개발자의 작업 습관"을 Claude Code에 입히는 도구라고 보면 됩니다.
비유하자면, Claude Code가 "재능 있지만 가끔 덤벙대는 주니어"라면, pjc는 그 옆에서 "계획서 보여줘 → 이 부분 빠졌네 → 검증했어? → 좋아 통과"를 챙기는 작업 절차와 안전장치입니다.
특정 언어 전용이 아닙니다 — 빌드/테스트 명령만 알면 어떤 언어·프로젝트에서도 동작합니다. (.NET·Android·Node/TS·Python·Go·Rust는 표식 파일로 자동 감지해 빌드·테스트 명령까지 채우고, 그 외는 물어서 채웁니다)
무엇을 해결하나요
| 자주 겪는 문제 | pjc의 대응 |
|---|---|
| 추측으로 코드를 쓰고, 없는 함수를 호출 | 코드 변경 전 영향 범위를 전부 조사하고, 계획을 적대적으로 검토 |
| A만 고치고 B·C를 빠뜨림 | 변경할 때마다 그걸 쓰는 다른 파일을 자동으로 찾아 함께 점검 |
| 확인 없이 "다 됐다"고 보고 | 빌드·테스트 + 2단계 검토 + 자기점검을 통과해야만 완료 |
| task마다 "다음 할까요?" 물음 | 한 번 승인하면 모든 task를 끝까지 자동 진행 |
| 사소한 오타 수정에도 거창한 절차 | 3줄 이내 단순 수정은 절차를 건너뛰고 바로 처리 |
| 빌드·테스트 명령을 매번 모름 | 프로젝트를 분석해 명령을 자동으로 파악·기록 |
| DB 데이터를 실수로 삭제·변조 | 위험한 DB 명령(전체 삭제/변조 등)을 자동 차단 |
| 과거에 한 작업을 매번 다시 조사 | 프로젝트 지식을 위키에 쌓고, 다음 작업 때 참조 |
빠른 시작
1. 사전 요구사항
- Windows 10/11 + PowerShell
- Claude Code v2.0 이상
2. 설치
claude plugin marketplace add jongcheol-pak/claude-harness-pjc
claude plugin install pjc@pjc-harness
claude plugin enable pjc@pjc-harness
설치가 끝나면 Claude Code를 다시 시작합니다.
3. 첫 사용
평소처럼 말하면 됩니다. pjc가 알아서 끼어듭니다:
> 로그인 화면에 "비밀번호 찾기" 링크 추가해줘
[pjc가 자동으로]
1. 계획을 세우고 → 검토한 뒤 → 당신에게 승인을 받습니다
2. 승인하면 → 구현하고 → 검증하고 → 완료를 보고합니다
처음 코드 작업을 시도하면, pjc가 작업에 필요한 명령·규칙(빌드·테스트 명령, 인코딩 규약, 금지 항목)을 담은 AGENTS.md 파일이 없다며 생성을 제안합니다. 빌드·테스트 명령과 아키텍처 선언 1줄을 채우고 나머지 절은 비워 만듭니다 — 앞은 그것이 없으면 검증이 성립하지 않아 즉시 필요하고 뒤는 비워 두면 첫 코드 작업이 계층 없이 시작되기 때문입니다. 나머지는 작업하며 확인되는 대로 채워집니다(추측해 채우지 않습니다).
AGENTS.md에는 프로젝트 정보를 넣지 않습니다. 프로젝트 성격·기술 스택·디렉터리 구조·아키텍처 상세는 위키가 정본이고AGENTS.md에는 위키로 가는 한 줄만 둡니다(예외는 계층을 어떻게 갈랐는지, 안 갈랐으면 그 근거를 적는 아키텍처 선언 1줄뿐입니다 — 코드를 쓸 때마다 필요하기 때문입니다). 이 파일은 매 세션 전문이 주입되므로, 코드를 읽으면 알 수 있는 것(구조)이나 계속 쌓이는 것(진행 상태)을 담으면 곧 주입 한도를 넘겨 그 세션이 파일을 통째로 못 보게 됩니다. 위키에 등록되지 않은 프로젝트는 계획을 세울 때 자동으로 등록합니다.
어떻게 동작하나요
pjc는 코드 작업을 계획 → 구현 → 검증 → 완료의 흐름으로 진행합니다.
1단계 — 계획 (당신과 함께)
요청을 받으면 바로 코드를 쓰지 않고 먼저 계획을 세웁니다.
- 어떤 파일을 건드려야 하는지 전부 조사합니다 (영향 범위 파악)
- 요청 밖이지만 함께 손봐야 할 것까지 검토합니다 — 그 변경 때문에 어긋나게 되는 문서·규약·검증 자산을 찾아, 안 하면 요청이 성립하지 않는 것은 작업에 포함하고, 해도 되고 안 해도 되는 것은 승인 전에 물어봅니다. 작업이 끝난 뒤에 "추가로 고칠 곳이 있습니다"라고 통보하지 않기 위한 장치입니다
- 계획이 참으로 삼는 사실(이 파일은 이런 구조다 등)을 근거와 짝지어 적습니다 — 확인하지 않은 전제는 그대로 드러나므로, 구현 중에 "계획이 틀렸다"며 멈추는 일이 줄어듭니다
- 새로 만들기 전에 이미 있는 코드·공통 컴포넌트를 먼저 검색해 재사용합니다 (중복 구현 방지 — UI 요소도 기존 공용 컴포넌트 재사용 우선)
- 작업을 작은 단위(T1, T2, …)로 나눕니다
- 위키에 적어 둔 함정을 그것이 걸리는 작업 옆에 붙입니다 — 프로젝트 전역 규약과 그 기능 고유의 주의점을 계획할 때 읽어, 해당 작업의 「함정」 줄로 옮깁니다. 조사 기록에만 남기면 정작 그 파일을 고치는 순간에는 한참 앞의 내용이 되어 다시 밟게 되기 때문입니다. 구현 단계는 작업을 끝내기 전에 그 줄을 어겼는지 한 번 대조합니다. 읽을 때는 페이지를 통째로 열지 않고 이번 작업에 걸리는 절만 뽑습니다 — 규약은 아카이브로 넘기지 않고 계속 쌓이는 파일이라 전문 읽기의 비용이 작업마다 늘어나기 때문입니다(실측으로 규약 본문 9개 절 중 한 번에 걸리는 것은 1~2절이고, 기능 페이지는 필요한 절이 전체의 4% 인 경우가 있었습니다). 절 제목이 *「언제 읽는지」*를 말하도록 쓰게 해 그 판정이 제목만으로 서고, 제목으로 갈리지 않으면 전문을 읽고 그 사실을 조사 기록에 남깁니다
- 새 파일을 만드는 작업에는 「왜 그 파일인가」를 계획에 적습니다 — 어느 모듈에 두는지, 색·간격 같은 스타일은 어느 공통 자산을 재사용하는지까지. 파일을 나눌지 말지는 코드가 쌓인 뒤에 정하면 이미 얹힌 것까지 함께 옮겨야 하기 때문입니다
- 모호한 부분은 선택지로 만들어 물어봅니다 — 이때 당신이 이미 말한 방향은 반드시 선택지에 들어갑니다. 예를 들어 "A 프로젝트와 동일하게 만들어줘" 라고 했으면 "A와 동일하게 구현" 이 첫 번째 선택지여야 하고, 다른 라이브러리로 비슷하게 만드는 대안들만 나열하는 것은 금지입니다(그건 선택지를 주는 게 아니라 요구를 바꾸는 것이기 때문). 추천은 빨리 끝나는 안이 아니라 문제가 사라지는 안에 붙고, 임시방편만 나열하지 않습니다. 선택지가 많아 화면 목록에 다 담기지 않으면 잘라내지 않고 전부 보여줍니다
- 별도의 "검토 담당"이 계획이 실측 위에 서 있는지 검사합니다 — 조사했다고 적었으나 실제로 돌리지 않은 명령, 빠진 호출자, 판정할 수 없는 완료 조건을 찾아냅니다
- 검토는 계획이 완성된 뒤 1회입니다. 지적을 고쳐 해소한 뒤 승인을 요청하고, 고치지 않은 것이 있으면 그 사실을 승인 화면에 적습니다
- 완성된 계획을 화면에 요약해 보여주고 승인을 기다립니다 ✋ —
T1: …T2: …처럼 각 작업이 무엇을 하는지 한 줄씩과, 따로 승인이 필요한 항목을 함께 냅니다. 파일을 열어야 판단이 서는 상태로 승인을 요청하지 않습니다
계획에 명시된 "알려진 승인 필요 항목"(비파괴 DB 스키마 변경·의존성 추가 등)은 이 1회 승인에 함께 포함됩니다 — 그래서 자율 진행 중 그런 항목마다 다시 멈추지 않습니다. 단 push·릴리즈 같은 외부 작업과, 계획에 없던 위험한 변경(파괴적 작업·DB 삭제 등)은 그 지점에서 따로 승인받습니다.
승인이 필요하지만 지금 받지 않아도 되는 일은 미뤄 두고 끝까지 진행합니다. 작업을 끝내는 데 없어도 되는 곁가지(계획에 없던 정리 같은 것)를 만나면, 거기서 멈춰 묻는 대신 하지 않고 지나간 뒤 완료 보고에서 한 번에 여쭤봅니다 — 승인 하나 때문에 자동 진행이 중간에 서지 않게 하려는 것입니다. 위험한 변경과 외부 작업은 여기 해당하지 않고 종전대로 그 자리에서 멈춥니다.
2단계 — 구현 (자동)
승인하면 여기서부터는 끝까지 자동입니다. task마다 다음을 반복합니다:
- 이 변경이 다른 곳에 영향을 주는지 미리 추적
- 최소한으로 코드 수정 (다음에 읽는 사람이 기준 — 이해를 해치지 않는 선까지만 줄이고, 고친 코드의 주석이 새 동작과 어긋나면 함께 고칩니다)
- 빌드·테스트 + 검토 담당의 검증
- 통과하면 저장하고 즉시 다음 task로
중간에 "다음 할까요?"라고 묻지 않습니다. 문제가 생겼을 때만 멈춰서 물어봅니다.
진행 중 화면에는 작업 시작 한 줄, 완료 한 줄만 나옵니다 — 분석·검증 과정을 늘어놓지 않고, 상세는 계획서에 적었다가 완료 보고에서 한 번에 알려줍니다(진행 중 서술은 읽히지도 않으면서 후반 작업의 품질을 떨어뜨리기 때문).
수정으로 호출부가 사라져 더 이상 쓰이지 않게 된 코드(고아 코드)도 감지합니다 — 안전한 것은 함께 정리하고, 애매한 것은 완료 보고에서 알려줍니다.
3단계 — 검증과 완료
모든 task가 끝나면 전체를 한 번 더 통합 검증하고, 빌드·테스트·검토를 모두 통과한 뒤에야 완료를 보고합니다. 이 마무리 구간에서도 화면에는 지금 어느 검증을 하는지 한 줄만 나옵니다 — 검증 출력과 검토 지적은 완료 보고에 모입니다.
자기가 고친 것 때문에 생긴 문제는 "남은 이슈"로 넘길 수 없습니다. 이번 변경이 원인인 회귀·깨진 호출부·어긋난 문서는 같은 작업 안에서 함께 고쳐야 완료로 인정되고, 고치는 범위가 승인받은 것을 넘으면 미루는 대신 멈춰서 물어봅니다. 완료 보고의 남은 항목에 적을 수 있는 것은 ① 원래부터 있던 별개 문제 ② 당신이 범위 밖으로 정한 것 ③ 개선 제안 셋뿐입니다. 그중 화면에 나오는 것은 대장에 실제로 올린 것과 다음 회차가 이어받을 것뿐입니다 — 올리지 않기로 판정한 항목은 계획서에 근거와 함께 남고 보고에는 싣지 않습니다.
작업 중 "다음에 하자"고 미룬 항목은 커밋되는 대장(docs/plans/deferred.md)에 축적되고, 다음 계획을 세울 때 자동으로 조회됩니다 — 계획서마다 흩어져 유실되는 것을 막습니다. 대장은 역할별로 셋으로 나뉘어 있어(대기 / 기각 종결 deferred-closed.md / 소진 batch 회고 deferred-history.md) 계획 때 열리는 것은 대기 파일 하나입니다.
할 일이 많아 회차를 나눈 경우, 완료 보고 뒤에 다음 회차 착수용 프롬프트가 코드블록으로 함께 나옵니다 — 그대로 복사해 새 세션에 붙여 넣으면 이어집니다. 담기는 것은 ① 다음에 할 일(당신이 말한 표현 그대로) ② 이번 회차가 무엇을 끝냈는지와 커밋 지점 ③ 착수 전에 다시 판정해야 할 것(그대로 믿으면 틀리는 지점) ④ 현황을 다시 재는 명령 넷입니다. 계획서를 미리 써 두지는 않습니다 — 그 조사는 이번 회차 시점의 것이라 낡고, 새 세션의 요구 확인이 통째로 빠지기 때문입니다. 회차를 나누지 않았으면 이 프롬프트는 나오지 않습니다.
대장으로 옮기기 전에 대화가 요약되어도 그 항목은 사라지지 않습니다. 계획서의 미뤄둔 항목마다 대장에 올렸는지를 나타내는 표시가 붙고(올림 / 걸러냄+사유 / 아직 판정 안 함), 아직 판정하지 않은 것이 몇 건인지 세션이 시작될 때마다 알려줍니다. 계획서는 다음 작업 때 교체되므로, 옮기지 못한 항목은 그때까지 알려지지 않으면 회차와 함께 사라집니다 — 실제로 작업이 끝났다는 표시 옆에 아직 옮기지 않은 항목이 남아도 그대로 넘어가던 자리입니다. 표시가 하나도 없는 예전 계획서는 전부 "아직 판정 안 함"으로 셉니다.
그 표시를 적는 자리는 한 가지로 정해져 있고, 벗어나면 기계가 잡습니다. 표시를 읽는 곳이 넷인데 전부 항목 첫머리에서 그것을 찾으므로, 표시를 굵은 글씨 안쪽에 넣으면 판정을 마친 항목이 "아직 판정 안 함"으로 세어지고 대장에 올렸는지 확인하는 검사가 통째로 조용해집니다. 그래서 정해진 자리를 벗어난 항목을 검사가 위반으로 잡습니다 — 표시를 읽지 못하는 상태 자체가 결함이기 때문입니다. 대장과 계획서의 제목이 조사 띄어쓰기만 다른 경우는 같은 항목으로 봅니다(옮기며 문장을 다듬는 것은 정상이고, 그 다듬기가 제목에 닿아도 옮긴 항목이 안 옮긴 것으로 잡히지 않아야 합니다).
같은 규칙이 여러 곳에 흩어지지 않게 기계가 감시합니다. 하나의 개념(예: "자기 유발 결함은 미룰 수 없다")이 여러 파일에 각자 서술되면 한쪽을 고칠 때 나머지가 조용히 낡습니다. 그래서 개념마다 정본 한 곳을 정해 두고, 그 밖의 언급이 정본을 가리키는 포인터인지 독자적인 재서술인지를 자동으로 가릅니다 — 재서술이 발견되면 검사가 실패합니다.
대장은 쌓이기만 하지 않습니다. 올라오는 것을 거르는 게이트와 쌓인 것을 비우는 조건이 함께 있습니다 — 리뷰어가 스스로 확신이 낮다고 표시한 지적과 그 자리에서 고칠 수 있는 것은 등재하지 않고(전자는 정말 문제라면 다음에 다시 관측되고, 후자는 미루는 대신 바로 고칩니다), 대기가 100건을 넘으면서 지난 정리 이후 새로 쌓인 것이 30건 이상이거나, 가장 오래된 항목이 30일을 지나거나, 대기가 절대 상한(130건)을 넘으면서 마지막 정리로부터 14일이 지났으면 다음 계획에 정리 작업이 자동으로 들어갑니다(첫 조건이 잔량만으로 열리지 않는 것은 전부 다시 살펴본 바로 다음 날 또 열리던 것을 막기 위해서고, 절대 상한은 그 안전장치 때문에 잔량이 계속 불어나기만 하는 상태를 닫습니다 — 그 상한에도 날짜 조건이 붙은 것은 잔량이 「다시 살펴보기」로는 줄지 않아 한 번 넘으면 계속 참이 되고, 실제로 이틀 사이 세 번 열려 그중 하나가 하루 전에 살펴본 구간을 다시 여는 일이 있었기 때문입니다). 정리를 시작할 때는 직전 정리가 건너뛴 구간과 그 이유를 이어받습니다 — 「가장 오래된 것부터」를 기계적으로 적용하면 방금 살펴본 자리를 다시 열게 됩니다. 정리할 때는 "조건이 오면 검토" 류(관측되면·근거가 생기면·데이터가 쌓이면)를 폐기하고 같은 뿌리의 항목을 하나로 묶습니다 — 그 조건이 실제로 충족되는 날이 곧 새로 등재될 시점이기 때문입니다. 이 둘이 없으면 미뤄둔 목록은 한 방향으로만 자라 아무도 끝까지 읽지 않게 됩니다.
「그 자리에서 고칠 수 있는 것」에는 계획에 없던 파일도 들어갑니다. 계획을 세울 때는 존재조차 몰랐던 문제가 작업 도중 드러나 판정을 그르치는 일이 있는데, 그것을 「계획 밖」이라는 이유로 미루면 간단한 수정도 다음 회차로 밀립니다. 다만 아무 때나 열리지는 않습니다 — 이번 작업이 그 결함 때문에 실제로 틀렸고, 그 사실이 "판정자가 그 자리에서 스스로 만들 수 없는 기록"(검토자의 지적문·검증 명령 출력·이미 커밋된 기록)에 남아 있어야 합니다. 고치고 싶은 것을 그 자리에서 스스로 정당화하는 길은 막혀 있습니다.
계획할 때 여는 것은 대기 목록 하나입니다. 대장이 커지면 계획 세션마다 그 전부가 컨텍스트에 실립니다 — 그래서 기각 종결분과 회차 기록을 별도 파일로 갈랐습니다. 조회·등재는 대기 파일 하나이고, 나머지 둘은 기각 이력을 찾거나 지난 정리 회차를 승계할 때만 열립니다.
같은 항목이 두 번 올라오지 않습니다. 등재 전 대조가 주제 그룹 안에서만 이뤄져 같은 건이 두 그룹에 나란히 남은 적이 있어, 대조 범위를 목록 전체로 넓혔습니다. 재확인 기록도 세 번을 넘으면 최신 하나만 남기고 나머지는 한 줄로 묶습니다 — 같은 결론이 반복되면 항목만 길어집니다.
판정에 쓰는 명령은 필요한 만큼만 출력합니다. 출력은 도구가 돌려주는 순간 컨텍스트에 들어가므로 나중에 요약해도 늦습니다. 다만 줄여서 잃는 것이 있으면 채택하지 않습니다 — 커밋 목록을 제목만 남기는 축약은 검증이 그 본문을 읽기 때문에 쓰지 않습니다.
계획서의 작업들이 서로를 무효화하는지 검토합니다. 앞 작업의 결과가 뒤 작업의 전제를 깨거나, 뒤 작업이 앞서 만든 것을 되돌리는 경우를 승인 전에 잡습니다. 여러 작업이 같은 값을 갱신할 때 그 순서가 적혀 있는지도 함께 봅니다.
계획서에 적는 판정 명령은 미리 한 번 돌려 봅니다. "이 검색 결과가 0건이면 통과"처럼 명령으로 완료를 판정하는 조건을 계획에 적을 때, 그 명령을 계획을 쓰는 시점에 실제로 실행해 현재 몇 건인지 함께 적습니다. 돌려보지 않고 기대값만 적으면 구조적으로 그 값이 나올 수 없는 조건을 완료 기준으로 박게 되고, 그때는 작업을 제대로 해도 통과하지 못하거나 반대로 아무것도 안 해도 통과합니다. 현재값을 함께 적으면 "원래 그랬던 것"과 "이번에 그렇게 만든 것"도 구분됩니다.
끝난 항목은 보관 이유가 있을 때만 남습니다. 구현된 것·다른 항목에 흡수된 것은 근거가 이미 커밋에 있으므로 대장에서 지우고, 기각한 것만 남깁니다 — 기각은 "아니라고 판단했다" 는 결론이라 대장 밖에 근거가 없고, 지우면 같은 항목이 다음 회차에 다시 올라와 같은 조사를 반복하게 됩니다. 지울 때는 항목마다 대응 커밋을 지목해야 하고, 지목하지 못하면 지우지 않습니다 — 근거가 정말 커밋에 있는지는 항목을 봐야 알 수 있고, 전제가 안 맞는 항목만 남기는 것이 이 확인의 목적입니다. 정리하다 항목을 조용히 잃는 일을 막기 위해 지운 개수를 누계로 기록해 전체 등재 수와 맞춰보는 절차도 함께 됩니다.
안전장치 (항상 작동)
작업 흐름과 별개로, 위험한 명령은 자동으로 차단됩니다. 이건 끌 수 없습니다.
- 파일 전체 삭제(
rm -rf /·rm -rf ~/*등 홈·시스템 루트와 그 내용물 글롭), git 히스토리 파괴 - DB 데이터 삭제·변조: 전체 삭제(
DELETEWHERE 없이), 전체 변조(UPDATEWHERE 없이),DROP/TRUNCATE, ORM 대량 삭제 등 - 단,
WHERE 조건이 있는 일상적인 DB 작업은 그대로 통과합니다
단순 작업은 빠르게
모든 작업에 거창한 절차를 강제하면 오히려 불편합니다. 그래서 3줄 이내의 단순 수정은 계획 없이 바로 처리합니다:
- UI 문구·라벨 변경, 색상·아이콘 교체
- 오타·주석 수정
- 단일 라인 설정·리소스 변경
기준은 "3줄 이내 + 새 함수/구조 추가 없음 + 의도가 명확"입니다. 이 경우에도 다른 파일에 영향이 가면 자동으로 알려줍니다.
주요 기능
Skills (작업을 수행하는 능력)
| 기능 | 언제 작동하나 | 무엇을 하나 |
|---|---|---|
| 계획 수립 | "기능 추가", "구현" 등 | 코드 변경 전 계획 + 검토 + 요구 확정(이해한 요구를 승인 시 재진술하고 intent/에 남긴다) |
| 구현 | 계획 승인 후 자동 | 모든 task를 끝까지 자동 진행 |
| 디버깅 | "버그", "에러", "안 됨" 등 | 근본 원인을 찾는 체계적 디버깅 |
| 위키 운영 | "위키에 등록/업데이트" | 프로젝트 지식을 쌓고 다음 작업 때 참조 |
| 프로젝트 사실 기록 | "AGENTS.md에 기록" 또는 hook 제안 수락 | 빌드·DB·테스트 방식을 AGENTS.md에 축적(재확인 줄이기) |
Subagents (검토 담당)
작업을 직접 하는 Claude와 별개의 검토자 둘이 결과를 점검합니다. 작성자와 검토자를 분리해 "자기 일을 자기가 검토하는" 맹점을 줄입니다.
| 검토자 | 모델 | 언제 | 무엇을 |
|---|---|---|---|
| plan-reviewer | Sonnet | 계획 완성 후 1회 | 계획이 실측 위에 서 있는지 — 조사 기록의 명령 열이 비었는지, 적힌 명령이 그 주장을 낼 수 있는지, 위키를 읽었거나 건너뛴 기록이 있는지, 읽은 함정이 계획·구현 어느 자리로든 갔는지, 바꿀 심볼의 호출자가 파일 목록에 다 있는지 |
| completion-reviewer | Opus | 모든 task 완료 후 1회 | 계획 전체와 최종 상태의 대조 — 요구가 산출물에 나타났는지, 완료 표시가 진실인지, 성공 기준을 직접 재봤을 때 참인지 |
호출은 이 두 곳뿐입니다. task마다 검토자를 부르지 않습니다 — Claude Opus 5는 지시 없이도 자기 작업을 검증하므로, 그 위에 검토 단계를 얹으면 비용과 시간만 배가 되고 품질은 오르지 않습니다(Anthropic 프롬프팅 가이드의 권고).
검토 흐름의 규칙:
- 검토자는 읽기만 합니다 — 두 정의 모두
Write·Edit·NotebookEdit이 제거돼 있고, 지적을 반영하는 것은 Claude 본체입니다. 검토와 수정의 주체를 나눠야 "자기가 쓴 것을 자기가 통과시키는" 경로가 막힙니다. - 심각도로 걸러 내지 않습니다 — 검토 프롬프트에 "중요한 것만 보고하라"를 넣으면 모델이 문자 그대로 따라 더 적게 보고합니다. 전부 보고하게 하고, 무엇을 고칠지는 호출한 쪽이 정합니다.
- 확신이 낮은 지적도 냅니다 —
(판정 유보)표시를 붙여 배출하되, 근거를 대지 못하는 인상만 남는 지적은 적지 않습니다. - 계획 질문의 추천(★)은 질문당 하나, 근본 해결에 — 쉽게 끝나는 선택지가 아니라 문제가 사라지는 선택지에 붙습니다.
- 검토자가 호출되지 않는 환경이면 그 사실을 보고에 적고 진행합니다 — 리뷰 부재를 통과로 적지 않습니다.
Hooks (자동 안전망)
당신이 신경 쓰지 않아도 자동으로 작동하는 장치들입니다.
- 위험한 명령 차단 (끌 수 없음)
- 하니스 안전장치(hook) 자체를 코드로 개조·무력화하는 시도 차단 (끌 수 없음 — 설치된 hook 스크립트·설정을 조작하지 못하게 함). 지우는 것도 막습니다 — 판정 규칙을 담은 파일을 지우면 그것을 읽던 안전장치가 함께 꺼지므로, 고치는 것만 막아서는 절반만 잡는 셈입니다. 판정에 쓸 규칙 파일을 읽지 못하면 그 사실을 화면에 알립니다 — 조용히 통과하면 안전장치가 꺼진 것을 아무도 모릅니다. 이 판정은 설치된 위치에만 적용되므로, 이 플러그인을 직접 개발하는 저장소에서는 정상 작업이 막히지 않습니다.
- AGENTS.md에 거기 있으면 안 되는 것이 들어가는 것 차단 — 매 세션 전문이 주입되는 파일이라 진행 상태·인계 서술이 쌓이면 주입 상한을 넘겨 그 세션이 명령도 금지선도 못 보게 됩니다. 막는 것은 둘입니다: ① plan 진행 상태·"다음 작업"·"다음 회차" 같은 인계 서술(헤딩·볼드 제목 형태일 때만 — 본문에 스쳐 지나가는 표현은 통과) ② 디렉터리 트리(구조는 위키가 정본). 진행 상태는
plan.md, 끝난 회차는 git 커밋, 프로젝트 구조는 위키로 안내합니다. - 외부 작업(push·릴리즈·패키지 배포) 경고 — 무엇을 외부 작업으로 볼지는 규칙 파일이 정본이라 판정 목록을 코드가 아니라 그 파일에서 고칩니다. 규칙 파일을 읽지 못하면 이 경고만 꺼지고 그 사실을 화면에 알립니다(차단 안전망은 계속 동작합니다).
- 커밋 직전 변경 내용에서 시크릿 감지 (커밋 직전 최종 방어선). 자격증명으로 보이는 값은 커밋을 차단하고, 오탐 여지가 있는 나머지(API 키·비밀번호 값·토큰·IP·
.env스테이징)는 경고만 한다 — 공개 저장소에 한 번 올라간 자격증명은 이력에서 회수할 수 없기 때문.git add를 같은 명령에 붙여 보내도(git add -A && git commit) 아직 스테이징되지 않은 새 파일까지 미리 검사한다. 이미 추적 중인 파일은 새로 추가되는 라인만 검사한다(이력에 이미 있는 내용은 재신고하지 않음 — 시크릿 예시·탐지 규칙을 다루는 파일이 커밋마다 다시 걸리는 오탐 방지).- 차단 대상 (구체적으로): ① 개인키 블록 ② DB·서비스 접속 URI에 아이디·비밀번호가 박힌 형태 ③ 아이디/비밀번호 쌍 — 계정 관련 라벨(한글·영문) 뒤에 인용부호로 감싼 두 값이 온 형태. 한 줄에 슬래시로 이어 쓴 것뿐 아니라 라벨과 값이 줄을 나눠 적힌 것(콜론 두 줄·표의 라벨-값 행 두 개)도 포함합니다 ④ DB 연결 문자열 — 서버 키 뒤 어느 자리에 자격증명 키가 오든, 그 키를 띄어 쓴 표기까지 잡습니다(한 줄 안에서만 성립).
- 한 번에 너무 많은 파일을 커밋하면 차단합니다 —
git add로 미리 검사하는 파일이 50개를 넘으면 나머지를 검사하지 못하는데, 검사하지 못한 파일에 자격증명이 있어도 통과하므로 그 상태로는 커밋을 막습니다(시크릿은 하나만 새어도 이력에서 회수할 수 없기 때문). 커밋을 나눠 한 번에 50개 이하로 스테이징하면 그대로 진행됩니다. 실제로 이 경계에 닿는 커밋은 드뭅니다. - 차단하지 않고 경고만 하는 것: 인용부호 없는 평문 쌍, API 키·토큰·IP·
.env스테이징. 오탐이 곧 작업 중단이라 차단은 확실한 것만 합니다 — 나머지는 경고와 코드 검토자가 잡습니다. 값이 순수 숫자이거나 상태·오류 코드 나열(ERR_401 / ERR_402류)이면 자격증명으로 보지 않습니다. - 값 자리에 「값」이 아니라 「참조」를 적었으면 차단하지 않습니다 — 환경변수 표기(
$env:…·${…}·%…%), 코드 조회(process.env.…·os.environ[…]), 설정 키 경로(appsettings:Db:Pwd), 「환경변수 …로 지정」 같은 안내 문구. 차단 메시지 자신이 *"값을 지우고 환경변수 이름만 남기라"*고 안내하므로, 그 안내를 따른 문서가 다시 막히면 안 됩니다. - 오탐 시 우회는 사용자만 설정한다(
CLAUDE_HARNESS_ALLOW_SECRET=1, Claude Code 시작 전 터미널에서)
- 계획서를 스크립트로 고치는 것 차단 — 계획서는 git이 추적하지 않아 잘못 쓰면 되돌릴 수단이 없습니다. 실제로 절을 바꾸는 스크립트가 파일 대부분을 지운 적이 있고, 그때 계획서를 읽는 검사들이 읽을 것이 없어진 채 통과했습니다. 그래서 계획서를 쓰는 명령만 막고 읽는 명령은 그대로 둡니다 — 읽어서 다른 파일로 내보내는 것도 통과합니다. 판정은 「그 명령이 무엇을 쓰려 하는가」이지 「명령에 계획서 이름이 나오는가」가 아닙니다(후자면 대장에서 그 이름이 든 줄을 지우는 정상 작업이 막힙니다). 명령을 조각으로 나눌 때 따옴표 안의
;·|는 구분자로 보지 않습니다 — 그러지 않으면sed -i "s|a|b|" 계획서처럼 따옴표 안에 구분자를 쓴 형태가 조각을 어긋나게 만들어 그대로 새어 나갑니다. 도구가 PowerShell이면\를 글자 그대로 읽어 Windows 경로("C:\")가 조각내기를 깨뜨리지 않습니다. - 저장 직후 줄바꿈이 규약과 다르면 경고 — 편집 도구는 줄바꿈을 LF로 쓰는데 이 저장소의 작업 트리 규약은 CRLF라, 저장한 자리에서 알려 줍니다. 되돌릴 수 있는 문제라 차단이 아니라 경고이고, 줄바꿈이 테스트 입력인 폴더는 대상에서 뺍니다.
- 계획 없이 코드 쓰는 것 방지
- AGENTS.md(프로젝트 가이드)는 계획을 세울 때 최소 골격으로 생성 (저장 전 전문을 보여주고 승인을 받음)
- task 완료 커밋 전 계획서 체크박스 갱신 강제 (완료 표시 없이 완료 커밋을 하려 하면 차단 — 계획서와 실제 진행이 어긋나는 것 방지)
- 파일 인코딩·줄 수 검사, 그리고 편집 직후 민감정보 경고 (파일을 저장할 때마다 검사합니다. git이 추적하는 파일은 아직 커밋하지 않은 추가분만 보므로, 이미 커밋된 예시·픽스처가 매번 다시 경고되지 않습니다 — 시크릿 규칙이나 예시를 설명하는 문서가 자기 자신을 계속 신고하는 문제를 없앤 것입니다. 다만 새로 적은 내용은 커밋하기 전까지는 저장할 때마다 알려주고, 아직 git에 없는 새 파일이나 git이 무시하는 파일은 종전처럼 전체를 검사합니다)
- 변경이 영향을 주는 곳 자동 경고
- 자율 루프가 중간에 멈추는 것은 스킬 문면이 막습니다 — 기계는 그 판정을 하지 않습니다. 정지 의도는 어휘가 아니라 「도구 호출 없이 말만 하고 turn을 끝냈다」는 사실에 있는데, 한국어 어미 조합이 무한해 정규식이 수렴하지 않습니다. 멈추는 네 형태는
plugins/pjc/skills/implement/references/loop-stop-patterns.md에 있습니다. - 빌드·테스트·DB 명령 실행 시 AGENTS.md에 기록 제안 (다음 작업 때 재확인을 줄임 — 승인 시에만 기록)
- 세션 시작·재개·컨텍스트 요약 직후에 plan.md 진행 상태·위키 vault 설정 상태·AGENTS.md 전문을 자동 주입 (대화가 길어져 요약되면 Claude가 읽었던 작업 규칙의 뒷부분이 사라지는데, 요약 직후에는 루프 제어 규칙의 원문을 그대로 실어 줍니다 — 작업 중이면 "언제 멈추고 무엇을 별도로 승인받는가"에 해당하는 두 절을 규칙 문서에서 잘라 넣고, 계획 중이면 계획의 절대 규칙 원문 · 승인 직후에 쓰는 위키 큐 기록 규약을 같은 방식으로 실어 주고, 위키 조회 절차는 원문 대신 그 파일의 경로 한 줄을 알려 줍니다(조회 절차가 전용 문서로 분리돼 그 파일 하나만 읽으면 끝나므로, 요약으로 확보한 여유를 원문으로 도로 쓰지 않습니다) 직전 작업이 끝난 계획서가 남아 있는 상태도 계획 중으로 봅니다) (AGENTS.md가 주입 한도에 가까워지면 넘기기 전에 알리고, 넘겼으면 큰 절을 별도 문서로 옮기는 방법을 함께 안내합니다 — 한도를 넘으면 그 세션은 프로젝트 가이드를 통째로 잃습니다) (위키 vault는 설정·실재하면 그 경로를, 설정됐으나 폴더가 없으면 그 사실을 1줄로 알립니다 — 미설정이면 아무것도 표시하지 않습니다. Claude가 "위키가 없다"고 짐작해 참조를 건너뛰는 것을 막기 위한 장치로, 위키를 쓰지 않는 프로젝트에는 표시되지 않습니다. 이 알림은 프로젝트 성격·구조가 필요할 때 어디를 먼저 읽을지도 함께 지시합니다 — AGENTS.md의
## 위키절이 지목한 허브 1개. 계획·구현 스킬을 발동하지 않는 간단한 수정·질문 세션에서도 프로젝트 맥락을 코드 대신 위키에서 얻게 하려는 것입니다) (AGENTS.md는 프로젝트 가이드 정본 — 16KB 이하면 전문, 초과 시 섹션 목차 + 전문 Read 지시로 폴백. 요약 직후엔 규약 재확인 리마인더 포함 — 긴 자율 루프의 규칙 유실 방지). (위키가 밀렸으면 그 프로젝트에서 작업을 시작할 때 한 줄로 알립니다 — 위키 허브가 기록해 둔 시점 이후 코드에 쌓인 커밋 수, 허브를 마지막으로 갱신한 뒤 지난 날짜, 그리고 "위키와 코드가 어긋난다"고 발견해 두고 아직 반영하지 않은 항목 수를 세어, 30커밋·14일·1건 중 하나라도 넘으면 표시합니다. 이 신호는 종전에 위키 작업 세션에서만 보여서, 정작 그 프로젝트를 고치고 있는 세션에는 닿지 않았습니다 — 알림을 받아야 할 사람에게 가지 않는 셈이라 위키가 조용히 뒤처졌습니다. 알리기만 하고 반영은 하지 않습니다 — 무엇을 지우고 무엇을 남길지는 사람이 정해야 하는 판단이라, 반영은 "위키 업데이트"라고 말할 때 별도 세션에서 합니다). 위 주입이 경로 지목에서 원문 발췌로 올라간 이유는 — 스킬은 요약 후 앞부분만 재부착되고 다시 불러도 복구되지 않는데, 경로만 알려 주면 실제로 읽었는지 확인할 방법이 없고 지목한 문서를 다 읽으면 요약으로 확보한 여유를 도로 쓰기 때문입니다. 위키 조회 절차만 그 반대로 되돌린 것은 그 절차가 전용 문서로 분리돼 「다 읽어도 그 파일 하나」가 됐기 때문이고, 나머지 셋(루프 제어 두 절·계획 절대 규칙·큐 기록 규약)은 여전히 원문을 싣습니다 - 끝나지 않을 검색 경고 —
find / …처럼 최상위 폴더 전체를 훑는 명령은 도구 시간 제한(10분) 안에 끝나지 않습니다. 제한에 걸리면 명령을 띄운 셸만 종료되고 검색 자체는 백그라운드에서 계속 돌아 CPU를 먹습니다(실제로 12개가 15~20시간 동안 코어 3개를 점유한 적이 있습니다). 실행 전에 이를 알려 범위를 좁히도록 유도합니다 — 막지는 않으므로 정말 필요하면 그대로 진행됩니다.find . …처럼 범위가 정해진 검색은 경고하지 않습니다. - 위험한 경로를 변수에 담아 지우는 명령 경고 —
X=/처럼 최상위·홈 경로를 변수에 넣은 뒤 그 변수를 삭제 명령에 쓰면(rm -rf $X), 위 「위험한 명령 차단」은 값이 변수를 한 번 거쳐서 잡지 못합니다(문자열을 실행해 보지 않는 방식의 한계라 의도적으로 남겨 둔 사각입니다). 그 형태를 실행 전에 알립니다 — 막지는 않으므로 의도한 명령이면 그대로 진행됩니다. 같은 명령줄 안에서 대입한 경우만 봅니다(앞선 명령에서 만든 변수·명령 결과를 담은 변수는 대상 밖).X=./build처럼 상대 경로·하위 폴더를 담은 정상 정리 명령은 경고하지 않습니다. - 남겨진 콘솔 프로세스 자동 정리 — 위처럼 부모가 사라졌는데 혼자 남아 CPU를 먹는 프로세스(
more·find)를 세션을 시작할 때·세션을 닫을 때 자동으로 정리합니다. 화면에는 아무것도 표시하지 않고 이벤트 로그에만 기록하므로, 무엇이 정리됐는지는 그 로그를 읽어 확인합니다. 살아 있는 창이 쓰는 중인 프로세스는 건드리지 않습니다. - 하네스 레포에서만 — 미뤄 둔 일감(Deferred 대장)의 잔량과 「가장 오래 방치된 항목」을 1줄로 알림. 다음에 하기로 미룬 항목들은 계속 쌓이는데, 그 대장을 언제 한 번 비울지를 정하는 기준 중 하나가 가장 오래 판정을 안 받은 항목이 며칠 됐는가입니다. 그 날짜를 사람이 손으로 세다가 같은 오산이 두 번 났습니다(항목마다 재확인 기록이 여러 개인데 그중 가장 최근 것을 봐야 하는 걸 놓쳤습니다) — 이제 기계가 세어 세션 시작에 알려 줍니다. 값을 재는 규칙은 대장 규약이 정본이고, 규칙과 다르게 처리하는 부분(릴리즈 번호로만 적힌 기록)이 있으면 그 건수도 함께 표시해 그 항목만 사람이 확인하게 합니다.
- 하네스 레포에서 세션을 시작하면 설치본과 레포의 플러그인 버전이 다를 때 자동 경고 (재설치 전까지 세션이 구버전으로 동작한다는 혼동 제거)
명령 실행 시 작동하는 안전망들은 한 프로세스로 묶여 실행돼 반응이 빠릅니다(도구 호출당 PowerShell 기동 2회). 위험 명령 차단(끌 수 없는 마지막 방어선)은 다른 안전망과 분리해 독립 실행하므로, 통합의 영향을 받지 않습니다. 통합 검사 모듈이 로드에 실패하면(설치 손상 등) 조용히 통과하는 대신 경고를 표시해, 안전망이 꺼진 상태를 바로 알 수 있습니다.
커밋 직전 참고 문서 낡음 고지: git commit 을 실행하면, 하니스가 참고하는 문서가 실제와 어긋나 있는지 그 자리에서 알려 줍니다 — 골든 케이스 수·버전처럼 기계가 대조할 수 있는 값은 check-harness-consistency.py --fix 로 갱신되고, 산문 서술·외부 사실처럼 기계가 잴 수 없는 것은 「이번 커밋이 이 축을 건드렸다」로 고지만 합니다(단 외부 사실 축은 마지막 확인 표기가 90일을 넘었거나 표기가 없을 때만 뜹니다). 위키가 레포보다 몇 커밋 뒤에 있는지도 같은 자리에서 나옵니다. 차단이 아니라 경고입니다.
차단/경고 이벤트 로그 (오탐 리뷰용): hook이 차단·경고를 낼 때마다 발생 시점·hook 이름·발동 규칙·명령 요약이 ~/.claude/.state/hook-events/{YYYY-MM}.jsonl에 1줄씩 쌓입니다(90일 지난 파일은 자동 정리). 정상 작업이 자꾸 차단·경고되는 것 같으면 Claude에게 "hook 이벤트 로그에서 최근 차단 내역 검토해줘"라고 요청하세요 — 오탐 수정이 추측이 아니라 실측 데이터 기반이 됩니다. 명령에 시크릿이 감지되면 그 명령 원문은 로그에 기록하지 않으며(안전 우선), 로깅이 실패해도 차단·경고 동작에는 영향이 없습니다.
쌓인 로그는 그 jsonl 을 직접 읽어 집계합니다 — Claude에게 "hook 이벤트 로그 집계해줘"라고 하면 됩니다(전용 도구는 없습니다).
자주 쓰는 명령
대부분 자동으로 작동하지만, 직접 부를 수도 있습니다:
| 이렇게 말하면 | 이게 작동합니다 |
|---|---|
| "기능 추가", "리팩토링", "구현" | 계획 수립 |
| "버그", "에러", "안 돼" | 디버깅 |
| "위키에 등록/업데이트" | 위키 운영 |
위키 연동 (선택 기능)
프로젝트 지식을 쌓아두고 재사용하는 기능입니다. 쓰려면 먼저 위키 폴더를 설정해야 하며, 설정하지 않으면 이 기능만 비활성화될 뿐 나머지 pjc 기능은 정상 작동합니다.
설정 방법 (최초 1회)
위키를 처음 쓸 때 폴더를 한 번만 지정하면 됩니다:
"이 프로젝트 위키에 등록해줘" ← 이렇게 요청하면
↓
"LLM WIKI 폴더 경로를 알려주세요" ← Claude가 경로를 물어봄
↓
경로 입력 (예: D:\MyWiki 또는 기존 Obsidian vault 경로)
↓
설정 완료 — 이후 다시 묻지 않음
- 설정한 경로는 PC의 개인 설정 파일(
~/.claude/llm-wiki-config.json)에 저장됩니다. plugin을 업데이트해도 유지되며, 위키 내용도 plugin 밖 폴더에 있어 안전합니다. - 위키 폴더를 옮기거나 삭제하면, 다음 사용 때 Claude가 새 경로를 다시 물어봅니다.
- 위키 폴더가 git으로 관리되지 않으면, Claude가 기존 파일을 수정·삭제하기 전에 사본을 위키 안 백업 폴더(
90_archive/backup/{날짜}/)에 남깁니다 (이전 날짜 사본은 다음 실행 때 자동 정리 — 단 삭제된 프로젝트 백업과 복구 직전 사본은 유일한 사본이라 보존합니다). 잘못 갱신됐을 때 "위키 되돌려줘"라고 요청하면 이 백업으로 복구합니다 (차이를 보여주고 확인 후 되돌림 — 복구 직전 상태도 별도로 백업해 복구 자체를 되돌릴 수 있습니다). - git 관리 중인 폴더면 사본을 아예 만들지 않습니다 — 페이지 분할·자동 수정·복구처럼 여러 파일을 한 번에 바꾸는 작업 직전에 커밋을 하나 남겨 그 지점이 되돌림 기준이 됩니다. 되돌릴 때는 그 작업이 손댄 파일만 되돌리므로, 같은 시간에 Obsidian에서 손으로 편집하신 것은 영향받지 않습니다. 그 커밋에 실패하면 작업을 시작하지 않고 알립니다 — 되돌릴 기준이 없는 채로 고치지 않기 위해서입니다. 다만 커밋이 하나도 없으면 git 복구가 불가하므로, 그때는 git이 아닌 폴더로 보고 사본을 남깁니다.
- 폴더를 지정하지 않으면 위키 참조·저장 단계는 그냥 건너뜁니다 (계획·구현·검증은 정상 진행).
무엇이 기록되나 (큐 태그)
- 스킬 개선 큐 ([SKILL-IMPROVE]): 어느 프로젝트에서든 pjc 스킬을 쓰다 스킬 자체의 결함·불편을 발견하면 위키의 전용 파일(
skill-feedback.md— 다른 대기 항목과 섞이지 않게 따로 둡니다)에 1줄 기록합니다. 아무거나 적지 않고 세 조건을 모두 만족할 때만 기록합니다 — ① 스킬 규약 자체의 문제인가(그 프로젝트만의 사정이 아니라) ② 고칠 지점을 짚을 수 있는가 ③ 실제로 작업이 막혔거나 되돌리게 됐거나 같은 일을 반복하게 됐는가. 기록된 항목은 하니스 플러그인 작업을 시작할 때 자동으로 조회되고(계획 단계), 세션을 열면 대기 건수와 가장 오래된 항목의 경과일이 한 줄로 표시됩니다 — 쌓아만 두고 잊지 않게 하기 위함입니다. 위키를 설정하지 않았으면 묻지 않고 건너뛰며, 대신 그 프로젝트의 plan.md에 기록해 유실을 막습니다. - 결정 이력 ([DECISION]): 기획 대화·계획 승인·구현 완료 때 정해진 결정(채택·보류·기각·번복)을 대기 목록에 기록해 두면, 구현이 끝나는 시점에 그 프로젝트의 결정 이력(
decisions.md)으로 자동 반영됩니다(별도 위키 세션을 열 필요가 없습니다 — 다만 다른 프로젝트 항목이거나 위키에 아직 등록되지 않은 프로젝트처럼 사람의 판단이 필요한 경우는 대기 목록에 남겨 두고 그 사유를 알려줍니다). 다음 계획을 세울 때 Claude가 이 이력을 먼저 확인해 예전에 보류·기각한 기획을 모르고 다시 논의하는 일을 막습니다. "이 기능 언제 넣었지 / 왜 안 하기로 했지" 같은 질문도 이 이력으로 답합니다. - 프로젝트 작업 사실 ([PROJECT-FACT]): 그 프로젝트에서 작업할 때 알아야 할 규약·주의사항(예: "버전 올리면 곧바로 릴리즈 발행")을 대기 목록에 기록해 두면, 구현이 끝나는 시점에 그 프로젝트의 작업 규약 파일(
conventions.md)로 자동 반영됩니다(결정 이력과 같은 방식 — 사람의 판단이 필요한 경우만 대기 목록에 남습니다). 단 특정 프로젝트가 아니라 기술·도구에 딸린 사실(예: "이 라이브러리는 이렇게 쓰면 조용히 실패한다")은 그 프로젝트의 규약 파일이 아니라 기술 지식·레시피 쪽으로 안내되며, 어디에 둘지는 확인을 거쳐 정합니다. 작업을 시작할 때 Claude가 이 파일을 읽어오므로, PC를 바꾸거나 Claude 메모리가 지워져도 프로젝트 작업 지식이 유실되지 않습니다 (Claude 메모리는 PC 로컬 — 프로젝트 사실은 위키에, 빌드·테스트 명령 같은 레포 귀속 사실은 AGENTS.md에, 개인 선호만 메모리에 저장하는 역할 분담). - 증상별 인덱스 ([SYMPTOM]): 디버깅에서 근본원인이 확정되면 "증상 → 검증된 원인 → 해법 페이지" 매핑이 위키에 쌓입니다. 비슷한 증상을 다시 만나면 이 인덱스를 진입점으로 씁니다 — 다만 행의 원인은 그 사례에서 검증된 것이므로 가설로만 쓰고, 원인 확정은 현재 코드·증거로 합니다. 미검증 실패("A를 시도했으나 안 됨")는 저장하지 않습니다.
- 나머지 셋은 손댈 것이 없습니다 ([K-DRIFT]·[K-MISS]·[K-ROUTE]): 대기 목록(
pending.md)에 쌓이는 것은 위의 [DECISION]·[PROJECT-FACT]·[SYMPTOM] 셋과 이 셋을 합한 여섯 가지입니다 — 위키가 코드를 따라오지 못한 자리([K-DRIFT]), 위키에서 찾아봤는데 없던 지식([K-MISS]), 절 제목만으로는 어느 대목을 읽을지 못 정해 문서를 통째로 읽은 자리([K-ROUTE])입니다. 셋 다 고칠 대상이 위키 자신이라 다음 위키 세션이 알아서 소비하며, 사용자가 판단하실 것은 없습니다. 대기 목록 파일을 직접 열었을 때 모르는 표시로 보이지 않도록 이름만 적어 둡니다.
쌓인 지식을 다루는 방식
- 재사용 지식 우선: 위키를 갱신할 때마다 "다른 프로젝트가 쓸 지식이 나왔는가"를 먼저 판정합니다. 원인·기전이 그 프로젝트의 스택·코드에 종속되지 않으면 한 프로젝트에서 겪은 것이어도 범용 패턴으로 올려 두고, 판단이 애매하면 그 프로젝트 안에만 남깁니다. 프로젝트별 기록은 코드가 바뀌면 낡지만 이렇게 올린 지식은 낡지 않습니다.
- 등록 안 된 프로젝트는 등록합니다: 계획을 세울 때 그 프로젝트가 위키에 없으면 묻지 않고 등록합니다(프로젝트 페이지를 만들어 성격·기술 스택·구조를 담습니다). 미등록으로 두면 그 프로젝트는 매번 코드를 다시 분석해야 하기 때문입니다. 대기 목록에 쌓인 지식은 저장소 주소(URL)를 함께 적어 프로젝트 이름이 바뀌어도, 위키를 여러 PC에서 함께 쓰더라도 대상을 잃지 않습니다.
- 등록하지 않는 것: 참고용으로 clone해 둔 남의 저장소입니다. 내 커밋이 하나도 없으면 참고용으로 보고 건너뜁니다(git 저장소이고 스택 표식 파일이 있어야 한다는 조건도 함께 봅니다). 표식이 없는 프로젝트(셸 스크립트 모음·문서 저장소)도 자동 등록되지 않으므로 직접 요청하면 됩니다.
- 어느 PC에서 열어도 같은 프로젝트로 알아봅니다: 위키는 프로젝트를 저장소 주소로 식별합니다. 예전에는 폴더 경로로 알아봤는데, 위키를 여러 PC에서 함께 쓰면 경로가 서로 달라 다른 PC에서는 못 알아보는 문제가 있었습니다. 저장소 주소는 PC가 바뀌어도, 폴더 이름을 바꿔도, 프로젝트 이름을 바꿔도 그대로입니다. 저장소 안이라면 하위 폴더에서 세션을 열어도 알아봅니다. (폴더 경로도 계속 적어 두지만, 그건 그 PC에서 파일을 직접 확인해야 하는 점검에만 씁니다.)
- 뒤처짐 표시: 위키 페이지가 저장소를 따라오지 못한 상태면 그 페이지 맨 위에 경고 한 줄을 답니다. 점검 도구는 몇 커밋이 밀렸는지도 함께 알려 줍니다. 작업 전에 위키를 참고할 때는 경고가 달려 있지 않아도 Claude가 직접 재어 확인합니다 — 경고를 다는 것은 사람·Claude의 판단이라 빠질 수 있고, 그때 그 페이지를 여는 쪽이 낡은 줄 모른 채 읽는 것을 막기 위함입니다.
- 위키 사용 기록: 계획 때 위키에서 무엇을 읽고 그것이 어느 작업의 주의사항으로 들어갔는지, 구현 중 실제로 그 주의사항에 걸렸는지를 회차마다 1줄씩
docs/plans/wiki-usage.md에 남깁니다. 여러 회차가 쌓이면 이 파일만 보고 「위키를 읽고만 있는지 · 실제로 도움이 되는지」를 판정할 수 있습니다. - 공용 레시피 역방향 갱신: 여러 프로젝트가 공유하는 기능 레시피를 한 프로젝트에서 개선하면, 위키 갱신 때 그 개선이 공용 레시피에도 반영됩니다 (프로젝트마다 제각각 진화해 위키가 갈라지는 것 방지).
- 질문 답변 개선: 위키에 질문하면 원문 나열이 아니라 결론 요약 → 상세 → 출처 순으로 정리해 답하며, 시간·이력 질문("그동안 무슨 변화가 있었지")은 결정 이력·최근 변경·작업 로그를 시간순으로 합성해 답합니다.
파일이 커지면 (자동 정리)
- 파일이 커지면 스스로 나눕니다: 위키 페이지·기록 파일이 정해둔 크기에 닿으면 점검 도구가 직접 정리합니다 — 오래된 결정·작업 기록은 보관 폴더로 옮기고, 긴 문서는 가장 큰 절의 본문을 하위 문서로 옮긴 뒤 그 자리에 "정본은 여기" 안내 한 줄을 남깁니다. 내용을 요약하거나 지우지 않고 위치만 옮기며, 옮기기 직전 사본을 남겨 되돌릴 수 있습니다. 나눴다는 사실을 알리지 않습니다 — 승인을 묻지 않으니 결정할 것이 없고, 무엇이 만들어졌는지는 위키 기록에 남습니다. 알리는 것은 나누기에 실패했을 때뿐입니다(그 페이지는 크기에 막힌 채 남습니다).
- 크기·분할 이야기는 사용자에게 나오지 않습니다: 도구가 나눌 수 있는 파일이든, 나눌 경계가 없어 Claude가 직접 손대야 하는 파일이든(작업 규약처럼 항목만 길게 이어진 문서가 그런 경우입니다) 전부 알아서 처리하고 조용히 넘어갑니다. 크기 경고는 Claude가 읽고 처리하는 신호이지 사용자가 결정할 것이 아니라서, 「한도까지 몇 % 남았다」·「다음엔 나눠야 한다」를 보실 일이 없습니다.
- 옮긴 자리를 못 찾는 일이 없게: 안내 줄이 가리키는 문서와 그 안의 절 이름까지 실재하는지 점검합니다 — 파일만 확인하면 「옮겼는데 못 찾는」 상태가 그대로 통과합니다.
- 긴 절에는 소제목을 권합니다: 한 절이 통째로 길면 필요한 대목만 읽을 수 없으므로, 소제목이 하나도 없는 큰 절을 알려줍니다(정보 안내 — 자동으로 고치지는 않습니다).
- 프로젝트 안내 문서가 커지면 옮깁니다:
AGENTS.md가 세션 주입 상한에 닿으면 큰 절을 다른 문서로 옮기고 그 자리에 안내 한 줄을 남깁니다. 빌드·테스트 명령과 금지 항목은 항상 그 파일에 남습니다 — 세션이 그것을 잃으면 빌드도 못 하고 금지선도 모릅니다. 그 파일에 남을 절이 대부분이라 옮길 것이 없을 때는 「AGENTS.md 정리해줘」로 절 안을 줄이는 경로를 안내합니다 — 명령·값은 남기고 "왜 그런가" 는 상세 문서나 위키로 보냅니다. 이 정리는 지우는 것을 포함하므로 무엇을 어디로 보낼지 계획을 먼저 보여 주고 승인을 받은 뒤에만 실행합니다.
사용 흐름
1. (설정 후) "이 프로젝트 위키에 등록해줘"
→ 프로젝트를 분석해 지식 정리
2. 이후 작업할 때 (자동)
→ 계획·디버깅 단계에서 위키의 과거 기록을 참조
→ "예전에 비슷한 걸 했었지" 하고 재조사를 줄임
3. 작업 끝나면
→ 위키에 남길 내용(기능 변경·개선 교훈)이 있으면 반영할지 물어봄
위키는 Obsidian 같은 마크다운 기반 도구로 열어볼 수 있는 폴더 구조입니다. 기존 vault를 그대로 써도 됩니다. 위키 형식은 공개 지식 표준인 OKF(Open Knowledge Format) v0.2와 정합하도록 만들어져(번들 경계·버전 선언·한 줄 요약 필드), 나중에 다른 도구·조직과 지식을 교환하기 쉽습니다.
인덱스는 자동으로 만들어지고, 첫 화면은 얇게 유지됩니다. 위키 첫 화면의 목록(프로젝트·기능·가이드·지식·미해결 질문)은 각 문서에 적힌 정보에서 파생되므로 손으로 맞출 필요가 없습니다. 기능·가이드 목록은 개인/업무/가이드별 파일로 나뉘어 있어, 첫 화면을 통째로 읽지 않고 필요한 목록에서 검색어로 바로 찾습니다(한글·영문 어느 쪽으로 찾아도 걸립니다). 손으로 쓴 구역(증상별 인덱스 등)은 생성 표시 밖에 있어 그대로 보존됩니다.
백업은 자동으로 정리됩니다. 위키 폴더가 git 저장소가 아니면 수정 전 사본을 남기는데, 그 사본이 무한히 쌓이지 않도록 이전 날짜 것을 다음 실행 때 걷어냅니다(삭제 백업과 복구 직전 사본은 유일 사본이라 남깁니다). git 저장소면 사본 대신 작업 직전 커밋이 그 자리를 대신하므로 쌓일 것이 없습니다.
위키 폴더가 git 저장소면 변경을 자동으로 커밋합니다. 작업이 끝날 때마다 커밋하고 세션 끝에 한 번 올립니다 — 위키는 다른 작업 중에 부수적으로 갱신되는 곳이라 매번 물으면 하던 일이 끊기기 때문입니다(코드 저장소는 종전대로 확인을 거칩니다).
위키 작업 중에도 화면에는 한 줄만 나옵니다. 어느 작업이 무엇을 대상으로 도는지(예:
📚 위키: B(ingest) — 프로젝트명)만 표시하고, 무엇을 왜 고치는지 설명하거나 읽은 내용을 요약하지 않습니다. 대신 작업이 끝나면 바뀐 파일마다 한 줄씩 무엇을 어떻게 바꿨는지 정확히 알려줍니다 — 진행 중에 줄인 만큼 완료 보고가 더 정확해집니다. 삭제·복구 확인처럼 답을 받아야 하는 질문과 대기 목록 잔량 보고는 그대로 나옵니다.
기능 문서마다 "관련 파일" 지도(그 기능을 구성하는 파일 목록)를 기록해, 기능 이름으로 검색하면 관련 파일에 바로 도달합니다. 코드 작업 중 위키와 코드가 어긋난 걸 발견하면 위키의 대기 목록(pending)에 남겨 다음 위키 갱신 때 자동으로 챙기고, 위키 점검(lint)은 링크·분량·인덱스 동기·파일 경로 실존·시크릿 유입 등 30여 항목을 기계적으로 검사합니다. 분량은 곧 막힐 상태가 됐을 때 한 번만 경고합니다 — 여유가 얼마 남지 않은 문서만 알려 정작 급한 문서가 알림 더미에 묻히지 않게 합니다. 그 경고를 받으면 위키 세션이 승인을 묻지 않고 그 자리에서 처리합니다 — 문서 종류에 따라 하위 문서로 나누거나 오래된 내용을 보관 위치로 옮기며, 어느 쪽이든 요약해 줄이지 않고 옮깁니다. 착수 직전 사본을 떠 두어 실패하면 되돌린 뒤 무엇을 어디로 옮겼는지 보고합니다. 나눌 하위 주제가 없어 쪼갤 수 없는 문서는 그 판정을 문서에 적어 경고를 멈추되, 상태는 계속 보이고 그 뒤로 내용이 더 늘면 판정이 풀려 다시 알립니다.
더 알아보기 (고급)
작업 흐름 상세 다이어그램
사용자 요청
↓
[계획] 당신과 함께
- 컨텍스트 수집 (AGENTS.md 없으면 최소 골격 생성)
- 영향 범위 전수 조사
- task 분해 (T1, T2, …) + 작업 유형 분류
- 검토자의 적대적 검증
- 사용자 승인 1회 ✋
↓
[구현] 끝까지 자동
각 task 반복:
- 영향받는 곳 사전 추적
- 최소 변경 구현
- 유형별 검증 (작은 건 빠르게, 큰 건 철저하게)
- 저장 후 즉시 다음 task
↓
[통합 검증]
- 전체 빌드 + 테스트
- 완료 검토자의 최종 점검
↓
최종 보고 ✋
작업 유형별 검증 깊이
작업의 위험도에 따라 검증 강도를 다르게 합니다 — 작은 변경은 빠르게, 큰 변경은 철저하게.
| 유형 | 예 | 검증 |
|---|---|---|
| 문서/설정 | .md, .json |
최소 |
| 단순 코드 | 한 파일·한 메서드 | 가벼운 검토 |
| 일반 코드 | 2-3 파일, 호출처 갱신 | 표준 검토 |
| 복잡/광범위 | 다중 파일, 시그니처 변경 | 전체 검토 |
공식 Claude Code 기능과의 관계
pjc는 Claude Code 내장 기능을 대체하지 않고 보완합니다.
/code-review, /security-review: pjc는 작성 중 계획 준수를 검증하고, 공식 기능은 PR 단계에서 버그·보안을 점검합니다. 둘 다 쓰면 이중 점검이 됩니다.
권장 흐름: pjc로 작성·검증 → PR 생성 → 공식 /code-review로 재점검
AGENTS.md란
프로젝트의 빌드·테스트 명령과 규칙을 담은 파일입니다. pjc가 작업할 때 이 파일을 참조합니다. 없으면 생성을 제안하며, 직접 작성할 수도 있습니다.
pjc는 특정 언어 전용이 아닙니다. 빌드·테스트 명령은 한 번 실행해 통과한 것만 적으므로 언어를 가리지 않고, 확인하지 못한 값은 비워 둡니다 — 추측치를 미리 박아 넣지 않는 쪽이 다음 세션을 오도하지 않습니다. pjc의 계획·검증·자율 루프도 언어를 가리지 않습니다.
생성된 AGENTS.md는 그대로 써도 동작하지만, 프로젝트 스타일에 맞게 다듬으면 더 좋은 성능을 냅니다. 빈 칸을 채우고 프로젝트 고유의 규칙·함정·컨벤션을 추가할수록 Claude가 추측을 줄여 더 정확하게 작업합니다. 빌드·테스트 명령으로 시작해 점진적으로 보강하는 것이 기본 동작이며, 빌드·테스트·DB 명령을 실행할 때마다 기록 제안이 따라옵니다.
설치 관리
# 업데이트
claude plugin marketplace update pjc-harness
claude plugin update pjc@pjc-harness
# 제거
claude plugin uninstall pjc
claude plugin marketplace remove pjc-harness
로컬 개발 모드 / 배포 워크플로
개발용으로 로컬 폴더에서 직접 쓰거나, 수정 후 GitHub에 배포하려면:
# 로컬 설치 (개발용)
.\install.ps1
# GitHub 모드 일괄 설치 (정리 + enable + 검증)
.\install.ps1 -GitHub jongcheol-pak/claude-harness-pjc
# 배포 (개발 PC에서 수정 후)
git add -A && git commit -m "변경 내용" && git push
# → 사용 PC에서 위의 "업데이트" 명령 실행
구버전 캐시 회수
/plugin update는 버전마다 ~/.claude/plugins/cache/pjc-harness/pjc/<버전>/ 을 새로 만들고 예전 것을 지우지 않아 캐시가 단조 증가합니다. -PruneCache가 오래된 버전 폴더를 회수합니다.
# 열거만 — 한 바이트도 지우지 않고 대상 버전·파일 수·크기만 보여준다
.\install.ps1 -PruneCache
# 실제 회수 (-ConfirmPrune 이 있어야 지운다)
.\install.ps1 -PruneCache -ConfirmPrune
# 보존할 최신 버전 수를 바꾼다 (기본 3)
.\install.ps1 -PruneCache -KeepVersions 5 -ConfirmPrune
보존 대상은 「최신 N개」에 더해 레포 plugin.json의 현행 버전과 Claude Code가 기록한 설치본 버전이며, 뒤의 둘은 -KeepVersions가 작아도 빠지지 않습니다 — 지금 돌고 있는 세션의 hook이 설치본 폴더에 살아 있어, 지우면 그 세션의 안전장치가 통째로 사라집니다. 둘을 따로 세는 것은 갈리기 때문입니다 — 버전을 올린 뒤 /plugin update 전까지 레포가 설치본보다 앞섭니다. -KeepVersions의 하한은 1이고, 레포 plugin.json을 읽지 못하면 열거도 하지 않고 멈춥니다.
회수한 구버전이 다시 필요하면 GitHub 태그에서 재설치합니다.
트러블슈팅
plugin 명령이 안 보여요
Claude Code를 재시작하거나 /reload-plugins를 실행하세요. 그래도 안 되면 claude plugin enable pjc@pjc-harness로 활성화 상태를 확인하세요.
안전장치(hook)가 너무 자주 막아요
하니스의 hook은 항상 켜져 있어 끌 수 없습니다. 정상 작업인데 막혔다면, 계획(plan)을 먼저 만들거나 명령을 더 구체적으로(예: 삭제 명령에 WHERE 조건 추가) 바꾸면 통과합니다. 위험한 명령 차단(파일 삭제·DB 삭제 등)은 안전을 위한 것이니, 정말 필요한 작업이면 더 좁은 범위로 나눠 실행하세요.
다음 정상 작업들은 계획 없이 통과합니다 — 임시 폴더 정리(
$env:TEMP\...하위 —Join-Path로 조립한 하위 폴더 경로 포함), 프로젝트 내 단일 파일chmod +x, 현재 폴더 상대 정리(Get-ChildItem . -Recurse | ...), 상위 폴더 정리(rm -rf ../build류), 테스트/재현용 신규 파일(tests/·repro*, 30줄 이하), 마크업·스타일 파일(.xml/.html/.css). 위험 차단(홈·시스템 삭제, DB 파괴 등)은 그대로이며, 여기에 경로가 상위로 올라가기만 하다 끝나는 형태(..가 연달아 이어져 드라이브 루트에 닿는 것)와 루트 전체 글롭이 포함됩니다.알려진 한계: 인자가 3개 이상인 경로 조립(
Join-Path a b c)은 아직 커버하지 않아 막힐 수 있습니다 — 그때는 경로를 한 문자열로 이어 쓰면 통과합니다.
한글이 깨져요
PowerShell 인코딩 문제일 수 있습니다. pjc의 모든 스크립트는 UTF-8(BOM)로 저장되어 있으니, Claude Code와 터미널이 UTF-8을 쓰는지 확인하세요.
호환 환경
pjc는 두 부분으로 나뉘며, OS 의존성이 다릅니다.
| 구성 | OS 의존 | 설명 |
|---|---|---|
| Skills · Subagents (계획·구현·디버깅·검증 로직) | OS 무관 | 지침(markdown)이라 어디서나 동작 |
| Hooks (위험 명령 차단·권한/보안 변경 차단·외부 작업(push·릴리즈) 경고·민감정보 경고·plan 강제 등 자동 안전망) | pwsh 7 우선·5.1 폴백 | hook 스크립트는 Claude Code가 띄운 PowerShell에서 직접 실행(자식 셸 재기동 없음). 실행 셸은 Claude Code의 powershell 해석을 따르며(실측: pwsh 7 있으면 pwsh 우선), 스크립트는 내장 powershell.exe(5.1) 호환을 유지; macOS/Linux는 pwsh 7 |
| 항목 | 지원 |
|---|---|
| OS | Windows 10/11: 완전 지원·검증. macOS/Linux: pwsh 7 설치 시 동작하도록 구현됐으나 실제 환경 미검증(실험적) |
| 런타임 | Windows: 추가 설치 불요 — 실행 셸은 Claude Code가 결정(실측: pwsh 7 있으면 그쪽 우선), 스크립트는 내장 powershell.exe(5.1) 호환 유지. macOS/Linux: pwsh 7 필요(brew install powershell 등) |
| Claude Code | 최소 v2.0 · 권장 v2.1.269+ — --filter 이름 검증과 골든 러너 병렬 모드가 안정된 판이다. 미만에서도 동작하나 부분 실행 필터가 조용히 0건을 돌 수 있다 |
| 대상 언어 | 모든 언어 동작 — .NET, Android, Node/TS, Python, Go, Rust는 표식 파일로 자동 감지·자동 설정. 그 외(Flutter·Swift·Java·C++·Ruby 등)는 빌드/테스트 명령만 입력하면 동일하게 작동 |
요약: 자동 안전망(hook)은 OS에 무관하게 동작하도록 구현됐습니다. Windows는 검증 완료 — pwsh 7이 있으면 그쪽에서, 없으면 내장 powershell.exe(5.1)에서 동작해 추가 설치 없이 안전망이 항상 동작합니다. macOS/Linux는 pwsh 7 필요·실험적(미검증) 입니다(
brew install powershell등).
설계 철학
- 재작업 방지 > 토큰 절약: 검증에 드는 비용은 잘못 만든 걸 다시 만드는 비용보다 쌉니다.
- 계획은 함께, 구현은 자동: 방향은 사람이 정하고, 실행은 Claude가 끝까지.
- 확실한 안전망: 검토는 확률적이지만, 위험 명령 차단 같은 hook은 결정적으로 작동합니다.
라이선스
MIT
-
v1.300.0 Latest
6시간 전분할이 만든 비계를 예산 판정에서 뺀다.
-
v1.299.0
9시간 전축 ⑩ 「핵심 포인터 실재」가 리터럴 문면의 실재도 잰다.
-
v1.298.0
10시간 전하니스 스킬의 삭제 후보 34곳 제거와 1곳 통합.
-
v1.297.0
11시간 전20260918 스킬 전수 검토가 낸 결함 중 v1.296.0 이 닫지 않은 나머지와, 정본이 서로를 가리키던 갈림 넷을 고쳤다.