--- name: ko-tech-writer description: 'Writes or revises Korean technical prose across three registers — reader-facing documents (tech-blog posts, technical docs), spoken scripts, and derived compressed assets (teasers, summaries) — through a fixed pipeline: register detection, real-sample calibration of the target venue, a translationese-removal pass, honesty-level layering (reader information vs internal audit vocabulary), a number/claim gate, and a rendition + perceptual QA pass. Triggers: "기술문서 써줘", "테크블로그 초안 잡아줘", "이 문서 번역투 고쳐줘", "블로그체로 다듬어줘", "이 글 회사 기술블로그에 올릴 수 있게 다듬어줘", "발표 대본 다듬어줘", "낭독 대본 점검해줘", "이 스크립트 소리 내서 읽을 때 걸리는 데 있나".' user-invocable: true allowed-tools: ["Read", "Write", "Edit", "Bash", "Grep", "Glob", "WebFetch"] model: sonnet --- # ko-tech-writer — 한국어 기술문서 집필·개고 파이프라인 한국어 기술 산출물을 쓰거나 개고한다 — **독자 대면**(테크블로그 글 · 기술문서 · 발표 파생 자산)과 **청자 대면**(발표 대본 자체) 둘 다이며, 레지스터는 Step 0 에서 가른다. 핵심 전제: **좋은 문장은 취향이 아니라 절차다** — 실물 표본으로 톤을 캘리브레이션하고, 번역투를 패턴 목록으로 제거하고, 수치는 근거와 창을 달고, 렌더 결과를 눈으로 확인한다. > 출처: 2026-08-10 발표 기술문서 세션에서 실측으로 벼려진 규율의 자산화. 이 문서의 규칙 > 클래스는 그 세션의 개고에서 실제로 검출·수리된 것들이다 — 근거 원장은 그 세션 기록 > (`fh_completed_2026-08-10` 및 해당 개고 커밋 이력. 비공개 세션 기록이라 외부 배포본 > 독자에게는 도달하지 않는 내부 포인터다). **실측 근거가 없는 클래스를 추가하지 않는 것**이 > 이 문서의 유지 규칙이다. 이 SKILL.md 자체는 독자 대면 문서가 아니라 하네스 자산이므로 > 이 파이프라인의 적용 대상이 아니다(FH 하우스 스타일을 따른다). ## Step 0 — 대상 판별 (레지스터 분기) 같은 내용도 매체에 따라 규율이 다르다. 먼저 셋 중 무엇인지 정한다: | 대상 | 레지스터 | 이 스킬의 적용 | |---|---|---| | **독자용 문서** (블로그 글·기술문서) | 문어 존댓말 (습니다체) | Step 1~5 전체 | | **낭독 대본** (발표 스크립트) | 구어 발표체 | Step 2~4 + **Step 5 콜드리드** + **Step 5-s(소리 렌더)** — 구어 리듬 유지, 줄표는 «쉼»으로만 실현되므로 소리로 안 들리는 동격·재진술 줄표 제거. 🟥 **Step 5 를 N/A 로 비우지 않는다**: 낭독은 «소리로 렌더»되므로 렌더 산출물이 없는 게 아니라 **렌더 매체가 소리**다 | | **파생 압축 자산** (티저·요약 이미지·1장 슬라이드) | 자립형 평문 | Step 2~**5** + **자립성 검사**: 화면·본문 맥락 없이 서야 하므로 정본 어휘·주장 범위·은어를 따로 대조. 렌더 산출물을 만들면 Step 5 지각 QA 필수 | 검증된 원문에서 파생 자산을 만들 때도 재검사한다 — 압축은 주장 범위를 움직일 수 있다 (예: «지점 앞에서 벼려졌다» → «도메인에서 확인해 온»으로 줄면 담당 범위가 넓어져 읽힌다). ## Step 1 — 실물 캘리브레이션 (표본 없이 톤 단정 금지) 게재 매체가 지정되지 않았으면 **먼저 묻는다**(한 줄). 답을 받을 수 없는 환경이면 일반 규율로 진행하고 그 사실을 이력에 명기한다. 게재 목표 매체의 **실제 표본을 1편 이상** 확인(WebFetch)하고 세 가지를 기록한다: 1. **문체**: 존댓말 변형(습니다/해요), 도입 형식(질문형/선언형) 2. **구성**: 소제목 밀도, 마무리 관행(일반화 + 트레이드오프 + 실무 조언 등) 3. **시각물**: 다이어그램/그래프/표를 어느 밀도로 쓰는가 캘리브레이션 기록은 **산출물 이력**(작업 로그·PR 본문·문서 frontmatter)에 남긴다 — 게재 본문에는 노출하지 않는다. 표본을 확인할 수 없으면 **무엇을 시도했고 왜 안 됐는지**(호출 실패·매체 미상 등)를 같은 이력에 명기하고 일반 규율(습니다체·소제목 세분화)로 진행한다 — 확인 안 된 톤을 확정처럼 쓰지 않는다. **시도 기록 없는 «확인 불가»는 Done When 1조를 충족하지 않는다.** ### Step 1-v — 매체 프로필: tech.kakaopay.com (2026-10-17 실측) > 출처: `tracks/_meta/ko_style_venue_kakaopay_2026-10-17.md`(내부 근거 원장 — 배포본에 미포함) — 게재 글 11편(kakaopay 8 + tech.kakao.com 3, 전부 열람 성공)을 스크립트로 센 값이다. > 🟥 **11편에서 센 범위이지 블로그 전체가 아니다.** 본문은 옮기지 않았고 수치만 적는다. 대조군(tech.kakao.com)은 > 요약·리뷰어 틀이 없어 **kakaopay 규칙으로 일반화하지 않는다.** 이 표본에 QA/테스트 글은 1편뿐이라 > QA 특화 관행은 **UNVERIFIED** 다. | 항목 | 측정값 (11편 중) | 이 스킬에서의 쓰임 | |---|---|---| | 레지스터 | 습니다체가 기본 — 10편에서 문장 종결의 약 89~100%. 해요체 문장은 요약·리뷰어 코멘트에서 주로 관찰됐고(KP1 10문장·KP4 8문장 등 본문에도 일부), 본문 전체가 해요체인 글이 1편(KP7). 절 안의 드리프트는 집계하지 않았다 — 관찰됨, 건별 판정 안 함 | S9 의 «표본 기준 단일화» 기준 = 습니다체. 제목은 한다체·명사형이 따로 있다 | | 틀 | kakaopay 8편 전부 요약(1~4문장), 6편에 💡 리뷰어 한줄평 박스, 이어서 시작하며 · 번호 매긴 h2 · 마치며 · (참고 자료) · 끝 바이라인 + 태그. 마치며 6/8 (KP3·KP6 은 소감/참고 자료로 닫음) | 초안 골격으로 쓴다. 바이라인·리뷰어 박스는 게재 채널 몫이라 본문 초안에는 자리만 둔다 | | 도입 | 소속·역할 자기소개 인사가 8편 중 5편, 독자 질문 훅이 흔함 | 자기소개는 필수 아님 — 주제나 장면으로 바로 여는 글도 3편 | | 소제목 밀도 | 1000자당 1.2~2.3 (전체 0.6~2.6) | | | 문장 길이 | 중앙값 18.5~61자, 보통 35~50자, p90 56~105자 | Step 2-b 리듬 대조의 외부 눈금 | | 영어 용어 | 한글(English) 최초 풀이가 가장 흔하고, English(한글)이 그다음, 제품·도구명은 원어 그대로. 컨텍스트·프롬프트·메트릭 같은 음차는 자유롭게 씀 | 첫 등장에 한글(English) 형태로 적는다. N9·N6 과 함께 본다 | | 기호 | « » 「 」는 **11편 전부 0건**. 줄표는 0~1.4/1000자(6편이 0, 1.0 이상은 2편뿐), 화살표는 0~1.0(6편이 0) — 금지는 아니나 소수 습관이고 제목과 단계 나열에 몰림. 곡선 따옴표 " "는 용어·인용에 흔함 | Y1/Y2 가 이 매체에서 «외래»인 근거. 줄표·화살표는 S1 이 따로 다룬다 | | 시각물 | 이미지 0.0~2.5/1000자, 발표 기반·도구 글이 1.2~2.5 | | 번역투 어휘의 매체 내 빈도(을/를 통해 0.0~1.0, 에 대해 0.0~0.9, 이라는 0.1~1.5 /1000자)는 위 파일 §Word-order 에 있다 — 🟥 **그것은 이 매체에서 «관찰된 범위»이지 교정 대상이라는 판정이 아니다**(관찰됨, 건별 판정 안 함 — 수확도 교정 쌍 0). 아래 Step 2 의 «추가하지 않은 것» 참조. ## Step 2 — 문체 규율 (번역투 클래스 목록) 아래는 실측으로 검출된 클래스다. **기계 스캔 + 눈 판정**으로 제거한다 (grep은 후보를 표시할 뿐, 남길지 판정은 문맥으로): 🟥 **정규식을 표 안에 두지 않는다.** GFM 표 셀에서 `|` 는 열 구분자라, **이스케이프하면 복붙 실행이 깨지고**(rg 에서 `\|` 는 리터럴 파이프) **안 하면 렌더가 깨진다.** 두 뿔 어느 쪽도 답이 아니므로 패턴은 전부 아래 코드블록에 두고 표는 번호로만 가리킨다. 🟥 **여기에 숫자를 적지 마라 — 계측 대상은 Step 2-a 의 정본 픽스처다.** 파일은 편집할 때마다 자라므로 **자기 자신을 대상으로 적은 크기는 다음 편집에서 조용히 거짓이 된다.** 초판이 그렇게 적었고, 적대 라운드가 그 숫자들이 **같은 커밋 안에서 이미 죽어 있는 것**을 실측으로 보였다. 기전만 적는다: **이스케이프판은 리터럴 파이프를 찾으므로 0건을 내고, 저자는 그걸 「잔여 0」으로 읽는다.** 크기가 필요하면 Step 2-a 의 레인을 돌려라. | # | 클래스 | 검출 | 수리 | check-class | |---|---|---|---|---| | **S1** | 줄표 이어붙임 「~다 — ~고,」 | `S1a` 분모(2분할) + `S1b` 판정 대상 | 문장 분리. 줄표는 **일을 하는 곳만** 남긴다(열거 매달기·리듬 결속·**인용된 원문**) — 남긴 이유를 적는다 | measured | | ~~S2~~ | *(비어 있다 — 「범위 표기의 물결표」가 여기 있었다. 2026-08-25 Added-Scope 판정으로 **별건 분리**: 그 클래스는 자기 행에 「낭독 대본은 N/A」라고 적어, 이 변경의 명시된 일과 다른 일이었다. 번호는 재사용하지 않는다 — 후속 변경이 이 자리로 돌아온다)* | — | — | — | | **S3** | 용어-머리 「**X** — 설명」 | `S3` | 「**X**: 설명」 콜론형 | measured | | **S4** | 콜론 나열투 「관측된 분업은: …」 | 서술어 없는 `:` 도입. ⚠️ **정본 레인 C3 에 후보 패턴이 있다** — 다만 후보 표시용이고 판정은 눈이다 | 완결 문장으로 (「…분업은 ~라는 것입니다」) | judged | | **S5** | 조각문 「걸리는 층.」 | 서술어 없는 마침. ⚠️ **정본 레인 C4 에 후보 패턴이 있으나 «닫힌 명사 어휘»라 recall 이 낮다**(스크립트 주석이 그렇게 적는다) — 넓히려면 형태소 분석이 필요하다 | 서술어 복원 (「걸리는 층입니다」) | judged | | **S6** | 소유 직역 「~을 갖다/가지다」 | `S6` — 갖추다(「절차를 갖춘」)는 «have» 직역이 아니라 레인이 뺀다(tuning doc 1건에서 2건 오탐 — 보고치, n=1, 독립 아님) | 존재문으로 (**「이전 상태를 갖지 않는다」 → 「이전 상태가 없다」**). 영어 `have` 의 직역이고, 한국어는 소유보다 존재로 말한다. 소유가 실제 논점인 자리(권한·지분)는 남긴다 | measured | | **S7** | 내부 조어·은어 | `S7` — 🟥 **라틴 약어 후보는 기계가 뽑는다**: `python3 scripts/ko_tech_writer_calibrate.py --scan "$F"` 의 `C16` 행(`[A-Z]{2,}` 약어 중 첫 등장에 풀이 `TERM(한글…)`·`한글(TERM)`·`TERM =`·`TERM은/는 … 입니다` 가 없는 것; 제목 첫 등장은 제목 안 풀이만 인정해 `heading-before-gloss`). 후보 전용 — 널리 아는 약어 목록(기술 독자 기준)은 문서마다 고쳐라. 한글 조어(「캐릭터 옆」류)는 못 뽑는다. 그 밖엔 후보 낱말을 목록화해 전수 세고, 각 낱말의 **첫 등장 ±40자에 풀이가 있는지**를 기계로 본다. 「3회 이상 나오는데 첫 등장 풀이 0」이 우선 후보 | 청중 어휘로 평문화. 단 **화면이 어휘를 받치면**(실제 빨간 화면을 가리키는 발화) 유지 가능 — 근거를 적는다. 🟥 **독자층 눈금을 먼저 정한다** — 기술 청중에게 「레포·커밋·도메인」은 일상어다 | judged | | **S8** | 지시 불명확 대상어 (조어와 다른 축) | 타동사인데 목적어가 문장 안에 없는 낱말 — 「낸 것」·「돌렸다」·「그거」. **기계 패턴 없음, 눈**. 🟥 **풀이를 붙여도 안 닫힌다** — 어려운 게 아니라 「무엇을」이 비어 있다 | 목적어를 문장 안에 복원한다 (「낸 것」 → 「변경분」·「작성자」) | judged | | **S9** | 레지스터 드리프트 | 습니다↔해요↔평어 혼재 — 눈 | 표본 기준 단일화 | judged | | **S10** | 따옴표 기호 « » 「 」 (수확 Y1·Y2) | `S10` — 독자 대면 문서 한정. `[그림: …]`·`[차트: …]` 블록과 코드 펜스 안은 편집 대상 밖이라 제외(스캔 모드가 도려낸다). 🟥 이 레포의 내부 문서·이 SKILL.md 는 낫표를 많이 쓰므로 **대상 파일이 독자 대면인지 먼저 정한다**. 매체 프로필상 kakaopay 11편에 0건 | 작은따옴표 ' ' 또는 평문으로 (「«정리»하면서」 → 「'정리'하면서」, 「「2분」이면 충분합니다」 → 「2분이면 충분합니다」). 인용된 원문 안의 기호는 남긴다 | judged, candidate (origin A) — 출처 `tracks/_meta/ko_style_harvest_2026-10-17.md` §1-c, 삭제 토큰 «»36·「」47, 쌍 대부분 AI 스윕. 운영자는 렌더를 눈으로 보고 결함 3종을 별도로 적발했을 뿐 이 기호를 지목한 발화는 수확에 없다. 보정 §4 X1 | | **S11** | 절 기호 § (수확 Y3) | `S11` — 도구 출력을 축자 인용한 자리는 제외(수확에서도 6건을 남겼다) | 「§1.1-§1.6」 → 「1.1-1.6절」, 「README.md §Quick Start」 → 「Quick Start 항」 | judged, candidate (origin 미표기 → A 로 취급) — 출처 같은 파일 §1-c, 8건. 커밋 메시지에 «한국 회사 문서 관례» 진술이 있으나 수확이 origin 을 표기하지 않았다. 보정 X2 | | **S12** | 글말의 짧은 부정 안/못+동사 (수확 N3) | `S12` — 🟥 **후보 표시 전용.** 「안 되·돼·됩니다·된다·된·됨·됐다·되는·되나·되면·함(으로·을·이·은·과)」처럼 **어절 전체가** 정상 형태일 때만 부정 목록으로 뺀다(「안 되돌렸다」는 남는다)(tuning doc 1건에서 오탐 4건 전부가 이 형태 — 보고치, n=1, 독립 아님). 그래도 잔여 0 을 목표로 삼지 않는다. 그림·차트 블록과 코드 펜스 안은 제외 | 「안 잰」 → 「재지 않은」, 「못 읽었습니다」 → 「읽지 못했습니다」, 「못 고친다」 → 「고칠 수 없습니다」. 구어 대본에서는 정상이므로 낭독 레지스터는 대상 아님 | judged, candidate (origin A) — 출처 같은 파일 §1-b N3, 삭제 토큰 49(덱·FoD), 보정 T2 (노이즈 큼) | | **S13** | 구어 이유·연결 어미 ~니까요 ~고요 (수확 N4) | `S13` — 습니다체 독자 문서 한정 | 「물려받으니까요」 → 「물려받기 때문입니다」, 「부분이고요.」 → 「부분입니다.」. ⚠️ **낭독 대본에서는 구어가 정상**일 수 있다 — 이 쌍은 낭독 대본이 독자 문서로 바뀌는 과정에서 나왔다 | judged, candidate (origin 미표기 → A 로 취급) — 출처 같은 파일 §1-b N4, 삭제 토큰 13, 보정 T1 | | **S14** | 인칭 직역 당신 / ~을 필요로 하다 (수확 N5) | `S14` (🟥 «그것» 은 패턴에 없다 — 운영자 손편집이 넣은 낱말이라 정상 용법을 따로 판정한다) | 「당신에게서」 → 「손을」·「사람의」, 「PyYAML을 필요로 합니다」 → 「PyYAML이 필요합니다」. 🟥 **히트는 건별 판정이다**. | judged, candidate (origin A) — 출처 같은 파일 §1-b N5, 삭제 토큰 당신 22·필요로 2, 보정 T3 T4. 「그것」은 이 클래스의 패턴에서 뺐다(운영자 손편집이 넣은 낱말 — 수확 §3) | | **S15** | 라틴 문자 뒤 조사 띄어쓰기 (수확 N9) | `S15` — 그림·차트 블록과 코드 펜스 안은 제외 | 「Claude Code 는」 → 「Claude Code는」, 「Slack 은」 → 「Slack은」. 코드 스팬·표기 예시 인용은 제외 | judged, candidate (origin A) — 출처 같은 파일 §1-b N9, 6건 이상, 보정 T6 (정규식은 가장 깨끗하나 쌍은 AI 스윕) | | **S16** | 같은 대상의 이명·어휘 계열 불일치 (수확 N6) | 정규식 없음. **용어표 대조**: 후보 낱말쌍을 목록화하고 문서 전체에서 각 변형의 빈도를 센다(`rg -oi '자가 채점|자기 채점' "$F" | sort | uniq -c` 처럼(🟥 눈 판정 보조일 뿐 레인이 없다) 변형을 `|` 로 묶어 개수가 아닌 «몇 가지가 섞였나»를 본다). 화면과 대본, 또는 같은 장 안에서 갈리면 우선 후보 | 한 변형으로 단일화하고 용어표에 정본을 적는다 (「자가 채점」 → 「자기 채점」, 「컨텍스트」 → 「맥락」, 「이슈/버그」 → 「버그」). 🟥 **매체가 자유롭게 쓰는 음차(컨텍스트·프롬프트)는 이명이 아니다** — 한 문서 안에서 갈릴 때만 본다. 「검사 11 vs 테스트 30」 같은 계열 분포는 판정 재료일 뿐이다 | judged (origin R + 커밋) — 출처 같은 파일 §1-b N6, 10건, 리뷰어 지적이 3장에 복제돼 있던 사례. 레인 없음 | | **S17** | 어순: 목적어가 앞에서 주어를 밀어냄 (수확 N1) | **UNCALIBRATED — 기계 패턴 없음, 눈.** 수확이 시도한 정규식은 양성이 1건뿐이라 그 한 문장에 맞춘 것이다(일반화 안 됨) | 주어를 앞으로, 쉼표로 목적어절을 떼어 놓는다 (「통과를 막고 서는 게이트를 방법론들이 만듭니다」 → 「방법론들이, 통과를 막고 서는 게이트를 만듭니다」) | judged (origin O, 단일 지시) — 🟥 **희귀하지만 운영자가 직접 지시한 클래스**: 출처는 단일 운영자 지시 1건(120장 전수 스캔에서 같은 패턴 1건뿐, 리뷰어의 단독 지적 0건). 이 사실보다 강하게 적지 않는다. 출처 같은 파일 §1-b N1 · §4 N1 | | **S18** | 문장 이음매 끊김: 짧게 끊다 연결어·주어 연결을 잃음 (수확 N11) | **기계 패턴 없음 — 판단 전용.** 「연결어가 없는 문장」은 정규식으로 안 갈린다(증거 없는 패턴을 짓지 않는다). 눈: 소리 내어 읽다 문장 사이에서 멈추는 자리, 앞 문장의 주어·화제가 다음 문장에서 갑자기 바뀌는 자리 | 연결어(그런데·그래서·이어서)와 주어 연결을 복원한다 (「QA는 오랫동안 "…"를 물어 왔습니다. 검증 대상이 … 넘어오면서 질문이 뒤집혔습니다.」 → 「…라는 질문을 다뤄 왔습니다. 그런데 검증할 대상이 … 바뀌면서, 질문도 "…"로 바뀌었습니다.」). 🟥 **S1 과의 조정**: S1 이 줄표 이어붙임을 문장으로 나누라는 것은 **연결어를 버려도 된다는 허가가 아니다.** 나눈 뒤 두 문장이 «그런데/그래서»로 이어지는지 다시 읽는다. S1 의 문장 길이 압력은 이음매 복원보다 약한 제약이다 — Step 4-b 의 길이 게이트와 부딪히면 이 클래스가 이긴다(길이 게이트를 닫기 전에 이 클래스로 한 번 되읽는다) | judged (origin O) — 수확 «추가 운영자 교정» N11. S1 규율의 부작용 축(과교정). **«덜 고치기» 방향의 규칙** | | **S19** | 과순화: 번역투를 피하려 만든 비유·순우리말이 뜻을 흐림 (수확 N12) | **기계 패턴 없음 — 판단 전용.** 비유어 목록을 닫을 수 없다 | 업계에서 통하는 평범한 말로 되돌린다 (「이 글은 네 걸음으로 갑니다」 → 「이 글은 네 장으로 구성했습니다」, 「다음 걸음으로」 → 「다음 글에서는」). 판정: 처음 읽는 독자가 한 번에 뜻을 잡는가. 못 잡으면 순화를 취소한다 | judged (origin O) — 수확 N12. 번역투 제거 방향이 만든 과교정이므로 S1~S17 을 적용한 직후 **이 클래스로 한 번 되읽는다** | | **S20** | TMI 자기 단서: 독자 문서에 약점·내부 감사 문구를 앞세움 (수확 N13) | **기계 패턴 없음 — 판단 전용** (Step 3 의 문장 단위 기준을 적용). 후보 눈표지: 「밝혀 둡니다」·「싣지 않습니다」·수치 바로 뒤에 붙는 단서 문장 연속 | 독자의 다음 행동·판단을 바꾸지 않는 단서는 지운다. 강점·실측을 앞에, 한계는 짧게 뒤에. (「동료 심사를 거친 논문이 아니라는 점은 먼저 밝혀 둡니다」 같은 문장, 수치 뒤 단서 세 문장) | judged (origin O) — 수확 N13. Step 3 와 같은 축을 더 세게 적용. 🟥 논지를 받치는 정직(한계 절·소표본)은 지우지 않는다 — 지우는 것은 **자기감사 말투** | | **S21** | 내부 용어가 독자 본문에 샘 (수확 N14) | `S21` | 외부 독자 말로 바꾼다. 수확 목록: 팔(arm) · 계기 · 초록(=통과) · 공격 배터리 · 라운드 · 결박 · 정규화 · 이긴 기록 · 열화 방향 렌즈 (「시험 하네스」는 S22 에서 한 번만 센다). 🟥 **레인(C13)은 문맥 없이 뜻이 하나뿐인 합성어(공격 배터리·이긴 기록·열화 방향 렌즈)만 잡는다.** 결박(물리적 구속·보안 문서의 해시 결박)·팔·계기·초록·라운드·정규화는 일상어와 겹쳐 레인에 넣지 않았다 — S7(내부 조어)처럼 눈으로 본다. 히트는 후보다 | judged (origin O) — 수확 N14 는 낱말 목록이지 before→after 쌍이 아니다. C13 레인은 «만든 예문으로 판별되는지»만 보증한다(분포 밖 오탐률 미측정) | | **S22** | 「시험」 → 「테스트」 (수확 N15) | `S22` | 소프트웨어 맥락의 「시험 하네스」(수확)와 같은 꼴의 「시험 환경·결과·케이스·코드·자동화·통과」(추론 — 수확에 없음)는 「테스트」로. 🟥 붙여 쓴 합성어(임상시험·자격시험·모의시험)는 레인이 안 잡는다. 띄어 쓴 「수능 시험 결과」 같은 정당한 용법은 **잡힌다 — 알려진 과차단**(C9 와 같은 처리). 히트는 후보다 | judged (origin O) — 수확 N15 는 «시험 → 테스트» 한 줄뿐이고 쌍이 없다. C14 레인은 만든 예문으로 판별만 보증한다. 「시험해」·「시험했」은 «시도하다» 뜻이 흔해 레인에서 뺐다 | | **S23** | 외국식 표현 (수확 N16) | **기계 패턴 없음 — 판단 전용.** (경동사 «내다» 변종 「'통과'를 냈다」·「판정을 내는」만 레인 `C15` 가 후보로 표시 — 🟥 UNCALIBRATED, 예상 과차단은 «내다» 가 제출 뜻인 정상 용법(「'신청서'를 냈습니다」) — 「판정을 내리다」는 이 패턴에 안 걸린다) 수확의 세 사례는 서로 다른 이유라 하나의 패턴으로 안 묶인다 | 한국어 관용으로 바꾼다 (「잽니다」 → 「측정합니다」). 같은 부류로 기록된 것: 「실험의 결과는 이렇습니다」(영어 구조 직역) · 「문제의식은 짧습니다」(«생각이 짧다»로 읽힘 — 수확에 after 없음). 자기 점검: 그 문장이 영어로 먼저 떠올랐나 | judged (origin O) — 수확 N16. after 쌍이 1건뿐이다. 그 이상으로 일반화하지 않는다 | | **S24** | 제목: 한국어판 + 원제 병기 (수확 N17) | 체크리스트 항목 — 패턴 없음 | 영문 원제가 있는 글은 제목에 한국어판을 쓰고 원제를 병기한다. 발행 전 제목 줄에서 확인 | judged (origin O) — 수확 N17. 문체 클래스가 아니라 발행 체크 | > **S10~S24 의 위상 (2026-10-17 수확; S18~S24 는 같은 날 오후·저녁 운영자 교정 N11~N17)**: 근거 원장은 `tracks/_meta/ko_style_harvest_2026-10-17.md`(내부 근거 원장 — 배포본에 미포함. 운영자 손편집·외부 리뷰어 지적·운영자 발화에서 뽑은 before→after). > 🟥 **이 클래스들이 전부 «운영자 교정에 근거한다»고 읽지 마라.** 쌍마다 origin 이 O(운영자 직접)·R(외부 리뷰어)·A(AI 스윕·스킬 규율 적용분)로 갈리고, > **O/R 쌍으로 확인된 것은 S16(R)·S17(O, 1건)·S18(O, 1건)·S19(O, 2건)·S23(O, 1건)이다. S20~S22·S24 는 운영자 지적(origin O)이지만 before→after 쌍이 없다 — 위 표의 각 행이 한계를 적는다.** 나머지는 origin A 이거나 수확이 origin 을 표기하지 않은 것이라 `judged, candidate` 로 둔다 > (`measured` 는 O/R 쌍이 받친 클래스에만 쓴다). 그 수확은 하한이다 — 운영자의 가장 직접적인 손편집이 든 .key/.pptx 는 이진이라 못 열었다. > 🟥 **히트는 후보이지 자동 수리 대상이 아니다.** 수확 §3 이 보인다: 운영자 본인의 손편집이 「그것을」을 넣었고, > 「릴리스」→「릴리즈」·「두 번째」→「두번째」·「반복 사용을」→「반복사용을」처럼 표준 표기와 **반대 방향**으로도 갔다. > 정규식이 낸 후보를 일괄 치환하면 운영자 취향과 충돌한다 — 건별로 보고 남긴 것에는 사유를 적는다. > 🟥 **S10~S15 의 정규식은 위 수확 §4 의 보정을 따르되, 판별력은 Step 2-a 레인(C7~C12)이 따로 잰다.** > 코드블록과 레인의 패턴이 두 벌인 문제는 여기서도 그대로다. 수확 §4 도 «known-negative 는 같은 내용의 정상 문장이라 > 분포 밖 입력의 오탐률은 미측정»이라고 적었다. > > **추가하지 않은 것 (측정된 교정이 없음)**: `~를 통해` · `~에 대해` · `~에 있어서` · `~되어지다`. > 수확이 연 채널(커밋 20여 개의 삭제 토큰)에서 통해 1 · 대해 2 · 있어서 3 · 되어지 0 이고, 셋은 다른 이유로 지나가다 > 걸린 것이지 교정 대상으로 겨냥된 쌍이 아니다(컨트롤 「않았」22건은 살아 있어 계기 고장은 아니다). 🟥 **0 은 «연 채널에서만»의 > 0 이다** — 수확 §7 의 «못 연 것»(이진 덱, 스크린샷 교정, 미개봉 커밋)은 0 이 아니다. 게다가 이 표현들은 게재 매체 자체에서 > 관찰된다(`tracks/_meta/ko_style_venue_kakaopay_2026-10-17.md` — 통해 0.0~1.0, 대해 0.0~0.9 /1000자). ⇒ **패턴 목록·스캔·레인에 넣지 않는다.** 문맥으로 판단하고(매체에서 관찰되는 쓰임과 어색한 쓰임을 문맥으로 가른다), **자동 제거하지 않는다.** 근거가 쌓이면 그때 위 표에 번호를 받아 들어온다. > 같은 이유로 `~하는 것이다`·`~들` 과다도 넣지 않았다(수확 §2). > 수확의 Y4(범위 물결표)·Y5(화살표 글리프 미확정)·Y6~Y9, N2·N7·N8·N10 은 이번에 들이지 않았다 — 각각 기계 치환이라 사람 근거가 없거나 > 쌍이 없거나 방향이 갈리거나 소설 도메인이다(수확 §1). > **S8 의 1차 출처 (2026-08-24, 필드 리뷰)**: 발표 대본의 「낸것 / 안낸것」이 「**인풋 / > 아웃풋으로 직관화**」 권고를 받았다 — 내부 전용 축약어를 일반 청중 언어로 번역하라는 지적이다. > 🟥 **「낸 쪽」은 그 리뷰가 지목한 결함이 아니다** — 2026-08-18 에 「저자」→「낸 쪽」으로 이미 > 수리된 형태였다. **처방을 결함으로 인용하지 마라**(이 파일에서 두 번 났다). > ⚠️ 그렇다고 최종형도 아니다 — 같은 2026-08-25 에 다시 「작성자」로 갔다. 한 낱말이 두 라운드에 > 걸쳐 움직였다는 사실 자체가 S8 이 **눈 판정 클래스**인 이유다. ```bash F='대상.md' # 🟥 <> 는 셸 메타문자다. 따옴표로 감싼 실제 경로를 넣어라 # ── S1a 줄표 분모 — 🟥 2분할. en dash 는 «줄표»와 «범위 표기» 둘로 쓰이므로 한 통에 세면 # 분모가 부푼다. 줄표 분모 = ①전수 + (②−③) rg -c '[—―]' "$F" # ① em·horizontal — 전량 줄표 후보 rg -c '–' "$F" # ② en dash 전수 rg -c '[0-9]\s*–\s*[0-9]' "$F" # ③ 그중 범위 표기 = 정상. 줄표 분모에서 뺀다 # ── S1b 줄표 판정 대상 — 위험 부분집합만 건별로 판정 rg -n '(습니다|입니다|다|것|음)\s*[—–―]\s*\S' "$F" # 거짓 종결: 종결어미 뒤로 문장이 계속된다 rg -n '[—–―]\s*$' "$F" # 줄끝 # ⚠️ `" — "`(양쪽 공백) 금지 — 줄 끝 em dash 는 오른쪽 공백이 없어 구조적으로 안 잡힌다. # 🟥 여기에 크기를 적지 마라 — 대상이 움직이는 파일이면 그 숫자는 다음 편집에 죽는다. # ⚠️ 문자군은 `[—–―]` — em(U+2014)만 잡으면 en(U+2013)·horizontal(U+2015)이 샌다. # ── S3 용어-머리 「- **X** — 설명」. 🟥 `^\S+` 로 쓰면 «볼드 글머리»라는 자기 클래스 정의를 # 못 잡는다 — 정본 픽스처의 known-positive 를 0건으로 놓쳤다(2026-08-25 적대 라운드 적발). rg -n '^\s*[-*]\s+\*\*[^*]+\*\*\s*[—–―]\s' "$F" # ── S6 소유 직역 rg -n '(을|를) ?(갖(?!추|춘|출|춤|춰|췄|춥)|가지(?!런|각|치))' --pcre2 "$F" # 🟥 look-ahead 라 --pcre2 필수. 못 쓰는 환경이면 Python re 로 (S12 와 같은 이유) # ── S10~S15 측정 클래스 후보 (🟥 전부 후보 표시. 보정 출처: 수확 §4, 레인 C7~C12) rg -n '[«»「」『』]' "$F" # S10 rg -n '§' "$F" # S11 # S12·S15 는 look-around 가 필요하다 — 기본 `rg -n` 은 파싱 에러로 죽고 그 출력이 «0건»으로 읽힌다. Python `re` 로 돌린다 python3 -c 'import re,sys;rx=re.compile(r"(?/fixtures/` 를 먼저 쳐라.** **엔진 — 여기서 갈린다. 섞지 마라.** | 자리 | 엔진 | 왜 | |---|---|---| | **보정 레인**(위 스크립트) | **Python `re`** | 2026-08-17 실측: `rg` 로 고정했더니 **CI 에서 죽었다**(ubuntu-latest 에 ripgrep 부재, exit 10). 셸 안의 `[가-힣]` 은 GNU grep C 로케일에서 exit 2 → **«무매치»로 읽히는 fail-open**. `re` 는 세 허용 엔진 중 어디에나 있고 로케일을 안 탄다 | | **손으로 도는 임시 스캔** | `rg` | 로컬 대화형. ⚠️ `grep -P` 는 `\w` 가 ASCII 한정이라 금지(Step 4) | **클래스 라벨 대응** — 레인은 `C`, 이 문서는 `S` 다. 이름이 갈린 채로 두면 다음 사람이 다시 포크한다: | 레인 | 이 문서 | 레인 | 이 문서 | |---|---|---|---| | C1 줄표 이어붙임 | **S1** | C4 조각문 | **S5** | | C2 용어-머리 | **S3** | C5 소유 직역 | **S6** | | C3 콜론 나열투 | **S4** | C6 · C6b 전칭 | **Step 4-b** (S 번호 없음 — 다른 Step 소속) | | C7 따옴표 기호 | **S10** | C10 구어 이유 어미 | **S13** | | C8 절 기호 | **S11** | C11 당신·필요로 | **S14** | | C9 안/못+동사(후보) | **S12** | C12 라틴 뒤 조사 | **S15** | | C13 내부 합성어 | **S21** | C14 시험→테스트 복합어 | **S22** | | C15 경동사 «내다» (후보·**UNCALIBRATED**) | **S23** 일부 | C16 라틴 약어 후보 (후보) | **S7** 일부 | 🟥 **대응표는 «라벨» 대응이지 «패턴» 대응이 아니다.** 레인의 정규식과 위 코드블록의 정규식은 **서로 다른 문자열**이다(레인 C1 은 `" — "` 양쪽 공백형인데 이 문서는 그 형태를 금지한다). ⇒ **레인이 초록이라고 코드블록 패턴이 보정된 것이 아니다.** 둘을 한 벌로 만드는 것이 옳은 방향이나 오늘 안 했다 — 지금은 두 벌이고, 그 사실을 여기 적어 둔다. 🟥 **C6 · C6b 를 지우지 마라** — 챔버 carry-forward 는 Step 2 **와 Step 4** 둘 다를 대상으로 지정했고, 그 둘이 Step 4-b 쪽 절반이다. 레인을 손볼 때 같이 날아가기 쉬운 자리다. **미보정으로 남은 것 — 이름으로 남긴다**: `S7`(내부 조어 — 라틴 약어만 C16 후보 레인, 한글 조어는 눈) · `S8`(지시 불명확) · `S9`(레지스터 드리프트) · `S16`(이명, 용어표 대조뿐) · `S17`(어순, UNCALIBRATED) · `S18`·`S19`·`S20`·`S23`(판단 전용) · `S24`(체크리스트) · `P1`~`P3`(Step 5-s) 는 아직 레인이 없다. 「레인이 없다」는 **「결함이 없다」가 아니다.** ### Step 2-b — 부분 개고 전용: 기존 본문과의 리듬 대조 **문서 전체를 새로 쓰는 경우가 아니라 기존 문서에 문단·문장을 끼워 넣는 경우**, 위 클래스가 전부 0이어도 **삽입분만 이질적으로 읽힐 수 있다.** 클래스 목록은 «틀린 표현»을 잡지 «튀는 표현»을 못 잡기 때문이다. 삽입·개고분에 한해 두 가지를 **수치로** 대조한다: 1. **문장 길이 분포** — 본문 평문 문장의 길이 중앙값·상위 10%를 먼저 구하고, 삽입분의 각 문장이 상위 10% 안에 드는지 본다. 넘으면 끊는다. (본문에 더 긴 문장이 있어도 근거가 못 된다 — 그건 그 문단의 리듬이지 삽입분의 것이 아니다.) 2. **어휘 반복** — 삽입분 안에서, 그리고 **직전·직후 문장까지 포함해** 같은 어간이 3회 이상 연달아 나오는지. 특히 같은 글자가 뜻이 다른 채로 반복되면(«검사를 더 **붙**여도 … 지점 쪽에 **붙**습니다») 읽는 눈이 걸린다. > 실측(2026-08-11, 기술문서 v2.1 작업): 클래스 스캔 잔여 0인 삽입분이 본문 112문장 중 > 유일한 소유 직역 1건을 들여왔고, 문장 길이 **124자**(본문 중앙값 40자 · 상위 10% 78자), > 「내려가」 앞 문장 포함 4회 연속 · 「붙」 한 문장 안 2회였다. 셋 다 기존 클래스 목록으로는 > 안 잡혔고, **읽는 사람이 «톤이 다르다»로 먼저 알아챘다.** 의도 보존으로 제외하는 항목은 **명명된 사유**(열거 매달기·리듬 결속·화면 받침·**인용된 원문** — 도구가 찍은 출력이나 남의 글을 축자 인용한 자리는 고치면 «출력 그대로»가 거짓이 된다)에 한하며, 제외 목록은 Step 5 콜드리드 짝에게 **통독이 끝난 뒤** 별도 패스로 전달해 대조받는다 — 사전 전달은 첫-읽기 눈을 오염시키고, 자기가 쓴 사유만으로 무제한 제외하지 않는다. ## Step 3 — 정직 수위 층 분리 정직함에는 두 층이 있고, 독자 문서에는 한 층만 싣는다: - **싣는다 — 논지를 받치는 정직**: 한계 절, 소표본 명시, 자기 철회 사례, "측정 중". 이걸 빼면 글의 등뼈가 빠진다. - **뺀다 — 내부 감사 어휘**: 검증 원장의 자기감사 디테일("실적은 X만 주장한다", "도달만·채택 아님" 같은 규율-말투), 내부 등급/게이트 상태 세부. 내부 기록에는 남기고 독자 본문에서는 뺀다. 판단 기준 한 줄: **"이 문장이 독자의 다음 행동이나 판단을 바꾸는가?"** — 바꾸면 정보, 안 바꾸면 자기감사다. **문장 단위로 적용**하고, 한 절의 문장 대부분이 걸리면 절 단위로 제거를 검토한다. 경계 예시: «실패 3건은 내부 전용 API 의존이라 외부 재현이 안 된다»는 독자의 재현 판단을 바꾸므로 **정보**다. «실적은 머지된 것만 주장한다»는 저자의 집계 규율 서술이라 **자기감사**다. ## Step 4 — 수치·주장 게이트 (기존 검증 자산으로 라우팅 — 재발명 금지) **분모는 기계로 연다**: 본문의 **아라비아 숫자 전수**를 grep으로 추출해 목록을 만들고, 수치 주장이 아닌 항목(버전 표기·목차 번호·연도 등)을 **사유와 함께 제외**한 뒤, 남은 각 행에 아래 라벨 중 하나를 단다. 단위 목록으로 좁혀 시작하지 않는다 — 영문 단위(ms·GB)가 새기 때문이다. 한글 수사("세 배")는 아라비아 전수로도 못 잡으므로 **눈 판정 잔여**로 명기하고 통독에서 본다. 자기 눈으로 고른 수치만 채점하는 것은 measured가 아니다. ⚠️ **`\b` 경계 금지** — 유니코드 인식 엔진(ripgrep·GNU grep UTF-8 로케일·Python `re` — **`grep -P`는 예외다**: `(*UCP)` 없이는 `\w`가 ASCII 한정이라 숫자-한글 사이에 경계가 생긴다. 반드시 `rg` 로 고정)에서 **한글은 word 문자**라 숫자와 한글 사이엔 경계가 생기지 않는다. `\b\d[\d,]*\b`류 패턴은 숫자 뒤에 한글 조사·단위가 바로 붙는 표기(예: «7개»)를 놓친다. **known-pair로 직접 확인**(엔진 고정, 복붙 실행): 이 SKILL.md 자신에 `rg -n '\b\d[\d,]*\b'`와 `rg -n '\d(?:[\d,]*\d)?'`(끝자리 콤마를 삼키지 않게 끝을 숫자로 고정)를 각각 돌려 델타를 세면, 경계판이 놓치는 숫자가 나온다(측정일 기준 델타 수를 이력에 기록 — 놓치는 쪽은 대부분 조사·단위가 바로 붙는 주장 수치이고, 날짜·Step 번호처럼 뒤에 공백·기호가 오는 숫자는 양쪽 다 잡힌다). **경계 없는 추출**로 시작하고, 과다추출된 비주장 항목은 위 문장대로 사유와 함께 제외한다. ### Step 4-b — 전칭 단정 후보 검출 (오탐 허용 — 후보 표시용, 판정은 사람) «전부/모두/하나도 없다/전혀/일절/예외 없이» 류 전칭 단정 어휘 + **부정형 전칭**을 `rg -n '(안|못) ?(했|만들|나오|잡히)|지 않았(다|습니다)'`(엔진 고정, 복붙 실행)로 걸러 후보로 표시하고, 각 후보의 반례가 정말 없는지 본문·근거를 다시 대조한다. grep은 후보만 내고 판정은 사람이 한다 — 오탐 다수가 정상이다. **단, 후보를 세지 않거나 판정을 비워두는 것은 결함이다** — 판정할 사람을 구할 수 없으면 후보 목록을 그대로 남기고 이 조건을 **미충족으로 명시**하고 발행 판단자에게 넘긴다(자기 판정으로 대체 금지 — Step 5 격리 규율과 동형). 실측(비공개 원장, 2026-08-14): 같은 개고 세션에서 반례 탐색 없는 전칭 단정을 두 번 썼고, 한 번은 위 어휘 목록에 없는 **부정형**("~을 안 만들었다")이었다 — grep 어휘만으로 못 잡는 계열이 실재한다는 뜻이라 부정형 패턴을 함께 넣는다. **반례 탐색 없이 쓴 전칭 단정은 원문보다 개고본에서 더 잘 나온다** — 다듬는 행위 자체가 근거 재확인 없이 서술을 넓히기 때문이다. Step 5 재콜드리드가 뒤늦게 잡을 수도 있지만, 앞단에서 후보를 먼저 좁혀두면 그 라운드의 비용이 준다. 수치·주장에는 **두 가지 라벨**이 있고 서로 다른 상태다 — 섞지 않는다: - **«발행 직전 재측정 대상»** — 근거는 확인됐으나 **시간이 지나면 값이 변하는** 것 (다운로드·별 수·테스트 수). 측정 시점·조건(창)을 병기하고 이 라벨을 단다. - **«미확인»** — **근거 실물을 아직 확인하지 못한** 주장. 창을 지어 붙이지 않는다(조작된 정밀도). 라벨과 확인 경로(어느 저장소·로그를 보면 닫히는지)를 적고, 발행 전 해소를 필수로 남긴다. 미발견은 "미확인"이지 "없음"이 아니다. 기록에 없는 실적·사례는 1차 출처(저장소·PR·로그)를 직접 조회해 확인하고 나서 싣는다. - **출처 역추적이 필요하면** `/phantom-quench` 로 라우팅한다. 🟥 **차트 검증 스킬은 «있다»고 전제하지 마라 — 그러나 «없다»고도 적지 마라.** 이 줄의 이전 판은 「`dataviz` 스킬은 이 레포에 없다」고 적었는데 **그 명제는 거짓이다** — `dataviz` 는 런타임이 공급하는 **번들 스킬로 실재**한다 (2026-09-17 확인 — 근거는 세션의 스킬 목록이고, 🟥 **레포 grep 으로는 구조적으로 안 나온다**). 「레포 자산이 아니다」와 「그런 스킬은 없다」는 다른 명제다 — 전자를 후자로 접으면 **실재하는 스킬로 가는 포인터를 잃는다**. 차트를 그리게 되면 그 시점의 런타임에서 **확인하고** 쓰되, 없으면 「없음」으로 적는다. 프로젝트에 금지·조건 수치 목록(원장)이 있으면 발행 전 1패스 대조한다. 이 스킬은 **외부 검증 도구를 재발명하지 않는다**(출처 검증·차트 검증은 위 라우팅으로) — 스킬 안의 grep 열거·스캔은 절차의 일부이지 검증기 신설이 아니다. ## Step 5 — 렌디션 + 지각 QA - **md 정본은 항상** 만든다. 다이어그램은 mermaid(GitHub·주요 뷰어 네이티브 렌더). - **HTML/PDF 렌디션은 조건부** — 요청이 명시했거나 게재 채널이 요구할 때만 만든다(판단 주체는 요청/채널이지 저자의 재량이 아니다): 자체완결 HTML(외부 의존 없는 인라인 SVG 다이어그램, 시스템 한글 폰트 스택, `@page` 인쇄 규칙) → headless Chrome `--print-to-pdf`. - **md-only 예외의 범위는 좁다** — 게재 매체가 md 를 렌더하면(위키·GitHub 등) **md-only 산출물도 렌더 산출물이다.** N/A 는 게재 매체가 렌더를 하지 않음을 확인한 경우에만 쓴다. **매체가 미상이면**(Step 1 «확인 불가» 경로로 진행한 경우) N/A 자격이 없다 — GitHub 렌더를 기본 렌더러로 가정하고 지각 확인을 수행하며, 그 가정 사실을 산출물 이력에 남긴다. 실측(비공개 원장, 2026-08-14): 렌더된 표의 한 셀에 여러 항목이 뭉쳐 기호-뜻 대응이 깨졌는데, 원문엔 항목이 전부 적혀 있어 논리적 누락이 없었고 열 수·이스케이프 같은 기계 검사도 통과했다. 배경지식 0 콜드리드를 여러 라운드 돌렸는데도 **렌더된 표를 보는 사람만** 그 결함을 알아챘다 — «md-only니까 N/A»로 판단한 것이 오판이었다 — 위키가 md를 렌더하는 순간 렌더 산출물이 생긴다. - **지각 QA(필수 — 렌더 산출물이 있을 때, md-only라도 게재 매체가 렌더하면 포함)**: 렌더 결과를 **전 페이지 눈으로** 확인한다 — 라벨 잘림(한글 받침), 페이지 나눔, 표/그림 겹침, 다이어그램 텍스트 가림, **표 셀 안에 여러 항목이 한 줄로 뭉쳐 있는지**(구분자 반복 — 렌더된 표에서만 보이고 원문 grep으론 안 잡힌다). 도구 exit 0은 렌더 성공이지 가독성 판정이 아니다. 판정 짝은 **독립 2차 지각 패스**(다른 눈이 같은 렌더를 봄)다 — 콜드리드는 내용을 읽지 렌더 결함을 보지 않으므로 짝이 될 수 없다. - **발행 전 콜드리드 1패스**: 격리된 검토가 처음 읽는 눈으로 통독한다. 저자는 자기 글의 전제 결손을 못 본다. **격리의 정의**: 저작 맥락을 상속하지 않는 실행이다. 같은 레포에서 띄운 서브에이전트는 프로젝트 지침·메모리를 상속하므로 **완전 블라인드가 아니다** — 저작 맥락 차단이 필요한 판정(전제 결손·자기 어휘 검사)은 레포 밖 cwd의 headless 실행 + 컨트롤(알려진 결함 1건 동반)로 하고, 통독 수준 검토는 다른 에이전트로도 되지만 **어느 격리 수준이었는지 이력에 적는다.** 에이전트 디스패치는 호출 세션의 권한·도구를 따른다 (이 스킬의 allowed-tools 밖의 일이다). 강격리도 비저자 짝도 구할 수 없으면 해당 judged 조건을 **미충족으로 명시**하고 발행 판단자에게 넘긴다 — 자기 검토로 대체하지 않는다. - 🟥 **재콜드리드 — 지적을 반영해 고쳐 썼으면 고친 것을 다시 읽힌다.** 콜드리드 1회는 *초안*을 검증할 뿐이고, **발행되는 것은 수리본**이다. 수리는 결함의 주된 출처라서 «지적 반영»과 «통과»는 다른 사건이다. 본문이 바뀌었으면 라운드를 하나 더 돈다. **정지 조건은 라운드 수가 아니라 변경이다** — 그 라운드에 **새 지적이 0건이고 본문 변경이 0건일 때만** 닫는다(어느 하나만으로는 안 닫힌다). 고쳤으면 아직 안 닫힌 것이다. **미반영 지적이 남으면** 각 건에 명명된 사유 + 발행 판단자 수락 기록을 붙인다 — 없으면 미충족으로 명시(Step 5 다른 judged 조건과 동형 라우팅). 라운드마다 «지적 n건 · 반영 n건 · 본문 변경 여부 · **Step 4/4-b 스캔을 이 수리본에 재실행했는가(y/n)**»를 이력에 적는다 — 수리가 결함의 주된 출처인데 수치·전칭단정 게이트가 초안 기준에 머물면 바로 그 자리에서 새 결함이 태어난다. > 실측(2026-08-11): 1차 콜드리드가 초안의 삽입 지점 오류를 잡았고, **그 수리가 새 결함 > 3종**(소유 직역 · 문장 길이 124자 · 어휘 반복)을 낳았다. 재콜드리드를 안 돌아 그대로 > 발행될 뻔했고, 읽는 사람이 «톤이 다르다»로 먼저 잡았다. 돌려 보니 문체보다 큰 것까지 > 나왔다 — 삽입분의 주장이 **반례가 흔한 단정**이었고(«검사를 아무리 늘려도 잡히지 > 않는다»), 자리도 닫는 절이 아니라 한계 절이 맞았다. 문장 다듬기 라운드가 **주장 범위와 > 배치**를 되돌렸다. > 추가 관측(2026-08-25, 병렬 세션이 이 스킬을 비공개 문서 2종에 적용): 콜드리드 3라운드에서 > 지적이 **14 → 4 → 8** 로 갔고, **3차 8건 중 4건이 2차 수리가 만든 것**이었다. > ⚠️ `LOCAL-ONLY ATTESTATION — UNVERIFIED`: 그 세션의 자기신고이고 이 문서의 저자가 > 재측정하지 않았다. 논지의 하중선은 위 2026-08-11 실측이고 이건 보강이다. > ⚠️ **「독립 재현」이라 부르지 않는다** — 그쪽은 판정자가 하나인 약격리 콜드리드고 이쪽은 > 게이트라 관측 방식이 다르다. 정확한 표현은 **「관측 방식이 다른 둘에서 같은 방향이 나왔다」** > 까지이고, `n=2` 는 센 표현이다(그 세션이 스스로 이 조건을 붙여 넘겼다). ## Step 5-s — 소리 렌더 + 청취 QA (낭독 레지스터 전용) 🟥 **낭독 대본은 렌더 산출물이 「없는」 게 아니라, 렌더 매체가 「소리」다.** Step 5 를 N/A 로 비우면 그 표면은 한 번도 검사되지 않은 채 발행된다. **Step 5 콜드리드는 낭독에도 그대로 적용된다** — 이 절이 대체하는 것은 *지각 QA*(눈 → 귀)이지 콜드리드가 아니다. > **출처와 그 한계 (읽고 인용해라)**: 이 절의 축은 2026-08-09 낭독 렌즈 필드런의 **교정판** > A~F 에서 가져왔다. 🟥 **그 필드런이 자기 축 셋을 반증했으므로 초안 판본을 인용하면 안 된다** — > A 호흡은 계기가 틀렸고(아래), E 볼드 개수 기준은 판별력 0, D 어미 기준은 재조정됐다. > 그 렌즈 자체는 **챔버 KILL 판정**을 받았고(별도 자산으로 출하하지 않는다), 그 판정의 운영자 > 확정 carry-forward 는 「**새 계기를 짓기 전에 이미 있는 계기의 판별력을 세운다**」였다 — > 그래서 이 절은 축을 넓히지 않고 **텍스트로 기계화되는 셋만** 들여왔다. 🟥 **「실측 근거가 있는 > 셋」이 아니다** — 정본이 유효 판정한 축은 **넷**이고(B 지시어 · B′ 동음이의 · C 낭독불가 · > F 대구 음절 — 🟥 축자를 정확히 적는다: **✅ 를 받은 축은 B·C·F 셋**이고, 그중 **`✅ 유효` 라는 > 축자가 붙은 것은 C·F 둘**이다(B 는 `✅ 예측 적중 — 심장 맞다`). **B′ 는 `★ net-new`**. > ⚠️ **「유효 판정」이라는 표현은 정본에 한 번도 안 나온다** — 이 문서가 만든 말이다. > 🟥 이 줄은 **정정하면서 새 팬텀을 낳았던 자리다**: 적대 검토가 준 「유효 판정은 셋」이라는 > *지적자의 어휘*를 축자 확인 없이 그대로 옮겨 적었다. **정정도 인용이다 — 원문을 열어라.**), 그중 **C 낭독불가에서 P1·P2 둘이** 나왔다. 🟥 **P2 를 B′ 의 > 절반이라 적지 마라** — 정본은 `2,017` 연도 오독을 **C 행**에 싣고, B′ 행의 내용은 「계기」 > 計器/契機 하나뿐이라 「나머지 절반」이라 부를 것이 없다. 안 들어온 것은 아래 미측정 목록에 > 이름으로 있다. 보정은 Step 2-a 의 정본 레인을 쓴다 — **이 절을 위해 픽스처를 새로 짓지 마라.** **텍스트 렌즈로 잡히는 것 (기계 · 이 절의 분모)** 🟥 **엔진은 `rg` 로 고정한다** — `.{60,}` 류의 문자 계수와 `[가-힣]` 인식이 엔진마다 다르다. 축은 **셋뿐이고, 넷째는 미보정으로 이름만 남긴다.** 실측 근거 없는 축을 추가하지 않는 것이 이 파일의 유지 규칙이다(초판이 「한자어 연쇄」·「의 3연」 두 축을 근거 없이 넣었다가 뺐다). ```bash F='낭독본.md' # 🟥 <> 금지 — 실제 경로로 치환 # ── P1 낭독 불가 토큰 — 창: 줄. 소리로 읽는 법이 안 정해진 것 rg -n '[0-9]+/[0-9]+|★|%|[A-Za-z]{2,}' "$F" # 🟥 {2,} 다 — PR·CI·QA·AI·ML 이 가장 안 정해진다 # ── P2 단위 없는 숫자 — 분모 opener. 숫자 + 뒤 3글자를 다 뽑아 «단위가 붙었나»를 눈으로 본다 rg -on '[0-9][0-9,]*.{0,3}' "$F" # ── P3 거짓 종결 — 종결어미 뒤로 문장이 계속된다. Step 2 의 S1b 와 같은 계기다 rg -n '(습니다|입니다|다|것|음)\s*[—–―]\s*\S' "$F" ``` | 축 | 왜 (1차 출처 = 2026-08-09 필드런) | 계기의 성격 | |---|---|---| | **P1** 낭독 불가 토큰 | 기호·분수·영문·**2글자 약어**를 대본에 그대로 두면 **발표자가 무대에서 즉석에 정한다**. 실측: 26건 중 **8종이 읽는 법 미정**. 읽는 법을 대본에 박아라(「XYZ, 즉 <풀어 읽는 이름>」 — 약어를 처음 쓰는 자리에서 한 번) | 잔여 0 스캔. ⚠️ **오탐이 정상** — `ms`·`GB` 같은 단위는 사유를 붙여 제외한다 | | **P2** 단위 없는 숫자 | 실측: **단위 없는** `2,017` 이 「이천십칠」 = **연도로 들렸다**. 🟥 **계기는 「단위 없는 숫자」를 찾는 것이지 「한글 수사+단위」를 찾는 게 아니다** — 후자는 **수리된 형태**라, 그걸 스캔하면 처방을 결함으로 세게 된다(초판이 그렇게 틀렸다) | **분모 + 눈 판정**(Step 4 와 같은 형태). 잔여 0 이 아니라 «전건에 판정이 붙었나»로 채점한다 | | **P3** 거짓 종결 | A축의 **실제 얼굴**. 필드런에서 「60자 초과」는 **4건 전부 오탐**이었고, 그 자리에서 진짜로 나온 결함이 이것이다(3건) — 「습니다 —」 뒤로 문장이 계속되면 청중은 **문장이 끝난 줄 알고 주의를 놓는다** | 잔여 0 스캔 | **🟥 P4 호흡 — 미보정(UNCALIBRATED). measured 에서 뺀다.** 정본 상수는 **「한 호흡 ≤22자 · 38자는 아님」**(운영자 반복 낭독으로 실측)이고, 재는 단위는 **문장 길이가 아니라 「끊을 수 있는 자리 사이의 최장 구간」**이며, 세는 것은 **문자수가 아니라 낭독 음절수**다(`1,857` 은 5문자지만 6음절, `QA` 는 2문자지만 3음절 — 문자수로 재면 숫자·라틴이 든 문장이 **조직적으로 과소평가**된다). 이 셋을 다 만족하는 계기를 아직 안 만들었으므로 **축을 「미보정」으로 표기하고 measured 조건에서 제외**한다. **🟥 엔진 부재 시 degrade — 이 절은 `rg` 에 고정되어 있고, 그것이 §Step 2-a 와 긴장한다.** Step 2-a 는 보정 레인을 **Python `re`** 로 고정했다 — 이유는 ubuntu CI 에 `rg` 가 없기 때문이다. 그런데 위 `P1`~`P3` 는 `rg` 로 적혀 있고, §Done When 은 그 셋을 **`measured`** 로 건다. 두 줄이 같은 문서 안에 있으므로 부재 경로를 명시한다: - **`rg` 가 있는 노드** — 위 세 줄을 그대로 복붙해 실행한다(의도된 경로). - **`rg` 가 없는 노드** — 다른 엔진으로 바꿔도 되나, 🟥 **바꾸기 전에 known-pair 로 확인하고 바꿔라.** 정규식 방언이 달라지면 세 스캔은 에러를 내지 않고 **조용히 0건을 낸다** — 그것은 「결함이 없다」가 아니라 「계기가 안 돌았다」이고, **둘은 출력이 같다**. ⚠️ 어느 종류의 grep 이 `\s`·`\d` 를 지원하는지를 **기억으로 단정하지 마라** — POSIX ERE 는 그 둘을 정의하지 않아 구현마다 갈리고, 도는 것과 안 도는 것이 **같은 이름**을 쓴다. (이 문단의 초판이 「BSD `grep -E` 는 `\s` 를 리터럴 `s` 로 읽는다」고 단언했는데, 2026-09-17 실측이 **반증했다** — 그 머신의 `/usr/bin/grep -E 'a\sb'` 는 `a b` 만 잡고 `asb` 는 안 잡았다. 단언이 틀렸고, 그래서 이 줄은 «어느 구현이 뭐를 한다» 대신 «확인하고 써라»로 바뀐다.) known-pair: 이 문서가 이미 가진 양성 사례 한 줄 + 안 걸려야 할 한 줄을 같은 실행에 통과시켜 둘이 **갈리는지**를 본다. ⇒ **해당 행을 «미충족»으로 명시**하고 어떤 엔진이 없었는지 적는다. 통과를 주장하지 않는다 (`P4` 가 «미보정»으로 빠진 것과 같은 방향 — 없는 계기를 초록으로 접지 않는다). 파이썬 포팅은 **아직 안 만들었다** — 만들면 Step 2-a 레인으로 가야 하고, 그때까지는 이 칸이 비어 있다. 🟥 **`rg -n '.{60,}'` 를 쓰지 마라** — 초판이 그걸 넣었는데, 필드런이 이미 반증한 판본이다 (단위가 틀렸고, 「40~55자」조차 정본이 「출처 없이 쓴 값, **거의** 두 배 과대」로 교정한 값이었다. 60 을 22 로 나누면 약 2.7 배이나 그 수는 **정본에 없는 유도값**이라 라벨을 붙여 둔다). 잘못된 계기는 없는 계기보다 나쁘다 — 초록을 내주기 때문이다. **🟥 텍스트로는 구조적으로 못 잡는 것 — 이름으로 남기고 미측정으로 표기한다** 발음 충돌·혀 꼬임 · 억양과 강세 위치 · **실제 호흡 지점**(P4) · 말버릇·군말 · **5분 넘게 떨어진 지시어**(B 축 — 필드런의 심장이나 슬라이드-시각 매핑이 있어야 기계화된다) · **대구 음절 어긋남**(F 축 — 정본이 8건 중 6통과로 유효 판정했으나 여기 계기가 없다) · **동음이의 낱말**(B′ 축 **통째로** — 「계기」가 計器인지 契機인지는 숫자 단위로 안 갈리고, 문법적으로 완벽히 파싱되므로 청중은 *다른 문장*을 듣고 그냥 넘어간다. 화면에 없으면 복구 경로 0). 🟥 **이 넷은 「없는 축」이 아니라 「안 가져온 축」이다** — 정본에 있고, 여기에 계기가 없을 뿐이다. ⇒ **닫는 방법은 하나뿐이다: 소리 내어 통독 1패스.** 그리고 **짝은 「듣는 사람」**이다 — 저자가 자기 대본을 읽는 것은 생성자=평가자이므로 충족이 아니다(Step 5 지각 QA 와 동형). **🎧 청취 라운드 — 정지 조건 (Step 5 재콜드리드와 동형)** 소리를 실제로 렌더해 **듣는 사람**이 듣는다. 지적을 반영해 고쳤으면 **고친 것을 다시 들린다.** **정지 조건은 라운드 수가 아니라 변경이다** — 그 라운드에 **새 지적 0건 ∧ 본문 변경 0건**일 때만 닫는다. 라운드별 「지적 n · 반영 n · 본문 변경 여부」를 이력에 적는다. 🟥 **수리는 결함의 주된 출처다** — 낭독을 고치면 리듬이 바뀌므로 P1~P3 기계 스캔도 **그 수리본에서 재실행**한다. **🔧 기계 앵커 — 소리를 「산출물」로 만든다 (주체: 발표자·사람)** 🟥 **md 정본을 그대로 먹이지 마라** — TTS 는 `**`·`|`·`#` 를 그대로 읽는다. 평문으로 먼저 내린다: ```bash sed -E 's/`[^`]*`//g; s/\*\*//g; s/^#+ //; s/^\| *//; s/ *\| */ /g' "$F" > /tmp/script.txt say -o /tmp/script.aiff -v Yuna -f /tmp/script.txt # macOS 내장 TTS · 임의 TTS 가능 ``` 소리 파일을 산출물 이력에 첨부하고, 듣는 사람은 그 파일을 듣는다. 그러면 「렌더 매체가 소리다」가 비유가 아니라 **첨부 가능한 산출물**이 되고, Step 5 의 「스크린샷 첨부 + 미충족 명시」 degrade 와 같은 형태가 된다. ⚠️ **평문화 자체가 손실이다** — 표는 줄로 눌리고 강조는 사라진다. 무엇이 눌렸는지 확인하고, 눌린 자리가 발화에 필요하면 대본을 고쳐라(변환기를 고치는 게 아니다). ⚠️ TTS 는 사람 낭독의 **대리물**이다 — 억양·강세·말버릇을 보존하지 않는다. 대리물로 본 사실을 이력에 적는다. **degrade**: 듣는 사람을 못 구하면 **소리 렌더 파일을 이력에 첨부하고** 해당 Done When 을 **미충족으로 명시**하여 발행 판단자에게 넘긴다. 자기 낭독으로 대체하지 않는다(생성자=평가자). ## Done When 🟥 **클래스 목록을 여기에 다시 열거하지 않는다** — Step 2 표의 **check-class 열이 정본**이다. 괄호로 닫힌 열거를 여기 두면, Step 2 에 행을 추가할 때마다 새 클래스가 **채점되지 않은 채** 남는다(관측 2026-08-25: 그때 새로 넣은 클래스들이 어느 Done When 행에도 안 걸렸다. ⚠️ 그중 하나는 이후 Added-Scope 판정으로 별건 분리됐으므로 «둘»이라는 당시 개수는 지금 표와 안 맞는다). ⚠️ **아래 라우팅은 `measured`·`judged` 둘만 받는다** — Step 2 표에 `mandatory-pass` 행을 만들면 그 행을 받는 Done When 줄도 같이 만들어라. 안 그러면 이 문단이 막으려던 고아가 그대로 재발한다. | 조건 | check-class | |---|---| | 대상 매체 실물 표본 확인 기록이 산출물 이력에 존재 — 불가 시 **시도 내용·사유 포함** 명기(시도 기록 없는 「불가」는 불충족) | mandatory-pass | | Step 2 표에서 check-class 가 **`measured` 인 전 행**의 스캔 잔여 0 — **Step 2-a 보정을 먼저 실행**(`bash scripts/test_ko_tech_writer_lanes.sh` — 전 레인 `discriminates`)한 뒤 스캔. 🟥 레인이 없는 클래스는 **「보정 안 됨」으로 적고 measured 로 세지 않는다**(레인 부재는 결함 부재가 아니다). 분모 opener(S1a·P2)는 `neg=0` 이 원리적으로 불가능하므로 「양성이 출력에 나오는가」로 본다. 제외는 **명명 사유와 함께 목록화**하되, 전수가 큰 분모(S1a)는 **집계 1줄로 제외**하고 위험 부분집합만 건별로 적는다 | measured | | Step 2 표에서 check-class 가 **`judged` 인 전 행**의 통과 | judged — 짝: 콜드리드 통독(통독 후 제외 목록 대조) | | **부분 개고인 경우**(기존 문서에 삽입·수정): Step 2-b 리듬 대조 — 삽입분 각 문장이 본문 길이 상위 10% 이내 ∧ 어간 3회 연속 반복 0. 전문 신규 집필이면 N/A 명기 | measured | | 본문 수치 전건(기계 추출 분모 기준, `\b` 미사용 경계없는 추출, **발행 직전 최종본 기준**)이 라벨(창 병기/재측정 대상/미확인) 동반 + **한글 수사(세 배·두 배 등) 눈 판정 잔여 목록이 이력에 명기됨(0건이면 「0」으로 기록)** | measured | | 전칭 단정(부정형 포함) 후보 grep 스캔을 **발행 직전 최종본**에서 실행 — 후보 n건 수치 기록 | measured | | 위 후보 n건 각각에 반례 확인 결과(「확인함」/「확인 못 함」)가 붙음 — 미판정 0 | judged — 짝: Step 5 콜드리드(통독 후 후보 목록 대조) | | **파생 압축 자산인 경우**(Step 0 세 번째 레지스터): 자립성 검사(정본 어휘·주장 범위·은어 대조) 결과가 이력에 존재 — 해당 없으면 N/A 명기 | judged — 짝: 배경지식 0 콜드리드(원문 비열람) | | 렌더 산출물(HTML/PDF/이미지 — 파생 압축 자산 포함)이 존재하거나 **게재 매체가 md를 렌더하는 경우**(위키·GitHub 등) 전 페이지 지각 확인 — 게재 매체가 md를 렌더하지 않음을 확인한 경우만 N/A 명기(사유 기록). **매체 미상이면** GitHub 렌더 가정으로 지각 확인 수행(가정 기록) — N/A 불가. **낭독 대본은 N/A 가 아니라 Step 5-s 청취 QA 로 간다**(렌더 매체가 소리다) | judged — 짝: **독립 2차 지각 패스**(다른 눈이 같은 렌더를 봄) | | 콜드리드가 **변경 없음으로 닫혔다** — 마지막 라운드에 **새 지적이 0건이고 본문 변경이 0건**일 때 닫는다(어느 하나만으로는 안 닫힌다). 지적을 반영해 고쳤으면 그 수리본으로 한 라운드 더. **미반영 지적이 남으면** 각 건에 명명된 사유 + 발행 판단자 수락 기록을 붙임 — 없으면 미충족 명시. 라운드별 「지적 n · 반영 n · 본문 변경 여부」 + 격리 수준(강/약) 이력 기록. 🟥 **낭독 대본도 이 행의 대상이다** — Step 5-s 가 대체하는 것은 *지각 QA* 이지 콜드리드가 아니다 | judged — 짝: 격리 검토(Step 5 정의) | | **낭독 레지스터인 경우**: Step 5-s **P1·P2·P3** 실행 — P3 은 잔여 0. **P1 은 오탐이 정상이므로 「잔여 0」이 아니라 «전건에 판정 + 제외는 명명 사유와 함께 목록화»로 채점한다**(단위·고유명사가 늘 걸린다). P2 는 분모 전건에 판정. **P4 호흡은 미보정이라 이 조건에 안 들어간다**(빠뜨린 게 아니라 제외한 것이며, 그 사실을 이력에 적는다). **낭독 레지스터가 아니면 N/A 명기** | measured | | **낭독 레지스터인 경우**: 소리 렌더(md→평문 변환 후 TTS) 파일이 이력에 존재 + **듣는 사람**의 확인. 못 구하면 파일만 첨부하고 미충족 명시(자기 낭독 대체 금지). **낭독 레지스터가 아니면 N/A 명기** | judged — 짝: 듣는 사람 | | 제목에 한국어판 + 원제 병기(S24, 영문 원제가 있는 글만) | judged — 제목 줄 확인 | | 정직 수위 분리(Step 3)가 적용됨 | judged — 짝: 발행 승인자 확인 또는 격리 적대 검토. 둘 다 불가하면 **미충족으로 명시 보고**(자기 검토로 대체 금지) | ## 역할 경계 (중복 아님을 명시) - `hub-persona-auditor` **에이전트** — 완성된 대외 초안의 **페르소나 감사**(검토). 이 스킬은 **저작·개고 절차**다. Step 5 콜드리드에서 그 에이전트를 짝으로 쓸 수 있다(라우팅 관계). - `fh-preprep:preprep` — 발표 **표면 사이**(덱↔원고↔노트)의 정합을 본다. 이 스킬은 **한 편의 산문/대본 자체**를 본다. 🟢 경계는 preprep 쪽이 먼저 그어 놓았다 — 그 스킬은 초판에 있던 Step 2 복제 레인(`L9`)을 **빼면서** «번역투·레지스터·수치 게이트·지각 QA 는 `ko-tech-writer` 로 간다» 고 명시했다. **Step 5-s 는 그중 «낭독의 지각 QA»** 자리다 — 재발명이 아니다. ⚠️ **겹치는 축 하나**: preprep 의 `L5 jargon`(조어가 낭독면 첫 등장에 풀이를 달았나, 차단) ↔ 이 문서의 `S7`. 같은 것을 두 번 재지 않도록, preprep 을 돌린 발표 대본은 `S7` 을 «preprep `L5` 로 대체»로 적는다. 🟥 그 둘이 정말 같은 것을 잡는지는 **정의 대조로만 판단했고 같은 대본에 둘 다 돌려본 적은 없다** — 측정이 아니다. - `harness-doctor --lint` — **하네스 자산**의 언어 패턴(자기마케팅) 검출. 이 스킬은 독자 대면 문서가 대상이고 번역투·레지스터·정직 수위까지 다룬다. - 플랫폼 내장 문서 기능 — 특정 문체 캘리브레이션·정직 수위 층 분리·지각 QA 파이프라인은 내장에 없다(이 스킬이 더하는 것은 거버넌스다). 독립 실행 및 degrade 경로: phantom-quench 미설치 → 해당 라우팅을 수동 대조로 · WebFetch 불가 → Step 1 «확인 불가» 경로(시도 기록 의무) · headless Chrome 부재 → HTML/PDF 렌디션을 «미생성»으로 명기하고 md 정본만 산출 · **Step 4-b 판정 주체(사람) 부재 → 후보 목록을 그대로 두고 해당 Done When 을 미충족으로 명시**(자기 판정 대체 금지) · **독립 2차 지각 패스 부재 → 렌더 스크린샷을 산출물 이력에 첨부하고 해당 Done When 을 미충족으로 명시**(저자가 같은 렌더를 두 번 보는 것으로 대체 금지 — 생성자=평가자가 된다). **듣는 사람 부재 → 소리 렌더 파일 첨부 + 해당 Done When 미충족 명시**(자기 낭독 대체 금지) · 🟥 **TTS 부재**(macOS 아닌 노드 · `say` 없음 · 한국어 보이스 미설치) **→ 소리 렌더를 「미생성」으로 명기하고, 사람이 직접 소리 내어 읽은 뒤 듣는 사람이 확인한다** — 기계 앵커가 없어지는 것이지 청취 라운드가 없어지는 게 아니다. 듣는 사람까지 없으면 그 Done When 은 미충족이다. ⚠️ 이 스킬은 `say` 를 **어느 노드에서도 실행해 본 적이 없다** — 플래그 형태만 확인했다. · 각 degrade는 산출물 이력에 적는다. **언어 범위**: 이름 그대로 **한국어 전용**이다. Step 0·1·3·4·5의 구조는 언어 무관이지만 Step 2 문체 클래스가 전부 한국어 실측이라, 영어 지원은 영어 실측 클래스가 쌓인 뒤 별도 확장(`en-` 자매 또는 일반화)으로 간다 — 실측 없는 클래스를 미리 짓지 않는다(유지 규칙).