The interface is localized. Skill descriptions and documents are machine-translated by AI into your language; code, commands, paths and technical terms stay in the original, and the author's document governs.
Explore skills
Productivity · SKILL.md

preprep

preprep

한국식 발표대본과 장표에 특화된 준비 하네스. 레퍼런스를 먼저 묻고(공식 장표가이드 · 참고 덱), 대화로 주제·구성·전개를 세운 뒤, 기승전결 배치안을 «여러 개» 내고 사람이 고른다. 제작 후 바닥 검사 — 금지 인용이 어느 면에 남았나, 원고와 노트의 단위 참조가 갈렸나, 재생성이 사람 편집을 삼켰나, 장 사이 의존이 깨졌나, 조어가 낭독면 첫 등장에 풀이를 달았나, 장당 발화가 상한을 넘었나. 리허설 녹화를 들으면 쉼·접속사·문장 끝 억양·끝인사 크기를 코칭 표로 낸다(advisory). Triggers "발표 준비", "발표 대본 만들어줘", "장표 점검해줘", "덱이랑 대본 어긋난 데 있나", "발표 자료 정합성", "리허설…

Independent GitHub snapshot · Automated classification · Original documentation governs

Skill documentation

GitHub

name: preprep description: '한국식 발표대본과 장표에 특화된 준비 하네스. 레퍼런스를 먼저 묻고(공식 장표가이드 · 참고 덱), 대화로 주제·구성·전개를 세운 뒤, 기승전결 배치안을 «여러 개» 내고 사람이 고른다. 제작 후 바닥 검사 — 금지 인용이 어느 면에 남았나, 원고와 노트의 단위 참조가 갈렸나, 재생성이 사람 편집을 삼켰나, 장 사이 의존이 깨졌나, 조어가 낭독면 첫 등장에 풀이를 달았나, 장당 발화가 상한을 넘었나. 리허설 녹화를 들으면 쉼·접속사·문장 끝 억양·끝인사 크기를 코칭 표로 낸다(advisory). Triggers "발표 준비", "발표 대본 만들어줘", "장표 점검해줘", "덱이랑 대본 어긋난 데 있나", "발표 자료 정합성", "리허설 대본 확인", "리허설 녹화 코칭해줘", "presentation prep".' user-invocable: true allowed-tools: ["Read", "Bash", "Grep", "Glob"] model: sonnet

preprep — 한국식 발표대본·장표 준비 하네스

특화가 한국식인 이유는 장식이 아니다. 낭독 대본의 존댓말 레지스터, 조어를 첫 등장에 풀어주는 관습, 어절 중간에서 끊기지 않는 줄바꿈, 영어 직역이 남긴 번역투 — 이것들은 한국어 발표에서만 하중을 지고, 영어권 디자인 렌즈가 구조적으로 못 잡는다.

🟥 왜 «별도 하네스»여야 하나 — 스킬 하나로는 안 되는 자리

운영자 정의(2026-08-29): 「발표자료를 짓고 대본도 동기화하고 관련된 기술문서도 싱크하여 출하할 수 있게 하는 능력이 하네스를 별도로 두어야 하는 이유의 정체다.」

기존 스킬은 전부 표면 하나를 본다 — deep-clarify 는 요구를, ko-tech-writer 는 산문 한 편을, corpus-grounding-expander 는 코퍼스를. 🟥 셋이 같이 움직이는 것과 «출하 가능 상태»를 아무도 소유하지 않는다. 그 자리가 이 하네스다.

장표 ── 대본 ── 기술문서        셋은 «같은 것의 세 면»이지 세 문서가 아니다
  └──────┴──────┘
     동기화 + 출하 가능 상태 ← 여기를 소유하는 것이 이 하네스의 정체

그래서 레인 중 셋(L2 unit-ref · L7 regen · L8 interslide)이 표면 사이를 본다. 한 면만 보는 도구로는 구조적으로 못 잡는 자리이고, 실측이 그것을 세 번 보여줬다 — 재생성이 발표자 노트 20곳을 삼켰는데 빌드는 성공했고, S8 을 빼자 S9 가 성립 불가가 됐는데 렌더를 한 장씩 다 봐도 구조적으로 안 잡혔고 운영자가 잡았으며, 도해에 구워진 텍스트는 XML 을 읽는 눈에 구조적으로 안 보였다.

발표는 자산군이다. 덱 하나가 아니라 덱 + 원고 + 발표자 노트 + 기술문서 + Q&A prep + 초록 + 리허설 대본이고, 그것들이 서로 어긋나는 자리에서 사고가 난다. 한 장씩 봐서는 안 잡힌다 — 눈은 표면 하나를 보고 결함은 표면 사이에 있다.

🟥 이 하네스는 «검사기»가 아니다 — 레인은 마지막에 오는 바닥이다

운영자 정의(2026-08-29): 「위치 틀어짐, 일관성 없음, 번역투 등의 문제가 없고 구성을 잘 만들어내면 되겠지. 기승전결에 맞게끔 구성도 도와주고. 결국 많이 물어봐서 기초를 세우고 그것 기반으로 만들어서 퇴고를 하는 식일 거야. … 결국에는 취향이 중요하니까.」

그래서 무게중심은 만들기 전과 만드는 중에 있고, 레인 아홉은 산출물이 아니라 floor 다. 레인이 초록이라고 좋은 발표가 아니다. 레인이 빨가면 나갈 수 없을 뿐이다.

층무엇누가 정하나
기계가 알아서번역투 · 위치 틀어짐 · 논지 안 맞음 · 내용 순서🟥 묻지 않고 최적화한다. 여긴 사람 시간을 쓸 자리가 아니다
사람과 대화로알맹이 — 아이콘 하나, 대본을 취향에 맞춰 고치기, 주제 · 구성 · 전개 · 디자인🟥 절대 피할 수 없다. 자동으로 정하면 그게 틀린 것이다

운영자 정의(2026-08-29): 「사람의 손이 번역투나 위치 틀어짐, 논지 안 맞음, 내용 순서에 맞는지를 최적화 알아서 시켜주고, 그 안의 디테일한 알맹이들을 … 사람과의 소통으로 맞춰나가는 것. 이건 절대 피할 수 없지.」

🟥 두 층은 실패 방향이 반대다. 위는 «물어보면 마이너스»다 — 번역투를 고칠까 묻는 것 자체가 사람 시간을 쓰는 것이고 기계가 그냥 해야 한다. 아래는 «안 물으면 마이너스»다 — 아이콘 하나, 대본 한 줄의 말맛은 물어봐야만 맞는다. 어느 쪽을 반대로 하면 하네스가 방해물이 된다.

«알아서 커버» 가 지금 어디까지 되나 — 정직하게

운영자가 든 예시로 그대로 대조한다. 일일이 지적 안 해도 커버되어야 하는 것들이다.

