


공개 API를 깨지 않고 저수준 라이브러리를 작게 고치기
저수준 시스템 라이브러리를 AI가 고치거나 바꿀 때 쓴다. 변경은 작게 하고, 요청이 없으면 공개 API와 ABI를 바꾸지 않으며, 빌드와 바뀐 하위 시스템의 테스트를 돌리고, 메모리 오류에도 안전하게 실패하게 하며, 원격으로 push하지 않는다.
이 AI 규칙을 사용하려면
## 변경은 작게, 요청이 없으면 공개 API와 ABI 바꾸지 않기
안정적인 공개 응용 프로그램 프로그래밍 인터페이스와 응용 프로그램 바이너리 인터페이스를 엄격한 제약으로 취급한다.
### 편집 전
- 단순하지 않은 작업에 앞서 저장소의 빌드, 테스트, 구성, 기여, 릴리스 문서를 읽는다.
- 요청된 변경을 담당하는 하나의 하위 시스템이나 사안을 식별한다.
- 수정하는 모든 파일의 로컬 관례를 따른다.
- 관련 없는 사용자 변경 사항과 추적되지 않은 산출물을 그대로 보존한다.
### 변경 경계
- 광범위한 재작성보다 최소 차이와 점진적인 후속 변경을 우선한다.
- 관련 없는 코드의 이름, 순서, 형식을 바꾸거나 정리하지 않는다.
- 명시적으로 요청받지 않은 새 공개 인터페이스를 추가하지 않는다.
- 명시적으로 요청받지 않은 기존 공개 인터페이스나 바이너리 계약을 변경하거나 없애지 않는다.
- 선택적 기능의 동작, 기능 축소 빌드, 컴파일 시점 기능 가드를 보존한다.
- 빌드나 기능의 기본값을 암묵적으로 변경하지 않는다.
겉보기에 어색한 코드가 호환성 경계에 있다면 테스트, 이력, 주변 동작이 달리 보여 줄 때까지 실제 경계 사례를 다루고 있을 수 있다고 가정한다.
## 표준 절차로 빌드하고 바뀐 하위 시스템의 테스트 실행하기
특수한 검사에 의존하기 전에 저장소의 표준 구성, 컴파일, 테스트 절차를 사용한다.
### 기본 순서
1. 지정된 빌드 디렉터리를 구성하거나 다시 구성한다.
2. 영향을 받는 대상을 컴파일한다.
3. 현재 단계에 맞는 테스트 모음을 실행한다.
4. 빌드가 새로운 경고를 만들지 않았는지 확인한다.
빌드 디렉터리가 아직 없다면 재구성 전용 경로가 아니라 초기 구성을 사용한다. 실질적인 코드 변경이 있을 때마다 수정한 대상을 다시 빌드한다.
### 최소 대상별 검사
- 변환 또는 텍스트 셰이핑 로직에는 전용 동작 테스트 모음을 실행한다.
- 축소, 서브세팅 또는 그래프 작업에는 해당 하위 시스템 테스트 모음을 실행한다.
- 공개 인터페이스 작업에는 응용 프로그램 프로그래밍 인터페이스 테스트 모음을 실행한다.
- 명령줄 도구 작업에는 관련 도구를 다시 빌드하고 작은 대표 샘플로 실제 실행해 본다.
- 버그 수정이나 파서 강화에는 가능하면 가장 가까운 회귀 테스트, 퍼징 입력, 퍼징 대상 또는 예상 결과를 추가하거나 갱신한다.
대상별 검사는 반복 작업을 빠르게 하지만 공유 동작이나 릴리스 준비 상태가 영향을 받는 경우 더 넓은 검증을 대체하지 않는다.
## 하위 시스템별로 고칠 곳을 고르고 프로젝트 방식 따르기
코드를 수정할 위치를 선택하기 전에 인접한 책임을 이해한다.
### 책임 경계
- 핵심 라이브러리 동작을 설치 도구, 성능 측정, 문서, 언어 바인딩, 실험적 구성 요소와 분리한다.
- 그래프 도우미가 축소 절차의 동작에 관여하면 해당 절차의 일부로 취급한다.
- 래스터, 벡터, 그래픽 또는 이와 비슷하게 지나치게 큰 번역 단위에서는 분기를 더 추가하는 대신 범위가 분명한 도우미를 추출하고 책임별로 분리한다.
- 언어 통합에서는 빌드 연동을 변경하기 전에 네이티브 빌드 정의와 언어 패키지 매니페스트를 모두 확인한다.
### 기존 관례
- 프로젝트에서 확립된 할당, 오류, 분기 예측, 널 객체, 컨테이너, 유틸리티 패턴을 사용한다.
- 프로젝트 래퍼가 이식성이나 안전 동작을 담고 있다면 플랫폼의 원시 기능보다 이를 우선한다.
- 프로젝트에 확립된 컨테이너와 유틸리티가 있다면 핵심 코드에 외부 컨테이너 라이브러리를 도입하지 않는다.
- 공개 인터페이스 문서는 저장소에서 관례로 정한 소스 또는 문서 위치에 추가한다.
중복된 파싱, 캐싱 또는 도우미 로직이 퍼지기 시작하면 중앙화하되, 범위가 제한된 수정을 관련 없는 아키텍처 재작성으로 바꾸지 않는다.
## 메모리 오류나 악의적 입력에도 지원하는 모든 환경에서 안전하게 실패하기
할당 실패, 적대적 입력, 컴파일러 다양성, 기능 축소 빌드를 지원 범위의 정상적인 일부로 취급한다.
### 할당과 파서 안전성
- 새 코드가 메모리 압박에서 안전하게 실패하도록 기존 할당 및 오류 처리 패턴을 따른다.
- 입력 처리를 강화하기 전에 기존 파서 가드와 퍼징 기반 구조를 확인한다.
- 할당 실패를 주입했을 때 최소 허용 결과는 충돌, 범위 밖 접근, 메모리 손상이 발생하지 않는 것이다.
- 실험적 구성 요소에서는 메모리 압박 시 최선을 다해 조기에 실패하는 동작을 허용한다.
- 구성 요소 계약이 요구하지 않는 한 할당 실패 뒤의 부분 작업을 보존하기 위한 목적으로만 복잡한 롤백 로직을 추가하지 않는다.
### 이식성
- 컴파일러, 운영 체제, 아키텍처 비트 폭, 교차 빌드, 기능 축소 빌드의 회귀를 실제 버그로 취급한다.
- 프로젝트가 지원하는 도구 체인과 정수 비트 폭 전반에서 가정을 검증한다.
- 컴파일 시점 기능 가드와 대체 경로를 실제로 계속 실행해 본다.
- 저수준 코드를 단순화할 때 원래의 복잡성이 정렬, 오버플로, 수명, 에일리어싱 또는 플랫폼별 동작을 처리했는지 확인한다.
원래 실패를 입증할 수 없는 수정 전용 변경보다 재현 가능한 회귀를 우선한다.
## 생성된 테이블은 손으로 고치지 않고 생성기로 다시 만들기
모든 빌드 설명과 생성 결과를 소스 변경과 동기화한다.
### 빌드 시스템 변경
- 옵션, 구성 요약, 설치 도구, 테스트, 종속 대상을 함께 갱신한다.
- 패키징이나 교차 빌드 동작이 영향을 받는다면 주 빌드 시스템만 변경하지 말고 지원되는 모든 빌드 시스템을 확인한다.
- 작업이 기본값 변경을 명시적으로 요구하지 않는 한 옵션 기본값을 보존한다.
- 영향을 받는 선택적 기능의 활성화 형태와 비활성화 형태를 모두 검증한다.
### 생성 데이터
- 생성기, 원본 데이터 또는 빌드 자동화 흐름을 수정한 다음 결과를 다시 생성한다.
- 작업이 명시적으로 요구하지 않는 한 생성된 표나 색인을 수작업으로 편집하지 않는다.
- 생성 결과, 로컬 테스트 자원, 글꼴 또는 추적되지 않은 산출물을 폐기할 수 있다고 가정하지 않는다.
- 다시 생성된 차이에 예상하지 못한 범위 확장이나 비결정적 변경이 없는지 검토한다.
생성기 변경이 공개 데이터나 테스트 예상값에 영향을 준다면 같은 제한적 변경 안에서 관련 테스트와 문서를 갱신한다.
## 공개 API는 요청받을 때만 추가하고 버전 표시와 문서 붙이기
사용자에게 보이는 동작을 코드, 문서, 버전 관리, 빌드 연동이 조정된 하나의 변경으로 취급한다.
### 공개 인터페이스 승인 경계
- 공개 선언은 내부 구현 파일이 아니라 지정된 공개 헤더나 모듈에 둔다.
- 요청이 명시적으로 허용한 경우에만 새 공개 영역을 추가한다.
- 새 인터페이스가 허용되면 저장소에서 요구하는 버전 표식과 릴리스 노트 항목을 추가한다.
- 생성되는 섹션 색인, 문서 매니페스트 또는 참조 목록은 승인된 절차로 갱신한다.
- 호환성을 깨는 변경이 명시적으로 승인되지 않는 한 바이너리 배치, 심볼 가시성, 호출 규약, 소스 호환성을 보존한다.
### 사용자에게 보이는 동작
- 라이브러리나 설치 도구를 통해 기능이 보이게 되면 관련 문서를 갱신한다.
- 설치와 빌드 연동을 새로 공개된 동작과 동기화한다.
- 공개 인터페이스 문서와 생성 색인은 로컬 관례가 요구하는 위치에 둔다.
- 성공한 실행을 얻기 위한 목적으로만 실패 중인 테스트를 비활성화하지 않는다. 정당한 예외와 그 영향을 문서화한다.
## 먼저 근본 원인을 찾고 push 없이 커밋하기
변경을 완료로 제시하기 전에 원인과 결과를 입증한다.
### 작업 방법
1. 가능하면 문제를 재현한다.
2. 수정 코드를 작성하기 전에 근본 원인을 이해한다.
3. 중요한 모호함이 남아 있다면 추측하지 말고 질문한다.
4. 비정상적으로 복잡해 보이는 코드를 단순화하기 전에 이력을 확인한다.
5. 가장 가까운 회귀 범위를 추가하거나 갱신한다.
6. 변경한 하위 시스템, 영향을 받는 구성, 더 넓은 동작을 검증한다.
### 커밋 규율
- 코드, 빌드 로직, 생성 결과 또는 테스트 입력을 커밋하기 전에 전체 테스트 모음을 실행한다.
- 문서만 또는 지속적 통합만 변경한 경우 해당 영역에 영향을 줄 수 없을 때에만 전체 테스트를 생략할 수 있다. 생략 사실을 보고한다.
- 각 커밋은 하나의 문제나 사안에만 집중한다.
- 원격 저장소에 절대 푸시하지 않는다. 푸시는 권한을 가진 사람에게 맡긴다.
- 저장소의 하위 시스템 접두사, 기여 표시 트레일러, 메시지 관례를 사용한다.
- 여러 줄 커밋 메시지에는 이스케이프된 줄바꿈 시퀀스 대신 파일이나 편집기 기반 입력을 사용한다.
- 실제 수행한 작업이 뒷받침하는 경우에만 근본 원인, 수정, 테스트를 설명한다.
인계 시 변경 범위, 실행한 테스트, 경고, 지원되지 않는 구성, 해결되지 않은 위험, 수행하지 않은 검증을 보고한다.
