협업은 풀 리퀘스트에서 시작하지 않는다. 서로 안전하게 의견을 내고, 같은 문제를 보고 있으며, 무엇을 확인해야 다음 결정을 내릴 수 있는지 합의할 때 이미 시작된다. 이 문서는 Angular의 기여 가이드가 행동 강령, 질문, 버그, 기능 요청을 구분하는 방식에서 출발해 내가 문서와 패키지를 만들며 사용해 온 작업 원칙으로 연결한다.
네 가지 신호를 구분한다
| 신호 | 먼저 필요한 것 | 남겨야 할 결과 |
|---|---|---|
| 관계가 안전하지 않다 | 행동 강령과 비공개 신고 경로 | 사람을 보호하는 조치 |
| 사용법이나 판단 기준이 궁금하다 | 질문과 공개적으로 재사용할 수 있는 답 | 답변 또는 문서 |
| 약속한 동작과 실제 동작이 다르다 | 최소 재현과 기대 결과 | 버그 이슈와 회귀 테스트 |
| 아직 없는 결과가 필요하다 | 문제, 범위, 대안에 대한 합의 | 기능 제안과 검증 계획 |
이 구분은 사람을 돌려보내기 위한 분류가 아니다. 질문을 버그처럼 다루거나 기능 제안을 구현부터 시작할 때 생기는 왕복을 줄이고, 각 대화가 다음 행동으로 이어지게 하는 장치다.
사람을 먼저 보호한다
열린 협업은 의견의 강도가 아니라 참여자가 안전하게 반대할 수 있는지로 판단한다. 출신, 정체성, 경력, 사용하는 언어와 관계없이 같은 존중을 적용하고, 괴롭힘과 모욕은 기술적 논쟁으로 포장하지 않는다. 안전 문제가 생기면 공개 토론에서 사실관계를 겨루게 하지 말고 프로젝트가 정한 비공개 경로로 운영자에게 알린다.
내가 리뷰할 때 지키려는 기준은 다음과 같다.
- 사람의 능력이나 의도를 평가하지 않고 관찰 가능한 변경과 영향에 관해 말한다.
- “안 된다”에서 멈추지 않고 어떤 계약이 깨지는지, 무엇으로 확인할 수 있는지 설명한다.
- 제안한 범위를 넘어선 개선은 현재 변경의 필수 조건인지 후속 작업인지 구분한다.
- 내가 잘못 이해한 사실이 확인되면 결론과 문서를 함께 고친다.
- 중요한 결정은 나중에 참여한 사람도 맥락을 복원할 수 있도록 공개 기록으로 남긴다.
한국어와 영어 문서를 함께 유지하는 것도 이 원칙의 일부다. 번역은 부록이 아니라 같은 결정에 접근하는 두 개의 입구다. 용어가 서로 어긋나면 DDD 핸드북에서 설명한 것처럼 회의, 이슈, 테스트와 코드가 사용하는 언어도 함께 점검한다.
질문은 학습의 기록으로 남긴다
일반적인 사용법이나 설계 판단을 묻는 질문은 버그 이슈와 분리한다. 질문에는 달성하려는 결과, 현재 이해, 이미 시도한 것, 막힌 지점을 적는다. 답변자는 실행 가능한 다음 단계와 그 판단의 전제를 설명한다. 대화 중 약속한 동작과 실제 동작의 차이가 재현되면 그때 버그 이슈로 전환한다.
반복해서 찾을 가능성이 있는 답은 일회성 대화로 끝내지 않는다. 이 저장소에서는 Next.js, pnpm, Node.js와 TypeScript에 관한 질문을 버전이 명시된 Deep Dive로 남기고, 원문과 검증일을 함께 기록한다. 예를 들어 Next.js 16은 렌더링 경계와 MDX 파이프라인을, pnpm 11은 워크스페이스와 공급망 정책을 다시 확인할 수 있는 답으로 만든다.
좋은 질문은 다음 정보를 짧게 제공한다.
### 하려는 일
달성하려는 결과와 그 이유
### 막힌 지점
관찰한 결과, 기대한 결과, 이미 시도한 것
### 환경
관련 버전, 실행 위치, 필요한 최소 설정버그는 재현 가능한 차이로 설명한다
이슈를 열기 전에 열린 이슈와 닫힌 이슈, 진행 중인 풀 리퀘스트를 검색한다. 같은 현상이 이미 논의됐다면 새 설명을 흩뜨리지 말고 기존 기록에 새로운 재현 조건을 보탠다. 새 이슈가 필요하다면 다음 정보를 포함한다.
- 기대한 동작과 실제 동작을 각각 한 문장으로 적는다.
- 문제를 재현하는 데 필요하지 않은 코드와 데이터를 제거한다.
- 재현 단계, 버전, 운영체제처럼 결과를 바꿀 수 있는 환경을 기록한다.
- 로그와 화면은 결론이 아니라 관찰 증거로 첨부하고 민감한 값은 제거한다.
- 회귀를 막을 수 있는 가장 작은 검증 경계를 제안한다.
최소 재현은 제출자를 의심하기 위한 요구가 아니다. 유지보수자가 같은 실패를 확인하고, 수정 뒤에 같은 경로가 통과하는지 판단하기 위한 공동의 기준이다. 재현을 줄이는 과정에서 사용법 문제나 실제 실패 경계가 드러나기도 한다.
내 작업에서는 검증 범위를 문제의 경계에 맞춘다. 문서 메타데이터와 외부 값 변환은 단위 테스트,
한글·영문 쌍과 내부 링크·검색 인덱스는 콘텐츠 계약 테스트, 실제 탐색과 접근성은 Playwright로
확인한다. 모든 변경에 무조건 E2E를 추가하는 대신, 실패를 가장 가깝고 안정적으로 재현하는 테스트를
선택하고 사용자 흐름이 걸쳐 있을 때 통합 또는 E2E 검증을 더한다. TypeScript 6은
외부 값을 unknown에서 검증하는 경계를 보여 준다.
기능은 해결책보다 문제를 먼저 합의한다
기능 제안은 구현 아이디어가 아니라 아직 충족되지 않은 결과에 관한 설명으로 시작한다. 여러 소비자나 공개 API, 데이터 모델, 운영 방식에 영향을 주는 큰 기능은 이슈에서 먼저 논의한다. 새 문서 주제를 추가하거나 기존 주제를 크게 다시 쓰는 일도 같은 범주다. 방향이 합의되기 전에 큰 구현을 시작하면 좋은 코드라도 프로젝트가 선택하지 않은 문제를 풀 수 있다.
큰 기능 제안에는 다음을 적는다.
- 누가 어떤 상황에서 겪는 문제인지와 현재 우회 방법
- 기능이 제공해야 할 결과와 의도적으로 포함하지 않을 범위
- 고려한 대안과 선택 기준
- 기존 사용자, 공개 계약, 마이그레이션에 미치는 영향
- 성공을 확인할 테스트, 측정값 또는 사용 시나리오
작은 기능은 바로 풀 리퀘스트로 제안할 수 있다. 다만 “작다”는 코드 줄 수가 아니라 이미 합의된 방향 안에 있고, 영향 범위가 국소적이며, 쉽게 되돌릴 수 있고, 검증 방법이 명확하다는 뜻이다.
DDD 핸드북은 기능 목록보다 문제 공간과 언어를 먼저 정하는 방법을 설명하고, tooling 패키지는 반복되는 저장소 정책을 공개 계약으로 바꾼 사례다. 이 경험에서 기능 문서는 화면 목록보다 경계, 소비자, 호환성과 검증 방법을 먼저 보여 줄수록 구현과 리뷰가 짧아진다는 원칙을 얻었다.
이슈는 이유를, 풀 리퀘스트는 증거를 소유한다
이슈는 왜 이 작업이 필요한지와 어떤 결과를 받아들일지 기록한다. 풀 리퀘스트는 선택한 구현, 트레이드오프, 테스트 결과와 남은 위험을 기록한다. 둘을 연결하는 것이 이상적이지만 별도 이슈가 항상 필요한 것은 아니다. 연결된 이슈가 없다면 풀 리퀘스트 본문이 문제 설명과 수용 기준까지 포함해야 한다.
검토 가능한 변경은 하나의 목적을 가진다. 리뷰 피드백을 반영한 뒤에는 관련 테스트를 다시 실행하고, 설계가 바뀌었다면 설명과 문서도 함께 갱신한다. 성능 개선은 느낌이 아니라 같은 조건의 벤치마크로, 사용자 동작 변경은 재현 가능한 시나리오로 입증한다.
### 문제와 의도
왜 지금 바꾸는지, 무엇을 해결하는지
### 변경과 비범위
선택한 구현, 의도적으로 하지 않은 일
### 검증
실행한 명령과 결과, 수동으로 확인한 시나리오
### 영향과 후속 작업
호환성, 남은 위험, 별도로 다룰 일문서로 연결된 경험
| 문서 | 협업에서 다시 사용하는 경험 |
|---|---|
| DDD 핸드북 | 구현 전에 문제와 보편 언어를 맞춘다. |
| tooling | 반복되는 팀 규칙을 실행 가능한 공유 계약으로 만든다. |
| Deep Dive | 버전과 검증일을 붙여 기술 질문의 답을 재사용한다. |
이 문서들은 별개의 주제를 설명하지만 같은 흐름을 따른다. 사람과 문제를 먼저 이해하고, 경계를 명시하며, 실행 가능한 증거를 남긴다. 협업 규칙의 목적은 절차를 늘리는 것이 아니라 다음 사람이 같은 판단을 더 적은 추측으로 이어 가게 하는 데 있다.