운영자 예시지금무엇이 보나
위치가 어긋나 있다🟢 덮인다ooxml/gate.py ⑥ 화면 밖 도형 · P1/P3 (넘길 때 튐 · 인접 어긋남) · P4 algn/mirror(같은 줄인데 정렬이 갈림 · 좌우 대칭인데 크기가 갈림) ⚠️ 그 검사에 붙은 사고 수치(26p · 1,854,400 EMU)는 gate.py 자신의 인라인 주석 말고 대조할 기록이 없다 — 거짓이라는 뜻이 아니라 독립 출처가 없다는 뜻이다
번역투🟢 덮인다⑤에서 ko-tech-writer Step 2
주어가 빠져 있다🔴 미구현 (판별자는 있다)🟥 «패턴만으로는 못 한다»고 적었던 것을 정정한다 — 판별자가 이미 실재한다: 주어 생략의 가부는 문장이 아니라 화면이 정한다. 그 문장이 뜨는 화면에 참조 대상이 있으면 생략이 맞고, 참조 대상이 사라지는 장에서 복원한다. 화면 텍스트는 이미 추출되므로 이건 judged 가 아니라 measured 후보다. 다만 복원/유지는 4등급으로 갈린다 (목적어=복원 · 주어+신정보=복원 · 주어+구정보=그대로 둔다 · SOV 재배열) — 전부 복원하면 번역투를 새로 만든다. 미구현 상태다
화면이 너무 비어 보인다🔴 미구축gate.py 는 «밖으로 나갔나»를 보지 «안이 비었나»를 안 본다. 🟥 정정 2026-09-01 — 「pptx→PDF 가 끊긴다」는 거짓이었고, 그 오진이 이 항목을 막고 있었다. known-pair: soffice 부재는 참(which soffice → not found · LibreOffice.app 없음) · pdftoppm 실재는 참(/opt/homebrew/bin/pdftoppm) — 그런데 PowerPoint AppleScript save as PDF 로 120장 덱이 실제로 12회 렌더됐다(/tmp/v11*.pdf 12개, 최신본 120페이지 %PDF-1.3, 2026-09-01 실측). ⇒ 끊긴 것은 **「LibreOffice 경로」**지 **「pptx→PDF」**가 아니다. 🟥 미구축 사유가 바뀐다: 「렌더가 안 된다」(장애물 실재) → 「기준선을 아직 안 쟀다」(장애물 없음). 두 상태는 다르고, 전자는 «못 한다»로 후자는 «안 했다»로 읽힌다. [[feedback_rule_misdescribes_its_own_machine]] 기준선 형태는 정해져 있다: 레퍼런스 덱을 실측해 장 유형별 화면 자수 기준선을 세우고 미달 장을 센다 — 값은 발표마다 다시 재야 한다. 🟥 정정 2026-09-04 — 기준선을 실제로 쟀다, 다만 반대편(과밀)이다. 121장 한국어 덱 실측: 화면 자수 중앙 118 · 평균 133 · P90 207 · 최대 808. 읽는 부담(신규 글자 ÷ 발화 초) 중앙 10.0 · P90 16.9(§레인 R4·R5). ⚠️ 값은 발표마다 다시 재야 한다 — 임계를 코드에 안 박고 그 덱 자기 분포에서 뽑는 이유가 이것이다. 그리고 이건 게이트가 아니라 순위표다 — 정의상 항상 약 10%가 뜬다, 「후보 0건」을 목표로 삼으면 오독이다(§정직한 한계 참조). 「비어 보인다」쪽(하한)은 여전히 기준선이 없다 — 잰 것은 과밀(상한) 뿐이라 이 행은 아직 🔴 미구축으로 남는다
원고와 화면이 갈린다🟢 덮인다 (2026-09-10 신설)L14 screen-parity. 그 전까지는 이 하네스의 정체(「표면 사이」)에서 가장 큰 쌍이 비어 있었다
흐름이 매끄럽지 않다🟡 절반 덮인다L8 은 «지시 대상이 해소되나»를 볼 뿐 «논지가 서나»를 못 본다. 🟢 그 부분집합 하나는 이제 덮인다 — L9 progression 이 «선언된 단계가 화면에서 빠졌나»를 본다(압축에서 첫 칸이 떨어지는 실사고). ⚠️ «논지가 서나» 자체는 여전히 미해결이고, 되읊음 대조(리뷰어가 요약한 뜻이 저자 의도와 반대인가)는 사람이 한다

🟥 미구축 셋을 「advisory 라서 괜찮다」로 덮지 않는다. 지금은 ④·⑤ 단계에서 사람이 하고 있고, 그건 운영자 정의상 기계가 해야 할 일이 사람에게 남아 있다는 뜻이다. 다음 개선의 과녁은 여기다 — 특히 「흐름」과 「주어」는 공통화될 수 있는 시행착오라 성공 정의에 직접 걸린다.

⚠️ 「논지 안 맞음 · 내용 순서」에는 아직 레인이 없다. L8(장 사이 의존)이 가장 가깝지만 그것은 «지시 대상이 해소되나»를 볼 뿐 «논지가 서나»를 못 본다. 지금은 ④ 구성 단계에서 사람이 하고 있고, 미구축이라고 여기 적어 둔다 — 없는 것을 있는 것처럼 두지 않는다.

이 하네스의 본체 — 그리고 성공을 무엇으로 재나

운영자 정의(2026-08-29, 이 하네스의 정본): *「초기 영혼 심기를 질의응답을 통해서 같이 하고, 하네스를 통해서 발표 자료 짓는 것 자체를 가속화시키고, 말미에는 페르소나나 스킬들로 커버 못 한 취향의 영역을 사람과의 소통으로 깎아내는 것. 그게 하네스의 본체다. 사람 손이 필연적으로 갈 수밖에 없는 하네스이지만, 적어도 우리가 겪어왔던 *구성과 형식, 그리기 등 공통화될 수 있는 시행착오만 단축시킬 수 있다면 그걸로 성공인 거다.」

🟥 성공 정의가 「사람 손을 없앤다」가 아니다. 사람 손은 필연이고, 그것을 없애려는 하네스는 취향의 자리를 기계가 뺏어 결과를 나쁘게 만든다. 재는 것은 하나다 — 공통화될 수 있는 시행착오가 줄었나. 구성 배치를 처음부터 더듬는 것, 형식을 매번 다시 정하는 것, 도해를 영점부터 그리는 것. 그것들만 줄면 성공이다.

🟥 그리고 이 완료조건은 도달 가능하다. 「다음에 이만한 발표가 오면 재자」 같은 조건은 영영 안 오므로 검증이 아니라 미루기가 된다(FH: 도달불가 Done-When 은 회피를 훈련시킨다). 반면 «이번에 겪은 시행착오 중 무엇이 공통화되나»는 지금 이 자리에서 셀 수 있다.

이것은 FH 교리의 이 도메인 사례다 — 하네스의 payoff 는 「시행착오를 사람에게서 하네스로 옮겨, 사람 시간을 줄이고 주의를 비가역 지점으로 보내는 것」. ①단계를 «영혼 심기»라 부르는 이유도 같다: FH 실측에서 방향층(판단 회로)이 있으면 같은 토큰이 크게 효율적이었다. 🟥 다만 «정체성 선언»과 «심지(판단 회로)»는 다르고, 그 구분이 여기서 하중을 진다 — 선언만 떼어낸 12런에서는 약한 모델이 오히려 올랐다(Haiku 1.67 → 2.33). 원출처는 그 팔을 "정체성 선언이 순손실" 이라고 못박는다. 그러므로 ①이 심는 것은 «우리는 이런 하네스다» 라는 선언문이 아니라, 뒤 단계가 근거로 삼을 판단의 축이다 — 그래서 요구사항 수집이 아니라 같이 세우는 것이다. ⚠️ 초판은 이 자리에 «105런에서 영혼 선행이 결정적, 선언을 빼면 약한 모델 성능이 갈렸다» 고 적었다. 표본(105는 전체 합계, 해당 팔은 12런)과 방향이 둘 다 틀렸고, 격리 그라운딩 감사가 잡았다.

