Imported from zer0ken/skills (
codex/sucks/SKILL.md). Install upstream withnpx skills add zer0ken/skills --skill sucks. Copyright stays with the author.
sucks - 한국어 기술 문서 문체
Keep it simple. 글은 목적을 이루는 데 필요한 최소한의 내용만 담는다. 군더더기 없는 글이 가장 좋은 글이다.
목적
한국어 산문의 문체를 감으로 잡지 않고 규칙으로 검사한다.
적용 대상
한국어로 쓰는 모든 산문에 적용한다.
- README
- 설계 문서
- 스펙
- 이슈 본문
- PR 본문
- 커밋 메시지 본문
- 슬라이드 본문
- 코드 주석
이 스킬은 다른 글쓰기 규칙과 함께 적용한다. 전역 AGENTS.md의 명료체 규칙처럼 특정한 글에 따로 정해진 규칙이 있어도 이 스킬이 물러나지 않는다. 두 규칙이 한 문장에서 서로 어긋날 때만 다른 규칙을 따르고, 그 밖의 모든 곳에는 이 스킬을 최대한 강하게 적용한다.
제목
제목은 이름이지 문장이 아니다. 제목은 그 절이 무엇을 다루는지 가리키는 명사구다. 제목에 문장을 넣으면 절이 제목을 설명하는 관계가 뒤집혀서, 제목이 절을 요약하게 된다. 요약을 받은 독자는 절을 읽을 이유를 잃는다.
종결어미(~다, ~요, ~습니다)와 서술어를 쓰지 않고, 문장부호(., !, ?)를 붙이지 않는다.
- 나쁜 예:
캐시를 도입해 응답 속도를 개선했다,왜 인덱스가 필요한가? - 좋은 예:
캐시 도입과 응답 속도,인덱스 필요성
다음 네 가지에 모두 적용한다.
- 문서 제목
- 절 제목
- 목차 항목
- 슬라이드 제목
절
절에도 응집도와 결합도가 있다. 절 하나가 한 주제를 얼마나 온전히 담는지가 응집도이고, 절이 다른 절에 얼마나 기대는지가 결합도다. 코드에서와 같이 응집도는 높이고 결합도는 낮춘다.
한 절은 한 주제를 끝까지 다룬다. 한 절이 여러 주제를 담으면 독자는 문장마다 어느 주제에 속하는지 판단해야 한다. 한 주제가 여러 절에 흩어지면 독자는 흩어진 절을 다 읽기 전까지 그 주제를 이해하지 못한다.
- 나쁜 예: 설치 절이 설정 파일 형식을 일부 설명하고, 뒤의 설정 절이 나머지를 설명한다
- 좋은 예: 설치 절은 설치만 다루고, 설정 파일 형식은 설정 절이 전부 다룬다
절은 다른 절을 읽지 않아도 이해된다. 절을 다 읽은 독자가 그 주제를 이해했다고 표시하고 다음 절로 넘어갈 수 있어야 한다. 상호 참조는 독자를 읽던 자리에서 떼어내므로 최소로 줄인다.
절의 순서는 독자가 이해하는 순서다. 앞 절이 세운 것과 독자가 처음부터 알던 것만으로 이해되게 배치한다. 글쓴이가 조사한 순서나 시스템의 내부 구조 순서로 정하지 않는다. 뒤 절을 먼저 읽어야 이해되는 절은 자리가 틀린 것이므로, 참조를 붙여 메우지 말고 순서를 바꾸거나 두 절을 합친다.
레벨
한 글은 하나의 레벨에서 서술한다. 글이 다루는 레벨은 제목과 첫 문단이 정한다. 도중에 더 아래 레벨로 내려가면 독자는 앞에서 세운 이해에 이어 붙일 자리를 잃는다. 기술이 무엇을 하는지 소개하다가 함수 이름, 필드 이름, 코드가 나오면 레벨이 내려간 것이다.
- 나쁜 예:
git-pptx는 변경된 슬라이드만 diff로 보여줍니다. XML은 태그마다 줄을 나눠 textconv로 넘깁니다 - 좋은 예:
git-pptx는 변경된 슬라이드만 diff로 보여줍니다. 어떤 슬라이드가 바뀌었는지는 함께 저장한 미리보기 이미지로 확인합니다
레벨을 내려야 하면 절을 나누고, 그 절의 제목이 새 레벨을 알린다. 한 문단 안에서는 내려가지 않는다.
사례를 열거하지 않는다. 기능의 성질을 한 번 서술하면 그 성질을 만족하는 사례는 독자가 채운다. 사례 열거는 레벨을 내리는 한 방식이고, 늘어놓은 목록은 곧 명세로 읽혀서 빠진 항목은 지원하지 않는다는 뜻이 된다. 열거는 그 목록이 실제로 전부일 때만 쓴다.
- 나쁜 예:
Chrome, Firefox, Safari, Edge에서 접근할 수 있습니다 - 좋은 예:
브라우저에서 접근할 수 있습니다
목록
열거할 때는 불릿으로 뺀다. 열거할 목록이 실제로 전부일 때에도 문장 안에 쉼표로 늘어놓지 않는다. 문장에 묻힌 목록은 항목 수를 세려면 다시 읽어야 하고, 항목마다 붙는 설명을 달 자리가 없다.
- 나쁜 예:
설정은 홈 디렉터리, 프로젝트 루트, 실행 인자 순으로 읽습니다 - 좋은 예: 앞 문장이
설정은 다음 순서로 읽습니다라고 밝히고, 홈 디렉터리와 프로젝트 루트와 실행 인자를 각각 한 줄로 적는다
항목마다 속성이 여러 개면 표로 만든다. 불릿 한 줄에 속성을 여러 개 담으면 독자는 항목을 비교할 때마다 줄 안에서 같은 속성의 자리를 다시 찾아야 한다. 표는 속성마다 열이 정해져 있어 세로로 읽으면 비교가 끝난다.
- 나쁜 예:
- retries: 기본값은 3, 실패한 요청을 다시 보내는 횟수가 이어지는 불릿 목록 - 좋은 예: 설정 이름과 기본값과 설명을 각각 열로 둔 표
속성이 하나뿐이면 불릿을 쓴다. 표는 열이 두 개 이상일 때만 쓴다.
문장
주어를 생략하지 않는다. 동작의 주체는 프로그램이고 이름으로 부른다. 무주어 문장은 글쓴이가 직접 하는 것처럼 읽힌다.
- 나쁜 예:
디렉터리에는 그대로 씁니다 - 좋은 예:
decomp는 git-pptx 디렉터리에 그대로 저장합니다
한 가지를 서술하는 평서문으로 쓴다. 허락 표현과 독자를 코치하는 2인칭 명령을 쓰지 않는다.
- 나쁜 예:
열어둔 채로 돌려도 됩니다 - 좋은 예:
덱을 편집 중인 상태에서 실행해도 안전합니다
에둘러 쓰지 않는다. 도입을 깔고 다음 문장에서 답하는 구조를 만들지 않는다.
- 나쁜 예:
파트 이름을 정규화하는 이유가 있습니다. 스크립트가 생성한 덱은... - 좋은 예:
decomp는 기본적으로 파트 이름을 정규화합니다. 스크립트가 생성한 덱은...
단어
도메인의 용어를 그대로 쓴다. 쉬운 말로 바꾼 것이 아니라 틀린 말로 바꾼 것이 된다.
- 나쁜 예:
미리보기를 그립니다,쓰는 법 - 좋은 예:
미리보기를 렌더합니다,사용법
한자어를 조어하지 않는다. 재-는 -하다가 붙는 동작성 명사에만 붙는다. 생성하다가 되므로 재생성은 되고, 번호하다가 안 되므로 재번호는 안 된다.
- 나쁜 예:
관계 ID 재번호는 걸러내지 못합니다 - 좋은 예:
관계 ID의 번호를 다시 매기는 것은 걸러내지 못합니다
고유어 단위 명사는 정해진 부류의 사물에만 붙는다. 벌, 장, 자루 같은 고유어 단위 명사는 세는 대상의 부류가 낱말마다 정해져 있다. 부류를 벗어나 쓰면 뜻이 넓어지는 것이 아니라 문법에 어긋난 말이 된다. 기술 문서가 세는 대상은 대부분 어느 부류에도 들지 않으므로 개, 건, 번, 회, 가지를 쓴다.
| 단위 | 세는 부류 |
|---|---|
| 벌 | 옷. 그릇과 수저처럼 짝을 갖춘 덩어리 |
| 장 | 종이와 유리처럼 얇고 넓적한 것 |
| 자루 | 연필과 삽처럼 손에 쥐는 긴 것 |
| 대 | 차와 기계 |
| 채 | 집과 건물 |
| 그루 | 나무 |
| 마리 | 짐승 |
| 켤레 | 신발과 양말처럼 짝을 이루는 것 |
| 송이 | 꽃과 포도 |
-
나쁜 예:
프로필마다 설정 한 벌을 둡니다 -
좋은 예:
프로필마다 설정 파일을 하나씩 둡니다 -
나쁜 예:
실행할 스크립트가 세 장 남았습니다 -
좋은 예:
실행할 스크립트가 세 개 남았습니다
부류에 실제로 드는 대상에는 그 단위를 쓴다. 서버는 기계이므로 서버 두 대라고 쓰고, 슬라이드는 낱장이므로 슬라이드 세 장이라고 쓴다.
고유어 동사는 정해진 부류의 목적어에만 쓴다. 짓다는 집과 밥과 이름처럼 목적어의 부류가 정해진 동사이지, 만드는 일 전반을 가리키는 말이 아니다. 부류를 벗어난 목적어에 붙이면 뜻이 넓어지는 것이 아니라 문법에 어긋난 말이 된다. build가 만드는 대상은 어느 부류에도 들지 않으므로 build를 짓다로 옮기지 않고 빌드하다로 쓴다.
-
나쁜 예:
프로젝트를 짓는 데 3분이 걸립니다 -
좋은 예:
프로젝트를 빌드하는 데 3분이 걸립니다 -
나쁜 예:
컨테이너 이미지를 지어서 레지스트리에 올립니다 -
좋은 예:
컨테이너 이미지를 빌드해서 레지스트리에 올립니다
기술적 대상에 비유를 쓰지 않는다.
- 나쁜 예:
pptx는 속이 zip입니다 - 좋은 예:
pptx는 슬라이드마다 XML 파일이 들어 있는 zip입니다
용어는 도입한 뒤에 쓴다. 처음 나올 때 정의하고 그다음부터 하나의 이름으로 부른다. 디렉터리라고만 하면 어느 디렉터리인지 알 수 없다.
외국어 키워드는 원어와 번역을 함께 적는다. 글의 주제를 이루는 개념을 외국어 그대로 적을 때, 처음 나오는 자리에 원어(번역) 형태로 둘 다 적는다. 원어만 적으면 독자는 그 말이 가리키는 개념을 모른 채 읽고, 번역만 적으면 독자가 원문 자료에서 그 개념을 다시 찾을 이름을 잃는다.
- 나쁜 예:
이 문서는 idempotency를 다룹니다 - 좋은 예:
이 문서는 idempotency(멱등성)를 다룹니다
병기는 처음 한 번만 한다. 그다음부터는 원어를 그 개념의 이름으로 삼아 끝까지 같은 말로 부른다.
- 나쁜 예:
write amplification(쓰기 증폭)을 측정한 뒤 write amplification(쓰기 증폭)을 줄입니다 - 좋은 예:
write amplification(쓰기 증폭)을 측정한 뒤 write amplification을 줄입니다
코드에 그대로 나오는 식별자와 명령어에는 병기하지 않는다. 번역할 대상이 아니라 부를 이름이다. 커밋처럼 한국어 기술 문서에 자리 잡은 외래어도 독자가 이미 아는 말이므로 병기하지 않는다.
금지 용어
표에 적힌 말은 쓰지 않는다. 어느 것도 틀린 말은 아니다. 다만 가리켜야 할 대상을 가리지 않고 글자만 채우는 쓰임이 굳어져서, 문장이 참인 채로 아무것도 알리지 못하게 된다. 대신 쓸 말은 문맥마다 다르므로 표에는 방향만 적는다.
| 금지 | 왜 | 대신 |
|---|---|---|
N갈래 (세 갈래, 네 갈래, 여러 갈래) |
세는 수만 있고 세는 대상이 없다. 독자는 무엇이 셋인지 모른 채 셋이라는 것만 받는다 | 세는 대상의 이름을 적는다 |
~한 자리 (고친 자리, 고장난 자리, 남은 자리) |
대상 대신 그것이 놓인 위치를 부른다. 무엇을 고쳤고 무엇이 고장났는지가 문장에서 사라진다 | 그 대상의 이름을 적는다 |
조용히 ~한다 (조용히 실패한다, 조용히 무시된다, 조용히 멈춘다) |
효력이 없었다는 사실과 그것을 알리는 신호가 없었다는 사실을 부사 하나로 뭉친다. 무엇이 어떻게 됐고 어떤 신호가 빠졌는지가 문장에서 사라진다 | 결과와 신호 부재를 따로 적는다. 결과는 무시된다, 누락된다, 반영되지 않는다, 실행되지 않는다로, 신호 부재는 오류 없이, 경고 없이, 종료 코드 0 으로처럼 적는다 |
~를 가른다 (성능을 가른다, 승패를 가른다, 결과를 가른다) |
나뉜다는 사실만 남고 무엇을 기준으로 어떻게 나뉘는지가 없다. 판단의 기준과 나뉜 값이 문장에서 사라진다 | 기준과 결과를 따로 적는다. 기준은 ~를 기준으로 결정한다, ~에 따라 결정된다로, 결과는 ~를 넘으면 ~가 된다처럼 조건과 값으로 적는다 |
-
나쁜 예:
개인정보 보호 조치를 네 갈래로 나눠 제시합니다 -
좋은 예:
개인정보 보호 조치를 암호화와 접근권한, 접속기록, 점검으로 나눠 제시합니다 -
나쁜 예:
갈래가 남아 있는 자리는 다음과 같습니다 -
좋은 예:
갈래가 남아 있는 스크립트와 슬라이드는 다음과 같습니다
자리라는 낱말 자체를 금지하는 것이 아니다. 글 안의 위치를 가리키는 소개하는 자리는 그대로 쓴다. 금지하는 것은 이름이 있는 대상을 그 이름 대신 위치로 부르는 쓰임이다.
-
나쁜 예:
--label bug 가 조용히 무시됐다 -
좋은 예:
gh 가 --label bug 를 반영하지 않았고, 오류 없이 종료 코드 0 을 돌려줬다 -
나쁜 예:
설정 파일의 위치가 로딩 순서를 가른다 -
좋은 예:
로더는 설정 파일의 위치를 기준으로 로딩 순서를 결정한다 -
나쁜 예:
청크 크기가 검색 품질을 가른다 -
좋은 예:
청크 크기가 512 토큰을 넘으면 검색 품질이 떨어진다
가르다라는 동사 자체를 금지하는 것이 아니다. 물리적으로 나누는 머리를 가르다는 그대로 쓴다. 금지하는 것은 판단이나 결과가 나뉜다고만 적어 기준을 빼는 쓰임이다.
정보
서술한 사실은 주장과 인과로 이어져야 한다. 참인 사실도 설명하지 못하는 자리에 놓이면 독자를 막는다. pptx가 zip이라는 사실은 버전 관리가 어려운 이유가 아니라 압축을 풀 수 있는 이유다.
한정어를 빠뜨리지 않는다. 한정어 하나가 문장의 참거짓을 바꾼다.
- 나쁜 예:
슬라이드를 렌더한 이미지를 저장합니다(매번 전체를 렌더한다는 뜻) - 좋은 예:
변경된 슬라이드를 렌더한 이미지를 저장합니다
제약 항목은 네 가지를 다 적는다. 증상만 적으면 독자가 판단할 수 없다.
-
무엇인지
-
언제 발생하는지
-
어떻게 보이는지
-
막을 수 있는지
-
나쁜 예:
관계 ID 재번호는 걸러내지 못합니다 -
좋은 예:
관계 ID는 PowerPoint가 다른 도구로 만든 덱을 처음 저장할 때 자기 순서대로 다시 매기는 값입니다. 내용이 같은 슬라이드가 변경으로 잡히지만, 정규화가 여기까지 처리하지 못해 막을 방법이 없습니다. 두 번째 저장부터는 나타나지 않습니다.
자기 검사
산문을 쓴 뒤 절과 문단마다 확인한다.
- 제목이 문장인가. 종결어미와 서술어를 뺀 명사구로 바꾼다.
- 한 절이 한 주제만 다루는가. 흩어진 주제가 있으면 한 절로 모은다.
- 다른 절을 읽어야 이해되는 절이 있는가. 참조를 붙이지 말고 순서를 바꾸거나 합친다.
- 문단마다 레벨이 같은가. 소개하는 자리에 함수 이름이나 코드가 섞였는지 확인한다.
- 사례를 열거한 곳이 있는가. 성질 하나로 줄일 수 있는지 확인한다.
- 남긴 열거가 문장 안에 쉼표로 들어가 있는가. 불릿 목록으로 뺀다.
- 불릿 한 줄에 속성이 여러 개 들어갔는가. 표로 바꾼다.
- 주어가 있는가. 없다면 누가 하는 동작인지 이름을 넣는다.
- 도메인 용어를 다른 말로 바꾼 곳이 있는가.
재-,-화,-성으로 만든 조어가 있는가. 원래 있는 단어인지 확인한다.- 고유어 단위 명사를 쓴 곳이 있는가. 세는 대상이 그 단위의 부류에 드는지 확인한다.
- 고유어 동사를 쓴 곳이 있는가. 목적어가 그 동사의 부류에 드는지 확인한다.
- 정의 없이 쓴 명사가 있는가.
- 주제를 이루는 외국어 키워드에 번역을 병기했는가. 처음 나오는 자리에만 병기했는지 확인한다.
- 서술한 사실이 바로 앞뒤 주장과 인과로 연결되는가.
- 한정어를 빼서 더 넓은 주장이 된 문장이 있는가.
- 제약을 적었다면 네 가지 질문에 다 답하는가.
- 금지 용어를 쓴 곳이 있는가. 표의
대신열대로 바꾼다.
두 가지 실패 모드
지적을 받고 반대 극단으로 가는 것이 흔한 실패다.
| 실패 | 증상 |
|---|---|
| 번역투 AI 문서체 | 무생물 주어, 과도한 피동, 명사 쌓기, 영어 어순의 강조 구문 |
| 블로그체 | 짧게 끊어 치는 문장, 구어체 동사, 2인칭 명령, 수사적 도입 |
목표는 둘 사이가 아니라 둘 다 아닌 중립 기술 문어체다.
설치와 업데이트
PowerShell (Windows):
irm https://raw.githubusercontent.com/zer0ken/skills/main/codex/sucks/install.ps1 | iex
Bash (macOS/Linux/WSL):
curl -fsSL https://raw.githubusercontent.com/zer0ken/skills/main/codex/sucks/install.sh | bash
같은 명령이 설치와 업데이트를 모두 한다. 다시 실행하면 최신 판을 받는다.
Keep it simple. 규칙을 다 지킨 글에도 뺄 것이 남는다. 지워도 목적이 그대로인 문장을 찾아 지운다.
