에이전트 여럿에게 일을 시킬 때, 기능 하나에 이슈를 몇 개 만드는가.
안 A 계층마다 이슈를 만든다. 부모 1 + 기획·프론트·백엔드·테스트 4 = 5개
안 B 기능당 이슈 하나만 만든다. 계층은 그 이슈 안의 진행 단계다
안 A는 계층마다 상태와 담당이 트래커에 보인다. 누가 어디서 멈췄는지가 목록에 그대로 뜬다.
대신 사람이 기능 하나를 따라가려면 문서 다섯 개를 오가야 한다. 그리고 개정 전 표준이 배정을 낱개로, 커밋 전 확인을 티켓마다 하게 했으므로 이슈 개수가 그대로 사람 개입 횟수가 된다.
기능 1개 → 이슈 5개 → 배정 4회 + 커밋 확인 4회 = 개입 8회
기능 10개 → 이슈 50개 → 개입 80회
이 글은 안 B를 고른 기록이고, 동시에 이 표준을 두 번 갈아엎은 기록이다. 1차에서 이슈를 하나로 합쳤고, 2차에서 그 하나에 무엇을 어떤 문장으로 쓸지, 그리고 그 하나가 얼마나 커도 되는지를 정했다. 그리고 2026-10-24에는 두 개정 아래 깔려 있던 전제를 뒤집었다(「먼저」 절). 뒤집은 이유와 그때 같이 무너진 규칙들이 아래에 있다.
먼저: 에이전트는 사람 없이도 만들고, 넘기는 일만 사람이 있을 때 한다
이건 원칙이 아니라 전제다. 처음 세운 전제는 반대였고, 2026-10-24에 뒤집었다. 옛 전제와 그 이유를 지우지 않고 남긴다 — 옛 이유는 지금도 맞는데, 그런데도 왜 뒤집었는지를 같이 봐야 새 전제가 설명된다.
처음 전제는 「에이전트는 사람이 있을 때만 돈다」였다. 무인 운영을 하지 않기로 하면 설계해야 할 것이 통째로 사라졌다.
밤·주말에 락이 걸린 채 방치되면? → 그 시간에 아무것도 안 돈다
에이전트가 죽은 걸 어떻게 감지하나? → 죽으면 사람이 본다
일감이 생긴 걸 어떻게 알아채나? → 사람이 배정할 때 안다
폴링도 웹훅도 하트비트도 필요 없었다. 대가는 야간과 주말에는 처리량을 벌 수 없다는 것이었고, 그 대가를 감수한 이유는 사람이 인지 못 한 채 굴러간 프로젝트를 되돌리는 비용이, 늦어지는 비용보다 크다는 것이었다.
뒤집은 계기는 사람의 시간이 하루 두 시간뿐이라는 것이다. 내가 퇴근 뒤에 하는 프로젝트에는 평일 20~22시에만 사람이 붙는다. 처음엔 그 두 시간 안에서 에이전트를 돌리는 구조를 세웠다 — 진행 중인 이슈는 하나만 두고, 22시 안에 닫을 크기만 연다. 그때 내가 짚었다. 에이전트를 쓰는 이유는 사람이 손대야 하는 부분만 사람이 하고, 나머지는 에이전트가 혼자 하게 하려는 것이다. 두 시간 동안 에이전트가 끝나기를 기다리면, 사람에게 하나뿐인 시간이 기다림으로 샌다.
그래서 사람이 하는 일을 「넘기는 일」로 좁혔다.
| 사람 없이 해도 된다 (만드는 일) | 사람이 있을 때만 한다 (넘기는 일) |
|---|---|
| 브랜치 · 커밋 · 푸시 · PR 열기 | PR 병합 |
| 테스트 · 기계 확인 | 운영 배포 |
| 디자인 시안 · 카드 · 영상 · 글 | 디자인 · 마케팅 컨펌, 플랫폼 게시 |
| 이슈에 댓글 달기 | 이슈 상태 전환 |
| 기획 |
왼쪽의 커밋 · 푸시 · PR은 사람이 일을 맡기면서 거기까지 요청했을 때만 사람 없이 한다. 요청받지 않았으면 지금처럼 커밋 직전에 멈춘다(원칙 11).
오른쪽은 대부분 결과물이 다음 사람이나 바깥으로 건너가는 순간이다. 병합하면 여럿이 같이 쓰는 통합 브랜치로, 게시하면 고객에게, 완료로 바꾸면 트래커를 보는 팀원에게 넘어간다. 기획은 건너가는 순간은 아니지만 사람과 함께 만드는 일이라(원칙 5) 같은 칸에 넣었다. 그래서 이 글에서 「넘기는 일」은 이 여섯을 가리킨다. 사람의 두 시간에는 이것만 하고, 끝날 때 다음 일을 맡긴다.
옛 전제를 세운 이유는 지금도 맞다. 다만 그 비용을 다른 방법으로 묶었다. 사람이 모르는 채 굴러간 프로젝트를 되돌리는 비용은 세 가지로 막는다.
- 기획은 사람과 함께 만든다(원칙 5). 에이전트는 사람과 정한 계약만 실행한다
- 계약 밖의 일을 만나면 멈추고 묻는다(위상 표준 원칙 5)
- 넘기는 일은 사람이 있을 때만 한다. 병합 · 배포 · 게시 · 상태 전환처럼 명령으로 하는 것은 사람이 정하고, 손은 사람과 말하는 유일한 에이전트인 마스터가 움직인다. 일하는 에이전트의 워크트리 안에서는 훅이 그 명령을 막는다(위상 표준 원칙 21). 컨펌과 기획은 사람과 나누는 대화라 막을 명령이 없으므로 규칙으로 지킨다
그러면 틀렸을 때 잃는 것이 그 밤에 맡긴 브랜치들과 하룻밤치 토큰으로 묶인다. 병합 전이라 통합 브랜치는 그대로이고, 브랜치를 버리면 끝난다.
뒤집어도 옛 전제가 없애 준 것은 다시 생기지 않았다. 같은 세 질문에 답이 바뀌었을 뿐, 폴링도 하트비트도 여전히 필요 없다.
밤·주말에 락이 걸린 채 방치되면? → 잠글 것이 없다. 파일을 잠그던 목록은 원칙 15에서 없앴다
에이전트가 죽은 걸 어떻게 감지하나? → 사람의 시간이 시작될 때 마스터가 찾는다
일감이 생긴 걸 어떻게 알아채나? → 여전히 사람이 맡길 때 안다. 스스로 집지 않는다
락은 한 에이전트가 파일을 쥐고 다른 에이전트가 못 들어오게 막는 장치다. 그런 목록 자체가 없으므로, 밤새 멈춘 에이전트가 남을 막는 일도 없다. 멈춘 채 기다리는 동안에는 토큰도 쓰지 않는다(위상 표준 원칙 16). 죽은 에이전트를 찾는 자리는 위상 표준 원칙 17이다.
대가는 둘이다. 하나는 밤새 틀린 방향으로 간 브랜치를 다음 날 버리면 그 밤의 토큰이 통째로 사라진다는 것이다. 그래서 맡기는 양을 다음 날 두 시간 안에 검토할 수 있는 양까지로 묶는다. 「22시 안에 닫을 크기」가 에이전트가 일하는 시간을 사람의 두 시간에 맞췄다면, 이것은 사람이 검토하는 양만 맞춘다. 무엇으로 그 양을 셀지(이슈 수인지 계약 수인지)는 정하지 않았다 — 맡기는 사람이 다음 날 두 시간을 떠올리며 고른다. 다른 하나는 규칙을 지켜보는 사람이 없다는 것이다. 그래서 명령으로 하는 넘기는 일은 글로 적는 것만으로는 안 되고 훅으로 박는다. 그 훅도 실수를 막을 뿐, 작정한 우회까지는 못 막는다.
뒤집으면서 같이 버린 안이 셋 있다. 「진행 중인 이슈는 하나만 둔다」, 「22시 안에 닫을 크기만 연다」, 그리고 두 시간 안에 닫으려면 큰 기능을 잘게 쪼개야 하니 「원칙 2(기능이 커도 기본은 쪼개지 않는다)를 고친다」였다. 셋 다 「에이전트가 사람의 두 시간 안에서 돈다」를 전제로 세운 안이라, 그 전제와 함께 버렸다. 원칙 2는 고치지 않았다.
옛 전제는 「사람이 있어야만 도니, 일은 사람이 감당할 수 있는 모양이어야 한다」로 두 개정을 이끌었다. 이슈 다섯 개는 감당되지 않아 하나로 합쳤고(1차), 서식 없는 이슈 하나도 감당되지 않아 절과 문장을 정했다(2차). 사람이 넘기는 일만 하는 지금도 그 말은 그대로다 — 사람은 다음 날 두 시간 안에 그 일을 검토할 수 있어야 한다.
원칙 1. 기능 하나에 이슈 하나만 만든다
정해야 했던 건 이거였다 — 이슈를 무엇의 단위로 만드는가.
안 A — 계층마다 만든다. 부모 이슈 하나에 기획·프론트·백엔드·테스트 이슈를 매단다. 얻는 것은 상태와 담당이 트래커에 그대로 보이는 것이다. 어느 계층에서 멈췄는지를 목록만 보고 안다. 그리고 아직 시작하지 않은 계층에도 다른 계층이 정보를 남길 자리가 미리 생긴다.
버린 이유는 사람이 기능 하나를 따라가려면 문서 다섯 개를 오가야 하는 것이다. 그리고 그 다섯이 각자 다른 시점에 쓰였으므로, 읽는 사람은 매번 문맥을 처음부터 다시 세운다. 기능이 열 개면 이슈가 쉰 개고, 그때부터는 목록을 여는 것 자체가 일이 된다.
골랐다 — 안 B, 기능당 이슈 하나. 안 A가 못 지켜주는 것은 사람이 보는 단위와 일의 단위가 같다는 것이다. 기능 하나를 알고 싶으면 문서 하나만 열면 된다.
기획 → 개발 → 테스트
이 순서가 곧 의존이다. 트래커에 의존을 적지 않는다 — Jira 링크와 GitHub 텍스트는 표현이 달라서, 둘 다 지원하면 어댑터가 갈리고 갈리는 순간 한쪽만 고쳐진다. 적을 곳이 없으면 어긋날 곳도 없다.
대가는 트래커가 진행 상태를 덜 보여주는 것이다. 이슈 하나가 “지금 개발 중”인지 “테스트 중”인지는 목록에 안 뜬다. 그건 댓글을 열어야 안다(원칙 10).
원칙 2. 기능이 커도 기본은 쪼개지 않고 계약 개수로 신호만 띄운다
원칙 1이 「기능 하나에 이슈 하나」로 못 박았는데 그 기능의 크기를 정한 규칙이 없었다. 지금까지 정한 것들이 상한을 네 방향에서 이미 누르고 있는데도, 숫자가 없어서 어긴 것을 아무도 몰랐다.
기획이 닫을 때 계약을 다 쓴다 → 한 번의 대화로 다 뽑히는 크기여야 한다
작업 세션 하나가 기획과 개발 → 세션 하나가 감당하는 크기여야 한다
댓글이 다섯 줄을 안 넘는다 → 세 줄로 요약되는 크기여야 한다
PR 하나에 테스트까지 얹는다 → 오래 안 열려 있을 크기여야 한다
위 네 번째 줄의 PR은 내 브랜치에서 고친 내용을 통합 브랜치에 합쳐 달라고 요청하는 것이다.
안 A — 상한을 넘으면 기획을 못 닫게 막는다. 얻는 것은 큰 이슈가 확실히 안 생기는 것이다. 버린 이유는 기능 축으로 쪼갤 수 없는 기능이 왔을 때 억지로 쪼개게 되는 것이다. 그 억지 쪼개기가 원칙 3이 금지하는 모양이 된다.
골랐다 — 안 B, 막지 않고 묻는다. 계약 개수가 기준을 넘으면 에이전트가 「쪼갤까요」를 묻고 사람이 답한다. 기본값은 「그대로 간다」다. 원칙 1이 이슈를 다섯에서 하나로 줄인 이유가 “이슈 개수가 곧 개입 횟수”였고, 쪼개는 것은 그 방향을 되돌리는 일이라 웬만하면 안 한다.
ai-map.rb(이 저장소의 글 섹션 색인을 만드는 도구. 코딩 스탠다드 글에서 1,000 토큰 넘는 섹션이 있으면 막지 않고 목록으로만 알려준다)가 1,000 토큰 넘는 섹션을 막지 않고 목록으로 알려주는 것과 같은 모양이다 — 크기가 문제라서가 아니라 「기능이 둘 섞였을 수 있다」는 신호라서다.
세는 것을 계약 개수로 한 이유는 그 시점에 셀 수 있는 게 그것뿐이라서다.
| 후보 | 기획이 닫는 순간에 아나 |
|---|---|
| 계약 개수 | 안다. 방금 쓴 것이다 |
| 세션이 감당할까 | 모른다. 해봐야 안다 |
| 사람이 읽을 diff | 모른다. 기획은 코드를 읽지 않는다 |
| 배포 단위인가 | 주관적이라 판정이 안 선다 |
계약 개수가 작업량의 대리 지표가 되는 것은 원칙 7이 「한 줄 = 한 검증 항목」으로 단위를 정규화해뒀기 때문이다. 정규화가 없었으면 못 쓸 지표였다. 테스트를 짜지 않는 설정 계약(원칙 12)도 똑같이 센다 — 만드는 작업량은 같고, 배포 때 사람이 확인하는 일도 검증이다.
세는 시점이 기획이 닫기 직전인 것도 우연이 아니다. 아직 안 닫혔으므로 본문을 갈라도 원칙 8(추가만 허용)에 안 걸린다. 닫는 순간부터 불변이 시작된다.
기준 숫자는 project.yml의 split_ask_at에 두고(원칙 17), 설치 템플릿의 값은 15다. 15는 2026-10-21에 처음 정한 값이다. 그 전까지 이 원칙에는 숫자가 없었다 — 「재본 값이 아니다. 설치 템플릿의 값은 임의값이고, 돌려보고 고친다」고만 적혀 있었다. 그때 값을 비워 두는 안도 있었지만 비어 있으면 아무도 안 채우고, 이 규칙이 안 돈다는 것조차 안 보여서 버렸다.
그런데 2026-10-21에 열어 보니 그 버린 모양이 실제로 일어나 있었다. 설치 템플릿(install.sh · install.ps1)에는 「임의값」은커녕 이 키가 아예 없었고, 표준을 깐 두 프로젝트의 project.yml에도 없었다. 키가 없는 것은 값이 빈 것과 같은 모양이다. 규칙은 「기준을 넘으면 묻는다」인데 기준이 어디에도 없으니 지금까지 한 번도 울릴 수 없었고, 안 돈다는 것이 안 보여서 아무도 몰랐다.
그래서 값을 정해야 했다. 근거로 쓸 수 있는 것은 한 프로젝트의 계약 enum 28개였다. 그 프로젝트는 기능 하나의 계약을 enum 하나에 상수 한 줄씩 적으므로, enum 하나의 상수 개수가 곧 그 기능에 쌓인 계약 수다. 28개 enum의 상수 개수를 줄 세우면 이렇다.
0 1 2 2 4 4 4 5 6 7 7 8 8 9 9 9 11 11 12 | 24 24 24 25 26 29 34 38 43
12와 24 사이가 비어 있다. 작은 쪽 열아홉 개와 큰 쪽 아홉 개가 뚜렷하게 갈리고, 15는 그 빈 구간 안에 든다. 15로 두면 큰 쪽 아홉 개에서만 묻고 작은 쪽에서는 한 번도 안 묻는다.
한계가 있다. 이 숫자는 이슈 하나의 계약 수가 아니라 기능 하나에 지금까지 쌓인 계약 수다. 여러 이슈에 걸쳐 쌓였으니 이슈 하나로 보면 더 작았을 것이고, 그래서 15는 넉넉한 값일 수 있다. 그래서 고칠 근거를 같이 모은다 — 물을 때마다 「몇 개에서 물었고 사람이 쪼갰나」를 그 이슈의 [기획 완료] 댓글에 한 줄로 남긴다(원칙 10). 이 기록은 프로젝트마다 흩어지므로 집계는 표준 저장소의 별도 이슈([coding-standards#7](https://github.com/TaegyuHan/coding-standards/issues/7))에서 한다. 각 프로젝트가 물을 때마다 그 이슈에 같은 한 줄을 댓글로 달고, 댓글이 열 개가 되면 그 이슈에서 다시 본다. 물었는데 거의 안 쪼갰으면 올리고, 15 아래에서도 쪼개자는 말이 나오면 내린다.
대가가 하나 더 있다. 설치기는 project.yml을 없을 때만 만든다(원칙 17). 그래서 이미 설치된 프로젝트에는 템플릿을 고쳐도 키가 들어가지 않는다. 그 프로젝트가 직접 넣어야 한다.
원칙 3. 쪼갤 때는 기능 축으로만 자르고, 못 자르면 큰 채로 간다
쪼개기로 했으면 어디를 자르느냐가 남는다. 축이 하나뿐이다.
// 자르면 안 되는 축 — 순서가 생기는데 적을 곳이 없다
이슈 A: 주문 취소 API → 이슈 B: 주문 취소 화면
// 자르는 축 — 아무거나 먼저 해도 된다
이슈 A: 주문 취소 | 이슈 B: 부분 취소
계층으로 자르면 B는 A가 끝나야 시작할 수 있다. 그런데 원칙 1이 순서를 트래커에 적지 않기로 했으므로 적을 곳이 없고, 사람이 B를 먼저 배정해도 아무도 안 막는다. 배정받은 에이전트는 API가 없는 채로 화면을 만들다 막힌다.
둘을 가르는 검문은 새로 만들지 않았다. 원칙 12가 「테스트 세션은 자기 이슈의 계약만 읽는다」로 이미 정해뒀으므로 거기서 그대로 나온다.
이 이슈의 테스트를 이 이슈의 계약만으로 짤 수 있는가.
화면 이슈의 계약은 “취소 버튼을 누르면 취소된다”인데 백엔드가 없으면 테스트가 안 돌아 걸린다. 부분 취소는 자기 코드만으로 돌아 통과한다. 다른 후보였던 「각각 따로 배포할 수 있는가」는 배포의 뜻이 프로젝트마다 달라 판정이 흔들려서 버렸다 — 기능 플래그를 쓰면 화면 이슈도 배포 가능이 된다.
기능 축으로 못 자르면 자르지 않는다. 억지로 계층으로 자르면 아무도 모르는 순서가 생기는데, 그건 큰 이슈 하나보다 나쁘다. 대가는 원칙 2의 네 상한을 어긴 이슈가 그대로 남는 것이다.
쪼갠 상대는 서로의 「범위 밖」에 이름만 적는다.
## 범위 밖
- 부분 취소
- 관리자 강제 취소
새 자리를 만들지 않은 것이다. 원칙 6의 「범위 밖」이 원래 하던 일이고, 테스트 세션도 그 절을 읽으므로 없는 기능을 검증해서 실패로 올리는 일이 같이 막힌다.
이슈 번호는 적지 않는다. 번호를 적으면 그건 이슈 간 링크이고, 원칙 1이 피한 자리에 발을 걸친다. 대신 그 이슈를 찾으려면 사람이 트래커에서 검색해야 한다.
원칙 4. 나누는 것은 세션이지 이슈가 아니다
이슈를 합치면 곧바로 따라오는 질문이 있다 — 그러면 계층을 나눈 것은 무엇이었나.
계층을 나눈 근거를 다시 읽으면 전부 「문맥이 섞이면 안 된다」이지 「이슈가 따로여야 한다」가 아니었다.
| 나눈 자리 | 근거 | 실제로 요구하는 것 |
|---|---|---|
| 요구와 설계 | 갈려야 검증자가 생긴다 | 판단 주체 분리 |
| 개발과 테스트 | 같은 세션이면 자기가 만든 것에 맞춘 테스트가 나온다 | 세션 분리 |
이슈를 넷으로 쪼갠 것은 그 분리를 트래커에 표현하려다 나온 부산물이었다. 에이전트 종류가 넷이라 이슈도 넷이 됐고, 사람은 넷을 따라가게 됐다.
그래서 세션과 이슈를 따로 정한다.
| 세션 | 맡는 계층 |
|---|---|
| 작업 세션 | 기획 → 개발 |
| 테스트 세션 | 테스트 |
안 A — 계층마다 세션도 따로 연다. 넷을 그대로 유지한다. 버린 이유는 넘길 때마다 다음 세션이 읽을 것을 써야 하는 것이다. 그 쓰기 비용이 이슈를 장황하게 만든 원인이었다. 그리고 판단 주체가 넷이면 전환 지점도 넷이라, 이슈만 합쳐도 사람이 멈추는 횟수는 그대로다.
골랐다 — 안 B, 세션 둘. 기획과 개발은 판단 주체를 가를 이유가 없다. 요구와 설계를 갈랐던 것은 프론트가 요구를 내고 백엔드가 설계할 때의 얘기였고, 기획은 원래 API를 설계하지 않는다. 한 세션이 앞에서 사람과 기획을 만들고 뒤에서 그대로 개발한다.
대가는 개발이 기획 의도를 그대로 물려받는 것이다. 기획을 되돌아보게 만들 제3자가 세션 안에 없다. 그 자리를 사람이 든다(원칙 5·9).
원칙 5. 기획은 사람과 에이전트가 대화로 만든다
에이전트가 혼자 기획을 만들지 않는다. 사람에게 묻고 답을 받아 함께 만든다.
이 규칙이 다른 것들과 성격이 다르다. 개발과 테스트에서 사람은 검문관이지만, 기획에서는 저자다.
| 단계 | 사람의 역할 |
|---|---|
| 기획 | 같이 만든다 — 묻고 답하고 생각을 맞춘다 |
| 개발 | 확인한다 (커밋 전. 밤에 맡긴 일은 PR에서) |
| 테스트 | 확인한다 (커밋 전. 밤에 맡긴 일은 PR에서) |
안 A — 에이전트가 초안을 만들고 사람이 고친다. 얻는 것은 사람이 백지에서 시작하지 않는 것이다. 검토가 창작보다 싸다.
버린 이유는 초안이 그대로 굳는 것이다. 에이전트가 채운 빈칸은 근거 없이 그럴듯한데, 사람은 그걸 검토 대상이 아니라 배경으로 읽는다. 그리고 기획 의도는 에이전트의 소유 범위 밖이라, 채워 넣은 순간 소유 범위를 넘은 것이다.
골랐다 — 안 B, 대화로 만든다. 안 A가 못 지켜주는 것은 채워진 빈칸과 정해진 것을 구별하는 일이다. 물어서 답을 받으면 그건 정해진 것이고, 안 물었으면 아직 안 정해진 것이다. 경계가 흐려지지 않는다.
이건 「막히면 사람에게 올린다」를 앞쪽 끝까지 민 것이다. 그 규칙은 막혔을 때 올리게 하는데, 이 원칙은 막히지 않아도 애초에 혼자 시작하지 못하게 한다.
대가는 기획이 자동화 대상에서 빠지는 것이다. 개입 횟수만 보면 이게 제일 무겁다. 그 계산은 원칙 11에 있다.
묻는 방식은 2026-10-24에 정했다. 대화로 만든다고 정해 두자 다음 문제가 드러났다 — 사람이 타이핑하는 시간이다. 에이전트가 「어떻게 할까요?」처럼 열린 질문을 던지면, 사람이 답을 처음부터 써야 한다. 하나뿐인 저녁 두 시간이 답을 쓰는 데 샌다. 그래서 에이전트가 판단을 먼저 세우고, 예/아니오나 2~3개 중 고르기로 묻는다. 「직접 입력」과 「더 쉽게 설명하기」는 그 2~3개와 따로 늘 붙는다. 기획이 뚜렷해질 때까지 이렇게 좁혀 간다.
// 이렇게 묻지 않는다
취소 알림은 어떻게 할까요?
// 이렇게 묻는다
제 판단: 취소 알림은 이번 범위 밖으로 둡니다. 결제 취소와 따로 실패할 수 있어서입니다.
1. 범위 밖으로 둔다 이번 기능이 작아진다. 알림은 다음 기능에서 정한다
2. 이번에 같이 만든다 알림이 실패할 때의 계약까지 이번에 써야 한다
3. 직접 입력
4. 더 쉽게 설명하기
첫째는 열린 질문이라 사람이 답을 처음부터 써야 한다. 둘째는 에이전트가 판단과 이유를 먼저 내놓았으므로, 사람은 번호 하나로 답한다. 판단이 틀렸으면 2번을 고르고, 둘 다 아니면 3번에 직접 쓴다. 질문 자체가 이해되지 않으면 4번을 골라 더 쉽게 다시 쓰게 한다. 선택지마다 「고르면 무엇이 되는가」를 붙이는 것과 3번 · 4번은 위상 표준 원칙 6의 선택지 서식에서 가져왔다. 이 원칙이 더하는 것은 맨 앞의 「제 판단」 한 줄이다. 위상 표준을 쓰면 묻는 쪽은 작업 에이전트이고, 「제 판단」도 선택지와 함께 작업 에이전트가 채운다. 사람 말로 옮기는 것은 마스터다.
판단을 먼저 내밀면 사람이 그대로 받아 버릴 위험이 있다. 위에서 버린 안 A(에이전트가 초안을 만들고 사람이 고친다)가 굳는 것과 같은 모양이다. 그래서 판단을 한 번에 한 쟁점만, 이유와 함께, 고르면 무엇이 되는지와 나란히 내민다. 사람이 매번 하나를 고르므로 고르지 않은 것이 정해진 것처럼 굳지 않는다. 그래도 사람이 살피지 않고 1번만 누르면 막을 길이 없다 — 이것이 이 방식의 대가다.
이 방식을 어디에 둘지에서 안이 둘이었다. 이 블로그에는 비슷한 대화법이 이미 스킬로 있다. 표준을 정할 때 쓰는 탐구 대화 방식으로, 판단을 먼저 내밀고 「동의하십니까?」 하고 예/아니오로 묻는다.
안 A — 그 스킬을 배포본에 통째로 싣는다. 배포본은 이 블로그에서 고쳐 다른 프로젝트에 깔리는 규칙 묶음이다. 얻는 것은 이미 다듬어진 규칙을 그대로 쓰는 것이다. 버린 이유는 둘이다. 그 스킬은 이 블로그 자신의 규칙이라 배포본과 섞지 않기로 정해 두었고, 그대로 실으면 블로그에서만 쓰는 내용까지 그 프로젝트에 들어간다. 그리고 같은 규칙이 두 벌이 되어, 하나를 고치면 다른 하나가 조용히 낡는다.
골랐다 — 안 B, 배포본에 있는 이 표준의 절차 파일(스킬) 기획 절에 「판단을 먼저 세우고, 예/아니오나 2~3개 중 고르기로 묻는다」 한 줄을 덧붙이고, 선택지 서식은 위상 표준 원칙 6을 가리킨다. 안 A가 못 지켜주는 것은 선택지 서식의 원본이 원칙 6 하나로 남는 것이다.
원칙 6. 본문은 기획이 만든 것 전부를 다섯 절로 담는다
이슈가 하나면 그 본문이 언제 무엇을 담는지를 정해야 한다.
안 A — 사람이 이슈를 만들 때 확정한다. 기획 결과는 세션에만 남는다. 얻는 것은 본문이 가장 빨리 존재하는 것이다. 배정과 동시에 읽을 것이 생긴다.
버린 이유는 기획이 구체화한 것이 어디에도 안 남는 것이다. 입력 범위·예외·상태 전이는 대화에서 나오는데, 본문이 그 앞에서 닫히면 테스트가 검증할 수 없는 것이 생긴다. 테스트 세션은 기획 대화를 보지 못한다(원칙 12).
골랐다 — 안 B, 기획이 닫을 때 확정한다. 안 A가 못 지켜주는 것은 기획 산출물이 놓일 자리다.
그 자리를 자유 산문으로 두는 안도 있었다. 버린 이유는 무엇이 빠졌는지 아무도 모르는 것이다. 범위 밖을 안 적으면 테스트가 과잉 개발하고, 미정을 안 적으면 그걸 버그로 올린다. 빠진 것은 빈칸으로 보이지 않는다. 그래서 절을 고정했다.
## 목적
주문 취소 시 결제까지 함께 취소한다.
## 범위 밖
- 부분 취소
- 취소 수수료 정산
## 계약
- `S200_CANCEL_본인_PAID` PAID, PREPARING 상태만 취소할 수 있다
- `S400_CANCEL_본인_SHIPPED` 그 외 상태는 400으로 거부한다
- [C3] 결제 취소가 실패하면 주문 취소도 롤백된다
- [C4] 취소된 주문은 CANCELED 로 전이한다
## 정하지 않은 것
- 취소 알림 발송 여부
## 버린 안 — 테스트 세션은 읽지 않는다
- 취소 요청을 큐에 넣고 비동기 처리 → 결제사 응답을 사용자가 즉시 못 본다
- 취소 가능 상태를 설정값으로 뺌 → 상태 전이가 코드 밖으로 나가 검증이 안 된다
예시에 나온 400은 HTTP 상태 코드 중 요청이 잘못됐다는 뜻이고, ‘롤백‘은 하던 작업을 전부 없던 일로 되돌리는 것이다 — 여기서는 결제 취소가 실패하면 주문 취소까지 되돌린다는 뜻이다. ‘비동기 처리’는 결과가 끝날 때까지 기다리지 않고 다음 일을 먼저 하는 방식이다. 위 계약 절에서 S200_CANCEL_본인_PAID처럼 이름으로 적은 줄과 [C3]처럼 번호로 적은 줄이 섞여 있는데, 계약 하나를 댓글에서 무엇으로 가리키는지는 바로 다음 원칙 7에서 정한다 — 번호([C1])로 시작했다가 이름(S{상태코드}_{ENDPOINT}_{ACTOR}_{STATE})으로 바뀐 경위가 거기 있다.
「버린 안」이 본문에 들어온 것이 2차 개정에서 뒤집힌 자리다. 1차에서는 본문에 계약만 담고 버린 안을 첫 댓글로 보냈는데, 댓글은 세 줄에서 다섯 줄이라 안 다섯 개가 들어가지 않는다. 규칙 둘이 같은 글에서 서로를 부정하고 있었다.
옮길 자리 후보가 셋이었다. decisions.md로 전부 보내는 안은 기능별 잡동사니로 커져서 「기능을 넘는 것만」이라는 그 파일의 기준을 무너뜨린다(원칙 18). 기획 댓글만 분량 예외로 두는 안은 「댓글은 짧다」가 첫 댓글부터 깨져서 나머지 넷의 근거까지 약해진다.
골랐다 — 본문에 절로 둔다. 둘이 못 지켜주는 것은 사람이 문서 하나만 열고 계약과 그 경로를 같이 보는 것이다. 원칙 1이 이슈를 하나로 합친 이유가 그것이었다.
대가는 원칙이 하나 무너진 것이다. 1차의 “본문에는 계약만 담는다”는 더 이상 사실이 아니다. 본문은 기획의 산출물 전부이고, 댓글은 일어난 일이다. 다만 진행 상황·구현 방법·작업 결과는 여전히 본문 밖이다.
원칙 7. 계약은 통과와 실패를 가르는 한 줄로 쓰고 이름으로 가리킨다
절을 고정해도 계약 절 안을 어떻게 쓰는지가 남는다.
안 A — 산문으로 서술한다. 얻는 것은 기획이 가장 가볍다는 것이다. 대화에서 나온 말을 그대로 옮기면 된다.
버린 이유는 테스트가 무엇을 몇 개 검증해야 하는지 판단해야 하는 것이다. 한 문단에 조건이 셋 섞여 있으면 세 개로 읽을지 하나로 읽을지가 사람마다 다르고, 원칙 12이 요구하는 「계약으로 못 짜겠으면 올린다」의 판정 기준이 서지 않는다.
골랐다 — 안 B, 한 줄이 검증 항목 하나다.
가리키는 값은 처음에 [C1] 번호였다. 나중에 이름으로 뒤집었다. 번호는 짧아서 댓글에 쓰기 좋았는데, 두 가지가 걸렸다.
하나 — 이슈마다 C1부터 다시 센다. C2로 전체 검색을 하면 이슈 수만큼 걸리고, 어느 이슈의 것인지 열어봐야 안다. 번호가 이슈 안에서만 통하는 값이었다.
둘 — 계약표 표준과 부딪혔다. API 테스트 계약표 표준은 「계약에 순번을 매기지 않는다」고 이미 정해뒀다. 이름이 무엇을 검증하는지 말하므로 번호는 정보를 더하지 않는다는 이유였다. 같은 계약을 한쪽은 번호로, 다른 쪽은 이름으로 부르고 있었다.
그래서 계약표가 이미 소유한 이름 체계를 그대로 쓴다 — S{상태코드}_{ENDPOINT}_{ACTOR}_{STATE}. 전역에서 유니크하고, 검색되고, 뜻까지 같이 보인다. 대신 댓글이 길어진다. 여럿을 가리킬 때는 공통 앞부분으로 줄여 S200_CANCEL_*처럼 쓴다.
이슈를 쓸 때 상수가 아직 없어도 된다. 이름이 표의 칸에서 기계적으로 정해지므로 표만 적으면 이름이 따라 나온다.
// 계약이 아니다 — 통과와 실패를 가를 수 없다
- `S200_CANCEL_본인_PAID` 취소를 적절히 처리한다
// 계약이다
- `S200_CANCEL_본인_PAID` PAID, PREPARING 상태만 취소할 수 있다
계약을 가리키는 값이 이 표준에서 제일 많은 것을 푼 장치다. 댓글이 짧아야 하는데 짧으면 무엇을 가리키는지 흐려진다는 문제가 있었는데, 처음에 번호가 생기자 세 줄 안에서 정확히 지목할 수 있게 됐고, 이름으로 바꾼 뒤에도 그 일은 그대로다.
[테스트 완료] S200_CANCEL_* 검증. S400_CANCEL_본인_SHIPPED 미검증.
[확인 필요] S400_CANCEL_본인_SHIPPED 가 모호하다. 개발에서 막혔다.
[답] S400_CANCEL_본인_SHIPPED → 재취소는 400.
본문에 S400_CANCEL_본인_CANCELED 추가함.
댓글의 분량 제한이 처음으로 지킬 수 있는 규칙이 됐다. 1차에서 3~5줄이 안 지켜졌던 이유가 가리킬 좌표가 없어서였다.
대가는 기획이 문장을 쪼개는 수고를 지는 것이다. “적절히 처리한다”로 넘어가지지 않으므로 모호한 자리가 기획 단계에서 드러나고, 그때 사람에게 다시 물어야 한다. 그 수고가 원칙 5이 기획을 대화로 만든 이유와 같은 방향이다.
원칙 8. 본문은 계약 추가만 허용하고 수정과 삭제는 막는다
본문이 곧 계약이면 그걸 고칠 수 있느냐가 남는다. 1차에서는 “그 뒤로 고치지 않는다”였는데, 그 규칙이 곧바로 다른 규칙과 부딪혔다.
막혀서 확인 필요로 올리는 이유가 대부분 「계약이 부족하다」인데, 사람이 답을 주면 그 답이 곧 계약이다. 본문이 완전히 불변이면 그 답이 갈 곳이 없다.
안 A — 사람의 답을 댓글에 두고 그게 계약 효력을 갖는다. 얻는 것은 본문을 전혀 안 건드리는 것이다. 버린 이유는 테스트가 그 답을 못 보는 것이다. 원칙 12이 댓글을 못 읽게 하므로 계약이 둘로 갈라지고, 테스트는 갈라진 줄 모른 채 통과한다.
안 B — 이슈를 닫고 새로 판다. 얻는 것은 본문이 완전한 불변이라 기획이 쓴 것과 테스트가 본 것이 100% 같은 것이다. 버린 이유는 작은 누락 하나에도 이슈가 번식하는 것이다. 원칙 1이 세운 「기능 하나에 이슈 하나」가 바로 무너진다.
골랐다 — 안 C, 추가만 허용한다. 둘이 못 지켜주는 것은 계약을 한 곳에 유지하면서 이슈도 하나로 유지하는 것이다.
- `S400_CANCEL_본인_CANCELED` 재취소 요청은 400으로 거부한다 (추가: #7 답변)
불변의 뜻이 여기서 정확해진다 — 「글자가 안 변한다」가 아니라 「이미 쓴 계약의 뜻이 안 바뀐다」다. 그래서 규칙이 셋이다. 기존 줄을 고치지 않는다, 지우지 않는다, 이름을 재사용하지 않는다.
마지막이 조용한 함정이다. S400_CANCEL_본인_SHIPPED를 지우고 그 이름을 다른 뜻으로 다시 쓰면 이미 달린 “S400_CANCEL_본인_SHIPPED 검증함” 댓글이 거짓말이 된다. 이름은 댓글이 가리키는 주소라서, 주소를 재사용하면 과거 기록 전체가 어긋난다.
대가는 본문에 죽은 줄이 남는 것이다. 범위가 줄어도 그 계약을 지우지 못한다. 그때는 새 줄로 뒤집고 옛 줄을 남긴 채 둔다 — 뒤집힌 기록이 남는 편이 기록이 사라지는 것보다 낫다.
원칙 9. 댓글은 사람만 읽는다
이슈 글이 장황해진 진짜 원인은 독자가 둘인데 요구가 정반대라는 것이었다.
에이전트가 읽는다 → 손실이 없어야 한다. 요약하면 믿고 틀리거나 못 믿고 다시 읽는다
사람이 읽는다 → 짧아야 한다. 길면 안 읽는다
한 문서가 둘을 겸하면 장황한 쪽으로 수렴한다. 손실이 더 비싼 실패라서다.
안 A — 둘을 한 문서에 담되 섹션으로 가른다. 사람용 요약을 위에 두고 에이전트용 전문을 아래에 붙인다. 얻는 것은 한 곳만 보면 되는 것이다.
버린 이유는 가른 자리가 지켜지지 않는 것이다. 요약에 세부가 새고 전문에 소감이 섞인다. 그걸 검사할 사람이 없고, 어긋나도 아무것도 안 깨지므로 틀어진 채로 계속 간다.
골랐다 — 안 B, 독자를 하나로 자른다. 댓글은 사람만 읽는다. 에이전트가 이어받을 정보는 세션이 든다. 안 A가 못 지켜주는 것은 짧게 쓸 근거다. 에이전트가 읽지 않는다고 정해두면 짧아도 되는 이유가 규칙으로 생긴다.
본문과 댓글의 분업이 여기서 한 문장으로 정리된다 — 본문은 「합의된 것」이고 댓글은 「일어난 것」이다. 합의는 고쳐 쓰면 이전 합의가 사라지지만, 일어난 일은 쌓여야 한다. 그래서 이미 쓴 댓글도 고쳐 쓰지 않는다. 바뀌었으면 새 댓글을 단다.
대가는 무겁다. 세션이 끊기면 복원할 수 없다.
세션이 살아 있다 → 탐색 0회. 문맥이 이미 있다
세션이 죽었다 → 전부 다시 파악한다. 이슈에는 계약과 사람용 세 줄뿐이다
다시 파악하고 진행하기로 했다. 복원을 위한 기록을 남기지 않는다 — 그 기록을 남기는 비용이 애초에 장황함의 원인이었다. 세션이 자주 죽는다면 이 판단이 뒤집힌다.
원칙 10. 댓글은 사건마다 하나씩 다섯 서식 중 하나로 쓴다
1차에서는 「한 계층당 댓글 하나, 세 줄에서 다섯 줄」이었다. 그런데 확인 필요는 계층이 아니라 사건이고, 한 계층에서 여러 번 난다. 계층당 하나를 지키려면 이미 쓴 댓글을 고쳐야 하는데, 그건 원칙 9의 「일어난 일은 쌓인다」를 깬다.
단위를 계층에서 사건으로 옮겼다. 그리고 무엇을 빠뜨렸는지 검사할 기준이 없으면 필수 항목이 조용히 빠지므로 서식을 다섯으로 고정한다.
[기획 완료] 계약 18개 확정.
- 계약 18개에서 쪼갤지 물음 → 그대로 감
- 부분 취소는 범위 밖으로 뺌
- 판단 필요: 없음
[개발 완료] S200_CANCEL_* · S400_CANCEL_* 구현.
- 결제 취소를 한 트랜잭션으로 묶음
- 판단 필요: 없음
PR #42 · feat/order-cancel
[테스트 완료] S200_CANCEL_본인_PAID · S400_CANCEL_본인_SHIPPED 검증.
S200_CANCEL_본인_PREPARING 미검증.
- S200_CANCEL_본인_PREPARING 은 외부에서 상태를 확인할 경로가 없다
[확인 필요] S400_CANCEL_본인_SHIPPED 가 모호하다. 개발에서 막혔다.
- "그 외 상태"에 CANCELED 재취소가 포함되는지 안 적혀 있다
- 구현을 임의로 정하면 계약이 조용히 바뀐다
[답] S400_CANCEL_본인_SHIPPED → 재취소는 400.
본문에 S400_CANCEL_본인_CANCELED 추가함.
[개발 완료] 예시의 ‘트랜잭션‘은 DB 작업 여러 개를 한 묶음으로 묶어, 하나라도 실패하면 전부 되돌리는 것이다 — 여기서는 결제 취소와 주문 취소를 한 묶음으로 묶었다는 뜻이다.
[기획 완료]의 둘째 줄은 원칙 2에서 「쪼갤까요」를 물었을 때만 쓴다. 물었으면 몇 개에서 물었고 사람이 쪼갰는지를 한 줄로 남긴다. 그래도 네 줄이라 다섯 줄 안에 든다.
두 항목이 선택이 아니라 필수다.
[개발 완료]의 PR 번호와 브랜치 이름. 원칙 13이 「사람이 테스트 세션에 브랜치를 준다」로 정했는데, 사람이 그 브랜치를 읽는 곳이 여기뿐이다. 1차 규칙의 “링크로 대신할 수 있으면”은 선택으로 읽혔고, 그러면 경로가 끊긴다[테스트 완료]의 검증한 계약 이름과 못 한 이름. 사람이 세 줄만 보고 계약 대비 커버리지를 안다. 계약을 이름으로 가리키는 값어치가 여기서 나온다
[답]은 누가 쓰는지도 정해야 했다. 사람은 세션 안에서 말로 답하지 트래커에 타이핑하지 않는다. 사람이 직접 쓰게 하는 안은 귀찮으면 세션에서만 답하고 트래커에는 안 남아 계약이 조용히 사라진다.
골랐다 — 에이전트가 받아적고 사람이 확인한다. 대신 에이전트가 사람의 말을 계약 문장으로 번역하므로 번역 오류가 계약에 박힐 수 있다. 확인을 붙인 것이 그걸 막는 장치이고, 확인 전에는 계약을 추가하지 않는다.
원칙 11. 계층이 바뀔 때 배정하지 않고 승인받는다
이 원칙의 마지막 조항(개발 → 테스트는 배정이다)은 멀티 에이전트 위상 표준이 회수했다. 아래에 고쳐 적었다.
계층 전환을 사람이 어떻게 통과시키는가.
안 A — 계층마다 사람이 배정한다. 개정 전 방식이다. 얻는 것은 사람이 매번 무엇을 시키는지 고르는 것이다.
버린 이유는 배정이 사람에게 문맥 재구성을 시키는 것이다. 트래커를 열고 티켓을 찾고 읽고 담당을 정한다. 횟수보다 이 준비 비용이 크다.
골랐다 — 안 B, 에이전트가 묻고 사람이 답한다. 계층을 넘기 전에 넘어가도 되는지 묻고 답을 받는다. 안 A가 못 지켜주는 것은 사람이 이미 문맥 안에 있을 때 묻는 것이다. 방금 결과를 본 자리에서 예/아니오만 하면 된다.
이건 「에이전트가 큐에서 스스로 집는다」로 되돌아가는 게 아니다. 그 안을 버린 이유는 “사람이 인지 못 한 채 굴러간다”였는데, 묻고 기다리는 것은 인지의 반대가 아니라 인지 그 자체다.
개정 당시에는 둘 중 하나만 승인이었다. 개발 → 테스트는 세션이 끊기므로 물어볼 세션이 없고, 거기는 사람의 배정이었다.
그 자리를 멀티 에이전트 위상 표준이 회수했다. 2depth가 3depth를 직접 만들므로 사람이 끼지 않는다. 테스트가 필요한지는 구현해 본 쪽만 알기 때문이다.
1. 이슈 배정 (작업 세션 시작)
2. 기획 → 개발 전환 승인 ← 세션 안에서 묻는다. 예/아니오
3. 커밋 전 확인 (개발 결과)
4. 테스트 세션 시작 ← 2depth 가 3depth 를 만든다. 사람이 안 낀다
5. 커밋 전 확인 (테스트 결과)
6. PR 머지
개입 8회에서 6회가 됐지만, 6회의 무게가 균등하지 않다. 1번은 기획 대화 전체라 나머지 다섯을 합친 것보다 무겁다.
이건 손해가 아니라 자리 이동이다. 그 대화는 지금도 어차피 일어난다 — 다만 흩어진 티켓 넷에 나눠져서, 사람이 넷을 오가며 문맥을 매번 다시 세운다. 재구성 비용을 없애는 대신 대화를 앞에 한 번 몰아 넣는 것이다.
여기서 3·5번(커밋 전 확인)을 없애는 안은 아예 안 올렸다. 커밋 대기 표준이 이미 답한 자리라서다 — 커밋해버리면 멈출 계기가 사라진다.
그런데 마스터가 밤에 맡긴 일에서는 3·5번이 6번으로 합쳐졌다(2026-10-25). 밤에 맡긴 작업 에이전트가 3번에서 멈추면 4번이 시작되지 못한다. 테스트 세션은 개발 브랜치를 출발점으로 새 브랜치를 따서(원칙 13) 일하는데, 브랜치에 들어 있는 것은 커밋된 내용뿐이라 커밋 전의 변경은 따라오지 않기 때문이다. 그러면 이 이슈 하나를 보느라 저녁을 두 번 쓴다 — 다음 날 저녁에 커밋을 허락하고, 그 밤에 돈 테스트의 결과를 그다음 저녁에 본다. 그래서 맡길 때 커밋 · 푸시 · PR까지 함께 요청하고, 확인은 다음 날 저녁에 PR에서 한 번에 한다. 커밋 대기 표준이 커밋 전에 멈추게 한 두 이유(품질 검토 · 흐름 파악)는 PR 리뷰와 마스터의 상황판(진행 중인 일을 한 표로 보여 주는 화면)이 받는다. 경위는 커밋 대기 표준 원칙 4-4에 있다. 「커밋해버리면 멈출 계기가 사라진다」는 걱정은 이렇게 풀린다 — 멈추는 자리가 사라지지 않고 PR 병합으로 옮겨 간다. 병합은 넘기는 일이라 사람이 있을 때만 일어난다. 2번(기획 → 개발 승인)은 맡기는 자리에서 받는다 — 기획은 사람이 있을 때 끝내고 맡기기 때문이다.
원칙 12. 테스트는 세션을 끊고 본문의 세 절만 읽는다
테스트를 왜 따로 떼는가. 같은 세션이 구현을 들고 있으면 자기가 만든 것에 맞춘 테스트가 나오고, 구현이 틀렸을 때 테스트도 같이 틀린다.
그런데 1차 이전에는 이 규칙이 같은 표준 안의 다른 규칙과 부딪혔다. 착수할 때 앞 계층 이슈를 전부 읽게 했으므로, 규칙을 지키면 백엔드 이슈를 읽게 되고 읽는 순간 구현 의도가 그대로 들어왔다. 세션을 가른 값어치가 사라진다. 이건 장부에 열어둔 채 닫지 못한 항목이었다.
세션을 끊고 댓글을 사람 전용으로 잘라내자 그 경로가 구조적으로 사라졌다.
개발 세션의 문맥 → 세션이 끊겼으므로 못 본다
개발이 남긴 댓글 → 원칙 9이 읽지 못하게 한다
읽을 수 있는 것 → 이슈 본문
그런데 2차에서 본문에 「버린 안」이 들어오면서 옆문이 하나 생겼다. 버린 안에는 “이 방식으로 만들려다 말았다”가 섞일 수 있고, 그건 구현 의도다.
그래서 읽는 절을 지정한다 — 「계약」·「범위 밖」·「정하지 않은 것」 셋이다.
| 절 | 읽나 | 왜 |
|---|---|---|
| 계약 | 읽는다 | 검증할 대상 그 자체다 |
| 범위 밖 | 읽는다 | 없으면 안 만들기로 한 것까지 테스트한다 |
| 정하지 않은 것 | 읽는다 | 없으면 미정을 버그로 올린다 |
| 버린 안 | 읽지 않는다 | 구현 의도가 섞일 수 있다 |
| 목적 | 읽는다 | 한 문장이라 의도가 실리지 않는다 |
규칙만 두면 안 지켜지므로 절 제목 자체에 박는다 — ## 버린 안 — 테스트 세션은 읽지 않는다. 읽는 쪽이 그 줄을 보는 순간 알게 된다.
- 계약 이름마다 테스트를 대응시킨다. 이름에 걸리지 않는 테스트를 만들지 않는다.
- 단 「설정 — 배포 때 확인」 표시가 붙은 계약은 대응시키지 않는다.
- 계약으로 테스트를 짤 수 없으면 구현을 읽지 말고
확인 필요로 올린다.
예외 줄은 2026-10-21에 들어왔다. 한 프로젝트의 로그 파일 롤링 이슈는 계약 여섯 개가 전부 설정이었는데, 「계약 이름마다 테스트를 대응시킨다」를 그대로 따르자 테스트가 1,058줄 나왔고 대부분이 설정 파일을 다시 읽어 해석하는 코드였다. 그 설정 파일을 아무도 안 고쳐도 다시 깨질 수 있는가를 물어, 누가 고쳐야만 깨지는 설정은 자동 테스트 대신 배포 때 확인한다는 판정은 테스트 층위 선택 표준 원칙 0이 한다. 표시는 이슈 본문의 계약 줄에 붙이고, 계약표 쪽 표기는 API 테스트 계약표 표준과 계약 커버리지 게이트 표준 원칙 5가 정한다. 표시는 기획을 닫을 때 그 계약 줄을 쓰면서 함께 붙인다 — 닫힌 뒤 기존 줄에 덧붙이면 원칙 8(기존 줄을 고치지 않는다)에 걸린다. 이 원칙이 바꾼 것은 한 줄뿐이다 — 그 표시가 붙은 계약 앞에서는 테스트 세션이 테스트를 만들지 않는다. 표시가 없으면 테스트 세션은 설정 계약 앞에서도 다시 1,058줄짜리 자리로 간다.
마지막 줄이 중요하다. 못 짜겠을 때 구현을 열어보는 것이 가장 자연스러운 다음 행동인데, 그게 이 원칙을 무효로 만든다. 계약으로 안 짜이면 그건 테스트의 실패가 아니라 계약이 부족하다는 신호다.
개발 세션에서 하는 간단한 동작 확인은 허용한다. 계약 검증만 테스트 세션이 한다.
원칙 13. 테스트 브랜치는 개발 브랜치에서 따고 개발 PR에 얹는다
테스트 세션이 무엇을 읽는지를 정하고 나면 어디에 서서 읽는지가 남는다. 1차 규칙에는 이 자리가 아예 비어 있었다 — PR 주소는 댓글에만 있고 테스트는 댓글을 못 읽으니, 규칙만 따르면 검증 대상을 찾을 방법이 없었다.
먼저 누가 알려주는가를 정했다. 본문에 기계 판독 칸을 두는 안은 기획 시점에 없는 값을 본문에 넣게 되어 원칙 8의 불변이 깨진다. 트래커 필드를 쓰는 안은 Jira와 GitHub의 표현이 달라 어댑터가 갈리고, 원칙 1이 의존 관계에서 이미 피한 자리로 되돌아간다.
골랐다 — 테스트 세션을 여는 쪽이 브랜치를 준다. 어차피 그 자리에서 세션이 열리니 거기에 얹는다.
개정 당시 그 「여는 쪽」은 사람이었다. 사람이 [개발 완료] 댓글에서 브랜치 이름을 읽어 넘겼고, 그래서 원칙 10이 그 항목을 필수로 만들었다. 에이전트끼리는 못 넘기지만 사람을 거치면 넘어간다는 계산이었다.
멀티 에이전트 위상 표준이 그 자리를 2depth로 옮겼다. 넘기는 것은 이슈 번호와 브랜치 이름 둘뿐이고, 구현 요약이나 변경 파일 목록은 넘기지 않는다. 넘기는 주체가 사람에서 구현한 당사자로 바뀌면서 옆문이 하나 생겼기 때문이다 — 방금 짠 쪽이 프롬프트를 쓰면 원칙 12가 막으려던 구현 의도가 거기로 샌다.
그 다음이 어디서 따는가다.
안 A — 개발 PR을 먼저 머지하고 통합 브랜치에서 딴다. 얻는 것은 PR이 오래 안 열려 있고 충돌이 작게 쌓이는 것이다. 버린 이유는 계약 검증을 안 거친 코드가 통합 브랜치에 먼저 들어가는 것이다. 테스트가 실패하면 이미 들어간 것을 되돌려야 한다.
골랐다 — 안 B, 개발 브랜치에서 따서 개발 PR에 얹는다. 안 A가 못 지켜주는 것은 검증된 것만 통합 브랜치에 들어간다는 것이다. 그리고 기능 하나 = 이슈 하나 = PR 하나로 단위가 전부 맞는다.
대가는 PR 하나가 오래 열려 있는 것이다. 그동안 통합 브랜치가 앞서가면 머지 충돌이 커진다.
원칙 14. 막히면 이슈를 닫지 말고 확인 필요로 올린다
에이전트가 못 하겠다고 판단했을 때 무엇을 하는가.
안 A — 자기가 판단해서 계약을 바꾼다. 구현할 수 없으면 스펙을 조정해서 진행한다. 얻는 것은 사람을 안 부르고 계속 도는 것이다.
버린 이유는 끊을 주체가 없는 루프가 생기는 것이다. 계약을 바꾸면 테스트가 검증할 대상이 바뀌고, 그건 기획 의도까지 되돌아가야 풀리는 문제일 수 있다. 그 판단은 에이전트의 소유 범위 밖이다.
골랐다 — 안 B, 원인을 [확인 필요] 댓글에 적고 라벨을 붙이고 멈춘다. 닫지 않는다.
막힌 자리를 계약 이름으로 가리킨다. 이름이 있으면 사람이 본문의 그 줄만 보면 되고, 답이 계약 한 줄 추가로 바로 이어진다(원칙 8). 이름으로 가리킬 수 없는 문제면 그렇게 적는다 — 그건 계약 절 자체가 부족하다는 신호라서 다른 답이 필요하다.
1차 이전에는 닫지 않는 이유가 하나 더 있었다 — 닫힌 이슈가 다음 계층의 대기를 풀어버렸다. 이슈가 하나가 되면서 그 경로는 사라졌지만, 확인 필요는 그대로 남는다. 기다리는 대상이 사람이라는 것은 이슈 개수와 무관하다.
그래서 라벨이 하나만 남는다. 선행 계층을 기다리는 라벨은 없앤다 — 이슈가 하나이고 순차라 그런 상태 자체가 없다.
| 라벨 | 무엇을 기다리나 | 누가 떼나 |
|---|---|---|
확인 필요 |
사람의 판단 | 사람 |
라벨이 줄면서 규칙도 하나 사라졌다. “자기 blocked(막혔다는 뜻의 라벨)는 자기가 떼지 않는다”는 쓰는 권한과 푸는 권한을 가르는 검문이었는데, 새 구조에서는 그 권한이 통째로 사람에게 간다(원칙 11). 에이전트끼리 갈랐던 것을 사람과 에이전트 사이에서 가르는 것이라 검문은 오히려 세진다.
원칙 15. 겹치는 파일은 목록으로 막지 않고 사람의 배정 순서로 푼다
이 항목은 1차에서 정했다가 2차에서 통째로 지웠다. 원래는 이슈에 만질 파일 목록(touch)을 붙이고, 착수 전에 겹치면 시작하지 않고 작업 중에는 그냥 진행하는 비대칭 규칙이었다.
비대칭의 근거는 지금도 맞다 — 착수 전에는 사람이 순서만 바꾸면 되니 회피가 공짜인데, 작업 중에는 이미 투자한 것을 버려야 하니 중단이 비싸다.
지운 이유는 목록이 놓일 자리가 없어서다. 2차에서 본문과 댓글의 소유가 확정되자 세 곳 다 막혔다.
본문에 두면 원칙 6가 금지한 구현 정보가 들어오고,
테스트가 원칙 12을 지켜도 구현 위치를 알게 된다
댓글에 두면 착수 전 겹침 검사를 하려고 에이전트가
다른 이슈의 댓글을 읽어야 해 원칙 9이 깨진다
기획이 쓰면 기획은 코드를 읽지 않는다. 추측으로 채우게 된다
세 번째가 결정적이다. 애초에 기획 단계에 없는 값을 기획 산출물에 요구하고 있었다.
골랐다 — 없앤다. 사람이 배정 순서로 푼다. 이슈가 기능 단위라 사람은 목록 없이도 “이 둘은 같은 데를 건드린다”를 안다. 그리고 파일 단위 락은 원래 실제 충돌보다 과하게 잡았다 — 같은 파일이라도 다른 곳을 고치면 git이 알아서 합친다.
같이 사라진 규칙이 둘 더 있다. 착수 절차의 겹침 검사가 빠져 착수가 두 단계가 됐고, 확인 필요가 붙은 이슈의 touch를 풀지 않는다는 규칙도 사라졌다. 뒤엣것은 금요일 저녁에 걸린 이슈가 월요일까지 파일을 잠그는 문제였는데, 목록이 없어지면서 잠글 것 자체가 없어졌다.
대가는 사람의 판단이 틀리면 충돌이 머지로 넘어가는 것이다. 그때는 배정받은 에이전트가 푼다 — 읽는 것은 양쪽 이슈 본문의 「계약」 절뿐이다. 충돌은 코드 문제라 계약과 코드만 있으면 풀리고, 댓글을 읽지 않으므로 원칙 9이 지켜진다. 계약으로 판단이 안 서면 확인 필요로 올린다.
원칙 16. 대기 브랜치는 폐기됐다 — 통합 브랜치의 점유자가 고정되면서 전제가 사라졌다
이 원칙은 더 이상 유효하지 않다. 멀티 에이전트 위상 표준이 마스터를 통합 브랜치에 상주시키면서 서브가 통합 브랜치로 갈 이유 자체가 없어졌다. 작업 브랜치는
worker-start --base-branch <통합 브랜치>로 딴다 — git은 체크아웃하지 않은 브랜치를 기준으로 새 브랜치를 따는 것을 막지 않는다.
대기 브랜치란 서브 에이전트가 작업을 배정받기 전까지 잠시 서 있던 전용 브랜치였다. 통합 브랜치(예: dev)는 한 워크트리에서만 체크아웃될 수 있는데, 대기 중인 에이전트가 통합 브랜치 자체를 차지해 버리면 다른 에이전트가 거기 설 수 없었다. 그래서 각 에이전트가 쉴 때 대신 서 있을 자리로 대기 브랜치를 따로 두었다.
지운 게 아니라 남겨둔 이유는, 이 규칙이 왜 생겼는지가 왜 사라졌는지의 근거이기 때문이다. 이점이 있어서 만든 규칙이었다면 지금도 남아 있었을 것이다. 아래는 그 경위다.
이 항목은 한 번 정했다가 뒤집었다. 원래는 “워커별 브랜치를 만들지 않는다”였다.
원래의 버린 이유는 지금도 유효하다 — 담을 내용이 없고 동기화 지점만 는다.
뒤집은 것은 이점을 발견해서가 아니라 다른 길이 막혀서다. 에이전트마다 워크스페이스가 따로인데 별도 클론이 아니라 워크트리다. 워크트리는 .git 하나를 공유하고, 한 브랜치는 한 워크트리에서만 체크아웃된다.
워커 A 가 dev 에 서 있다
→ 워커 B 는 dev 로 이동조차 못 한다
별도 클론이었으면 안 걸렸을 문제다. 그래서 이건 안이 틀렸던 게 아니라 전제가 바뀐 것이다. 클론을 파주는 도구가 생기면 되돌릴 후보로 남는다.
맞추는 방법에도 안이 둘이었다.
안 A — 대기 브랜치에 dev를 머지한다. 익숙한 방법이다. 버린 이유는 대기 브랜치에만 쌓이는 머지 커밋이 어디로도 안 가는 것이다. 대기 브랜치는 푸시하지 않으므로 그 커밋은 영원히 로컬에 남는다.
골랐다 — 안 B, git reset --hard origin/dev로 덮어쓴다. 담는 것이 없으니 히스토리를 보존할 이유도 없다.
git fetch origin
git switch <대기 브랜치>
git reset --hard origin/dev
한 줄씩 보면 이렇다. git fetch origin은 원격 저장소(origin)의 최신 기록을 받아 오기만 하고, 아직 내 브랜치에는 반영하지 않는다. git switch <대기 브랜치>는 작업 폴더를 대기 브랜치로 바꿔 끼운다(체크아웃과 같은 동작이다). git reset --hard origin/dev는 지금 바꿔 끼운 브랜치의 내용을 전부 버리고 방금 받아 온 origin/dev의 모습으로 덮어쓴다 — 커밋하지 않은 변경도 함께 사라진다.
이 한 줄이 커밋 대기 표준과 부딪혔고, 그쪽을 고쳐서 풀었다. 그 표준은 되돌리는 명령을 금지하되 「담는 것이 없다고 표준이 선언한 브랜치를 통합 브랜치 최신으로 맞출 때 + 작업 트리가 깨끗할 때(커밋하지 않은 변경이 하나도 없는 상태)」를 예외로 둔다. 대기 브랜치가 그 선언이고, 깨끗함은 착수 1번이 검사한다 — 이 표준의 작업 절차를 적어 둔 SKILL.md의 「착수」 단계 중 작업 트리 상태를 확인하는 자리를 가리킨다.
작업 브랜치는 대기 브랜치에서 딴다. 방금 덮어썼으므로 내용은 dev와 같고, PR 대상만 dev로 되돌린다. 결과가 모이는 곳이 기준이다.
원칙 17. 프로젝트 고유의 값은 .coding-standards/project.yml에 둔다
개정 전 표준은 “프로젝트마다 다르므로 프로젝트 설정에 둔다”까지만 적고 그 자리를 정하지 않았다. 그러면 프로젝트마다 다른 곳에 적히고, 에이전트가 어디를 볼지 모른다.
자리를 아무 데나 잡으면 안 되는 이유가 있다. 설치기가 덮어쓰는 목록이 정해져 있다.
CLAUDE.md AGENTS.md .agents/ .claude/ .codex/
.github/copilot-instructions.md .github/instructions/ config/
이 파일·폴더들은 Claude·Codex·Copilot 같은 AI 코드 어시스턴트가 매 요청마다 자동으로 읽어 들이는, 코딩 표준이 전달되는 통로다. 설치기가 표준을 새로 받을 때마다 이 목록을 통째로 다시 써 내려가므로, 여기에 프로젝트 고유 설정을 적으면 다음 업데이트 때 조용히 사라진다. 이 통로가 각각 무엇인지, 어느 도구가 읽는지는 규칙 전달 경로 표준에 정리되어 있다.
안 A — 루트 CLAUDE.md에 프로젝트 설정 절을 둔다. 얻는 것은 에이전트가 1단에서 판단 없이 읽는 것이다. 매 요청에 들어오므로 확실하다.
버린 이유는 관리 경로라 업데이트할 때마다 사라지는 것이다. 그리고 사라진 걸 아무도 안 알려준다. 표준 동기화 표준 원칙 7이 같은 이유로 「사본에서 규칙을 고치지 않는다」를 이미 정해뒀다. 그때는 규칙이 걸렸고 이번엔 설정이 같은 자리에 걸린다.
안 B — 표준마다 루트에 파일을 하나씩 둔다. 버린 이유는 표준이 늘 때마다 루트가 늘고, 에이전트가 볼 곳이 매번 달라지는 것이다. 지금 표준이 스물여덟 개다.
골랐다 — 안 C, .coding-standards/project.yml. 이 디렉터리는 관리 경로 목록에 없어서 업데이트가 손대지 않는다. 그리고 manifest.json·update.sh가 이미 거기 있어 표준 관련 파일이 한 곳에 모인다.
<프로젝트>/.coding-standards/
manifest.json 설치기가 매번 덮어쓴다. 손대지 않는다
project.yml ← 사람이 쓴다. 업데이트가 손대지 않는다
decisions.md ← 원칙 18
update.sh
설치기는 템플릿을 만들되 이미 있으면 덮어쓰지 않는다. manifest.json은 매번 새로 쓰는데, 설정 파일에 같은 짓을 하면 첫 업데이트에서 프로젝트 설정이 사라진다.
담는 것은 다섯이다 — 트래커 종류와 접속 방법, 계층의 실제 이름, 확인 필요 라벨의 실제 이름, 워크스페이스 경로와 통합 브랜치 이름, 쪼갤지 묻기 시작하는 계약 개수(split_ask_at, 원칙 2).
「에이전트별 대기 브랜치 이름」은 여기 있다가 빠졌다. 원칙 16이 폐기되면서 적을 것이 없어졌다.
계층 이름이 새로 들어온 자리다. 「기획 → 개발 → 테스트」가 모든 프로젝트에서 같은 이름일 리 없다. 다만 순서와 개수는 표준이 고정한다 — 원칙 1이 “계층 순서가 곧 의존”이라, 프로젝트가 순서를 바꾸면 그 원칙이 무너진다.
에이전트 개수는 이제 프로젝트가 정하지 않는다. 원칙 4가 세션 둘로 못 박았다.
원칙 18. 기능을 넘는 결정은 이슈가 아니라 decisions.md에 올린다
기획 대화에서 나온 결정은 어디에 남는가. 대부분은 이슈다 — 그 기능을 다시 만질 때 사람이 찾아가는 곳이 어차피 그 이슈고, 원칙 6가 본문에 「버린 안」 절까지 마련해뒀다.
문제는 여러 기능에 걸치는 결정이다. “이 프로젝트는 시간을 전부 UTC로 저장한다” 같은 것은 한 이슈에 묻히면 다음 기능에서 못 찾는다. 그리고 못 찾으면 다음 기획 대화에서 같은 것을 다시 정하고, 다르게 정한다.
안 A — 전부 이슈에 둔다. 얻는 것은 자리가 하나뿐이라 어긋날 곳이 없는 것이다. 버린 이유는 닫힌 이슈를 아무도 안 찾는 것이다. 결정이 살아 있는데 그것을 담은 이슈는 닫혀 있다.
안 B — project.yml에 같이 적는다. 버린 이유는 성격이 다른 것을 한 파일에 섞는 것이다. project.yml은 기계가 읽는 값이고 결정은 왜가 붙는 산문이다. 섞으면 설정을 읽으러 온 에이전트가 결정 전부를 끌고 온다.
골랐다 — 안 C, .coding-standards/decisions.md를 따로 둔다. 안 A가 못 지켜주는 것은 닫힌 이슈 밖에서 다시 찾을 수 있다는 것이고, 안 B가 못 지켜주는 것은 읽는 시점이 다른 둘을 나눠 두는 것이다.
- 그 기능 안에서만 통하는 결정은 이슈에 둔다. 다음 기능에도 적용되는 것만 올린다.
- 승격은 사람이 판단한다. 에이전트는 제안만 한다.
- 결정 한 줄과 이유 한 줄로 적는다. 길어지면 표준 후보이므로 사람에게 알린다.
- 기획을 시작할 때 이 파일을 먼저 읽는다.
대가는 자리가 둘로 늘어나 어긋날 수 있다는 것이다. 승격을 사람이 판단하게 한 것이 그걸 줄이는 장치다 — 자동으로 올라가면 이슈와 장부가 같은 것을 다르게 적기 시작한다.
원칙 19. 디자인 · 마케팅의 테스트는 기계 확인이고, 그 뒤에 운영자 컨펌이라는 관문이 선다
원칙 1의 「기획 → 개발 → 테스트」는 코드를 전제로 쓰였다. 테스트 계층은 계약을 테스트 코드로 검증하는데, 디자인(화면 시안)과 마케팅(카드 · 영상 · 글)은 테스트 코드로 검증할 수 없다. 그래서 이 일감들이 세 번째 계층에서 무엇을 하는지가 비어 있었다. 이 표준과 위상 표준 본문에 「디자인」 「마케팅」이 한 번도 나오지 않았다.
출발점은 내가 처음부터 못 박은 조건이다 — 디자인과 마케팅은 운영자가 눈으로 확인해야 하고, 컨펌이 나야만 밖으로 나간다. 고를 수 있는 안이 아니라, 사업이 그렇게 돌아가야 해서 붙은 조건이다. 운영자는 그 프로젝트를 운영하는 사람이고, 내 프로젝트에서는 나다. 콘텐츠 기록(edition.yml)의 confirmed_by가 전부 내 이름이었다.
그 조건 아래에서 정할 것이 다섯이었다.
하나 — 「밖으로 나간다」는 어디까지인가. 안 A — 고객이 보게 되는 모든 순간(운영 배포 · 인쇄 · 고객에게 보내는 문자와 서류)에 관문을 둔다. 얻는 것은 빠지는 자리가 없다는 것이다. 버린 이유는 이미 다른 장치가 막는 자리까지 겹쳐 막는다는 것이다. 운영 배포는 개발 일감이 거치는 테스트와 PR 병합이 이미 막고, 문자와 서류는 이 원칙이 다루는 디자인 · 마케팅 일감이 아니다. 인쇄해 쓰는 서류(계약서 · 서약서)는 법적 무게가 있어서, 운영자 확인이 따로 필요한지 이 원칙과 별개로 보기로 했다. 디자인 · 마케팅 결과물 가운데 곧바로 밖으로 나가는 것은 게시뿐이었다. 골랐다 — 안 B, 마케팅 결과물을 플랫폼(블로그 · 인스타그램 · Threads · 홈페이지)에 올리는 순간이다. 내 프로젝트의 콘텐츠 흐름(기획 → 기획 컨펌 → 카드 제작 → 카드 컨펌 → 게시 대기 → 게시)에 그 자리가 이미 있었다. 디자인은 밖으로 나가지 않는다. 그래도 컨펌은 받는다.
둘 — 디자인은 언제 컨펌받나. 내 프로젝트에서는 디자인 시안을 실제 화면 파일(HTML)로 만들어 design/ 폴더에 둔다. 이 일을 「퍼블리싱」이라 부른다 — 밖으로 내보낸다는 뜻이 아니다. 컨펌은 그 폴더에 퍼블리싱한 결과물을 보고 받는다. 개발은 컨펌된 것만 가져다 쓴다. 개발이 끝난 뒤에 컨펌하면, 컨펌에서 바뀌는 순간 개발이 다시 돈다. 디자인은 그 폴더 밖에서 만들지 않는다. 이 결정에는 전제 하나가 바뀐 것이 깔려 있다 — 나는 디자인 도구를 거의 쓰지 않고 디자인을 그 폴더에서 다루기로 했다.
셋 — 컨펌의 흔적을 어디에 남기나. 밤에 개발 에이전트가 사람 없이 「이 디자인 컨펌됐나」를 확인해야 한다는 것이 조건이었다. 안이 셋이었다.
안 A — 결과물 폴더마다 메타 파일을 하나 두고 confirmed_by(누가) · confirmed_at(언제)을 적는다. 콘텐츠 기록 edition.yml과 같은 모양이다. 얻는 것은 에이전트가 저장소 파일만 읽고 답을 안다는 것이다.
안 B — 트래커 이슈 상태(「컨펌 대기 → 완료」)로 남긴다. 얻는 것은 사람이 트래커에서 한눈에 본다는 것이다. 버린 이유는 에이전트가 확인할 때마다 트래커를 뒤져야 한다는 것이다. 어느 이슈가 그 디자인의 컨펌인지 결과물 쪽에는 적혀 있지 않으므로 넓게 조회하게 되는데, 그 프로젝트의 Jira는 이슈 100건을 받으면 19만 자가 넘게 나온다.
안 C — GitHub PR 승인으로 남긴다. 얻는 것은 리뷰와 흔적이 한 자리에 있다는 것이다. 버린 이유는 에이전트와 내가 같은 GitHub 계정을 쓴다는 것이다. 자기 PR은 자기가 승인할 수 없다.
골랐다 — 안 A. 안 B와 안 C가 못 지켜주는 것은 파일 하나만 읽으면 된다는 것이다. 이슈 상태의 원본을 트래커 하나로 둔 위상 표준 원칙 19와도 부딪히지 않는다. 트래커는 이슈의 상태를 들고, 결과물이 컨펌됐는지는 결과물 옆 파일이 든다. 메타 파일 말고 그 폴더의 결과물이 confirmed_at 뒤에 바뀌면 컨펌이 풀린 것으로 본다 — 컨펌한 뒤에 바뀐 것은 컨펌받지 않은 것이다. 컨펌을 적어 넣는 커밋은 메타 파일만 바꾸므로 여기에 들지 않는다. 에이전트는 confirmed_by를 스스로 채우지 않는다. 운영자가 컨펌했다고 말한 뒤에만 받아 적는다.
넷 — 사람 눈보다 먼저 기계로 재나. 이건 이미 하던 일이었다. 그 프로젝트의 콘텐츠 검사 스크립트가 사람이 컨펌하기 전에 요청한 규격과 결과물이 맞는지, 흐름이 맞는지(기획 없이 카드 단계로 왔다 · 컨펌 전에 게시했다), 서로 가리키는 것이 이어졌는지를 잰다. 나는 그 방식을 말로 정한 적이 없었는데, 이번에 디자인 · 마케팅 전체의 규칙으로 올렸다. 기계로 잴 수 있는 것은 에이전트가 먼저 재고, 통과한 것만 운영자에게 컨펌해 달라고 내놓는다. 사람 눈은 「좋은가」만 본다. 사람의 두 시간이 「사진 자리가 하나 모자라네」 같은 것을 찾는 데 새지 않게 하려는 것이다. 그 기계 확인을 만든 세션이 하는지, 원칙 12처럼 따로 띄운 세션이 하는지는 정하지 않았다.
다섯 — 단계 이름을 바꾸나. 안 A — 디자인 · 마케팅 일감은 세 번째 계층을 「컨펌」이라고 부른다. 얻는 것은 그 일감에서 무엇을 하는지가 이름에 드러난다는 것이다. 버린 이유는 한 프로젝트 안에서 계층 이름이 일감마다 갈라진다는 것이다. 원칙 17은 계층 이름을 project.yml에 프로젝트 단위로 두고 「순서와 개수는 고정, 이름만 바꾼다」고 정했다. 일감마다 이름을 바꿀 자리가 없다. 골랐다 — 안 B, 이름은 그대로 두고, 테스트는 기계 확인이 채우고, 운영자 컨펌은 단계 뒤에 서는 관문으로 둔다.
| 분야 | 1 기획 | 2 개발 (작업 세션) | 3 테스트 | 사람의 관문 |
|---|---|---|---|---|
| 개발 | 사람과 함께 | 코드 | 테스트 세션 | PR 병합 |
| 디자인 | 사람과 함께 | 정해 둔 폴더에 퍼블리싱 | 기계 확인 | 운영자 컨펌 → 그다음에 개발이 쓴다 |
| 마케팅 | 사람과 함께 | 카드 · 영상 · 글 | 기계 확인 | 운영자 컨펌 → 그다음에 게시 |
기획과 개발은 원칙 4대로 한 작업 세션이 이어서 한다. 이 표가 가르는 것은 분야마다 2 · 3번 칸에서 무엇을 하는가와, 그 뒤에 어떤 관문이 서는가다.
구조로 보면 비어 있던 것은 단계가 아니라 관문이었다. 처음에는 「세 번째 단계가 비어 있다」로 봤다. 그런데 세 번째 자리는 기계 확인으로 정하면 되고, 정말 정해진 적이 없던 것은 운영자 컨펌이 설 자리였다. 그 자리는 PR 병합과 같은 곳이다. 둘 다 「먼저」 절의 넘기는 일이라, 컨펌도 사람이 있을 때만 일어난다. 다만 디자인 쪽 기계 확인은 무엇을 잴지 아직 정하지 않아서, 지금은 자리만 있고 검사가 없다.
대가와 남은 것이 넷이다. 디자인이 컨펌을 기다리는 동안 그 디자인을 쓰는 개발은 시작하지 못한다. 무엇을 기계로 잴지는 아직 정하지 않았다 — 글(오탈자 · 금칙어 · 플랫폼별 글자 수)과 design/ 화면은 지금 검사가 없다. 그 프로젝트의 콘텐츠는 황달 · 유선염 같은 건강 정보를 다루므로 광고 규제(의료법 · 표시광고법)에 걸리는 표현이 있는지 확인이 필요한데, 이건 아직 짐작이고 확인하지 않았다. 그리고 디자인 결과물도 저장소 파일이라 PR 병합을 거치는데, 컨펌과 병합 중 무엇이 먼저인지는 정하지 않았다.
판단 기준 정리
| 질문 | 답 | 왜 |
|---|---|---|
| 사람 없이 돌아도 되나 | 만드는 일은 된다 | 넘기는 일만 사람이 있을 때 한다. 틀려도 잃는 것이 그 밤의 브랜치로 묶인다 |
| 넘기는 일이 무엇인가 | 병합 · 배포 · 컨펌 · 게시 · 상태 전환 · 기획 | 결과물이 다음 사람이나 바깥으로 건너가는 순간이다. 기획은 사람과 함께 만드는 일이라 같이 넣었다 |
| 이슈를 몇 개 만드나 | 기능당 하나 | 사람이 보는 단위와 일의 단위를 맞춘다 |
| 기능이 크면 쪼개나 | 웬만하면 안 쪼갠다 | 이슈가 늘면 개입이 는다. 원칙 1을 되돌리는 일이다 |
| 크다는 걸 무엇으로 아나 | 계약 개수 | 기획이 닫는 순간에 셀 수 있는 게 그것뿐이다 |
| 몇 개부터 묻나 | 15 (split_ask_at) |
한 프로젝트의 기능별 계약 수가 12와 24 사이에서 비어 있다. 집계 이슈에 댓글이 10개 쌓이면 다시 본다 |
| 쪼갤 때 어디를 자르나 | 기능 축 | 계층으로 자르면 순서가 생기는데 적을 곳이 없다 |
| 기능 축으로 못 자르면 | 큰 채로 간다 | 아무도 모르는 순서가 큰 이슈 하나보다 나쁘다 |
| 의존을 어디에 적나 | 안 적는다 | 계층 순서가 곧 의존이라 어긋날 곳이 없다 |
| 세션을 몇 개 두나 | 둘 | 판단 주체를 가르는 데 필요한 최소다 |
| 기획을 누가 만드나 | 사람과 함께 | 채운 빈칸과 정한 것을 구별해야 한다 |
| 기획에서 어떻게 묻나 | 판단을 먼저 세우고 고르게 한다 | 사람의 타이핑 시간을 줄인다. 서식은 위상 표준 원칙 6 하나다 |
| 본문에 무엇을 담나 | 절 다섯 개 | 빠진 것은 빈칸으로 보이지 않는다 |
| 계약을 어떻게 쓰나 | 한 줄 = 한 검증, 이름 | 못 짜겠다의 판정 기준이 서야 한다 |
| 본문을 고치나 | 추가만 한다 | 계약이 갈라지는 것과 이슈가 번식하는 것을 둘 다 막는다 |
| 계약 이름을 재사용하나 | 안 한다 | 과거 댓글의 참조가 거짓이 된다 |
| 댓글을 누가 읽나 | 사람만 | 독자가 둘이면 장황한 쪽으로 수렴한다 |
| 댓글 단위가 무엇인가 | 사건 | 확인 필요는 계층이 아니라 사건이다 |
| 계층을 어떻게 넘나 | 기획 → 개발은 묻고 승인받는다 | 사람이 문맥 안에 있을 때 물어야 싸다. 밤에 맡길 일은 맡길 때 받는다 |
| 테스트가 무엇을 읽나 | 본문의 세 절 | 버린 안에 구현 의도가 섞일 수 있다 |
| 「설정 — 배포 때 확인」 계약에도 테스트를 대응시키나 | 아니다 | 누가 그 설정 파일을 고쳐야만 깨지므로 고칠 때 실제 서버에서 한 번 확인한다. 대응시키면 설정을 다시 읽는 기계가 나온다 |
| 테스트가 어디서 따나 | 개발 브랜치 | 검증 안 된 코드를 통합 브랜치에 넣지 않는다 |
| 겹치는 파일을 어떻게 막나 | 안 막는다 | 목록이 놓일 자리가 세 곳 다 막혔다 |
| 막히면 닫나 | 안 닫는다 | 계약을 못 지킨 채로 끝난 것이 아니다 |
| 프로젝트 설정을 어디 두나 | .coding-standards/ |
관리 경로는 업데이트가 덮어쓴다 |
| 세션이 끊기면 | 다시 파악한다 | 복원용 기록이 장황함의 원인이었다 |
| 디자인 · 마케팅의 테스트는 | 기계 확인 | 사람 눈은 「좋은가」만 본다 |
| 운영자 컨펌은 단계인가 | 관문이다 | 계층 이름을 일감마다 가르지 않는다. PR 병합과 같은 자리다 |
| 컨펌 흔적은 어디에 두나 | 결과물 폴더의 메타 파일 | 사람 없이 도는 에이전트가 파일만 읽고 안다. 메타 파일 말고 결과물이 바뀌면 컨펌이 풀린다 |
이 표준을 정하기까지
시작은 “이슈 글이 장황하다”였다. 에이전트가 남기는 기록이 중구난방이고 너무 길어서 사람이 읽기 힘들다는 것이었다. 문체 문제로 들어왔다.
첫 진단이 틀렸다. 나는 원인을 독자가 둘이라 장황해진다로 봤다. 진단 자체는 나중에 맞는 것으로 드러났지만 고칠 자리를 틀렸다 — 본문을 어떻게 쓰느냐의 문제로 봤다.
진짜 문제는 개수였다. 이슈가 다섯 개라 사람이 따라갈 수 없다는 것이었고, 세어보니 이슈 개수가 그대로 사람 개입 횟수였다. 기능 열 개면 개입 여든 번이다. 그리고 이건 표준이 스스로 지목한 병목이었다 — 개정 전 글에 “배정 대기가 쌓이면 에이전트 부족이 아니라 사람 부족”이라고 적혀 있는데, 결론이 “에이전트를 줄인다”로만 갔다. 공급을 줄였지 개입 횟수 자체는 안 건드렸다.
내가 낸 안이 기각됐다. 나는 에이전트 넷을 유지하고 이슈만 합치자고 했다. 버린 이유는 한 줄이었다 — 판단 주체가 넷이면 전환 지점도 넷이라, 이슈를 합쳐도 브레이크 개수는 그대로다.
나눠야 했던 것이 세션이라는 게 그 다음에 나왔다. 계층을 나눈 근거를 다시 읽으니 전부 「문맥이 섞이면 안 된다」였다. 이슈를 넷으로 쪼갠 건 그걸 트래커에 표현하려다 나온 부산물이었다.
여기서 방향이 완전히 꺾였다. 나는 두 독자를 화해시킬 방법을 찾고 있었는데 — 짧은 요약과 포인터를 두고 상세는 PR과 좌표가 담게 하자는 안까지 냈다 — 답은 하나를 다른 데로 보내는 것이었다. 에이전트용 정보는 세션이 들고, 댓글은 사람만 읽는다.
그 순간 티켓 좌표(CODEMAP) 설계가 통째로 죽었다. CODEMAP은 이슈가 넷으로 쪼개져 있던 그 이전 구상(바로 위에서 “에이전트 넷을 유지”라고 한 그 구조)에서 쓰려던 장치였다 — 코드를 먼저 탐색하는 PM 에이전트(기획과 개발 사이에서 탐색만 전담하던, 지금은 없는 역할)가 “어느 파일 어느 줄을 봐야 하는지”를 다음 세션에 넘기기 위한 좌표였다. 그 좌표를 표시하는 마커, 좌표가 담을 정보 항목 여섯 개(필드 여섯 개), 넘기고 받는 사이 코드가 바뀌지 않았는지 확인하는 base SHA(그 시점 커밋의 해시) 검사, Jira·GitHub처럼 트래커마다 형식이 달라 맞춰 줘야 했던 어댑터 둘까지 — 전부 “탐색한 세션과 그걸 쓰는 세션이 다르다”는 전제 위에 있었다. 기획과 개발이 한 세션이면 탐색이 처음부터 한 번뿐이라 넘길 좌표가 없다. 마커·필드 여섯 개·base SHA 검사·어댑터 둘이 다 필요 없어졌고, PM 에이전트도 같이 사라졌다.
장부에 열어둔 항목이 저절로 닫혔다. 테스트 세션 분리와 읽기 규칙이 서로를 무너뜨리는 자리였는데, 새 구조에서는 테스트가 구현 의도에 접근할 경로가 아예 없다.
여기까지가 1차 개정이고, 2차는 “그래서 그 하나에 무엇을 어떻게 쓰나”에서 시작했다. 1차는 자리를 정했지 문장을 정하지 않았다. 본문은 「계약만」, 댓글은 「세 줄에서 다섯 줄」까지만 적혀 있었고, 그 둘 사이에 규칙이 서로를 부정하는 자리가 남아 있었다.
세어보니 논리가 깨지는 자리가 여섯이었다. 테스트가 검증 대상 브랜치를 알 방법이 없었고(PR 주소가 댓글에만 있는데 테스트는 댓글을 못 읽는다), 첫 댓글이 「버린 안 전부」와 「세 줄」을 동시에 요구했고, touch 목록이 본문에도 댓글에도 못 들어갔고, 머지 충돌 규칙이 “양쪽 이슈를 읽는다”로 댓글 규칙을 깼고, 개입 계산에서 PR 머지가 빠져 있었고, 확인 필요가 파일을 주말 내내 잠갔다. 전부 1차가 자리만 정하고 서식을 안 정해서 생긴 것들이다.
계약에 번호를 붙인 것이 그 여섯 중 셋을 한 번에 풀었다. 댓글이 짧아야 하는데 짧으면 무엇을 가리키는지 흐려진다는 것이 근본 문제였는데, 번호가 생기자 세 줄 안에서 지목이 가능해졌다. “C1~C3 검증, C4 미검증”이 세 줄이면서 손실이 없다. 1차에서 3~5줄이 안 지켜졌던 이유가 분량이 빡빡해서가 아니라 좌표가 없어서였다.
버린 안을 본문으로 옮기면서 1차 원칙 하나를 스스로 깼다. “본문에는 계약만 담는다”였는데, 그러면 버린 안이 갈 곳이 댓글뿐이고 거기는 3~5줄이다. decisions.md로 보내는 안은 그 파일의 기준을 무너뜨리고, 기획 댓글만 분량 예외로 두는 안은 「댓글은 짧다」를 첫 댓글부터 깬다. 본문의 정의를 「계약」에서 「기획의 산출물 전부」로 넓히는 쪽을 골랐다.
그 대가로 테스트의 격리가 샜다. 버린 안에는 구현 의도가 섞일 수 있는데 테스트는 본문을 읽는다. 읽는 절을 지정하고, 규칙만으로는 안 지켜지므로 절 제목 자체에 「테스트 세션은 읽지 않는다」를 박았다.
본문 불변이 계약 추가와 부딪히는 자리도 여기서 나왔다. 막히는 이유가 대부분 “계약이 부족하다”인데 사람이 답하면 그 답이 곧 계약이다. 댓글에 두면 테스트가 못 보고, 이슈를 새로 파면 「기능 하나에 이슈 하나」가 무너진다. 추가만 허용하기로 하면서 불변의 뜻이 「글자가 안 변한다」에서 「이미 쓴 계약의 뜻이 안 바뀐다」로 정확해졌다. 번호 재사용 금지가 그때 딸려 나왔다 — 주소를 재사용하면 과거 댓글이 전부 거짓이 된다.
touch는 자리가 없어서 지웠다. 본문에 두면 원칙 6가 금지한 구현이 들어오고 테스트에 새며, 댓글에 두면 겹침 검사를 하려고 에이전트가 댓글을 읽어야 한다. 그런데 세 번째가 결정적이었다 — 기획은 코드를 안 읽는데 만질 파일 목록을 요구하고 있었다. 애초에 없는 값을 산출물로 받으려던 것이다. 비대칭의 근거는 지금도 맞지만 적용할 데이터가 없다는 것이 드러나서 규칙을 통째로 지웠고, 주말 파일 잠금도 같이 사라졌다.
테스트가 설 자리를 정했다. 사람이 세션을 열 때 브랜치를 주기로 했는데, 그러려면 사람이 그 브랜치를 어디서 읽는지가 정해져야 했다 — [개발 완료] 댓글이고, 그래서 PR과 브랜치가 필수 항목이 됐다. 에이전트끼리는 못 넘기지만 사람을 거치면 넘어간다는 것이 이 구조의 성격을 그대로 보여준다. 개발 PR을 먼저 머지하는 안은 검증 안 된 코드를 통합 브랜치에 먼저 넣게 되어 버렸다.
마지막에 바닥이 비어 있는 걸 발견했다. 원칙 1이 「기능 하나에 이슈 하나」로 못 박아놓고 기능의 크기를 아무 데서도 정하지 않았다. 그러면 계약 서른 개짜리 이슈가 와도 막을 것이 없고, 방금 정한 것들이 순서대로 깨진다 — 댓글 세 줄이 서른 개의 결과를 못 담고, PR이 며칠 열려 있고, 세션 하나가 감당하지 못한다. 「이슈 개수가 곧 개입 횟수」를 풀었더니 그 반대편이 열려 있었다.
방향을 먼저 못 박았다 — 기본값은 안 쪼개는 것이다. 원칙 1이 이슈를 다섯에서 하나로 줄인 이유가 개입 횟수였으므로 쪼개는 것은 그 결정을 되돌리는 일이다. 그래서 규칙이 「쪼개라」가 아니라 「너무 길 때만」이 됐다.
그런데 쪼개는 순간 원칙 1이 깨진다는 게 곧바로 나왔다. 「계층 순서가 곧 의존이라 적을 곳이 없다」는 한 이슈 안에서만 성립하는 말이고, 이슈 A와 B 사이에는 그런 고정 순서가 없다. 계층으로 자르면 순서가 생기는데 적을 곳이 없어서 사람이 뒤엣것을 먼저 배정해도 아무도 안 막는다. 그래서 자르는 축을 기능으로 못 박고, 그 축으로 못 자르면 큰 채로 가기로 했다 — 아무도 모르는 순서가 큰 이슈 하나보다 나쁘다.
판정 검문은 새로 만들지 않아도 됐다. 원칙 12가 이미 「테스트 세션은 자기 이슈의 계약만 읽는다」로 정해놨으므로, 테스트가 자기 계약만으로 도느냐가 그대로 독립 여부의 판정이 된다. 후보였던 「각각 배포할 수 있는가」는 배포의 뜻이 프로젝트마다 달라 버렸다.
셀 수 있는 것이 계약 개수뿐이라는 것도 재보고 알았다. 세션 소진량도 diff 크기도 기획이 닫는 시점에는 모른다 — touch를 지운 이유(기획은 코드를 안 읽는다)가 여기서 한 번 더 걸렸다. 계약 개수가 대리 지표로 쓸 만한 것은 원칙 7이 「한 줄 = 한 검증 항목」으로 단위를 이미 정규화해놨기 때문이고, 그게 없었으면 못 쓸 지표였다.
쪼갠 상대를 적을 자리도 새로 안 만들었다. 「범위 밖」이 원래 하던 일이라 그대로 쓰고, 이슈 번호는 안 적기로 했다 — 번호를 적는 순간 그건 이슈 간 링크고 원칙 1이 피한 자리다. 기준 숫자는 정하지 않고 「재본 값이 아니다. 돌려보고 고친다」고만 적었다. 한 번도 안 돌려봤으므로 근거 있는 숫자가 없었고, 지어낸 숫자를 적으면 6개월 뒤에 잰 숫자로 오해한다고 봤다. 값은 설치 템플릿이 든다고 적었지만, 템플릿에 실제로 키를 넣는 일은 하지 않았다.
2026-10-21, 기준 숫자가 어디에도 없었다는 것을 알았다. 설치 템플릿에 키가 없어서 「돌려보고 고친다」가 돌 수조차 없었다. 값을 비워 두는 안을 버린 이유가 「비어 있으면 안 돈다는 것조차 안 보인다」였는데, 키가 아예 없는 템플릿이 바로 그 모양이었다. 그래서 15를 처음 정했다 — 한 프로젝트의 기능별 계약 수에서 빈 구간(12와 24 사이)을 골랐고, 기능별 누적이라 넉넉할 수 있다는 한계를 같이 적었다. 「돌려보고 고친다」만으로는 아무도 안 고친다는 것이 이번에 드러났으므로, 무엇을 모아서(물은 개수와 쪼갰는지) 어디서 세어(표준 저장소의 집계 이슈) 몇 번에(댓글 열 개) 다시 볼지까지 정했다.
같은 날 테스트 세션에 예외가 하나 생겼다. 설정만 바뀌는 이슈에서 「계약 이름마다 테스트를 대응시킨다」가 설정 파일을 다시 해석하는 테스트 1,058줄을 낳았다. 판정은 테스트 층위 선택 표준으로 보내고, 이 표준에는 「설정 — 배포 때 확인」 표시가 붙은 계약은 대응시키지 않는다는 한 줄만 두었다.
2026-10-24, 전제를 뒤집었다. 시작은 「열심히 하는데 진전이 없다」였다. 회사 일 · 블로그 · 퇴근 뒤의 프로젝트 세 갈래를 굴리는데, 퇴근 뒤의 프로젝트에 붙을 수 있는 사람의 시간은 평일 저녁 두 시간뿐이었다. 처음엔 그 두 시간 안에 에이전트를 맞추려 했다 — 진행 중인 이슈는 하나만, 22시 안에 닫을 크기만. 그때 내가 방향을 꺾었다. 에이전트를 쓰는 이유는 사람이 손대야 하는 부분만 사람이 하게 하는 것이라고. 그 순간 「사람이 있을 때만 돈다」는 사람에게 기다림을 만드는 전제가 됐다. 옛 전제가 막으려던 비용(아무도 모르는 채 굴러간 프로젝트)은 그대로 진짜였으므로, 버리지 않고 다른 셋(사람과 기획 · 계약 밖이면 멈춤 · 넘기는 일은 사람이 있을 때만)으로 묶었다.
같은 대화에서 디자인 · 마케팅의 빈칸이 나왔다. 내가 「일을 나눠 주는 관리 에이전트 하나에 기획 · 개발 · 디자인 · 마케팅 에이전트 넷」을 붙박아 두는 안을 냈다. 여기서 관리 에이전트는 1차 개정 때 사라진 탐색 전담 PM과 다른 자리다. 이 표준과 위상 표준에 맞춰 보니 기획은 단계이고, 개발 · 디자인 · 마케팅은 분야였다(「개발」은 단계 이름이기도 한데, 여기서는 코드를 만드는 분야를 가리킨다). 이슈마다 그 이슈가 어느 분야인지가 정해져 있고, 분야마다 알아야 할 것은 규칙 · 스킬 파일이 든다. 그러니 분야마다 에이전트를 붙박아 둘 필요가 없었다 — 이슈마다 새 작업 에이전트를 띄우면 그 에이전트가 이슈의 분야에 맞는 파일을 읽는다. 이것은 위상 표준 원칙 14(작업 에이전트는 이슈 하나마다 새로 만든다)가 이미 정한 답이라 그 안은 거기서 접었다. 일을 나눠 주는 자리도 위상 표준의 마스터가 이미 맡고 있었다. 그런데 단계를 끝까지 따라가 보니 세 번째 단계가 개발에만 정의돼 있었다. 다섯 쟁점을 하나씩 닫았고(원칙 19), 마지막에 정해진 적이 없던 것이 단계가 아니라 관문이라는 것이 드러났다.
같은 날 묻는 방식이 내 타이핑 시간에서 나왔다. 기획을 대화로 만들면 사람이 답을 처음부터 써야 하는 질문이 계속 온다. 에이전트가 판단을 먼저 세우고 고르게 하면 사람은 번호로 답한다. 비슷한 대화 방식이 블로그 쪽 스킬에 이미 있었지만, 배포본에 그 스킬을 통째로 싣지 않고 배포본 스킬의 기획 절에 한 줄을 더해 선택지 서식만 위상 표준을 가리키게 했다(원칙 5).
2026-10-25, 옮겨 적다가 커밋 대기와 부딪혔다. 하루 전에 정한 세 가지(사람 없이 도는 에이전트, 디자인 · 마케팅의 관문, 묻는 방식)를 이 글과 배포본 규칙에 옮겨 적다가, 밤에 맡긴 일이 커밋 전에 멈추면 테스트가 시작되지 못한다는 것을 알았다. 그래서 원칙 11의 커밋 전 확인 두 번을 PR 리뷰 한 번으로 합쳤다. 커밋 대기 표준 쪽 경위는 그 글의 원칙 4-4에 있다. 같은 자리에서 컨펌을 적는 커밋이 컨펌을 바로 푸는 모양도 잡았다 — 메타 파일만 바꾼 커밋은 셈에서 뺀다(원칙 19).
정리
- 에이전트는 사람 없이도 만들고, 넘기는 일만 사람이 있을 때 한다. 옛 전제가 막던 비용은 사람과의 기획 · 계약 밖이면 멈춤 · 넘기는 일은 사람이 있을 때만, 이 셋으로 묶는다
- 기능 하나에 이슈 하나. 계층은 이슈를 나누는 단위가 아니라 진행 단계다
- 기능이 커도 기본은 안 쪼갠다. 쪼개는 것은 이슈를 합친 결정을 되돌리는 일이다
- 쪼갤 때는 기능 축으로만. 테스트가 자기 계약만으로 도는지가 검문이다
- 나눠야 했던 것은 세션이지 이슈가 아니었다. 이슈 넷은 에이전트 넷의 부산물이었다
- 에이전트가 혼자 기획을 만들지 않는다. 채운 빈칸과 정한 것이 구별되어야 한다. 물을 때는 판단을 먼저 세우고 고르게 한다
- 본문은 기획의 산출물 전부를 다섯 절로 담는다. 빠진 것은 빈칸으로 보이지 않는다
- 계약은 한 줄이 검증 하나이고 이름으로 가리킨다. 이름이 짧은 댓글에서도 계약을 정확히 지목하게 한다
- 본문은 추가만 된다. 불변의 뜻은 글자가 아니라 이미 쓴 계약의 뜻이다
- 댓글은 사람만 읽고 사건마다 쌓인다. 독자를 하나로 잘라야 짧게 쓸 근거가 생긴다
- 계층 전환은 배정이 아니라 승인이다. 세션이 끊기는 개발 → 테스트도 배정이 아니다 — 2depth가 3depth를 직접 만든다(멀티 에이전트 위상 표준). 밤에 맡긴 일은 커밋 전 확인 두 번이 PR 리뷰 한 번으로 합쳐진다
- 테스트는 본문의 세 절만 읽는다. 버린 안은 절 제목으로 막는다. 「설정 — 배포 때 확인」 계약에는 테스트를 대응시키지 않는다
touch는 지웠다. 기획이 못 만드는 값을 기획 산출물로 요구하고 있었다- 세션이 끊기면 다시 파악한다. 복원용 기록을 남기는 비용이 장황함의 원인이었다
- 프로젝트 고유의 것은
.coding-standards/에 둔다. 관리 경로는 업데이트가 덮어쓴다 - 디자인 · 마케팅도 계층은 그대로다. 테스트는 기계 확인이고, 운영자 컨펌은 그 뒤에 서는 관문이다. 흔적은 결과물 옆 메타 파일이 든다
자신만의 철학을 만들어가는 중입니다.
댓글남기기