제작 흐름 — 다섯 단계, 레인은 마지막

🟥 새로 짓지 않는다. 아래 네 단계는 FH 에 이미 있는 능력을 이 도메인 순서로 합주하는 것이다(no-reinvention). 각 단계는 사람의 선택으로 끝난다 — 자동 결정이 있으면 그 단계는 틀렸다.

① 영혼 심기   /deep-clarify — 주제 · 내용 · 구성 · 전개 · 청중 · 시간 · «성공은 무엇인가».
              🟥 «많이» 묻고 **같이 세운다**. 받아적기가 아니다 — 답이 스펙이 되고 그 스펙이
              뒤 단계 전부의 근거다. 여기가 비면 뒤가 전부 기본값으로 채워진다
② 레퍼런스    「참고하려는 것이 있나」를 **먼저 묻는다**(ko-tech-writer §Step 1 과 같은 규율:
              표본 없이 톤을 단정하지 않는다). 행사 공식 장표가이드 · 좋다고 본 남의 덱 ·
              조직 템플릿. 있으면 /corpus-grounding-expander 로 그 실물을 근거로 세운다.
              🟥 «위반»은 원문 **문장**을 인용할 수 있을 때만 낸다 — 스와치·템플릿 실측값과의
              차이는 «위반»이 아니라 «차이»로만 낸다(§방법론 ⓖ, 숫자가 없는 원문에서 「위반」을
              냈다가 정정하고, 스와치만 근거로 「위반」을 냈다가 철회한 실사고)
③ 프런티어    ②가 비었거나 더 넓히고 싶을 때만. persona-innovator(Mode F) · /frontier-digest
              로 세련된 방법을 찾아온다. 🟥 찾아온 것은 **후보**지 결정이 아니다
④ 구성        기승전결. 하네스는 배치안을 «몇 개» 내고 사람이 고른다.
              🟥 하나만 내면 그건 제안이 아니라 결정이다
⑤ 제작·퇴고   마이크로매니징. 문체는 /ko-tech-writer 로 — 레지스터 · 실물 캘리브레이션 ·
              번역투 제거 · 수치 게이트 · 지각 QA.
              🟥 **도해를 건드렸으면 렌더한다** — 연결선 잔해 · 도형 종류 이탈 · 빌드 프레임
              텍스트 소실 · 부연-본문 밝기 경쟁 넷 다 렌더 없이는 구조적으로 안 보였다(§방법론 ⓒ).
              🟥 **장을 뺄 때는 뒤 장의 전제인지 먼저 본다** — 지운 장이 다음 장 부제의
              접속사(「그러나」 류)가 받는 말이었던 실사고가 있다(§방법론 ⓔ)
              🔷 **도해는 타입 있는 JSON 에서 굽는다**(2026-09-05 신설, 5단계 안의 갈래이지 6단계가
              아니다). `python3 diagram_from_json.py <spec.json> --out <png> --css <덱 토큰.css>
              --no-legend` — 외부 렌더러 archify(MIT, 로컬 설치·소스 복사 0)의 showcase validate 를
              **못 통과하면 굽기를 거부**하고, 통과하면 deliver → 뷰어 크롬 없는 SVG 단독 PNG(≥3840px)
              → 굽기 영수증. 덱 자기 규약(배경·강조색·폰트)은 archify CSS 변수 override 로 꽂는다 —
              archify 색을 덱에 가져오는 게 아니라 **덱 규약을 렌더러에 꽂는다**(§방법론 ⓓ). 가이드 뷰
              인터랙션은 장표에 없으므로 `--focus id,…` 빌드 프레임으로 번역한다(§B3 좌표 고정).
              🟥 archify 는 글자 크기 토큰이 없어 **viewBox 폭이 글자 pt 를 정한다**(720 → 라벨 29pt·
              부제 19pt / 1137 → 12pt) — 그래서 폭 상한이 굽기 거부 조건이다. 대응표·차이·취향 판정
              항목: `tracks-meta/dispatch/2026-09-05_archify-preprep/DESIGN_TOKENS.md`(운영자 로컬)
─────────────────────────────────────────────────────────────────
바닥         `python3 preprep.py` — 아래 레인. 걸리면 ⑤ 로 되돌아간다

②를 건너뛰지 마라. 「레퍼런스 있나」를 안 묻고 만든 것은 취향이 아니라 기본값이다.

출처: 챔버 런 #14 EMIT(2026-08-20). 실사용 검증 = 2026-08-29, 여러 차례 리뷰를 반영해 운영자가 정본으로 확정한 덱(ifkakao26_slides_v1.0)에 돌려 벼려졌다. 🟥 이 하네스가 그 덱을 통과시킨 것이 아니다 — 이미 확정된 뒤에 스캔했고, 발표 자체는 2026-10-14 로 아직 하지 않았다. 「이견 없이 통과」는 운영자 구두 보고(2026-08-29)이고 기록으로 대조할 문서가 없다 — 반대로 그 덱에 대한 리뷰 지적은 최소 3회차가 기록에 있다. 「다표면 읽기」는 이 하네스의 한 렌즈(L2) 이지 전체 이름이 아니다.

쓰는 법

SKILL=plugins/fh-preprep/skills/preprep     # 이 스킬의 위치
cd "$ASSET_ROOT"                            # 발표 자산군의 루트
cp "$SKILL/surfaces.example.yaml" surfaces.yaml   # 표면 목록은 사람이 적는다
python3 "$SKILL/preprep.py"
# exit 0 통과 · 1 발견 · 2 판정불가(계기오류/미측정 — PASS 아님)

🟥 표면 목록은 코드가 아니라 surfaces.yaml 에 있다. 챔버 런 실측: 목록을 코드에 박아서 같은 물건이 세 번 따로 지어졌다. 무엇을 표면으로 볼지는 발표마다 다르고, 그건 판단이다.

레인

레인무엇을 재나성격
L1 canon인용금지·조건필수·폐어가 전 표면에 걸리나. USE 와 MENTION 을 갈라서 낸다 — 🟥 폐어를 «걷어냈다»고 적은 원장 자신이 그 낱말을 담으므로, 이 구분이 없으면 원장이 자기를 신고한다차단
L2 unit-ref표면 쌍의 단위 참조 정합(원고 ↔ 노트)차단
L3 inventory선언된 표면이 실물로 있나 · 기계로 읽히나차단
L4 getput왕복 no-op 컨트롤 — 사람이 안 고쳤는데 왕복이 안 닫히면 그 차이는 왕복기 손실이다차단
L5 jargon선언된 조어가 낭독면 첫 등장에 풀이를 달았나차단
L6 pacing장당 발화 상한·평균·분포. 상한은 사람이 surfaces.yaml 에 적는다차단
L7 regen재생성이 사람 편집을 삼켰나차단
L8 interslide장 사이 의존이 깨졌나 (OK/BROKEN/UNRESOLVED)🟥 advisory
L11 promise앞에서 예고한 것이 뒤에서 상환되나 — 후보를 나열하고 «예고 N 회 vs 뒤에서 M 회»를 센다. 실사고: 「세 번」 예고에 상환 1건🟥 advisory · 판정은 사람
L10 adjacent-dup인접 장이 같은 문장을 다시 읽나 — 쪼갤 때 뒤 프레임에 원본을 통째로 남기면 앞 장에서 읽은 문장을 또 읽는다. 실측 117자 중 82자(70%)차단 (임계는 사람이 적는다. 미기재면 측정만)
L9 progression선언된 단계 중 하나가 화면에서 빠졌나 — 실사고: ①②③④ 중 ①이 화면에서 떨어져 리뷰어가 논지를 정반대로 읽었다. 개별 문장은 전부 옳았다차단 (선언된 것만 본다)
L12 diagram타입 JSON 도해가 «지금 JSON» 에서 validate 를 거쳐 구워졌나 — kind: diagram_source 표면의 굽기 영수증(*.receipt.json)으로 JSON 지문 일치 · showcase validate ok · PNG 실제 폭(IHDR 직독) ≥ 3840 · viewBox 폭 ≤ 720 · 여백. 실사고 후보 셋: JSON 고치고 PNG 안 구움 · 미검증 JSON 손렌더 · 픽셀은 충분한데 글자 12pt차단 (선언된 표면만 · 영수증 없는 손그림은 UNMEASURED, 0 아님)
L14 screen-parity원고의 화면 블록(🖥)과 덱 화면이 갈렸나 — surfaces.yaml 이 원고를 「화면 문자열의 정본」이라 선언해 놓고 그 선언을 집행하는 레인이 없었다. 실사고: 운영자가 PowerPoint 에서 7곳을 직접 고쳤는데 preprep 이 rc=0 을 냈다 — 덱은 새 문장, 원고는 옛 문장을 든 채로 통과🟥 advisory · known-pair(덱 한 벌 · 원고 두 벌) — 🟥 「짝 없는 줄」과 「문구만 다른 줄」을 갈라서 낸다. 이 덱 실측 53/38건이라 «후보 0» 이 목표가 아니다
L15 font서체가 그 덱의 배포 템플릿이 정한 집합을 벗어났나 — slides/ 안에서 «명시된» 서체만 판정하고, slideLayouts·slideMasters·theme 은 템플릿과 해시가 같으면 상속분으로 보고 판정하지 않는다. fonts.allow 미선언이면 템플릿 자신의 slides/ 분포에서 허용 집합을 유도한다. 테마가 이탈이면 +mn-* 참조 전부가 거기서 오므로 테마 한 곳만 지적한다차단 (🟥 fonts.template 미선언 = 상속과 저자 이탈을 구분 불가 → 그 사실을 노트에 적는다 · 서체 토큰 0 = UNMEASURED, 「이탈 없음」 아님 · fonts.intended 로 선언한 것은 «면제됨»으로 출력 — 면제도 가족 단위다 · 🟥 렌더되지 않는 것은 안 센다: 빈 런 · endParaRPr(빈 문단 끝서식) · 테마의 <a:font script=…> 폴백)
L15-b font-embed쓰는 서체를 덱이 «들고 다니나» — presentation.xml 의 embeddedFont 집합이 slides/ 가 부르는 서체 집합(a:latin·a:ea, 테마 참조는 풀어서)을 덮나. 🟥 L15 와 다른 실패를 잡는다: L15 는 «템플릿 집합을 벗어났나», 여기는 «발표장 PC에 설치돼 있다고 가정하고 있나». 실사고 2026-09-21: 한 덱이 안 쓰는 서체를 임베드하고 실제로 쓰는 둘(런 3,724회)을 안 넣은 채 제출됐다차단 (🟥 임베드 0 = UNMEASURED 아니라 FAIL — 이 축은 부재가 곧 결함이다. 면제는 fonts.embed_exempt(+why) · 임베드했지만 미사용은 노트로만 · a:sym/a:cs 전용 지정과 못 푼 테마 참조는 UNMEASURED)
L16 speech-coach리허설 녹화를 듣고 코칭 6항 표를 낸다 — ①발음(원고 ↔ 받아쓰기 어긋남 «후보») · ②쉼표 여유·접속사 끌기 · ③어미 밀당(문장 끝 300ms 피치) · ④첫·끝 인사 크기 · ⑤시선 · ⑥내용. 입력이 surfaces.yaml 의 문서가 아니라 녹화라 preprep.py 에 배선하지 않고 독립 CLI(lane_speech_coach.py)로 부른다. 아래 §발표 코칭🟥 advisory · exit 1 없음(문턱 전부 UNCALIBRATED) · ffmpeg 없음 = 전부 측정불가 exit 2 · whisper 없음 = ①② 측정불가, ③④ 는 오디오만으로
G ooxmlpptx 구조 9종 — 관계 참조 무결성 · 죽은 Content_Types Override · 화면 밖 도형 · 열린 도형 채움 · 선 굵기 토큰 래칫차단 (python3 ooxml/gate.py <풀린 pptx 트리>)
R1 orphan-connective선두 줄이 «그러나/그래서»로 뒤집는데 그 문장의 주어가 직전 장 어디에도 없다🟥 advisory · 실물 known-positive(실제 백업에서 뜬 결함)
R2 enum-dropped앞 장이 ①②③ 으로 센 것을, 이 장이 «이 셋 중…» 이라 부르며 번호 없이 재편한다 — 1:1 대응이 안 보인다🟥 advisory · 실물 known-positive
R3 lead-term-unbacked선두 줄이 강조색으로 선언한 낱말이 그 장 다른 어디에도 없다 — 화면이 자기 부제를 못 받친다🟥 advisory · 합성 뮤턴트 known-pair(자연 발생본이 파일로 안 남아 실물 2장을 줄여 만든 픽스처로만 계량됨 — R1·R2·P1·P3 과 증거 등급이 다르다)
R4 screen-heavy화면 자수가 이 덱 자기 분포(P90)의 상위권 — 한 장에 너무 많이 얹었다🟥 advisory · 순위표(게이트가 아니다 — 늘 자기 덱의 상위 약 10%가 뜬다, 「후보 0」이 목표가 아니다)
R5 read-load직전 장 대비 새로 뜬 글자 ÷ 발화 초 — 화면은 늘었는데 말은 짧다. 무대 지시([간지]/[진행])는 발화로 안 센다🟥 advisory · 순위표(R4 와 같은 성질)
P1 build-jitter같은 이름 도형이 연속한 두 장에서 조금 다른 자리에 있다 — 넘길 때 튄다🟥 advisory · 실물 known-positive — 결박 내역을 셋으로 갈라 낸다(이름+글자 / 이름만(글자 없는 도형) / 글자 불일치=제외). 🟥 앞 둘이 다 0 이면 「튐 없음」이 아니라 UNMEASURED. 의도된 연출은 geometry.intended 로 선언해서 면제하고, 면제된 것은 «면제됨»으로 출력된다. 🟥 뒤집힘(flipH/flipV)은 임계와 무관하게 낸다 — 상자가 한 EMU도 안 움직여도 화면에서는 화살표가 반대를 가리킨다(2026-09-10 실사고)
P3 adjacency한 도형의 오른쪽 끝과 다른 도형의 왼쪽 끝이 맞닿으려다 어긋났다🟥 advisory · 실물 known-positive · 🟥 절대 목록으로 읽지 마라(기저 오탐 76건 실측) — surfaces.yaml 의 geometry.baseline(이전 판 pptx)을 주면 편집 전/후 델타로 돈다. P2(near-miss, 같은 종류 모서리만 대조)는 미채택 — 구조적으로 실제 결함(다른 종류 모서리의 인접)을 못 잡아서다
P4 attr-consistency덱 자신의 분포가 판정 기준이다 — 같은 역할끼리 묶어 «혼자 다른 것»을 낸다. 축 넷: dash(같은 점선인데 굵기가 갈림) · algn(같은 줄인데 정렬이 갈림) · mirror(좌우 대칭인데 크기가 갈림) · echo(장을 가로질러 — 같은 문장이 매번 다른 크기·자리)🟥 advisory · known-pair 8팔(축 넷 × 양팔, 컨트롤 살아 있음) — 🟥 이 레인은 «다르다»만 본다, «틀렸다»는 사람이 판정한다. 의도는 attr_consistency.intended 로 선언

🟥 L15 의 본체는 검출이 아니라 «상속과 저작의 분리»다. 순진하게 서체 이름만 세면 이 코퍼스에서 오탐 85건이 나온다 — 그 85건은 전부 slideMasters/ 안에 있고, 배포 템플릿의 마스터에도 정확히 같은 85건이 있다(해시 동일, 2026-09-11 실측). 저자는 그 글자를 찍은 적이 없다. 진짜 이탈은 3런 하나뿐이었고(코드 데모의 고정폭 서체) 그건 «의도»였다. ⇒ 판별자는 영역 + 템플릿 해시 대조이지 서체 이름이 아니다. 뒤집으면, 템플릿에서 갈라진 마스터·레이아웃은 반대로 저자 책임이라 그 사실을 따로 보고한다. 코드: lane_font.py · self-test: test_lane_font.py(42항 — 5라운드에서 30→42) · 레인 래퍼 scripts/test_preprep_font_lanes.sh (되돌림 프로브 fixtures/font_revert_probe.py). known-negative 가 «서체 하나뿐인 덱»이 아니라 «마스터에 이질 서체가 있지만 템플릿과 동일한 덱» 인 것이 핵심이다 — 그게 실제로 틀렸던 자리다.

🟥 이 레인이 «안 읽는» 자리는 0 이 아니라 UNMEASURED 로 나간다 (5라운드 신설). 차트 (ppt/charts/)·SmartArt(ppt/diagrams/) 안의 글자는 화면에 렌더되지만 slides/ 밖이라 스캔 범위가 아니고, DrawingML 을 a 가 아닌 접두사로 묶은 장도 이 정규식 스캐너가 못 읽는다. 둘 다 그런 자리가 있으면 세어서 노트로 낸다 — 「안 읽었다」를 「이탈 없다」로 렌더하지 않는 것이 이 레인 전체의 규율이다([[feedback_not_found_is_not_zero_family]]).

🟥 cross-family 2라운드가 판정을 한 번 뒤집었고, 그 되돌림 자체가 계약이다. 1라운드는 «템플릿 자신의 마스터/레이아웃이 쓰는 서체는 오탐이니 노트로 강등하라»고 했고 그렇게 고쳤다. 2라운드가 그것을 fail-open 으로 지목했다 — 배포 템플릿의 레이아웃은 쓰이지도 않는 자리에 Office 기본값(Arial·Calibri)을 흔히 들고 있어서, 강등하면 저자가 그 이름으로 본문을 찍어도 종료코드가 안 움직인다. ⇒ 억제는 걷고 맥락 주석만 남긴다(finding 은 유지). 래퍼의 annotation 프로브가 이 되돌림이 다시 억제로 가지 않는지를 고정한다. 2라운드가 닫은 나머지 다섯: 자식 있는 defRPr 에서 비탐욕 정규식이 서체를 조용히 버림 · presentation.xml 의 r:id/id 속성 순서가 다르면 장 순서가 빈 리스트가 되어 0건 PASS · 테마의 <a:font script="..."> 보조 폴백을 위반으로 셈 · 면제가 정확일치라 선언한 가족의 굵기 변형이 안 덮임 · 갈라진 부품에서 원래 있던 서체까지 이탈로 보고. 🟥 구조적으로 못 보는 것 셋: 이미지에 구워진 글자 · 그 서체가 설치돼 있는지(파일은 이름만 적고, 없으면 렌더러가 조용히 대체한다) · 굵기 변형의 실재. 셋 다 파일 밖의 사실이라 0 으로 세지 않는다. 🟥 정정 2026-09-21 — 둘째의 «절반»은 파일 «안»의 사실이라 이제 잰다. 설치 여부는 여전히 못 보지만 «설치에 기대고 있나»(=임베드했나)는 잰다 — 그 자리가 L15-b font-embed 다. 즉 위 문장은 «못 본다»가 아니라 **«못 보는 쪽과 보는 쪽이 갈린다»**로 읽어야 한다. 이 구분 없이 인용하면 임베드 결함을 «구조적 한계»로 덮는다(실측: 한 덱이 실사용 서체 둘을 안 넣고 제출됐다).

🟥 L8 이 advisory 인 이유: 두 계기의 오탐을 **최저비용으로 무마하는 길이 「그 문장을 지우는 것」**이라, 종료코드에 태우면 원고를 나쁜 방향으로 미는 압력이 된다. 후보를 내고 판정은 사람이 한다. 오탐 다수가 정상이다.

🟥 R1~R5·P1·P3 이 전부 advisory 인 이유: L8·L11 과 같다 — 오탐의 최저비용 무마가 원고를 망가뜨리는 방향(문장 삭제·형식 왜곡)이라 종료코드에 태우지 않는다. preprep.py 배선도 findings 를 버리고 notes 로만 낸다(L8·L11 관례). --lane R1,R2,R3,R4,R5,P1,P3(또는 그룹 R·P)로 이 일곱만 골라 돌릴 수 있다 — 🟥 L1~L11 은 아직 이 --lane 필터를 안 탄다(늘 전부 돈다). 정본: tracks-meta/fh_signal_2026-09-04_preprep-evolution.md §1·§2 · 코드: lane_slide_relations.py · lane_geometry.py · 픽스처: fixtures/mk_slide_fixtures.py(테스트 시 생성) + fixtures/fixture_R3_{positive,negative}.pptx(실물 2장) · self-test: test_preprep_lanes_rp.py.

발표 코칭 (L16) — 원고를 «소리 내 읽은 결과」를 듣는다

python3 "$SKILL/lane_speech_coach.py" 리허설.mp4 --script 덱.pptx      # 노트가 원고. .txt/.md 도 된다
python3 "$SKILL/lane_speech_coach.py" 리허설.mp4 --audio-only           # 받아쓰기 없이 ③④ 만(선언)
# exit 0 = 범위 안 항목을 다 들었다(«좋은 발표」 아님) · 2 = 하나라도 못 들었다(통과 아님) · 1 은 안 쓴다

외부 입력 경계 7곳(도구 경로 · 모델 경로 · 녹화 디코드 · 원고 로드 · whisper 실행 · 덩어리 파일 준비 · 덩어리별 받아쓰기 파싱)은 그 경계 안에서 무엇이 터지든 그 항목만 측정불가(사유) · exit 2 로 떨어진다 — 트레이스백(exit 1 = «발견」으로 오독)이 아니다. 경계 밖(분석 코드)은 일부러 넓게 잡지 않았다.

부분 디코드도 «못 들음」이다 — ffmpeg 는 손상 패킷을 버리고도 rc 0 으로 끝난다. 그래서 stderr 오류 줄이 하나라도 있거나, 디코드된 길이가 녹화 길이(ffprobe)보다 2% 이상 짧으면 ①~④ 를 «부분(디코드 불완전 — 사유)»으로 내리고 exit 2 다. 들린 부분의 표는 그대로 나온다.

exit 2 = 일부 못 들음이지 실패가 아니다 — 표는 그대로 나오고, ①② 가 «부분(일부 못 들음)»이면 못 들은 덩어리의 위치(와 사유)가 같이 찍힌다. 그 자리만 귀로 확인하면 된다.

의존성없으면지정
ffmpeg (필수)①~④ 전부 측정불가 · exit 2PATH 또는 PREPREP_FFMPEG
ffprobe (ffmpeg 와 함께 깔림)녹화 길이 대조를 못 해 ①~④ 가 «부분(길이 대조 못 함)» · exit 2 — 잘린 디코드를 못 가리므로 «다 들음」이라 하지 않는다PATH · PREPREP_FFPROBE · ffmpeg 옆
whisper-cli + 모델 (선택)①② 측정불가, ③④ 는 오디오만으로 돈다 · exit 2 (--audio-only 로 빼면 0)PREPREP_WHISPER_CLI · PREPREP_WHISPER_MODEL(기본값 없음 — 일부러) · PREPREP_WHISPER_LANG(기본 ko)
python-pptx--script *.pptx 만 못 읽는다(①측정불가)—

녹화는 기계 밖으로 나가지 않는다 — 디코드·받아쓰기·분석이 전부 로컬이다. 명시 경로(PREPREP_*)가 틀리면 PATH 로 몰래 갈아타지 않고 «없음」으로 낸다. 상태는 셋이다: 잡음(계기가 돌았고 근거 시각이 있다) · 부분(후보이거나 기준선이 없어 묘사만) · 측정불가(이유를 «의존성 없음 / 설계상 범위 밖 / 사용자가 뺌」으로 갈라 적는다). 받아쓰기가 일부 덩어리에서 빠지면(JSON 없음 · 모양 이상 · 말소리 덩어리인데 낱말 0 — «말소리」는 길이가 아니라 유성 비율(≥0.25, UNCALIBRATED)로 가른다. 0.3초 «네」도 말소리다) ①② 는 «부분 — 일부 못 들음」을 넘지 못하고 누락 비율·위치를 내며 exit 2 다. 텍스트 원고는 UTF-8 → CP949 순으로 읽고, 둘 다 실패하면 ① 측정불가다. whisper-cli 가 있어도 실행이 안 되면(셰뱅 없음 등) ①② 측정불가다. ⑤시선은 영상이 필요해 설계상 범위 밖, ⑥내용은 L1~L15 몫이다.

🟥 한계 — 인용 전에 읽어라.

  • 받아쓰기 낱말 시각은 실측 최대 ~0.8초 어긋났다. 그래서 낱말 시각으로 쉼을 재지 않는다 — 쉼(≥0.15초)으로 자른 덩어리를 하나씩 받아쓰게 하고 시각은 덩어리(음향) 경계에서 가져온다. 덩어리 안에 붙은 접속사의 길이만 토큰 시각이고, 그건 UNCALIBRATED 로 표기된다.
  • 덩어리 단독 받아쓰기는 0.35초 미만 잡음에 «감사합니다」를 지어낸다(실측 16/550). 걸러내고 그 수와 시각을 출력한다. 🟥 버린 덩어리가 유성이면(말은 했는데 못 알아들음) 누락으로도 센다 — 환각 필터가 커버리지 검사를 우회하지 못하게. 다른 형태의 환각은 못 거른다.
  • ① 은 «후보」다. 받아쓰기 오류와 실제 발음을 이 계기만으로 못 가른다. 실측에서 관형형 «-는」이 «-ㄴ」으로 들린 자리가 같은 문장 TTS 대조군에서는 0/60 이었지만, 그래도 사람 귀로 확인하기 전엔 발음 판정이 아니다.
  • ③ 은 기준선이 없다. 한국어 평서문은 원래 내려간다 — «하강 비율이 높다」는 결함 판정이 아니라 모양의 묘사다. 사람 낭독 기준선(같은 화자의 «좋은 녹화」)이 생기기 전까지 «부분」을 넘지 않는다.
  • 보정 상수(끌기 1.30 · 구 끝 대리 쉼 0.60초 · 밀당 1반음 · 옥타브 의심 위 +6 · 아래 −12반음 · 발화 문턱 +12dB …)는 전부 녹화 1건(화자 1명)과 TTS 대조군에서 고른 값이다. 출력에 UNCALIBRATED 로 그대로 찍힌다. reps=1 — 이 저장소 자기 바(≥3) 미달.
  • self-test(test_lane_speech_coach.py)는 합성 신호 known-pair(쉼 · 끝 피치 하강/상승/평탄/밀당 · 끝인사 크기 · 접속사 늘임 · «-는」 탈락)와 가짜 받아쓰기·디코더로 퇴화 경로를 고정한다. 되돌림 프로브는 지역 문턱을 전역 문턱으로 바꿔 잡음 바닥이 오른 구간의 쉼이 사라지는지 본다. 🟥 합성 신호 통과는 «사람 목소리에서 맞는다」의 증거가 아니다 — 실화자 피치는 프레임 단위 손검증을 안 했다.

문체는 레인이 아니다 — 레퍼런스와 스킬이 한다

초판에는 ko-tech-writer Step 2 를 레인으로 복제한 L9 가 있었다. 뺐다. 이유가 둘이다.

🟥 ① 예측보다 레퍼런스다. 패턴으로 «나쁜 문장을 미리 맞히는» 것보다 참고할 실물을 묻고 받는 것이 확실하다. 회고 검증을 세 문서쌍에 돌렸는데 전부 판별 불가였다 — 고편집 쌍은 소음(base 52%·43%)이 신호를 덮고, 저편집 쌍은 사건 자체가 없었다(base 1.6%, 짚힌 8줄 중 1건, 기대값 0.13). 그리고 이 급의 산출물은 다시 오지 않으므로 앞으로도 측정 불가다. 반면 레퍼런스는 물어보면 그냥 받는다.

🟥 ② 그것은 중복이었다. L9 의 다섯 클래스는 ko-tech-writer Step 2·4-b 를 옮긴 것이고, 이 스킬은 ⑤에서 그 스킬을 부른다. 즉 빼도 능력은 정본 자리에 그대로 있다 — 제거는 손실이 아니라 중복 해소이고, 이 하네스가 이원화에서 지키는 단일-소스 원칙과 같은 자리다.

⇒ 번역투·레지스터·수치 게이트·지각 QA 는 ko-tech-writer 로 간다. 여기 레인으로 두지 마라.

갈라 적는 것 (합치면 계기가 거짓말한다)

  • USE ↔ MENTION — 금지어를 «쓴 줄»과 «쓰지 말라고 적은 줄»은 다르다. 거르지 않고 두 부류로 낸다. 죽은 필터는 진짜를 죽인다. ⚠️ 이 구분은 패턴 매칭으로는 못 가른다 — 제거된 L9 의 known-negative 픽스처 초판이 자기 헤더의 «언급»에 걸렸던 것이 그 실측이다. ko-tech-writer 로 넘길 때도 같은 한계가 따라가므로, 후보 목록을 사람이 볼 때 이 축을 먼저 갈라라.
  • 부재 ↔ 0 — 선언된 표면이 없으면 UNMEASURED 다. Keynote 는 사람만 읽는 면이라 영구 UNMEASURED.
  • 텍스트 레이어 ↔ 화면 — pptx 는 XML 만 본다. 이미지에 구워진 텍스트는 구조적으로 안 보인다. 생성기를 kind: figure_source 표면으로 세우면 사각이 좁아지지만 닫히지는 않는다.
  • 생성면 ↔ 사람 편집면 — 재생성은 사람 손질을 전량 덮어쓴다. 실측: 발표자 노트 20곳이 소리 없이 사라졌고 빌드는 성공했으며 원고↔빌드 대조는 «원고대로»였다. L7 의 자리다.

방법론 — 실사용 하루치에서 역산 (2026-09-04)

121장 한국어 발표 덱 한 벌을 하루 동안 실사용하며 나온 판단 축이다. 코드가 된 것은 §레인의 신규 레인들이고, 아래는 코드만으로는 안 닫히는(또는 아직 코드가 아닌) 것들이다.

ⓐ 장을 지워도 시간은 안 줄어든다

장 삭제만으로는 발화 시간이 0초 줄었다. 시간은 대사에 있고, 대사는 화면 글자에 묶여 있다(화면에 적혀 있으면 안 말할 수가 없다). 실제로 줄어든 것은 화면 자수를 깎았을 때뿐이다. ⇒ 분량 정리의 1순위 대상은 «장 수»가 아니라 «화면 글자»다.

ⓑ 전역 축은 한 장짜리 렌더로 판정하면 안 된다

색을 여러 면 바꾸고 한 장씩 렌더해서 「개선」이라 판정했는데, 전체를 이어서 넘겨 본 판정은 전달력 저하로 되돌렸다. 두 판정은 다른 것을 본다 — 한 장 안의 대비와, 여러 장을 흐르는 동안 「여기가 문제다」가 꽂히는 일관성은 같은 속성이 아니다. 후자는 한 장짜리 렌더에 구조적으로 안 나타난다. ⇒ 색·타이포 같은 전역 축은 연속 구간을 이어서 보거나 사람이 넘겨 봐야 한다. ⇒ 반대 방향도 같이: 한 장에서 보인 것을 전역으로 밀지도 마라 — 다른 장은 이미 다른 요소(예: 테두리 있는 카드)가 같은 문제를 막고 있을 수 있다.

ⓒ 렌더 없이는 구조적으로 안 보이는 것들

같은 하루에 렌더 없이는 놓쳤던 것 넷 — 옛 도해의 연결선 잔해(도형만 지우고 선을 안 지움) · 도형 종류가 덱 규약과 다름 · 빌드 프레임 전환에서 텍스트가 사라지는 자리 · 부연이 본문과 같은 밝기로 경쟁하는 자리. ⇒ 도해를 건드렸으면 렌더한다 — ⑤ 단계 규율.

ⓓ 새 도형을 넣기 전에 «같은 역할의 기존 도형»을 세라

새로 넣을 도형이 덱 전체와 혼자 달랐던 사고는, 덱에 이미 그 역할의 규약이 백 회 넘게 있었기 때문이었다 — 색도 형태도. 희귀한 값(전체 중 여섯 번뿐)이라도 그 여섯 번이 전부 같은 역할이면 그게 답이다. ⇒ 덱 자기 규약을 먼저 추출한다. 지어내는 것은 마지막 수단.

ⓔ 장을 뺄 때 «그 장이 받는 말이었나»를 본다

한 장을 지우자 다음 장 부제의 「그러나」가 받을 말을 잃었다. 삭제 전 뒤 장의 전제인지 확인한다 — ⑤ 단계 규율.

ⓘ 이름이 겹치는 도형을 «순번»으로 집지 마라 — 자리로 결박해라

2026-09-10 실사고. 한 장에 a-a1 이라는 같은 이름의 화살표가 셋 있었고, 그것들을 대칭으로 맞추려고 occurrence=0/1/2 로 집어 자리를 배정했다. 순번을 잘못 짚어 flipH 가 엉뚱한 도형에 남았고, 바깥 화살표 둘이 상자 «바깥쪽»을 가리켰다 — 모이는 그림이 벌어지는 그림이 됐다.

🟥 그리고 아무 계기도 안 잡았다. 기하 레인은 그때 flip 을 안 읽었고(지금은 읽는다), 편집 전/후 델타는 「새 어긋남 0건」을 냈으며, 렌더도 봤는데 내가 잘못 읽었다. 운영자가 눈으로 잡아 손으로 고쳤다. 계기와 눈이 같이 놓친 자리다.

⇒ 규율: 편집 대상을 이름으로 못 특정하면 지금 자리(x, y)로 결박한다. 순번은 XML 문서 순서라는 «저자가 모르는 사실»에 기대고, 틀려도 값이 다 들어가므로 집합으로는 옳아 보인다. 그리고 편집 뒤에는 바꾸려던 그 도형이 바뀌었는지를 이름이 아니라 자리로 되읽어 확인한다. (P1 이 「이름은 필요조건이지 충분조건이 아니다」로 배운 것과 같은 교훈의 편집 쪽 얼굴이다.)

ⓕ 「알고도 남긴 것」과 「몰라서 남은 것」을 갈라 적어라

팔레트 밖 색을 정해서 남긴 자리가 있었다. 그렇게 적지 않으면 다음 감사자가 다시 «발견»한다 (실측: 지운 색이 다른 색번호로 되살아나 있었다). 체크리스트 항목: presentation_checklist.md C6.

🟥 2026-09-10 — 이게 산문 규율만으로는 안 지켜졌고, 그래서 채널이 생겼다. 그날 49p→50p 의 격리 막대가 두꺼워지는 것을 P1 이 «튐»으로 냈고, 나는 그것을 «고쳤다». 운영자가 "49~50으로 격리 선이 두꺼워지는 거였는데 지금 그게 발생하지 않음" 이라고 지적해서 되돌렸다. ⓕ 는 그때 이미 이 문서에 적혀 있었다 — 읽고도 안 걸렸다. 규율이 사람 기억에 얹혀 있으면 다음 세션에서 또 새어 나간다([[feedback_half_fix_propagation_boundary]]).

⇒ 선언은 이제 surfaces.yaml 이 받는다 — geometry.intended · attr_consistency.intended. 세 가지가 규율이다:

① 면제는 «도형»이 아니라 «그 변화»에 걸린다  선언한 속성 말고 다른 게 바뀌면 그대로 뜬다
② `why` 가 비면 «면제»가 아니라 «오류»다      사유 없는 면제는 이 채널의 존재 이유를 지운다
③ 면제된 것은 «면제됨»으로 출력된다           조용히 사라지면 다음 감사자가 다시 «발견»한다

🟥 기계는 «선언되었나»만 보고 «옳은가»는 안 본다(CLAUDE.md §Mechanization Boundary — 채널은 굳히고 판단은 안 굳힌다). 그러니 이건 «연출을 자동으로 알아본다»가 아니다. 못 알아본다. 알아보는 것은 사람이고, 기계는 그 판단이 다음 세션까지 살아 있게 할 뿐이다.

ⓗ 「만들기」와 「설치」를 한 호출에 묶지 마라 — safe_install.py

2026-09-10 실사고: 편집 스크립트가 assert 로 죽었는데 뒤따르는 cp 가 그대로 돌아 120장 정본을 102장으로 잘린 파일이 덮었다(git 에서 복구). 근본 원인은 assert 가 아니라 앞이 실패해도 뒤가 도는 형태다 — 셸에서 ; 로 이은 줄은 전부 그 형태다.

python3 safe_install.py <후보> <정본>    # zip 무결성 · 필수 부품 · 장 수 · 파일↔목록 일치
                                         # · 복사 후 해시 재확인. 통과해야만 복사한다
... --dry-run          검사만        ... --expect N        장 수를 못 박는다
... --allow-shrink --why "<사유>"    의도한 축소(기본은 거부 — 비가역 표면은 fail-closed)

⚠️ 구조만 본다. 120장이 그대로 120장이면서 전부 빈 장이 된 경우는 통과한다 — 좁아진 것이지 닫힌 게 아니고, 그 자리는 레인과 렌더가 본다.

ⓖ 외부 가이드를 인용할 때 — «정의»는 «금지문»이 아니다

같은 레퍼런스를 두고 두 판정이 갈렸다: 폰트 크기 「위반」을 유보했는데 원문에 숫자가 한 개도 없어서 위반이 아닌 것으로 확정됐고, 색 「위반」은 스와치(정의)를 근거로 올렸다가 철회했다 — 색에 대한 유일한 문장은 「같은 위계에 같은 색으로 통일」이라 오히려 만족하고 있었다. ⇒ 레퍼런스에서 «위반»을 낼 때는 원문 문장을 인용하고, 스와치·템플릿 실측값은 «차이»로만 낸다 — ② 단계 규율.

정직한 한계 (2026-09-04 실측분, 인용 전에 읽어라)

§레인의 신규 텍스트 레인(orphan-connective · enum-dropped · lead-term-unbacked · screen-heavy · read-load)과 신규 기하 레인(build-jitter · adjacency)에 대한 캘리브레이션 잔여다. 이 절 없이 그 레인들의 수치를 인용하면 과계상이다.

  • reps=1. 텍스트·기하 신규 레인은 모두 known-positive 한 팔씩이다. 이 저장소 자기 바(≥3) 미달.
  • lead-term-unbacked 의 known-positive 는 합성 뮤턴트다(자연 발생본이 파일로 안 남았다). 나머지는 실제 백업에서 떴으니 증거 등급이 다르다 — 묶어 말하지 마라.
  • 오탐 0 은 n=1 코퍼스에서의 수치다. 다른 덱에 옮기면 임계(선두 줄 판별 · 강조색 비교 · 활용 어미 제외 · 자기분포 P90)를 다시 재야 한다.
  • enum-dropped 는 표에서 한 칸 어긋난 프레임에서 뜬다 — 같은 표의 이웃 프레임이라 부류는 맞지만 쪽수가 어긋난다.
  • adjacency 기저 오탐이 76건. 절대 목록으로 쓰면 안 된다 — 편집 전/후 델타 용법이 전제다.
  • L8 오탐 진단(«저희»·«그대로»)은 이 한 덱에서 나왔다. 다른 한국어 코퍼스에서 같은 비율인지는 미측정.

2026-09-10 추가분 (P1 결박 정정 · P4 신설)

  • 🟥 RETRACTED — 「P1 결박을 «이름 AND 글자»로 좁혀라」는 처방은 틀렸다. 2026-09-10 인계 노트가 그렇게 적었고 그대로 구현했는데, 원적 사건 재현 프로브가 그 자리에서 빨개졌다: 35p→36p 의 게이트 막대 s5017 은 글자 없는 도형이라 좁힌 결박이 P1 의 존재 이유였던 그 결함을 통째로 잘라냈다. 오탐을 없애면서 자기 known-positive 를 같이 죽인 형태다. **살아남은 처방은 좁히기가 아니라 «신뢰도로 가르기»**다 — 버리는 것은 «글자가 서로 다른 쌍» 하나뿐이고, 글자 없는 도형은 [이름만 결박] 이름표를 달고 후보로 남는다. ⇒ 인계 노트나 요약에서 「이름 AND 글자로 좁혔다」를 보면 그건 낡은 줄이다.
  • P1 결박 분포는 이 덱 한 벌 수치다 — 824쌍 중 이름+글자 425 · 이름만 334 · 불일치 65. 다른 덱은 도형 이름 규약이 달라 비율이 통째로 달라진다. 인용하려면 자기 덱에서 다시 재라.
  • P4 의 known-pair 는 reps=1 이고 생성 픽스처다. 축 넷 × 양팔이 각각 한 번씩이고, 이 저장소 자기 바(≥3) 미달이다. 다만 컨트롤이 죽지 않았음은 확인했다 — 두 팔의 도형 수·이름·자리가 같고 갈리는 값 하나씩만 다르다(negative 가 «볼 게 없어서» 조용한 것이 아니다).
  • P4 가 실물에서 잡은 것은 손검증 1건뿐이다. 완성 덱에서 후보 16건이 떴고 그중 71p [mirror](나란한 두 카드가 28pt ↔ 22/28pt)를 XML 로 직접 열어 실재 확인했다. 나머지 15건은 미검증이다 — 「16건 잡았다」로 인용하지 마라.
  • algn·mirror 축은 키가 엄격하다(정확히 같은 폭·같은 y / 허용 오차 안의 거울 자리). 한 픽셀 어긋난 «같은 줄»은 구조적으로 안 잡힌다. 실측에서 이 덱은 dash 0 · algn 0 이었는데, 그건 「그런 결함이 없다」가 아니라 「이 키로는 못 본다」일 수도 있다.
  • 크기 축은 명시 sz 만 읽는다. 플레이스홀더·테마 상속 크기는 XML 에 없어 UNMEASURED 다. 실측: 도형 1,901개 중 명시 크기가 있는 것은 990개(52%) — 나머지 절반은 이 축의 사각이다.
  • echo 축의 오탐률은 높은 쪽이다. 같은 문장이 요약 장에서 작게 다시 나오는 것은 정상이고, 이 레인은 그것과 «실수로 갈린 것»을 못 가른다. 순위표로 읽고 선언으로 걷어내라.

Done When

조건check-class
python3 preprep.py 가 선언된 전 표면에 대해 돌고 종료코드가 0/1/2 중 하나로 확정된다mandatory-pass
공통화된 시행착오가 줄었다 — 이번 제작에서 «지난번에도 겪었고 이번엔 안 겪은» 것을 이름으로 적을 수 있다(구성 배치 · 형식 결정 · 도해 영점 그리기). 0건이면 이 하네스는 이번에 값을 안 냈다judged — 적대 짝: 그 목록을 저자가 아닌 사람이 읽고 «그건 원래 안 겪는 것 아닌가»를 되묻는다
레퍼런스를 물었다 — 참고할 실물이 있나를 묻고, 있으면 그것을 근거로 세웠다. 없으면 «없다»고 기록했다(안 물은 것과 구분)mandatory-pass
단일 소스 드리프트 앵커가 통과한다 (scripts/test_preprep_drift_anchor.sh)measured
발견 목록을 사람이 판정했고, advisory 후보 중 남긴 것에는 남긴 이유가 적혔다judged — 적대 짝: 그 판정을 저자가 아닌 사람이 다시 읽는다(격리 그라운딩). 자기 판정으로 대체 금지
도해를 건드렸으면 렌더 결과를 첨부했다(§방법론 ⓒ)judged — 적대 짝: 렌더 파일이 실제로 존재하는지(경로·확장자·이번 편집 이후의 mtime)는 별도로 measured 로 확인한다. 「첨부했다」는 자기신고만으론 인정하지 않는다

이 하네스가 못 하는 것

발표를 잘 만들어 주지 않는다. 어긋난 자리를 찾을 뿐이고, 무엇을 말할지·어떤 순서로 놓을지는 판단이다. 그리고 위 「갈라 적는 것」의 네 사각은 좁아진 것이지 닫힌 게 아니다.

Saved skills