genetics-mcp 2.27.0 → 2.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/genetics.mjs +154 -455
  2. package/package.json +4 -5
  3. package/skills/gazette-report/scripts/boundary.py +8 -1
  4. package/skills/gazette-report/scripts/tone.mjs +1 -1
  5. package/skills/gazette-report/scripts/tone.test.mjs +3 -0
  6. package/skills/genetics-cell-id/SKILL.md +4 -5
  7. package/skills/genetics-report/SKILL.md +59 -39
  8. package/skills/genetics-report/assets/example/cases-briefing-designs.json +11 -11
  9. package/skills/genetics-report/assets/example/cases-briefing.json +3 -3
  10. package/skills/genetics-report/assets/example/cases.json +3 -3
  11. package/skills/genetics-report/assets/example/decision.json +43 -43
  12. package/skills/genetics-report/assets/example/report-briefing-designs.json +61 -61
  13. package/skills/genetics-report/assets/example/report-briefing.json +54 -54
  14. package/skills/genetics-report/assets/example/report.json +34 -45
  15. package/skills/genetics-report/assets/render.py +4 -6
  16. package/skills/genetics-report/assets/subset_font.py +1 -1
  17. package/skills/genetics-report/references/content-pipeline.md +1 -1
  18. package/skills/genetics-report/references/decision-format.md +90 -24
  19. package/skills/genetics-report/references/font-embedding.md +1 -1
  20. package/skills/genetics-report/references/history.md +38 -5
  21. package/skills/genetics-report/references/lim-portal-format.md +48 -24
  22. package/skills/genetics-report/references/process.md +28 -26
  23. package/skills/genetics-report/references/readability.md +5 -5
  24. package/skills/genetics-report/references/visual-first.md +18 -79
  25. package/bin/aarch64-apple-darwin/gcell +0 -0
  26. package/bin/aarch64-unknown-linux-musl/gcell +0 -0
  27. package/bin/manifest.json +0 -7
  28. package/bin/x86_64-apple-darwin/gcell +0 -0
  29. package/bin/x86_64-pc-windows-gnu/gcell.exe +0 -0
  30. package/bin/x86_64-unknown-linux-musl/gcell +0 -0
  31. package/skills/genetics-report/references/edition-review.workflow.js +0 -196
  32. package/skills/genetics-report/references/linear-read-test.workflow.js +0 -106
  33. package/skills/genetics-report/references/reader-review.workflow.js +0 -404
@@ -19,7 +19,7 @@
19
19
 
20
20
  | 없으면 | 무슨 일이 나는가 |
21
21
  |---|---|
22
- | `sections[].marg` (여백 주석 단) | 두 단 본문이 **한 단으로 선다.** 「문서처럼 꾸민 웹페이지」로 되돌아간다 |
22
+ | `sections[].marg` (절 첫머리 물음 · 답 — 관보 v4) | `why` 는 절 머리 밑의 **물음**, `key` 는 그 **답**, `advice` 는 절 끝의 「더 볼 곳」으로 선다(2026-10-13 — 왼쪽 여백 단과 영어 라벨 Why · Key Point · Advice 를 걷음). 없으면 절이 물음 없이 선다(⚠) |
23
23
  | `parts` (PART 층위) | 절만 늘어선다. 「먼저 읽을 것 / 경과 / 남은 것」이라는 **읽기 순서**가 사라진다 |
24
24
  | 주어별 톤(§14) | 요청 자리 밖에 경어체를 쓰면 관보 문법 위에서 겉돈다. **독자가 할 일을 요청 자리 밖에 개조식으로 적거나, 요청 자리를 개조식으로 맺으면 명령·하대로 읽힌다** |
25
25
 
@@ -123,14 +123,14 @@ python3 assets/render.py <report.json>
123
123
  |---|---|---|
124
124
  | `title_tag` | `<title>` — 브라우저 탭·링크 미리보기 | 빈 제목으로 나간다 |
125
125
  | `description` | `<meta name="description">` | 빈 값으로 나간다 |
126
- | `kicker` | 표지 머리말(작은 글자 한 줄) | 그 줄만 빠진다 |
126
+ | `kicker` | 표지 머리말(작은 글자 한 줄). 회사 이름 · 약호를 지어 넣지 않는다 — 보내는 쪽은 `issuer` 첫 칸이 진다 | 그 줄만 빠진다 |
127
127
  | `title` | 대제목 **첫 행**(굵게). 판권지 제목·러닝 푸터·자동 PART 이름의 폴백이기도 하다 | 표지 대제목이 안 선다 |
128
128
  | `title_sub` | 대제목 **둘째 행**(가늘게 — 회차·부제). 판권지 부제 폴백 | 둘째 행만 빠진다 |
129
129
  | `subtitle` | 표지 한 문단 요약(대제목 **아래**) | 요약문이 없다 |
130
130
  | `intro` | 같은 자리. **`subtitle` 보다 먼저 쓰인다**(`gazette.py Doc.cover()`) | — |
131
- | `doc_no` | 표지 문서번호 스트립. 판권지 부제 폴백 | 문서번호 칸이 빠진다 |
131
+ | `doc_no` | 표지 문서번호 스트립. 판권지 부제 폴백. 사용자가 쓰는 번호 체계가 있을 때만 적는다 — 회사 약호를 지어 넣지 않는다 | 문서번호 칸이 빠진다 |
132
132
  | `client` | 표지 우상단 고객사명. 러닝 푸터 폴백 | 로고도 없으면 우상단이 빈다 |
133
- | `issuer` | 발행처 스트립. 문자열 또는 목록(마지막 항목이 강조된다) | `doc_type`·`cover_date` 로 세운다 |
133
+ | `issuer` | 발행처 스트립. 문자열 또는 목록(마지막 항목이 강조된다). 첫 칸(발행처 · 결정 모드의 「보낸 곳」)은 `whoami` 가 보이는 운영사 이름이다 — 대화 맥락에서 회사 이름을 짐작해 적지 않는다. 운영사 줄이 없거나(키 자격 · 구성원 · 옛 서버) 「운영사 이름 미설정」이면 사용자에게 한 번 묻고, 「전체 관리자가 설정 › 보고서 브랜드 › 운영사 이름에 넣으면 다음부터 `whoami` 에 섭니다」라고 사용자에게 알린다. 이름을 모르면 첫 칸을 빈 글자 `""` 로 두고 칸을 빼지 않는다(빼면 대상이 보내는 쪽 자리로 온다 — SKILL 0단계 물음 7) | `doc_type`·`cover_date` 로 세운다 |
134
134
  | `doc_type` | `issuer` 폴백 조각 | — |
135
135
  | `cover_date` | `issuer` 폴백 조각 + 요약면 제목 옆 「기준」 날짜 — **수치의 기준일**이다. 기준일이 따로 없으면 작성일과 같게 둔다. 작성일과 다르면 `labels.as_of` 를 「작성」으로 바꾸거나, 기준일을 `colophon.mark` 와 그 수치를 싣는 표 캡션에 둔다. 작성일(`meta` 「작성」 · 판권지 「작성」 · `history` 마지막 `date`)과 묶어 대조하지 않는다 — 집계 기준일이 있는 문서의 뜻이 틀어진다 | 기준일 표기가 빠진다 |
136
136
  | `meta` | 표지 4칸 격자 `[{label,value}]`. 판권지 `rows` 폴백 | 격자가 안 선다 |
@@ -148,23 +148,41 @@ python3 assets/render.py <report.json>
148
148
  |---|---|---|
149
149
  | `parts` | PART 묶음 `[{no,title,tone,lede,questions[],roman}]` | **경고** 후 절 전체를 한 묶음으로 자동 생성 |
150
150
  | `sections` | 절 목록. 4절 참조 | 본문이 없다 |
151
- | `groups` | 건 묶음 `[{key,no,name}]` | `cases` 가 어디에도 안 실린다(**거절**) |
151
+ | `groups` | 건 묶음 `[{key,no,name,outside?}]` — 받는 쪽 뼈대의 항목이다(아래 `frame`). `outside` 는 뼈대 밖 묶음의 까닭 한 줄(`frame` 이 있을 때만) | `cases` 가 어디에도 안 실린다(**거절**) |
152
+ | `frame` | 거시 뼈대 `{name, title?}`(권함) — 아래 3.2b | 요약 종이에 뼈대 표가 안 서고, 한눈에 절(`status`)이 그 자리를 진다(옛 판 그대로) |
152
153
  | `cases` | 건 목록. 3.5절 참조 | `kind:"cases"` 절이 빈다 |
153
154
  | `summary` | 요약 문단 `[{lead,body,refs[]}]`. `summary_position:"front"` 이면 앞 요약면에도 선다 | 요지 부분이 빈다 |
154
155
  | `open_items` | 요청 항목 `[{title,priority,body,refs[]}]` | `kind:"asks"` 절이 빈다 |
155
156
  | `cta` | 요청 절 머리 강조문(문자열 목록) | 강조문이 안 선다 |
156
- | `grades` | 확인 등급 사전. 7절 참조 | 대조표 범례와 등급 표식이 안 선다 |
157
+ | `grades` | 확인 등급 사전. 7절 참조. 값 `[표식, 뜻]` 의 **뜻**이 문서 첫 건 머리의 풀이와 「건 읽는 차례」 표에 그대로 선다(관보 v4 — 기호는 첫 건 뒤 그 상자에서 처음 푼다) | 등급 표식이 안 서고, 뜻이 비면 첫 건 풀이 · 차례 표가 「grades 칸에 뜻이 없음」으로 선다 |
158
+
159
+ ### 3.2b 거시 뼈대 — `frame` (관보 v4 2026-10-13)
160
+
161
+ 받는 쪽은 이 문서를 자기가 이미 가진 뼈대로 읽는다 — 보낸 QA 자료의 쪽 · 항목, 접수한 건의 갈래.
162
+ 문서가 우리 원고 차례로 서면 독자는 「내 3쪽은 어디 갔나」를 스스로 짝지어야 하고, 짝이 안 맞는 자리는 아무도 모른 채 남는다(합의 착각).
163
+ 그래서 뼈대를 원고에 이름으로 박는다.
164
+
165
+ - `frame.name` — 받는 쪽이 부르는 이름(「QA 자료」). 요약 종이 머리말이 「QA 자료와 한 일」이 된다.
166
+ `frame.title` — 원래 제목(「QA 자료 1~9쪽」), 표 캡션 「QA 자료 1~9쪽과 한 일」. 없으면 `name`.
167
+ - 뼈대의 항목은 **`groups`** 다 — 묶음 이름을 받는 쪽 글자로(「QA 자료 3쪽 ①」), 차례도 받는 쪽 차례로 둔다.
168
+ 뼈대 밖에서 생긴 묶음(검수하며 함께 고친 것)은 `outside` 에 까닭 한 줄을 적는다. 그 묶음은 표 맨 뒤에 서고, 표 앞 줄이 「「함께 고친 것」은 QA 자료 밖의 것임. (까닭 문장)」으로 푼다 — `outside` 는 그 까닭 문장 하나(「검수하며 함께 찾아 고친 것」).
169
+ - 렌더러는 요약 종이의 결론 뒤에 **뼈대 표**(묶음 차례 그대로 → 건 · 확인 방법 · 상세)를 세운다. 한눈에 절(`kind:"status"`)의 지도 표와 표 아래 한 줄(`note`)은 이 표로 **옮긴다** — 그 절에 다른 것(원고 표 · 차트 · 흐름도 · 도해 · 그림 · 원문 인용)이 없으면 절째 걷고, 있으면 절은 남되 지도 표만 빠진다(표 번호 자리 N-1 은 비워 두어 본문의 「표 N-2」 가리킴이 그대로 맞는다). 새 원고에는 `status` 절을 두지 않고, 그 표 · 그림은 알맞은 절에 둔다.
170
+ - 지도 표의 칸은 **칸 규칙 표**(`private/builder/maptable.py` 의 `RULES` — 데이터 한 벌)가 고른다. 상태 · 확인 방법은 줄마다 값이 다를 때만 칸이고, 모두 같으면 표 밑 한 줄(「「확인 수준」은 2건 모두 「운영 환경 확인」.」)로 접힌다. 상세(건 번호)는 늘 선다. 한눈에 절 · 뼈대 표 · 결정 첫 종이가 같은 규칙 표를 읽는다 — 원고에 칸을 고르는 칸은 없다.
171
+ - 하실 일(`open_items`)은 `refs`(근거 건 「11.1」 · 절 「04절」)로 그 일이 나온 뼈대의 항목에 잇는다 — 요약 종이 목록에 「QA 자료 5쪽 ③에서 나옴 · 근거 11-1」 한 줄이 선다. 렌더러는 짐작하지 않는다: 근거가 건 · 절에 닿지 않으면 줄을 비우고 ⚠ 로 센다.
172
+ - `frame` 이 없는 원고(이미 나간 문서)는 옛 판 그대로 선다 — 바이트가 바뀌지 않는다. 결정 모드의 뼈대는 `decision_brief.frame` 이다(`decision-format.md` 1절, 최상위 `frame` 은 결정 모드에서 거절).
157
173
 
158
174
  ### 3.3 요약면·머리띠
159
175
 
160
176
  | 칸 | 뜻 | 없으면 |
161
177
  |---|---|---|
162
178
  | `summary_position` | `"front"` 를 선택하면 `summary[]` 요지를 문서 앞 요약면에 싣는다. 앞 요약만 필요하면 `kind:"summary"` 절을 따로 두지 않는다 — 둘 다 두면 같은 요지가 두 번 실린다 | 기존 현황·수치 요약면과 `kind:"summary"` 절 배치 유지 |
163
- | `notice` | 현황 줄 **객체** `{state,text}` | 현황 줄이 안 선다 |
179
+ | `notice` | 현황 줄 **객체** `{state,text}` — 관보 v4 요약면에서 `text` 가 **결론**(맨 위 큰 글)으로 선다 | 요약면 결론이 빠진다 |
164
180
  | `bar` | 상태 막대 `[{value,label,tone}]`. 건을 세는 막대면 대기(`wait`) 합은 미결 건 수나 판단 항목 수, 완료 합은 나머지 건 수나 전체 건 수와 같아야 한다 — 어긋나면 렌더러 ⚠(§10). **건이 아닌 다른 것을 세는 막대는 `bar_note` 에 셈 기준을 밝힌다**(그러면 대조하지 않는다) | 막대가 안 선다 |
165
181
  | `bar_alt` | 막대의 대체 텍스트(`role="img"` 의 이름) | 「전체 분포」로 선다 |
166
182
  | `bar_note` | 막대 아래 각주 한 줄 — 막대가 **무엇을 세는지** 밝히는 자리(§10 막대 대조의 탈출구) | 각주가 빠지고, 셈이 다른 막대면 §10 ⚠ 가 뜬다 |
167
- | `stats` | 수치 칸 `[{value,unit,label,accent,href,go}]`. **수치 칸은 서로 겹치지 않는 집합으로** — 한 칸이 다른 칸의 부분이면 하나를 빼거나 라벨에 관계를 드러내고(「그중 …」) `go` 가 교차표를 가리킨다. 집행자: 독자 검토 「결정권자」 관점 · 사람 눈(기계는 수치 칸을 대조하지 않는다) | 수치 칸이 안 선다 |
183
+ | `stats` | 수치 칸 `[{value,unit,label,accent,href,go}]`. **수치 칸은 서로 겹치지 않는 집합으로** — 한 칸이 다른 칸의 부분이면 하나를 빼거나 라벨에 관계를 드러내고(「그중 …」) `go` 가 교차표를 가리킨다. 집행자: 사람 눈(기계는 수치 칸을 대조하지 않는다) | 수치 칸이 안 선다 |
184
+ | `sections[].tables[].role` | 표의 역할 — `remaining`(남은 일) · `unchecked`(확인하지 않은 범위). 관보 v4 요약면이 남은 일 표를 「무엇 · 누가 · 그다음」 열로 옮겨 싣고, 확인하지 않은 범위는 개수와 절만 짚는다. 칸이 없으면 캡션이 **정확히** 「남은 일」 · 「확인하지 않은 범위」 · 「확인하지 못한 범위」인 표로 받는다(옛 원고) | 요약면에 남은 일 · 확인하지 않은 범위 줄이 빠진다 |
185
+ | (요약면 짜임 — 관보 v4) | 결론(`notice.text`) → (`frame` 이 있으면) 뼈대 표 「{name}와 한 일」 → 하실 일(`open_items` 제목 목록, `frame` 이 있으면 줄마다 출처) → 남은 일(역할 remaining 표) → 확인하지 않은 범위 한 줄 → 규모 한 줄(`stats` 가운데 하실 일 · 남은 일 절을 `href` 로 가리키는 칸과 결론 글에 같은 수 · 단위가 있는 칸은 뺌). 상태 막대(`bar`) · 막대 각주 · 숫자 칸은 그리지 않는다 — 옛 요약면은 같은 사실을 네 번 되풀이했다(2026-10-13 대표 「이 방식으로 계속」) | — |
168
186
  | `remain` | 머리띠 우측 판독부 수치(요청 잔여). 적으면 그 값이 이기므로 판단 항목 수와 달라지면 렌더러 ⚠(§10) — 비워 두는 것이 기본 | `open_items` 개수로 자동. 그것도 0이면 판독부가 빠진다 |
169
187
 
170
188
  ### 3.4 꼬리·인쇄·문서 설정
@@ -172,9 +190,9 @@ python3 assets/render.py <report.json>
172
190
  | 칸 | 뜻 | 없으면 |
173
191
  |---|---|---|
174
192
  | `appendix` | 부록 `[{no,title,rows[],note}]` | 부록면이 안 선다 |
175
- | `colophon` | 판권지 **객체** `{title,sub,rows[],mark,badge,note,tail}` | 다른 칸에서 세운다(2절 표) |
193
+ | `colophon` | 판권지 **객체** `{title,sub,rows[],mark,badge,note,tail}`. 회사 이름 · 약호를 지어 넣지 않는다 — 「발행」 행은 `issuer` 첫 칸과 같은 이름이다 | 다른 칸에서 세운다(2절 표) |
176
194
  | `footer` | 판권지 `note` 폴백(문자열 목록) | — |
177
- | `running_footer` | 인쇄 러닝 푸터의 뒷조각(`title · running_footer`) | `client` 로 대신한다 |
195
+ | `running_footer` | 인쇄 러닝 푸터의 뒷조각(`title · running_footer` — 꼬리말 왼쪽, 오른쪽은 「쪽 / 전체」). 쪽 머리말은 원고 칸이 아니라 렌더러가 세운다 — 절 번호 · 절 이름(`name`) · 그 절의 수, 요약 쪽은 `cover_date` 기준일(관보 v4, 2026-10-13). 번호가 없는 쪽(요약 · 부록 · 발행 이력)은 칸 없이 이름만 선다 — 회사 이름을 찍지 않는다(2026-10-15) | `client` 로 대신한다 |
178
196
  | `wide` | 문서 폭 CSS 값(`--wide`) | 시트 기본값 |
179
197
  | `marg_width` | 여백 주석 단 폭 CSS 값(`--marg`) | 시트 기본값 |
180
198
  | `labels` | 기본 라벨 덮어쓰기 `{키: 글자}` | 렌더러 기본 라벨 |
@@ -205,6 +223,7 @@ python3 assets/render.py <report.json>
205
223
  | `stats[]` | `value` · `unit` · `label` · `accent` · `href` · `go` | 첫 칸만 `accent: true` |
206
224
  | `meta[]` | `label` · `value` | `[k, v]` 배열도 받는다 |
207
225
  | `open_items[]` | `title` · `priority`(`must` 면 「가장 시급」) · `body` · `refs[]` | `refs` 는 **첫 하나만** 「근거」 단추가 된다 |
226
+ | `open_items[]` 결정 단위 칸(관보 v4) | `kind` — `pick`(하나 고르기) · `review`(표 훑고 이의 있는 행). 이 칸이 서면 항이 **결정 단위**로 선다 — 결정 모드와 같은 칸 이름이다. `due`(기한 글자 · 머리 오른쪽) · `table`(이 절 `tables[]` 의 자리, 0부터 — 그 표가 단위 안으로 옮겨 서고 절 끝에는 다시 서지 않는다) · `options[]` `{name, is_current}`(pick — 쪽지의 고르는 칸, `is_current` 인 길은 표 열 머리에 「지금 · 회신이 없으면 이대로」) · `no_reply` `{kind, text}`(kind: `keep` 지금 그대로 · `hold` 시작하지 않고 다시 여쭘 · `part` 공통 부분만 짓고 다시 여쭘) · `reply`(회신 문장 하나, 하십시오체 · 또는 `{text, attach[]}`) · `body`(남은 풀이). 문서의 첫 단위는 칸마다 묻는 말과 회신 쪽지로 풀어 서고(풀이 사례), 단위가 둘 이상이면 그 뒤 「하실 일 읽는 차례」 · 둘째부터 첫머리 기호 한 줄 · 절 끝 회신 모음이 선다 | 칸이 없으면 예전 꼴(머리 + 본문)로 선다 |
208
227
  | `cases[]` | `group` · `title` · `grade` · `symptom` · `cause` · `fix` · `how_to_check` · `remaining` · `source_url` · `source_text` · **`uid`** · `quotes` · `tables` · `plates` | 번호(`anchor`)는 **렌더러가 매기고**, `uid` 는 **서버가 발급한다**. `quotes`·`tables`·`plates` 는 **그 건에 묶인 근거**(11-10절) — 절의 같은 칸과 모양이 같고 건 필드표 바로 아래 선다 |
209
228
  | `appendix[]` | `no` · `title` · `rows[{label,value}]` · `note` | `rows` 가 비면 그 항목이 통째로 빠진다 |
210
229
  | `colophon` | `title` · `sub` · `rows[]` · `mark` · `badge` · `note` · `tail` | 넷(`title`·`rows`·`mark`·`note`)이 다 비면 판권지가 안 선다 |
@@ -273,11 +292,11 @@ python3 assets/render.py <report.json>
273
292
  | `kind` | 본문 장치를 정한다. 다섯뿐(5절) | **발행 거절** |
274
293
  | `part` | 이 절이 속할 PART 의 `no` | 첫 묶음으로 떨어진다. 없는 번호를 가리키면 **거절** |
275
294
  | `name` | 절 제목 | 제목이 빈다 |
276
- | `label` | 절 머리의 번호 글자 | 「제N절」 |
295
+ | `label` | 절 머리의 번호 글자 · 쪽 머리말 칸 글자(숫자 · 로마 숫자 칸이라 짧게 — 「01」) | 「제N절」 — 머리말 칸에는 절 번호만(「7」 — 세 글자는 칸에서 두 줄로 꺾이고 인쇄 칸 밖으로 샌다) |
277
296
  | `short` | 색인 레일에 쓰는 짧은 이름 | `name` 을 쓴다 |
278
297
  | `sub` | 차례에 붙는 한 줄 부제 | 차례에 부제가 없다 |
279
298
  | `lede` | 절 머리의 도입 한두 문장 | 도입 스트립이 빠진다 |
280
- | `marg` | 여백 주석 단 `{why,key,advice}` | **경고** — 두 단 본문이 한 단으로 선다 |
299
+ | `marg` | 절 첫머리 `{why,key,advice}` — why 물음 · key 답 · advice 더 볼 곳 | **경고** — 절이 물음 없이 선다 |
281
300
  | `tone` | 장 색. 여섯(6절) | `kind` 가 정한다 |
282
301
  | `group` | `kind:"cases"` 가 실을 그룹의 `key` | 그 절이 빈다. 없는 key 면 **거절** |
283
302
  | `count` | 절 머리·차례의 개수 배지 | `cases`·`asks` 는 자동으로 센다. 그 밖은 배지 없음 |
@@ -330,7 +349,7 @@ python3 assets/render.py <report.json>
330
349
  |---|---|---|
331
350
  | `asks` | 머리 강조문 + 요청 항목 목록(위 2px 괘선이 가른다) | `cta[]` · `open_items[]` |
332
351
  | `cases` | 건 필드표(증상·원인·조치·확인 방법·미결·원본) | 그 절의 `group` 에 속한 `cases[]` |
333
- | `status` | 대조표(4괘선 + 확인 강도 표식) | **전체** `cases[]` · 절의 `board_title`·`board_hint`·`note` |
352
+ | `status` | 대조표(4괘선 + 확인 강도 표식 — 칸은 칸 규칙 표가 고른다, 3.2b). **`frame` 이 있으면 지도 표 · `note` 는 요약 종이의 뼈대 표로 옮긴다** — 절에 다른 것이 없으면 절째 걷힌다(3.2b, ⚠ 한 줄) | **전체** `cases[]` · 절의 `board_title`·`board_hint`·`note` |
334
353
  | `summary` | 요지 블록(리드 + 본문 + 해당 절) | `summary[]` |
335
354
  | `note` | 기본은 강조 박스(미확인 사항 등), `presentation:"prose"` 를 선택하면 산문 문단 | 절의 `paragraphs[]` · 기본 박스의 `limit_label` · 산문의 `paragraph_kinds[]` |
336
355
 
@@ -431,10 +450,13 @@ python3 assets/render.py <report.json>
431
450
 
432
451
  | ⚠ | 무엇이 안 실렸는가 |
433
452
  |---|---|
434
- | 여백 주석이 없습니다 | 그 절의 `aside.marg` — 두 단 본문이 한 단으로 선다 |
453
+ | 첫머리 물음 · 답이 없습니다 | 그 절의 `div.ch-qa` — 절이 물음 없이 선다 |
435
454
  | PART 묶음이 없어 한 묶음으로 세웠습니다 | 읽기 순서 |
436
455
  | 절에 실을 내용이 없습니다 | `kind` 가 가리키는 데이터가 비었다 |
437
456
  | 그룹에 배정되지 않은 건 N개 | `cases[].group` 이 어긋났다(그룹이 아예 없을 때) |
457
+ | 뼈대(frame)가 있어 한눈에 절(…)의 표는 첫 종이의 뼈대 표가 대신하고, 절에 다른 것이 없어 걷었습니다 | `frame` 과 `kind:"status"` 절이 함께 왔다 — 그 절을 뺀다. 뒤 절 번호는 원고 차례 그대로라 한 칸 빈다(3.2b) |
458
+ | 뼈대(frame)가 있어 한눈에 절(…)의 표는 첫 종이의 뼈대 표가 대신하고, 절에는 나머지(표 N · 그림 N …)만 남겼습니다 | 그 절의 표 · 그림 같은 것을 알맞은 절로 옮기고 `status` 절을 뺀다(3.2b) |
459
+ | 하실 일 N 「…」의 근거(refs)가 건 · 절에 닿지 않아 … 어느 항목에서 나왔는지 잇지 못했습니다 | `frame` 이 있는데 그 `open_items[]` 의 `refs` 가 없거나 없는 건 · 절을 가리킨다 — 그 일이 나온 건(「11.1」)을 적는다 |
438
460
  | 그림 N장은 놓을 자리가 없어 | `logo`·`figure` 밖의 `role`(`hero`·`chapter`·`eof`) |
439
461
  | 도판 N장이 어느 절에도 걸리지 않아 | `sections[].plates` 나 `cases[].plates` 에 그 id 를 안 적었다 — 11-1절·11-10절 |
440
462
  | 열린 검토 회신 #N(이름 · 날짜) 「회신 본문」 — 집은 문장 「…」이 이 원문에 없습니다 — 원문이 바뀜 / 문장을 잃어 상위로 / 자리를 잃음 | `update_report` 만. **아직 반영 표시가 안 된** 회신이 집은 문장이 새 원문에 없다(3.5절 uid 항) — 이 판이 그 회신을 반영한 것이면 발행 뒤 `resolve_note(id, reply, rev)`, 아니면 회신 본문부터 읽는다(SKILL 9b). 핀을 살리려고 문장을 되돌리지 않는다 |
@@ -501,6 +523,7 @@ python3 assets/render.py <report.json>
501
523
  | 절 N 「이름」이 글로만 서 있습니다(M자) — 장치 목록의 절 장치 중 하나를 세우십시오 | 산문 400자 이상인데 장치 목록(`private/builder/devices.py`)의 절 장치 0. 건 절(`kind:"cases"`)은 건 다섯 칸의 글과 건에 묶인 표·인용·도판까지 함께 잰다(2026-10-01 — 전에는 건 절이 셈 밖이라 그림 0 인 공개판이 ⚠0 이었다) | 그 절의 요지를 표·흐름도·차트·원문 인용·도해·도판 가운데 하나로 세운다 — 고르는 법은 내용 모양(`visual-first.md` §4 장치 표) |
502
524
  | %s 인용 %d 에 출처 줄이 없습니다 — 원본 위치 한 구절(주소·쪽·행)을 적습니다 | `quotes[]` 에 `source_text`·`source_url` 둘 다 없다(`%s` 는 「절 N」 또는 「건 NN-n」) | 원문의 위치 한 구절(주소·쪽·행)을 적는다(§11-8) |
503
525
  | %s 도해 「%s」의 글자가 표시 %dpx 로 섭니다 — %dpx 이상이 되게 wide 로 두거나 노드를 줄입니다 | 굽은 도해의 가장 작은 font-size × (표시 폭 ÷ viewBox 폭) < 15px(readability R1 과 같은 잣대 — 고정 판이 15px 로 굽으므로 대개 서지 않는다) | `wide: true` 로 전폭에 세우거나 노드·라벨을 줄인다(§11-9) |
526
+ | 절 %s 차트 「%s」 — 구성 띠(form "share")의 %% 값 합이 %s 입니다 — 한 덩이의 조각이 아니라 겹치는 비율이면 막대(form "length")로 그립니다 | `form:"share"` · `unit:"%"` 인데 조각 값의 합이 100 에서 1.5 넘게 벗어난다 — 구성 띠는 한 덩이를 100 으로 나눠 그리므로 겹치는 비율(「1위가 맞음 39.9% · 셋 안 56.0%」)을 넣으면 모양이 거짓이 된다 | 겹치지 않는 조각으로 다시 나누거나(「후보 2~3위 16.1%」처럼 차를 셈) 막대로 그린다 |
504
527
  | 절 %s 시계열 「%s」의 표식 「%s」가 점에 없습니다 — marks[].x 는 points[].x 와 같은 값이어야 섭니다 | `charts[].marks[].x` 가 어느 `points[].x` 와도 같지 않다 | 점의 x 값 그대로 적는다(§11-7) |
505
528
  | 절 %s 시계열 「%s」의 표식 라벨 「%s」와 「%s」가 %.0fpx 겹칩니다 — 라벨을 줄이거나 하나를 빼고 세로선만 남깁니다 | 표식 라벨은 전부 같은 높이(`T+13`)에 서고 렌더러가 밀어내지 않는다 — 가까운 표식 둘의 글자가 포개진다. 폭은 전각 1.0 · 공백 0.28 · 그 밖 0.55 로 어림한다(`_lblw`) | 라벨을 줄이거나, 하나는 `label` 없이 두어 세로선만 남긴다(§11-7) |
506
529
  | 절 %s 도해 「%s」의 svg 칸(미리 구운 SVG)은 싣지 않습니다 — %s | `diagrams[].svg` — 작성자가 굳혀 넣던 SVG 칸은 2026-10-07(설계 문서 10 의 4번)부터 싣지 않는다. 원본(설계 데이터)이 문서 밖에 남아 다시 굽거나 고칠 수 없었다. 같은 칸에 `ir` · `compare` 가 있으면 그것을 굽고, svg 칸만 있으면 그림 번호도 안 잡는다 | 구조 · 흐름 · 순서 · 상태 그림은 설계 데이터(`ir`)로 넣는다 — 서버가 굽는다. 수치 · 띠 그림은 차트(§11-4 · §11-7)나 도판(§11-1)으로 |
@@ -518,7 +541,7 @@ python3 assets/render.py <report.json>
518
541
  | 핵심 굵게 표기가 한 곳도 없습니다 | 산문 3,000자 이상, `**…**` 도 편집기 굵게 구간도 0 | 절마다 핵심 한 구절을 `**…**` 로 굵게(§11-6). 문단 절반이 굵으면 굵기가 위계를 못 나른다. |
519
542
  | 과정 어휘가 %d곳에 있습니다(%s 「%s」 …) — 독자는 앞 회차·회신·판을 모릅니다. 정해진 것은 사실로 배경에, 결정 요청에는 열린 것만 | 원고의 글자 자리 어디든(`history`·`labels`·`forbid`·`origin`·`file`·`source_url`·`href`·`data`·`out`·`css`·`render` 제외)에 정규식 `정해짐 \| 회신 대기 \| 남은 물음 \| 정해진 것 \| 이미 정해진 \| 남은 것 (하나·둘·셋·넷) \| (N·첫·두·세)판 \| 정한 사항 \| 결정(한·된) 사항 \| (미 앞이 아닌) 결정임` 이 1곳 이상. 앞 `%s` 는 자리 경로를 5곳까지(「경로 「낱말」 · …」, 2026-09-26), 뒤 `%s` 는 마지막 자리의 걸린 낱말 — 한 곳이면 경로 하나와 낱말 하나. 주체 없는 결정 명사(「정한 사항」)는 누가·어디서 정했는지 없이 결정 경로를 사실처럼 싣는다 — 「미결정임」·표지 칸 이름 「결정 사항」·「나머지 사항」은 안 건다 | 회차 낱말(「이번 회차」)만이 아니라 **진행 상태 어휘와 구조**가 금지다 — 상태 열(「상태: 정해짐/회신 대기」)·「~ 그대로(변화 없음)」도 같다. 정해진 것은 **사실**로 요지(배경)에, 결정 요청 절에는 **지금 열린 것만**. 회차의 자리는 `history` 하나. 원고는 직전 판의 차분이 아니라 **독자의 0 상태에서 다시 쓴다** — 판마다 「처음 읽는 사람이 이 절에서 무엇을 알아야 하나」를 다시 묻는다(SKILL 3b · readability R11h) |
520
543
  | 절 %s 표 「%s」 제목이 개수로 진행 상태를 세고 있습니다 — 제목은 내용을 말해야 합니다 | `tables[].caption` 이 「…(하나·둘·셋·넷)과 … (하나·둘·셋·넷)」으로 끝난다 | 표 제목은 내용을 말한다 — 「정해진 것 셋과 남은 것 하나」처럼 상태를 세지 않는다(SKILL 3b) |
521
- | 권고 낱말이 %d곳에 있습니다(%s) — 결정권이 고객에게 있는 문서는 판단 항목을 물음으로 세우고, FCG 의견은 한 절에만 둡니다 | 정규식 `권고(?![량치]) \| 기각 \| 하지 않기로`(권고량·권고치 같은 값 이름은 빼고) 가 다음 자리에 1곳 이상 — `sections[].name·short·sub·lede·marg(why/key/advice)` · `sections[].tables[].caption·cols` · `summary[].label·lead` · `open_items[].title` · `notice.text` · `meta[][1]` · `parts[].title·lede` · `stats[].label`. 이름에 「의견」이 든 절(FCG 의견 절)과 `cases[]`·`appendix`·`history`·`labels`·`colophon`·`origin` 은 제외. `%s` 는 자리 이름 최대 3개 | 판단 항목은 **물음**으로, 결과는 두 길 대칭 한눈표 한 곳에, FCG 의견은 이름에 「의견」이 든 절 **하나**에만. 결정 모드는 `opinion` 칸만 면제다 |
544
+ | 권고 낱말이 %d곳에 있습니다(%s) — 결정권이 고객에게 있는 문서는 판단 항목을 물음으로 세우고, 의견은 한 절에만 둡니다 | 정규식 `권고(?![량치]) \| 기각 \| 하지 않기로`(권고량·권고치 같은 값 이름은 빼고) 가 다음 자리에 1곳 이상 — `sections[].name·short·sub·lede·marg(why/key/advice)` · `sections[].tables[].caption·cols` · `summary[].label·lead` · `open_items[].title` · `notice.text` · `meta[][1]` · `parts[].title·lede` · `stats[].label`. 이름에 「의견」이 든 절(보내는 쪽 의견 절)과 `cases[]`·`appendix`·`history`·`labels`·`colophon`·`origin` 은 제외. `%s` 는 자리 이름 최대 3개 | 판단 항목은 **물음**으로, 결과는 두 길 대칭 한눈표 한 곳에, 보내는 쪽 의견은 이름에 「의견」이 든 절 **하나**에만. 결정 모드는 `opinion` 칸만 면제다 |
522
545
  | 도판 「%s」 출처 줄에 원본 위치가 없습니다 — 쪽·행·주소·건 § 가운데 하나를, 화면 캡처면 화면 이름 · 날짜를 적습니다 | `assets[]` 가운데 `role:"figure"` · `provider:"user-provided"`(고객·제3자 자료에서 낸 도판. 그린 도판 `deterministic`·서버가 그린 삽화 `higgsfield` 는 세지 않음. 파일로 싣는 합성은 `user-provided` 라 센다 — 출처 줄에 건 § 나 부록 N 한 구절(결정 절처럼 건보다 앞에 서는 도판은 부록 N — 뒤 절 § 는 아래 「앞 절이 뒤 절을 가리키는 곳」에 걸린다))이고 보이는 출처 줄 `source_text` 에(`source_url` 은 도판에 그려지지 않아 보지 않는다) 정규식 `\d+\s*쪽 \| \d+\s*행 \| https?:// \| 건 § \| §\s*\d \| 부록\s*\d` 이 하나도 없다. **화면 캡처의 위치** — 출처 줄에 화면·창·페이지 이름과 날짜(「10. 1.」·「2026-10-01」·「10월 1일」)가 함께 서면 원본 위치로 친다(2026-10-01 사용자 결정 ②). `%s` 는 `id` | 출처 줄은 원본 위치 한 구절(readability R12e). 캡처는 「주문 목록 화면 · 8. 23.」 — 경고를 맞추려고 뜻 없는 「부록 N」을 붙이지 않는다. 흐리다·못 연다고 쓰기 전에 원본을 잰다 |
523
546
  | 도판 「%s」 출처 줄에 제작 설명이나 그림 번호가 있습니다(「%s」) — 위치 한 구절만, 제작 기록은 origin 으로 | `role:"figure"` 전부(provider 무관)의 `source_text` 를 주소를 지운 뒤 정규식 `(합성·재현)(이며·임·함·한 것·했) \| 예시(이며·임·라) \| (실제·실기기) 화면이 아님 \| 도안이 아님 \| 자리 표시 \| 규격(과 문구)?의 출처 \| 찍(음·은 것) \| 배율 \| N배 밀도 \| 크롭 \| 잘라 \| 자름 \| 그림 N-N` 으로 센다. **캡션은 보지 않는다** — 캡션의 한 낱말 「— 합성」·「재현」·「갈무리」는 정직성 이름표다. 출처 줄에서도 맨 낱말 「합성」·「재현」은 안 걸고 서술형만 건다. 「골밀도」 같은 값 이름은 「N배 밀도」가 아니라 안 걸린다 | 출처 줄에는 위치 한 구절만. 만든 방식·결정 경로는 `origin`(렌더 안 됨)과 도판 HTML 머리 주석에. 바깥 원본이 없는 우리 도안·흐름은 출처 줄을 비운다(readability R12e) |
524
547
  | 표 「%s」 주석이 %d문장입니다 — ※ 주석은 %d문장 안 | `tables[].note` 문장 3 이상(둘째 `%d` 는 상한 2). 문장은 렌더러가 문장 블록을 세우는 판별(`boundary.py` — 날짜 마침표 「2026. 9. 30.」·「9. 8.」은 경계가 아님)로 센다. | 두 문장 안으로, 나머지는 본문·건으로(readability R12a) |
@@ -530,7 +553,9 @@ python3 assets/render.py <report.json>
530
553
  | 해라체 명령이 %d곳 있습니다(%s 「%s」 …) — 독자가 할 일은 요청 자리에만 하십시오체로, 그 밖은 우리·사물·화면이 주어인 개조식입니다. 확인 방법은 결과를 볼 자리와 우리가 본 때·환경(「그 주문이 목록 첫 줄에 나타남({{그림:id}}), 8. 23. 운영 관리자 웹에서 봄」), 캡션·Advice 는 볼 자리의 이름으로 | 글자 자리 전부(「길」과 같은 자리)에서 정규식 `RX_CMD`(gazette.py) — 낱말 끝 「보라·하라·열라·누르라·찾으라·읽으라·두라·말라·가라·보시오·하시오」 뒤에 마침표·공백·닫는 따옴표가 오거나 글이 끝나면 센다. 「보라색」(한글이 이어짐)·「정할 것」(명사구)은 안 센다. `%s` 둘은 과정 어휘 행과 같은 꼴(자리 5곳까지 · 마지막 낱말) | 확인 방법은 독자가 그 결과를 볼 자리(이 문서의 그림·영상·원문, 또는 독자 자기 화면의 어디) + 우리가 그것을 본 때·환경 — 우리가 안 본 결과는 남은 것 칸에만(2026-10-01 사용자 결정. 9/26 의 「화면이 주어인 결과」를 고쳐 씀). 캡션·Advice 는 볼 자리의 이름(「03절 대조표」), 독자에게 부탁할 것은 요청 자리에서 하십시오체(5·5a). 경위: 캡션 규칙 「무엇을 보라는 것인지」가 캡션이 됐다(2026-09-17) |
531
554
  | 대화 이력 낱말이 %d곳에 있습니다(%s) — 독자는 이 문서를 만든 대화를 모릅니다. 합의·요청된 내용을 사실로 적습니다 | 과정 어휘와 같은 글자 자리(`tenant` 도 뺌)에서 정규식 `RX_TALK`(gazette.py) — 지난 대화를 가리키는 앞말 + (띄어쓰기) + 대화에서 끝난 일. 앞말 「앞서·지난번(에)·이전에·이미」 뒤에 「합의·협의」의 끝난 꼴(`_TALK_DONE` — 한·했·된·하신·하였·되었·해 주신·드린·함·됨)이나 「말씀드린·요청하신·안내드린」이 오면 센다. 「논의」의 끝난 꼴은 「지난번(에)·이전에·이미」 뒤에서만 센다 — 「앞서 논의한 바와 같이」는 문서가 제 앞 절을 되짚는 말이다. 앞말 없이 「요청하신 대로」·「말씀하신 대로」도 센다. 안 세는 것: 「앞에서」(문서 안 자리 — 「앞에서 논의한 대로」·「앞에서 말씀드린」), 절차를 말하는 「○○ 전에」·「사전에」·「○○에 앞서」(「적용 전에 협의함」·「적용에 앞서 합의한」), 끝나지 않은 꼴(「협의하여」·「협의 후」·「협의가 필요」·「이미 협의 중」), 앞말 없는 「합의한 일정」. 칸마다 한 번 세고 `%s` 는 「경로 「낱말」」 5곳까지(넘으면 「그 밖 N곳」) | 합의·요청된 내용을 **사실**로 적는다 — 누가 언제 말했는지가 아니라 무엇이 정해졌는지(SKILL 3b) |
532
555
  | 책임 낱말 「탓」이 %d곳에 있습니다(%s) — 원인은 대상의 원래 이름과, 그것이 어떻게 동작했는지로 적습니다 | 같은 자리에서 정규식 `RX_BLAME`(gazette.py) — 앞에 한글이 붙지 않은 「탓」 가운데, 뒤가 한글이 아니거나(글 끝·띄어쓰기·문장부호) 조사·서술격 조사로 **시작**하는 것을 센다. 조사 목록은 반려 이름과 같은 낱말 경계 `_JOSA_HEAD` — 「으로·까지·부터·보다·처럼·마다·조차·마저·한테·밖에」와 한 글자 「은·는·이·가·을·를·의·에·께·로·와·과·도·만·나·라·란·랑·인·일·임·입·였·뿐·들」. 첫머리만 보므로 뒤에 무엇이 이어지든(「탓이었습니다」·「탓으로만」) 세고, 자리에는 뒤에 붙은 한글까지 짚는다. 「남탓」(앞에 한글)·「탓하기」·「탓할」(조사 아닌 한글)은 다른 낱말이라 안 센다 | 원인은 대상의 원래 이름과 그것이 어떻게 동작했는지로. 참조 번호 경고를 피하려고 판 번호를 「새 버전 탓」으로 바꿔 적지 않는다 — 판 번호는 이제 참조 번호로 세지 않는다(2026-09-22 반려) |
533
- | 소속처가 반려한 이름이 %d곳에 있습니다(%s) — 작업하며 지은 이름은 문서 안에서 정의해도 독자가 모릅니다. 독자 화면의 원래 이름으로(%s) | 그 소속처의 반려 이름 목록(소속처 결정 장의 `rejected_names` 칸 — 이름마다 가장 새 결정이 이기고 뒤집힌 결정은 뺀다)이 렌더러에 왔을 때, 보이는 글자 전부(`history`·`labels` 포함 — `uid`·`id`·`plates`·`refs`·`tenant` 와 `origin`·`file` 등은 뺌)에서 이름마다 센다. 목록은 포털 발행·모의 발행이면 서버가(배포 뒤), 로컬 `render.py` 와 발행 직전 훅이면 MCP `list_rejected_names` 로 받아 얹는다 — 목록이 안 오면 이 행은 0 이 아니라 미확인이다(표 아래 「목록을 얻는 길」). 낱말 사이 띄어쓰기는 있든 없든 같은 이름이고, 앞에 한글이 붙거나 뒤에 조사 아닌 한글이 붙으면 다른 낱말이다(「예비판정」). 이름에 `near`(함께 설 낱말)가 있으면 그 낱말이 같은 문장 12자 안에 설 때만 센다. 첫 `%s` 는 원고에 적힌 글자로 자리 5곳까지, 둘째 `%s` 는 「이름 → 목록의 use」 | 0단계 이름 대응표의 독자 화면·문서 이름으로 바꾼다(SKILL 반드시 지키는 것 12). 목록은 그날 반려된 이름만 모은다 — 반려를 `remember_decision` 으로 적을 때 그 결정의 `rejected_names` 칸에 적는다(SKILL 9a단계 7행). 목록 밖의 새 이름은 독자 검토 이름 물음(`names`)과 사람 눈 |
556
+ | 고유어 수가 %d곳에 있습니다(%s) — 수는 아라비아 숫자로 씁니다(5건 · 2번째 · 기기 2대 · 12개월). 굳은 말(한눈에 · 한 번에 · 둘 다 · 가운데 하나)과 「」 안의 화면 문구는 그대로 둡니다 | 반려 이름과 같은 자리(발행 이력 · 라벨까지 독자에게 보이는 글자 전부)에서 정규식 `RX_NATIVE_NUM`(gazette.py)으로 낱말마다 센다 — 고유어 수(하나~열다섯 · 스무)에 단위(건 · 개 · 가지 · 곳 · 칸 · 줄 · 쪽 · 장 · 번 · 번째 · 명 · 종 · 단계 · 자리 · 묶음 · 문단 · 글자 · 주 · 갈래 · 군데 · 판)나 이름씨(기기 · 채널 · 값 · 점 · 수 · 화면 · 표 · 기록 · 선택지 · 방식 · 규칙 · 팀 · 날 · 달 …)가 붙은 것, 서수(첫째 ~ 다섯째), 홀로 쓴 수(하나 · 둘 · 셋 · 넷 · 다섯 · 여섯 — 뒤가 한글이 아니거나 조사 · 「씩」으로 시작). 안 세는 것: 굳은 말(`_NUM_IDIOM` — 한눈에 · 한꺼번에 · 한 번에 · 한 화면에서 · 둘 다 · 두 쪽 다 · 가운데 하나 · 중 하나 · 한쪽 · 한편 · 한때 · 하나도), 동사 「두다」의 「둘 것 · 둘 수 · 둘 때 · 둘지」, 「」·『』 안의 글(앱 화면 문구를 그대로 옮긴 자리), 숫자 뒤 「세」(26세). `%s` 는 「경로 「낱말 → 고칠 꼴」」 5곳까지(넘으면 「그 밖 N곳」) | 수는 아라비아 숫자로 — 수 + 단위는 붙여(「다섯 건」 → 「5건」 · 「두 번째」 → 「2번째」), 이름씨는 「N개 이름씨」(「두 값」 → 「2개 값」)이고 기기는 「기기 N대」, 날 · 달은 「N일」 · 「N개월」, 서수는 「N번째」, 홀로 쓴 수는 「N개」에 받침 없는 꼴의 조사(「셋을」 → 「3개를」). 이름을 키로 쓰는 칸(`grades`)은 **키와 그 이름을 쓰는 값을 함께** 바꾼다 — 값만 바꾸면 렌더러가 모르는 등급으로 보고 「미확인」 표지를 단다(2026-10-13 실측) |
557
+ | 발행처 이름 「%s」%s 3인칭으로 쓴 곳이 %d곳 있습니다(%s) — 이 문서는 발행처가 직접 말합니다. 서술은 「당사」, 요청 자리는 「저희」로 고칩니다(「」 안 원문 · 화면 글자와 라틴 제품 이름은 그대로). 포털은 이 원고를 받지 않습니다 | 발행처 이름(`issuer` 첫 칸 — 비면 보내는 쪽 이름 라벨 `labels.dc_who_sender`. 회사 꼴 「주식회사 · (주) · ㈜」을 걷고, 2자 미만이거나 1인칭 낱말 「당사 · 저희 · 우리 · 본사 · 폐사」이면 셀 이름이 없다)이 서술 칸에 선 자리마다 센다(`gazette.py voice_hits` — 서버 `report_publish.php report_voice_hits` 와 한 표 `tests/fixtures/issuer-voice.json`). 정체 칸(`issuer` · `kicker` · `doc_no` · `running_footer` · `client` · `title` · `title_sub` · `title_tag` · `cover_date`)과 보내는 쪽 이름 라벨은 안 세고, 표 모양 · 연락처 정체 칸(표지 `meta` 줄 · 판권지 `rows` · 결정 회신 받는 곳 `decision_brief.reply_to`)은 「보낸 {이름}」 꼴(「이 문서를 보낸 우리회사 담당자」)만 센다. 「」 · 『』 안, 원문 인용의 남의 말(`quotes` 의 `text` · `translation`), 라틴 이름 뒤에 띄어 쓴 라틴 대문자 낱말이 이어진 제품 이름(「Acme POS Daemon」), 식별자(「Acme-2026-0901」 · 「a/Acme/b」), 주소는 안 센다. 발행 이력 · 라벨 · 출처 줄 · alt 는 센다. `%s` 는 「경로 「짚은 글자」」 5곳까지(넘으면 「그 밖 N곳」). **포털은 새로 내기 · 고치기 · 편집기 발행에서 같은 자리를 거절한다**(dry_run 도 422 — 거절 글은 40곳까지 짚는다). 재굽기 · 결정 공개 · 서버가 짓는 문서는 이 경고로만 센다 — 이미 나간 문서는 다음에 고칠 때 걸린다(대표 2026-10-18 「발행처 3인칭 전부 금지」) | 발행처가 직접 말하게 고친다 — 서술은 「당사」(「우리회사가 확인함」 → 「당사가 확인함」 · 「우리회사 사무실」 → 「당사 사무실」), 요청 자리(요청 절 · `cta` · 판권지 회신 안내 · 물음 · 요청 PART 간지 도입문)는 「저희」(「이 문서를 보낸 우리회사 담당자에게」 → 「저희 검색 개선 담당자에게」). 「(우리회사 확인)」 같은 꼬리표는 떼고 그 사실의 근거를 1인칭으로 적는다(「당사 사무실의 시험용 POS 에서 확인함」). 연락처가 필요한 판권지 행은 「우리회사 검색 개선 담당」처럼 정체로 적는다. 한글 이름이 든 제품 · 화면 이름은 「」 안에 둔다 |
558
+ | 소속처가 반려한 이름이 %d곳에 있습니다(%s) — 작업하며 지은 이름은 문서 안에서 정의해도 독자가 모릅니다. 독자 화면의 원래 이름으로(%s) | 그 소속처의 반려 이름 목록(소속처 결정 장의 `rejected_names` 칸 — 이름마다 가장 새 결정이 이기고 뒤집힌 결정은 뺀다)이 렌더러에 왔을 때, 보이는 글자 전부(`history`·`labels` 포함 — `uid`·`id`·`plates`·`refs`·`tenant` 와 `origin`·`file` 등은 뺌)에서 이름마다 센다. 목록은 포털 발행·모의 발행이면 서버가(배포 뒤), 로컬 `render.py` 와 발행 직전 훅이면 MCP `list_rejected_names` 로 받아 얹는다 — 목록이 안 오면 이 행은 0 이 아니라 미확인이다(표 아래 「목록을 얻는 길」). 낱말 사이 띄어쓰기는 있든 없든 같은 이름이고, 앞에 한글이 붙거나 뒤에 조사 아닌 한글이 붙으면 다른 낱말이다(「예비판정」). 이름에 `near`(함께 설 낱말)가 있으면 그 낱말이 같은 문장 12자 안에 설 때만 센다. 첫 `%s` 는 원고에 적힌 글자로 자리 5곳까지, 둘째 `%s` 는 「이름 → 목록의 use」 | 0단계 이름 대응표의 독자 화면·문서 이름으로 바꾼다(SKILL 반드시 지키는 것 12). 목록은 그날 반려된 이름만 모은다 — 반려를 `remember_decision` 으로 적을 때 그 결정의 `rejected_names` 칸에 적는다(SKILL 9a단계 7행). 목록 밖의 새 이름은 사람 눈 |
534
559
  | 반려 이름 %d개를 대조 규칙으로 못 세웠습니다(%s) — 그 이름은 세지 않았습니다 | 렌더러에 온 목록의 항목이 대조 규칙을 못 세운다 — `pattern`(임의 정규식) 칸이 있거나 `near` 가 8낱말을 넘는다(`%s` 는 「이름: 까닭」). 쓰는 문(서버)이 같은 모양을 거절하고, 손으로 고친 결정 장도 서버가 읽을 때 같은 자로 다시 재어(`wiki_page_rejected_names`) 못 읽은 장으로 거른다(`report_rejected_names_pick` 의 `skipped` — 아래 「결정 장 N곳의 반려 이름 줄을 못 읽었습니다」 행). 그래서 서버가 준 목록(포털 발행·모의 발행, `list_rejected_names` 로 받는 `render.py`·발행 직전 훅)으로는 나지 않고, 렌더러를 포털·`render.py` 없이 직접 불러(`build.py`·`coined_scan()`) cfg 에 목록을 넣은 경우(시험 등)에만 난다 | 흔한 낱말이라 문맥으로 가를 이름은 `pattern` 대신 `near` 에 함께 설 낱말을 적는다 |
535
560
  | 결정 장 N곳의 반려 이름 줄을 못 읽었습니다(경로: 까닭 …) — 그 장의 이름은 세지 않았습니다 | **서버**(`report_publish.php report_rejected_names()`) — 그 소속처 결정 장의 앞머리 `rejected_names:` 줄이 JSON 목록이 아니거나 모양이 틀렸다(화면 원문 편집으로 깨진 경우). 발행·모의 발행 경고와 `list_rejected_names` 에 같이 선다 | 그 결정을 `get_case` 로 읽고 `remember_decision` 으로 같은 제목·`expected_revision` 에 다시 적는다 |
536
561
  | 소속처 반려 이름을 못 읽었습니다(까닭) — 이 렌더는 반려 이름을 세지 않았습니다 | **서버** — 결정 장 폴더를 못 읽었다(읽기 상한·입출력). 이 줄이 뜬 발행·모의 발행은 반려 이름을 세지 않은 것이다(`rejected_names_checked` 가 null). `list_rejected_names` 는 같은 까닭으로 실패한다 | 잠시 뒤 다시 모의 발행한다 — 되풀이되면 운영 확인 |
@@ -554,7 +579,7 @@ python3 assets/render.py <report.json>
554
579
  | %s 의 표 「%s」에 %s 가 없어 싣지 못했습니다%s | 표에 제목·행·열 머리 가운데 무엇이든 있는데 `cols` 나 `rows` 가 비어 그릴 수 없다. 열 머리를 `head`·`headers`·`columns`·`header` 로 적었으면 그 이름을 짚는다. **표가 빠지면 뒤 표 번호가 전부 당겨진다** | 열 머리의 이름은 `cols` 다 |
555
580
  | 절 %s 의 plates 배열 순서와 그림 번호가 다릅니다(전폭 「%s」 뒤에 본문 단 「%s」) — 차트·흐름도·본문 단 도판이 먼저 번호를 받습니다 | 한 절 `plates` 에서 `wide:true` 도판 뒤에 본문 단 도판이 적혔다 — 전폭은 그리드 밖이라 번호를 뒤에 받는다 | `plates` 를 본문 단 → 전폭 순서로 적는다 |
556
581
  | 작성일이 한 값이 아닙니다(%s) — 표지 「작성」 · 판권지 「작성」 · 발행 이력 마지막 date 는 공개하는 날 한 값으로(공개 직전 update_report 한 번) | 표지 `meta` 의 「작성」 행 · 판권지 `colophon.rows` 의 「작성」 행(`rows` 가 없으면 표지를 그대로 쓰므로 안 셈) · `history` 마지막 `date` — 셋에서 년·월·일을 0 채움으로 읽어(「2026.08.24」 = 「2026. 8. 24.」, 범위는 첫 날짜) 값이 둘 이상이다. 자리가 둘 미만이면 안 센다. `cover_date` 는 수치의 기준일이라 대조하지 않는다(§3.1) | 공개 직전에 한 번, 세 자리를 공개하는 날로 맞춘다 — SKILL 8단계 「수정 절차」로(받은 판에서 출발 · `body_rev` 를 실어 교체 — SKILL 3c · 체크리스트 10단계). 표기를 한 꼴로 맞추는 것은 사람 눈(§3.5) |
557
- | 화면을 말했는데 독자가 볼 증거가 없는 곳이 %d곳(%d건)입니다(%s) — 실제 화면·영상·원문을 그 건 plates 에 싣거나 {{그림:id}} 로 가리킵니다. 안 본 것이면 남은 것 칸으로 옮깁니다 | 건 다섯 칸과 절의 문단·흐름도 칸(`text`·`note`)을 문장으로 나눠(렌더러 문장 블록과 같은 자르기) **관찰 주장**을 센다 — 화면 낱말(목록·첫 줄·항목·페이지와 조사 붙은 줄·행 포함)이나 「」 인용 + 보이는 동사(뜸·보임·표시됨·나옴·켜짐·열림·띄움 …, 습니다체 「보입니다·뜹니다·표시됩니다」와 과거형 「나타났·보였·나왔·표시됐」 포함) · 조작(누르면·넣으면·저장하면·작성하면·보내면)이나 자리(단계·칸에) + 결과(진행됨·막힘·통과함·가입됨·저장됨 …, 습니다체 포함)나 보이는 동사 · 확인 방법 칸에서만 앱·웹·이용자 맥락의 결과. **표 칸(건·절 `tables`)은 세지 않는다** — 확인 프로필·조건표의 기대 결과, 위험 표의 계획, 기기별로 센 결과라 실물이 설 수 없다(2026-10-02 실측 — 지난 원고 14벌에서 표 칸까지 세면 작성자가 고칠 수 없는 지적이 42.5% 였고, 빼고 31.6%). 안 세는 문장: 「수 있·수 없」 가능성 · 「」 인용 없는 지시문·물음(「…는지 확인.」·「…는지 본다」 — 「…는지 확인함·했음·됨」·「…는지 봄」은 우리 기록이라 센다) · 끝이 확인 안 했음이고 관찰 동사가 그 목적어 안에 안긴 것(「…뜨는지는·…뜨는 것은·…뜨기까지의 시간은 + 확인하지 않았음」 — 같은 문장의 앞 절이 관찰 주장이면 센다: 구분 부호(「—」·「,」·「 - 」·「;」·「:」·「·」) 앞 끝맺은 절 「…보임 — 화면은 확인하지 않았음」, 이음 어미(「…지만·…으나·…는데·…고·…며·…면서」)로 끝난 관찰·결과·확인 기록 절 「…나타나지만 실기기는 보지 않았음」) · 낱말 오탐 셋(빌드·버전·번호·타깃·구성·배포본과 함께 선 「위젯 … 나옴」에 화면 낱말이 없을 때 · 누르기·넣기 같은 조작이나 화면·칸 같은 자리가 없는 「들어감」 · 번호 표식 목록 머리의 「띄우는」). 그 건(절)에 증거가 하나라도 있으면 안 센다 — `plates` 의 캡처·녹화·합성·문서 갈래 · `quotes` · 문장의 `{{그림:id}}` 가 가리킨 그런 도판(건이면 그 건 어느 칸이든) · 출처 줄·캡션이 `§N.M` 으로 그 건을 가리키는 절 도판 · 문장이 원문·출처를 말할 때의 건 `source_url`. 표(`tables`)는 증거로 치지 않는다 — 우리가 센 결과 표로만 받친 화면 주장은 §10 통과 기준 표의 행. 단 건 증거가 덮지 못하는 문장 둘 — 문장의 `{{그림:id}}` 가 전부 도안인 것(도해 `diagrams[]`·흐름도 `flow:N` 토큰도 도안 — 자기 그림으로만 잰다) · 「코드상·코드로 봄·코드 기준·도안 기준·설계상」처럼 화면 밖 근거를 스스로 밝힌 것. 도판 갈래(`gazette.py asset_evidence_kind()`): `role:"video"` 녹화 → 캡션 「실제 화면 아님」·「— 도안」·「— 재현」 도안 → AI 합성(`provider:"higgsfield"` · `origin` 의 Higgsfield·이미지 생성·참조 그림·도안 PNG) 도안 → 캡션 「— 합성」 합성 → `provider:"user-provided"` 캡처 → `origin`·출처 줄·캡션의 촬영·캡처·갈무리·녹화·스크린샷·실기기·시뮬레이터·에뮬레이터·「시험 기기 화면」·「… 제공)」 캡처 → 「찍어·찍은·찍음」은 `origin` 에 도안·그린·그리고·개념도·도해·재현·생성이 없을 때만 캡처 → 그 밖 도안. `assets[].evidence` 칸은 아직 읽지 않는다(도구 스키마와 함께 들인다) — 그래서 지금은 「문서」 갈래가 서지 않고, 원문은 `quotes`·건 `source_url` 로 싣는다. 헤지·층 낱말(「화면 미확인」·「(확인 전)」)과 「…것을 확인함」·「…것까지 확인함」은 지우지 않고, 확인 방법 끝의 「…, 8. 23. 운영 관리자 웹에서 봄」 꼬리도 증거로 받지 않는다(독자 자기 화면만 볼 자리로 둔 확인 방법은 §10 표의 행). `%s` 는 「건 NN-n 칸 이름 「문장 앞 24자」」 5곳까지(넘으면 「그 밖 N곳」), 건 수는 걸린 건·절의 수 | 화면을 말했으면 그 화면을 싣는다 — 캡처·녹화를 그 건 `plates` 에 두거나 문장에서 `{{그림:id}}` 로 가리키고, 찍은 환경·날짜는 캡션 꼬리에(「… · 운영 관리자 웹 · 8. 23. 촬영」, §11-1 — 그 꼬리의 「촬영」이 그린 판으로 구운 캡처도 캡처로 가른다). 도안은 설명이지 증거가 아니다. 우리가 안 본 것이면 확인 방법에서 빼 남은 것 칸에 「…는 확인하지 않았음」으로 옮긴다(2026-10-01 사용자 결정). 위 두 예외 밖에서는 건 단위로 재므로 실물 하나가 그 건의 다른 주장까지 덮는다 — 그 실물이 그 주장을 보이는지는 독자 검토·사람 눈 |
582
+ | 화면을 말했는데 독자가 볼 증거가 없는 곳이 %d곳(%d건)입니다(%s) — 실제 화면·영상·원문을 그 건 plates 에 싣거나 {{그림:id}} 로 가리킵니다. 안 본 것이면 남은 것 칸으로 옮깁니다 | 건 다섯 칸과 절의 문단·흐름도 칸(`text`·`note`)을 문장으로 나눠(렌더러 문장 블록과 같은 자르기) **관찰 주장**을 센다 — 화면 낱말(목록·첫 줄·항목·페이지와 조사 붙은 줄·행 포함)이나 「」 인용 + 보이는 동사(뜸·보임·표시됨·나옴·켜짐·열림·띄움 …, 습니다체 「보입니다·뜹니다·표시됩니다」와 과거형 「나타났·보였·나왔·표시됐」 포함) · 조작(누르면·넣으면·저장하면·작성하면·보내면)이나 자리(단계·칸에) + 결과(진행됨·막힘·통과함·가입됨·저장됨 …, 습니다체 포함)나 보이는 동사 · 확인 방법 칸에서만 앱·웹·이용자 맥락의 결과. **표 칸(건·절 `tables`)은 세지 않는다** — 확인 프로필·조건표의 기대 결과, 위험 표의 계획, 기기별로 센 결과라 실물이 설 수 없다(2026-10-02 실측 — 지난 원고 14벌에서 표 칸까지 세면 작성자가 고칠 수 없는 지적이 42.5% 였고, 빼고 31.6%). 안 세는 문장: 「수 있·수 없」 가능성 · 「」 인용 없는 지시문·물음(「…는지 확인.」·「…는지 본다」 — 「…는지 확인함·했음·됨」·「…는지 봄」은 우리 기록이라 센다) · 끝이 확인 안 했음이고 관찰 동사가 그 목적어 안에 안긴 것(「…뜨는지는·…뜨는 것은·…뜨기까지의 시간은 + 확인하지 않았음」 — 같은 문장의 앞 절이 관찰 주장이면 센다: 구분 부호(「—」·「,」·「 - 」·「;」·「:」·「·」) 앞 끝맺은 절 「…보임 — 화면은 확인하지 않았음」, 이음 어미(「…지만·…으나·…는데·…고·…며·…면서」)로 끝난 관찰·결과·확인 기록 절 「…나타나지만 실기기는 보지 않았음」) · 낱말 오탐 셋(빌드·버전·번호·타깃·구성·배포본과 함께 선 「위젯 … 나옴」에 화면 낱말이 없을 때 · 누르기·넣기 같은 조작이나 화면·칸 같은 자리가 없는 「들어감」 · 번호 표식 목록 머리의 「띄우는」). 그 건(절)에 증거가 하나라도 있으면 안 센다 — `plates` 의 캡처·녹화·합성·문서 갈래 · `quotes` · 문장의 `{{그림:id}}` 가 가리킨 그런 도판(건이면 그 건 어느 칸이든) · 출처 줄·캡션이 `§N.M` 으로 그 건을 가리키는 절 도판 · 문장이 원문·출처를 말할 때의 건 `source_url`. 표(`tables`)는 증거로 치지 않는다 — 우리가 센 결과 표로만 받친 화면 주장은 §10 통과 기준 표의 행. 단 건 증거가 덮지 못하는 문장 둘 — 문장의 `{{그림:id}}` 가 전부 도안인 것(도해 `diagrams[]`·흐름도 `flow:N` 토큰도 도안 — 자기 그림으로만 잰다) · 「코드상·코드로 봄·코드 기준·도안 기준·설계상」처럼 화면 밖 근거를 스스로 밝힌 것. 도판 갈래(`gazette.py asset_evidence_kind()`): `role:"video"` 녹화 → 캡션 「실제 화면 아님」·「— 도안」·「— 재현」 도안 → AI 합성(`provider:"higgsfield"` · `origin` 의 Higgsfield·이미지 생성·참조 그림·도안 PNG) 도안 → 캡션 「— 합성」 합성 → `provider:"user-provided"` 캡처 → `origin`·출처 줄·캡션의 촬영·캡처·갈무리·녹화·스크린샷·실기기·시뮬레이터·에뮬레이터·「시험 기기 화면」·「… 제공)」 캡처 → 「찍어·찍은·찍음」은 `origin` 에 도안·그린·그리고·개념도·도해·재현·생성이 없을 때만 캡처 → 그 밖 도안. `assets[].evidence` 칸은 아직 읽지 않는다(도구 스키마와 함께 들인다) — 그래서 지금은 「문서」 갈래가 서지 않고, 원문은 `quotes`·건 `source_url` 로 싣는다. 헤지·층 낱말(「화면 미확인」·「(확인 전)」)과 「…것을 확인함」·「…것까지 확인함」은 지우지 않고, 확인 방법 끝의 「…, 8. 23. 운영 관리자 웹에서 봄」 꼬리도 증거로 받지 않는다(독자 자기 화면만 볼 자리로 둔 확인 방법은 §10 표의 행). `%s` 는 「건 NN-n 칸 이름 「문장 앞 24자」」 5곳까지(넘으면 「그 밖 N곳」), 건 수는 걸린 건·절의 수 | 화면을 말했으면 그 화면을 싣는다 — 캡처·녹화를 그 건 `plates` 에 두거나 문장에서 `{{그림:id}}` 로 가리키고, 찍은 환경·날짜는 캡션 꼬리에(「… · 운영 관리자 웹 · 8. 23. 촬영」, §11-1 — 그 꼬리의 「촬영」이 그린 판으로 구운 캡처도 캡처로 가른다). 도안은 설명이지 증거가 아니다. 우리가 안 본 것이면 확인 방법에서 빼 남은 것 칸에 「…는 확인하지 않았음」으로 옮긴다(2026-10-01 사용자 결정). 위 두 예외 밖에서는 건 단위로 재므로 실물 하나가 그 건의 다른 주장까지 덮는다 — 그 실물이 그 주장을 보이는지는 사람 눈 |
558
583
  | 캡처 도판 「%s」 이 너무 작습니다(%d×%d) — 자리 표시면 실물로 바꿉니다 | 캡처 갈래(위 행의 `asset_evidence_kind()`) 도판이 긴 변 300px 미만이거나 짧은 변 100px 미만이다(`Doc.CAPTURE_MIN_LONG`·`CAPTURE_MIN_SHORT`). 치수는 실린 바이트(`data` — PNG·GIF·WebP·JPEG 머리)에서 읽고, 바이트가 없는 도판(로컬의 `file`·`source`, 받은 판)은 재지 않는다. 한 도판은 두 자리에 서도 한 번 센다(2026-10-02 — 본보기의 13×6 회색 자리 표시가 「캡처」로 갈려 증거 관문을 넘겼고, 베낀 원고는 실물 없이 ⚠0 이 된다) | 찍은 실물로 바꾼다. 실물이 아닌 그림이면 캡션에 「— 도안」을 달아 증거에서 뺀다 |
559
584
 
560
585
  위 표에서 여섯째 행(과정 어휘)부터 끝까지는 `gazette.py` 의 문구 **그대로**다(`%d`·`%s` 는 수·이름이 들어가는 자리) — 문구를 바꾸면 양쪽을 같이 바꾼다.
@@ -580,7 +605,7 @@ python3 assets/render.py <report.json>
580
605
  본보기가 건 행 「판단」과 의견 표 열 「판단」을 함께 실어 베낀 문서로 퍼졌으며, 그림 번호를 손으로 옮기다 두 번호의 뜻이 뒤바뀐 채 발행됐다.
581
606
  「앞 절이 뒤 절을 가리키는 곳」 행의 까닭(실사례 2026-09-14, 고객사 3차 보고 「읽다가 시험보는 줄 알 것 같음 — 장을 넘나들면서 이해해야 되는 구조」):
582
607
  절 순서가 아니라 앞 절이 뒤 절의 건 번호·「NN절」을 쓰고 낱말 정의가 부록·원고 밖에만 있어서였다 —
583
- 순서를 고친 3판에도 선형 읽기 뜀 지점 45. 기계는 ②(뒤 절 번호)만 세고 ①(정의 위치)은 독자 검토 linear 관점·사람 눈이다.
608
+ 순서를 고친 3판에도 선형 읽기 뜀 지점 45. 기계는 ②(뒤 절 번호)만 세고 ①(정의 위치)은 사람 눈이다.
584
609
 
585
610
  측정값(63.0kg · 12.5 · 3.1kg 꼴)은 참조 번호로 세지 않는다 — 앞자리 1~12 이고 단위가 안 붙는 것만 센다.
586
611
 
@@ -847,7 +872,7 @@ CSS 로는 못 한다. 우측 판독부에 남는 것은 문서 전체의 사실
847
872
  | `미확인` | 널리 쓰이나 1차 출처를 특정하지 못함 |
848
873
 
849
874
  **`verdict` 는 바깥 원본(문서·원문)을 실은 도판·인용에만 붙인다.** 우리가 그린 도해·도판에는 붙이지 않는다 —
850
- 그린 도해마다 「직접 확인」 칩이 서자 독자는 FCG 가 직접 해 본 것으로 읽었다(2026-10-01 사용자 결정 · 처음 읽는 독자 검토 심각도 4).
875
+ 그린 도해마다 「직접 확인」 칩이 서자 독자는 우리가 직접 해 본 것으로 읽었다(2026-10-01 사용자 결정 · 처음 읽는 독자 검토 심각도 4).
851
876
 
852
877
  **왜 강제하는가.** 실사례(2026-08-24): 원판이 3단으로 나눠 둔 이 축을 포털본이 통째로 버렸고,
853
878
  그 결과 2차 출처와 미확인 주장이 **사실로 단언돼** 고객에게 나갔다. 심지어 원 문서가 이미
@@ -864,8 +889,7 @@ CSS 로는 못 한다. 우측 판독부에 남는 것은 문서 전체의 사실
864
889
  수치를 「1차 문헌 미확인」으로 낮춰 적은 것이다. 둘 다 검사기가 못 잡는다 — **도판을 실었으면
865
890
  그 도판을 실제로 열어 본문과 대조해라.** 캡션만 읽고 대조했다고 치지 않는다.
866
891
 
867
- 집행자: 독자 검토 「도판」(figures) 관점 — PNG 를 Read 로 열어 본문과 대조하고, 그림이 본문을 반박하면 사실 틀림 독립 항목으로 올린다
868
- (`references/visual-first.md` §7) · 사람 눈.
892
+ 집행자: 사람 눈.
869
893
 
870
894
  ## 11-6. 인라인 표기 — 굵게 · 강조 · 칩 · 막대 톤 (2026-09-08)
871
895
 
@@ -1286,9 +1310,9 @@ AWS 요금 조사(2026-09)에서 트래픽·로그·DB 용량이 8월 1일 앞
1286
1310
 
1287
1311
  - 운영 python3 는 **3.6.8** 이다.
1288
1312
  f-string 의 중괄호 식 안에 역슬래시를 넣으면 SyntaxError — 로컬이 3.12+ 면 조용히 통과하고 운영에서만 터진다.
1289
- - `gazette.css` 는 **추출물이다.**
1290
- 손으로 고치지 마라 — `gazette-report` 스킬의 `extract.sh` 로 다시 뽑아 덮는다.
1291
- - 문서마다 달라지는 것(장 색 · PART 색 · 러닝 푸터 · 판형)은 `gazette.py` 의 `tail_css()` 가 낸다.
1313
+ - `gazette.css` 는 관보 v4(2026-10-13)부터 **원본이다**(파일 머리 주석). 보고 · 결정 두 모드가 싣고, 결정 모드는 그 위에 `decision.css`(v4 결정 층)를
1314
+ 얹는다(`build.py` `build_decision`). 옛 「추출물 — `extract.sh` 로 다시 뽑아 덮는다」는 v3 까지의 일이다.
1315
+ - 문서마다 달라지는 것(장 색 · PART 색 · 러닝 푸터 · 쪽 머리말 · 판형)은 `gazette.py` 의 `tail_css()` 가 낸다. 쪽 머리말은 종이마다 이름 붙은 쪽(`@page pgN`)이라 이어지는 쪽에도 같은 머리말이 선다(`sheet_heads` · `page_heads_css`).
1292
1316
  - 렌더러의 원본은 레포 하나다(`private/builder/`).
1293
1317
  스킬에 사본을 두지 마라 — `render.py` 가 `FORKABLE` 목록으로 막고 있다.
1294
1318
  - 원고 전체를 훑는 ⚠ 를 더하거나 서식 등록부(`REPORT_TEMPLATES`)에 칸을 더하면 `tests/builder.test.py` 와 로컬 `render.py` 로 끝내지 않는다.
@@ -48,13 +48,14 @@ python3 ~/.claude/skills/genetics-report/assets/render.py report.json
48
48
  | 질문 | 왜 이걸 묻는가 | 예시 답 |
49
49
  |---|---|---|
50
50
  | 이 문서를 **읽고 판정하는 사람**은 누구인가 — 직함이 아니라 *하는 일*로 | 직함(「팀장」)에서는 어휘 정책이 안 나온다. 행위(「검증한다」)에서는 나온다 | 「고객사 검수 담당 — 우리 작업이 실제로 해결됐는지 확인하는 사람」 |
51
- | 읽고 나서 **해야 할 행동**은 무엇인가 — 할 일이 둘이면 둘 다 목록으로 | `cta`·`open_items`·건별 `how_to_check` 가 여기서 결정된다. 할 일 목록은 독자 검토 `args.reader` 에 그대로 싣는다 | 「① 결정 물음에 회신한다 ② <독자 화면의 채널 이름> 앱에서 확인한다」 |
51
+ | 읽고 나서 **해야 할 행동**은 무엇인가 — 할 일이 둘이면 둘 다 목록으로 | `cta`·`open_items`·건별 `how_to_check` 가 여기서 결정된다 | 「① 결정 물음에 회신한다 ② <독자 화면의 채널 이름> 앱에서 확인한다」 |
52
52
  | 문서에 실어도 되는 **참조 체계**는 무엇인가 | 독자가 확인할 수 없는 참조는 신뢰에 기여하지 않고 노이즈만 된다 | 「본인이 제보한 원본 링크만. 내부 티켓 번호는 안 됨」 |
53
53
  | 전달 경로 — 포털 링크인가, 파일 하나인가, 인쇄도 도는가 | 포털은 셸이 문서 둘레에 요약·댓글을 놓는다. 파일 전달은 그것이 없다 | 「포털 링크 + 인쇄 가능해야 함」 |
54
54
  | 읽고 나서 **무엇을 결정하는가** — 선택지·선택지마다 달라지는 것·기한. 우리 의견을 낼지는 따로 묻는다 | 답에 정할 것이 기한과 함께 있으면 결정 블록(`decision_brief.decisions`)을 쓴다 — 문서가 결정 모드로 선다(`decision-format.md`). 결정마다 물음·기한·선택지가 칸이 되고, 의견은 내면 결정마다 `opinion` 칸 하나. 사용자 확인에 「결정 요청으로 낼까요, 보고로 낼까요」 한 줄 | 「[방식 A] 를 들일지, 그대로 둘지 — 12월 31일까지」 |
55
- | **이미 정해진 것**은 무엇이고 **누가·어디서** 정했는가(체크리스트 0a) | 정해진 것은 사실로 배경에 서고 결정 요청에서 빠진다 — 주체와 기록을 확인하지 않고 쓰면 열린 항이 닫힌 사실로 실리거나, FCG 가 대화에서 정한 것이 고객 결정처럼 읽힌다(SKILL 3b 「결정 주체」). 작업 폴더 `decisions.json`(발행 안 함): 항 · 내용 · 결정권(고객/FCG) · 정한 주체 · 기록(회신 원문·회의록·결정문의 이름과 날짜) · 사용자 확인 여부. 미확인 항은 원고에 쓰기 전에 한 번에 묻는다 | 「화면 문구 교체 — 결정권 고객 · 고객 회신 메일(날짜) · 확인함」 |
55
+ | **이미 정해진 것**은 무엇이고 **누가·어디서** 정했는가(체크리스트 0a) | 정해진 것은 사실로 배경에 서고 결정 요청에서 빠진다 — 주체와 기록을 확인하지 않고 쓰면 열린 항이 닫힌 사실로 실리거나, 우리가 대화에서 정한 것이 고객 결정처럼 읽힌다(SKILL 3b 「결정 주체」). 작업 폴더 `decisions.json`(발행 안 함): 항 · 내용 · 결정권(고객/우리) · 정한 주체 · 기록(회신 원문·회의록·결정문의 이름과 날짜) · 사용자 확인 여부. 미확인 항은 원고에 쓰기 전에 한 번에 묻는다 | 「화면 문구 교체 — 결정권 고객 · 고객 회신 메일(날짜) · 확인함」 |
56
56
  | 원고에서 부를 대상(판·환경·인스턴스·설정·요금·문서)마다 **독자가 보는 이름**은 무엇인가(SKILL 0단계 물음 5) | 작업하며 지은 이름은 문서 안에서 정의해도 독자가 모른다 — 대응표 없이 쓰기 시작하면 설명형 새 이름을 짓게 된다(SKILL 반드시 지키는 것 12). 작업 폴더 `names.md`(발행 안 함): 우리가 부르던 이름 / 독자 화면·문서의 이름 / 그 이름이 보이는 자리. 자료(화면 캡처·콘솔·원본 문서)에서 먼저 찾고 못 찾은 것만 한 번에 묻는다 | 「예비판 → <독자 화면의 채널 이름> 앱 · 고객 관리자 화면의 채널 목록」 |
57
57
  | 독자가 믿어야 할 **관찰 주장**(화면·흐름·화면 문구·동작)마다 무엇을 보여 줄 것인가 — 누가 찍고, 무슨 접근이 필요한가(SKILL 0단계 물음 6) | 우리가 코드·로그·대화로 본 것은 문서에 실리지 않으면 독자에게 없다. 원고를 다 쓴 뒤에 찾으면 결론 문장만 남는다. 작업 폴더 `evidence.md`(발행 안 함): 관찰 주장 / 보여 줄 것(캡처·녹화·원문·센 대상이 있는 표) / 누가 찍나 / 필요한 접근(계정·기기·창·메일함·자동 조작 허락). 모자란 접근은 원고 전에 대화창에서 한 번에 청한다. 구조 주장(「X 하면 항상 Y」)은 관찰 하나로 단정하지 않는다 — 코드 분기로 확인하고 팀 지식(`search_cases`)을 먼저 뒤진다 | 「저장한 주문이 목록 첫 줄에 나타남 — 캡처 · 우리가 운영 관리자 웹에서 · 운영 관리자 계정」 |
58
+ | 문서를 **보내는 쪽 이름**은 무엇인가(SKILL 0단계 물음 7) | 표지 발행처(`issuer` 첫 칸)와 결정 모드의 표지 「보낸 곳」이 이 이름으로 선다 — 이름은 정체 자리에만 서고, 본문에서 발행처는 「당사」(요청 자리 「저희」)다. 작성자가 개발사여도 문서는 발행처가 직접 말한다(SKILL 반드시 지키는 것 15 — 「(우리회사 확인)」 · 「이 문서를 보낸 우리회사 담당자」는 포털이 받지 않는다). 이름은 `whoami` 가 보이는 운영사 이름이다 — 대화 맥락에서 짐작해 적으면 다른 운영사의 문서에 엉뚱한 회사가 선다. 운영사 줄이 없거나(키 자격 · 구성원 · 옛 서버) 「운영사 이름 미설정」이면 한 번 묻고, 「전체 관리자가 설정 › 보고서 브랜드 › 운영사 이름에 넣으면 다음부터 `whoami` 에 섭니다」라고 사용자에게 알린다. 이름을 모르면 `issuer` 첫 칸을 빈 글자로 두고 칸을 빼지 않는다. 표지 머리글 · 문서번호 · 판권지에 회사 이름 · 약호를 지어 넣지 않는다 | 「`whoami` 의 「운영사: 우리회사」 그대로 — 문서번호는 사용자 번호 체계가 없어 비움」 |
58
59
 
59
60
  ### 이 답에서 곧바로 정해지는 것
60
61
 
@@ -214,10 +215,12 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
214
215
  반영 단계 어휘는 `references/content-pipeline.md` 「4.2 치환 유형」 B 행을 따른다. 실기기 확인이 없으면 같은 문장에 그렇다고 적는다.
215
216
  판정 규칙은 이용자가 확인할 수 있는 동작으로만 적고, 구현 규칙(어느 키로 판정하는지)은 싣지 않는다.
216
217
  **커밋·브랜치·파일·시험 도구·시험 건수는 이 표에만** 둔다 — 원고에 새면 `gazette.py` `text_scan()` 개발 식별자 ⚠(두 경로).
217
- 확인 수준보다 앞선 완료형 동사는 기계가 못 가린다 — 독자 검토에 `args.state` 로 이 표를 주면 state 관점이 대조하고, 나머지는 사람의 눈(SKILL 반드시 지키는 것 3).
218
+ 확인 수준보다 앞선 완료형 동사는 기계가 못 가린다 — 사람의 눈이 이 표와 대조한다(SKILL 반드시 지키는 것 3).
218
219
 
219
220
  ### 문체
220
221
 
222
+ **화자는 발행처다.** 문서는 발행처가 직접 말한다 — 「우리」는 원고에서 「당사」(요청 자리는 「저희」)로 쓰고, 발행처 이름을 3인칭으로 부르지 않는다(SKILL 반드시 지키는 것 15).
223
+
221
224
  **주어와 자리가 정한다.** 요청 자리 밖(요약·건·절 도입문·여백 주석·문단·표·부록)에는 우리·사물·화면이 주어인 문장만 두고 개조식
222
225
  (`~함` / `~했음` / `~임`). 독자가 할 일은 **요청 자리**(`cta`·`open_items`·PART I 간지(요청·결정 PART 일 때)·판권지 회신 안내·요청 절 항을 부탁하는 읽는 법 한 줄)에만 두고 사실 문장까지
223
226
  **하십시오체**(`~하여 주시기 바랍니다` / `~부탁드립니다` / `~하겠습니다`).
@@ -244,7 +247,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
244
247
  4. 검토 요청 — 요청 절에 남은 항 이름과 기한
245
248
 
246
249
  결정 모드는 요약을 받지 않는다(SKILL.md 4~6단계).
247
- 집행자: 독자 검토 structure 관점 · 사람 눈 — 기계 없음.
250
+ 집행자: 사람 눈 — 기계 없음.
248
251
 
249
252
  ### 확인 프로필 표 — 시험판·검수에서 무엇을 넣어 보면 되는가
250
253
 
@@ -252,7 +255,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
252
255
  - 경계마다 포함 쪽·제외 쪽 두 행을 둔다(≤·< 가 행 이름에 드러나게). 날짜로 정해지는 경계는 확인일 기준 상대값과 계산 예 하나.
253
256
  - 각 행을 **판정 코드나 정의로 확인한 뒤** 싣는다 — 문서의 나이·키 같은 정의가 앱의 정의(만 나이/세는 나이 등)와 같은지 먼저 본다.
254
257
  - 앱에서 만들 수 없는 조건은 행을 지우지 않고 대안을 적는다.
255
- 집행자: 사람의 눈(7단계 표 「확인 프로필 표」 행) · 독자 검토 facts 관점(`args.sources` 에 코드를 주면) — 기계 없음.
258
+ 집행자: 사람의 눈(7단계 표 「확인 프로필 표」 행) — 기계 없음.
256
259
 
257
260
  ### 요약 근거 게이트 — 발행이 **거절**된다
258
261
 
@@ -283,7 +286,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
283
286
  같은 데이터를 「고객이 해야 할 일」만으로 쓰면 책임 전가 문서가 되고, 「우리가 아직 못 닫은 것」을 먼저 밝히면 신뢰 문서가 된다.
284
287
  검수·보고 문서의 `open_items[].title` 은 「~ 요청」+기한 괄호(SKILL 5a)이고, 본문 첫 문장이 우리가 못 닫은 사실이다 — 「검증에 쓴 표본이 작습니다」·「같은 전화번호를 쓰는 계정의 주인은 저희가 판단할 수 없습니다」.
285
288
  결정 문서는 결정 블록을 쓴다 — 정할 것은 `decisions`, 확인 요청은 `confirms` 로 서고 결정 모드는 `open_items` 를 받지 않는다(`decision-format.md`).
286
- 표지·현황 줄에는 사실문으로만 올린다. 읽는 법(`guide`)에는 요청 절의 확인 요청을 가리키는 요청 한 줄을 둘 수 있다(2026-09-15 사용자 결정) — 그 밖의 요청문은 두지 않는다(요청 자리 밖, SKILL 5). 집행자: `gazette.py` `brief_checks()` 기한 ⚠(「확인 요청」 문구로 갈림) · 독자 검토 decider 관점.
289
+ 표지·현황 줄에는 사실문으로만 올린다. 읽는 법(`guide`)에는 요청 절의 확인 요청을 가리키는 요청 한 줄을 둘 수 있다(2026-09-15 사용자 결정) — 그 밖의 요청문은 두지 않는다(요청 자리 밖, SKILL 5). 집행자: `gazette.py` `brief_checks()` 기한 ⚠(「확인 요청」 문구로 갈림) · 사람 눈.
287
290
 
288
291
  | 규칙 | 어기면 |
289
292
  |---|---|
@@ -311,7 +314,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
311
314
  `marg` 가 비면 렌더러가 경고한다(`gazette.py Doc.marg()`).
312
315
 
313
316
  ```
314
- 절 03 「처리 현황」에 여백 주석(marg.why/key/advice)이 없습니다 — 두 단 본문이 한 단으로 섭니다
317
+ 절 03 「처리 현황」에 첫머리 물음 · 답(marg.why · marg.key)이 없습니다 — 절이 물음 없이 섭니다
315
318
  ```
316
319
 
317
320
  거절이 아니라 경고다.
@@ -391,7 +394,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
391
394
  앞 PART 의 요지·대조표·여백 주석이 뒤 PART 간지의 물음에 먼저 답하고, 같은 사실이 PART 이름만 바꿔 두 번 선다.
392
395
  요청(`asks`)이 없는 문서(회신 없는 정황 공유)는 1 요청만 빼고 「경과 / 남은 것」으로 가른다 — 원인은 경과 PART 안의 건이 맡는다.
393
396
  예외는 결정한다 모드 하나다 — 요지를 결정 PART 에, 건을 근거 PART 에 두는 것은 `asks` 가 곁에 있어 요지가 결정의 배경이 될 때뿐이다.
394
- 집행자: 독자 검토 「구조」 관점(`references/reader-review.workflow.js`) · 사람의 눈(7단계 표 「PART 간지」 행) — 렌더러 ⚠ 없음(경위: `references/history.md` §9).
397
+ 집행자: 사람의 눈(7단계 표 「PART 간지」 행) — 렌더러 ⚠ 없음(경위: `references/history.md` §9).
395
398
 
396
399
  절이 하나뿐인 묶음도 간지를 둔다 — 간지는 장식이 아니라 층위 표시다.
397
400
 
@@ -451,17 +454,16 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
451
454
 
452
455
  ## 7단계 — 검수
453
456
 
454
- 관문은 넷이고, 넷 다 다른 것을 본다. 순서는 SKILL.md 「작업 체크리스트」 7단계 행(로컬 렌더 → dry_run → 조판 검사 → 독자 검토 → 사람 눈)이고, 조판 검사 8종은 단일 HTML 로 전달할 때 돈다.
457
+ 관문은 셋이고, 셋 다 다른 것을 본다. 순서는 SKILL.md 「작업 체크리스트」 7단계 행(로컬 렌더 → dry_run → 조판 검사 → 사람 눈)이고, 조판 검사 8종은 단일 HTML 로 전달할 때 돈다.
455
458
 
456
459
  | 층 | 무엇을 보는가 | 통과 기준 |
457
460
  |---|---|---|
458
461
  | `dry_run` warnings(로컬 렌더 ⚠ 포함) | 무엇이 **안 실렸는가** · 규칙 낱말·모양 | 작성자가 고칠 수 있는 ⚠ 0건 |
459
462
  | 검사기 8종 | 조판이 **성립했는가** | 각 검사기의 0건 |
460
- | 독자 검토(`reader-review.workflow.js`) | 처음 읽는 사람·결정권자가 **읽히는가** · 도판을 열어 잰 틀 · 1차 자료와 맞는가 | Verify 를 통과한 발견 반영 · 「⚠ 도판 N장 미열람」 없음(SKILL 체크리스트 7단계 독자 검토 행 — 미열람·「서버 보관」 줄의 id 가 모두 원고에서 보관 표식인 장이면 사람이 열람 주소에서 보고 핸드오프에 적어 통과) |
461
463
  | 사람의 눈 | 이 문서가 **이 독자에게 맞는가** | 판단 |
462
464
 
463
- 결정 모드는 독자 검토 층이 다르다 — 공개 문서마다 원고를 모르는 독자 한 번, 점수 없이 막힌 자리만(`decision-format.md` 6절).
464
- 아래 사람의 눈 표 가운데 표지 · 요약면 · PART 간지 · 여백 주석 · 의견 한 절 · 선택지 이름·순서 대조 행은 그 모드에 자리가 없다 — 첫 화면 머리와 결정 장이 서고, 선택지는 `options[]` 한 곳에서 찍힌다.
465
+ 결정 모드에서는 아래 사람의 눈 표 가운데 요약면 · PART 간지 · 여백 주석 · 의견 한 절 · 선택지 이름·순서 대조 행이 자리가 없다 — 첫 화면 머리와 결정 장이 서고, 선택지는 `options[]` 한 곳에서 찍힌다.
466
+ 표지 행은 종이에서 본다 — 화면 첫 창은 머리 한 띠지만 인쇄하면 1쪽이 v1 표지 단독(쪽번호 없음)이다(경위: `references/history.md` §21).
465
467
 
466
468
  ### `dry_run` 이 실질적 유일한 품질 관문이다
467
469
 
@@ -528,7 +530,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
528
530
  | 표지 가운데 | 빈 마당이 그대로인가. **채우지 마라** — 그것이 문법이다 |
529
531
  | 차례 | 항목 수가 절 수와 맞는가. 죽은 링크가 없는가 |
530
532
  | 이 문서 읽는 법 | 질문형이 `~합니까?` 로 새지 않았는가 |
531
- | 요약면 | `notice.state` 가 실제 상태와 맞는가. 상태 막대 라벨이 무엇을 세는지 `bar_note` 가 밝히는가. 수치 칸(`stats`)끼리 겹치는 집합이 없는가 — 겹치면 하나를 빼거나 라벨에 관계를 드러낸다. 막대 합·머리띠 잔여와 문서의 셈 대조는 `gazette.py` `tally_scan()` ⚠, 수치 칸 겹침은 사람의 눈(독자 검토 decider 관점) |
533
+ | 요약면 | `notice.state` 가 실제 상태와 맞는가. 상태 막대 라벨이 무엇을 세는지 `bar_note` 가 밝히는가. 수치 칸(`stats`)끼리 겹치는 집합이 없는가 — 겹치면 하나를 빼거나 라벨에 관계를 드러낸다. 막대 합·머리띠 잔여와 문서의 셈 대조는 `gazette.py` `tally_scan()` ⚠, 수치 칸 겹침은 사람의 눈 |
532
534
  | PART 간지 | 인쇄에서 각각 1쪽 단독으로 서는가. **간지 물음(`questions`)만 이어 읽어 PART 마다 다른 물음인가**, 앞 PART 의 요지 lead·여백 주석 key·표 행이 뒤 PART 물음에 먼저 답하지 않는가. 같은 시각·금액·건 제목이 두 PART 에 서면 한쪽은 건 번호로 가리키기만 한다(readability R12g) — 기계는 세지 않는다 |
533
535
  | 절 첫 화면 | 두 단으로 서는가. 한 단이면 `marg` 가 빈 것이다 |
534
536
  | 여백 주석 | 본문 첫 문장의 복사본이 아닌가. 셋을 채우려고 넣은 줄이 없는가 |
@@ -538,22 +540,22 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
538
540
  | 요청 자리 | 반대다 — `cta`·`open_items`·PART I 간지·판권지 회신 안내가 **사실 문장까지 하십시오체로 맺는가**. 명사형 종결(`부탁드림`·`바람`·`하시면 됨`)이 남아 있지 않은가 |
539
541
  | 본문 전체 | 낱말 중간에서 줄이 바뀐 곳이 없는가 |
540
542
  | 본문 전체 | 독자가 조회할 수 없는 식별자가 남아 있지 않은가 — 해시·코드 파일·개발 도구·커밋·브랜치 같은 개발 식별자는 `gazette.py` `text_scan()` ⚠(두 경로), 고객사·제품명 같은 문서마다 다른 금칙 값은 포털 발행에 그물이 없어 **여기가 마지막 관문이다** |
541
- | 본문 전체 | (코드 작업을 녹인 문서) 「반영함·보이지 않음·빠짐」 같은 완료형 동사가 원고 밖 상태 표의 확인 수준(코드·시험판·실기기·운영)을 넘지 않는가 — 기계 없음, 독자 검토 state 관점(`args.state`) · 사람의 눈(4단계 「코드 작업을 녹일 때」) |
542
- | 건 · 절 산문 | 화면·흐름·화면 문구·동작을 말하는 문장(관찰 주장)마다 **독자가 볼 증거가 문서 안에 있는가** — 그 건·절의 실제 캡처·녹화·원문 인용·외부 문서(센 대상이 있는 표는 수·대조 결과의 증거 — 화면 주장은 표만으로 받치지 않는다). 도안(「— 도안」·「— 재현」)은 설명이지 증거가 아니다. 없으면 찍어 실었는가, 우리가 안 본 것이면 남은 것 칸으로 옮겼는가 — 「화면 미확인」·「코드상」 같은 헤지로 넘기지 않는다. 자리 세기는 `gazette.py` `evidence_scan()` ⚠(readability R14), 그 증거가 그 주장을 실제로 보이는지는 독자 검토 evidence 관점 · **사람의 눈** |
543
- | 배경 · 결정 요청 | 「정해진 것」으로 쓴 항마다 결정 장부에 결정권·정한 주체·기록·확인이 있는가. 결정권이 고객인 항을 기록 없이 사실로, FCG 가 정한 항을 고객 결정처럼 쓰지 않았는가 — 주체 없는 결정 명사만 `gazette.py` `text_scan()` 과정 어휘 ⚠, 그 밖은 사람의 눈 · 독자 검토 facts 관점(SKILL 3b 「결정 주체」) |
543
+ | 본문 전체 | (코드 작업을 녹인 문서) 「반영함·보이지 않음·빠짐」 같은 완료형 동사가 원고 밖 상태 표의 확인 수준(코드·시험판·실기기·운영)을 넘지 않는가 — 기계 없음, 사람의 눈(4단계 「코드 작업을 녹일 때」) |
544
+ | 건 · 절 산문 | 화면·흐름·화면 문구·동작을 말하는 문장(관찰 주장)마다 **독자가 볼 증거가 문서 안에 있는가** — 그 건·절의 실제 캡처·녹화·원문 인용·외부 문서(센 대상이 있는 표는 수·대조 결과의 증거 — 화면 주장은 표만으로 받치지 않는다). 도안(「— 도안」·「— 재현」)은 설명이지 증거가 아니다. 없으면 찍어 실었는가, 우리가 안 본 것이면 남은 것 칸으로 옮겼는가 — 「화면 미확인」·「코드상」 같은 헤지로 넘기지 않는다. 자리 세기는 `gazette.py` `evidence_scan()` ⚠(readability R14), 그 증거가 그 주장을 실제로 보이는지는 **사람의 눈** |
545
+ | 배경 · 결정 요청 | 「정해진 것」으로 쓴 항마다 결정 장부에 결정권·정한 주체·기록·확인이 있는가. 결정권이 고객인 항을 기록 없이 사실로, 우리가 정한 항을 고객 결정처럼 쓰지 않았는가 — 주체 없는 결정 명사만 `gazette.py` `text_scan()` 과정 어휘 ⚠, 그 밖은 사람의 눈(SKILL 3b 「결정 주체」) |
544
546
  | 표지 · 판권지 · 발행 이력 | 작성일 세 자리(`meta` 작성 · 판권지 작성 · `history` 마지막 `date`)가 한 값이고 공개하는 날인가. 공개 전 판을 `history` 에 쌓지 않았는가 — 세 자리 대조는 `gazette.py` `date_scan()` ⚠(두 경로), 공개하는 날인지와 `history` 행 수는 **사람의 눈**(SKILL 3c · 10단계) |
545
547
  | 본문 전체 | 「A에서 B로」 전환 공식 헤드라인이 없는가 — **기계가 안 잡는다**(SKILL.md 카피 게이트 표) |
546
548
  | 본문 전체 | 부정 서술의 주어가 사람·조직·국가가 아닌가 — 기계는 「이유 없는 부정 종결」까지만 잡는다(content-pipeline §6.4) |
547
549
  | 본문 전체 | (결정권이 고객에게 있는 문서) 권고 낱말이 제목·표 열·절 이름·여백 주석·요약면에 배어 **동의만 받는 틀**인가. 우리 의견은 한 절 한 자리에만 있는가 — 기계는 **낱말까지**(`gazette.py` ⚠ W1). 동의만 받는 틀인지 · 의견 한 자리 여부는 **사람의 눈**(SKILL.md 카피 게이트 표) |
548
- | 도판 출처 줄 · 인용 | 도판 출처 줄이 **위치 한 구절**인가(readability R12e — 쪽·행·주소·건 § 가운데 하나, 캡처는 「화면 이름 · 날짜」, 우리 도안은 비움). 원본 이름·찾을 낱말은 건이나 부록 출처 목록에 있는가. 「흐리다」「못 연다」는 말은 원본 해상도로 **잰 뒤** 쓴 것인가 — 고객·제3자 자료에서 낸 도판(`user-provided`)의 원본 위치 누락은 `gazette.py` ⚠ W2, 재고 썼는지와 인용이 원문 그대로인지는 **사람의 눈**(독자 검토 「원본 대조」 관점) |
549
- | 보이는 자리의 제작 메타 · 증거 범위 | 출처 줄·캡션·부록·요청 본문에 제작 메타(「합성이며」·「재현임」 같은 서술·제작 도구·배율·자르기 좌표·스크립트 이름·결정 경로)가 있는가 — 그것은 `origin` 과 도판 HTML 머리 주석에만. 반대로 캡처·영상 캡션 끝에는 **증거 범위** 한 구절(찍은 환경·기기·날짜·옮겨 적은 부분 — 「… · 운영 관리자 웹 · 8. 23. 촬영」·「… · 알림 문구는 옮겨 적음 — 합성」)이 있는가(readability R12e). 도안·합성의 정직성은 캡션 끝 한 낱말(「— 도안」·「— 재현」·「— 합성」 — AI 로 만든 합성 그림은 「— 도안」, readability R14) — 출처 줄은 `gazette.py` `text_scan()` 제작 메타 ⚠, 캡션 꼬리·부록·요청 본문은 **사람의 눈** · 독자 검토 Verify 의 노이즈 거름 |
550
+ | 도판 출처 줄 · 인용 | 도판 출처 줄이 **위치 한 구절**인가(readability R12e — 쪽·행·주소·건 § 가운데 하나, 캡처는 「화면 이름 · 날짜」, 우리 도안은 비움). 원본 이름·찾을 낱말은 건이나 부록 출처 목록에 있는가. 「흐리다」「못 연다」는 말은 원본 해상도로 **잰 뒤** 쓴 것인가 — 고객·제3자 자료에서 낸 도판(`user-provided`)의 원본 위치 누락은 `gazette.py` ⚠ W2, 재고 썼는지와 인용이 원문 그대로인지는 **사람의 눈** |
551
+ | 보이는 자리의 제작 메타 · 증거 범위 | 출처 줄·캡션·부록·요청 본문에 제작 메타(「합성이며」·「재현임」 같은 서술·제작 도구·배율·자르기 좌표·스크립트 이름·결정 경로)가 있는가 — 그것은 `origin` 과 도판 HTML 머리 주석에만. 반대로 캡처·영상 캡션 끝에는 **증거 범위** 한 구절(찍은 환경·기기·날짜·옮겨 적은 부분 — 「… · 운영 관리자 웹 · 8. 23. 촬영」·「… · 알림 문구는 옮겨 적음 — 합성」)이 있는가(readability R12e). 도안·합성의 정직성은 캡션 끝 한 낱말(「— 도안」·「— 재현」·「— 합성」 — AI 로 만든 합성 그림은 「— 도안」, readability R14) — 출처 줄은 `gazette.py` `text_scan()` 제작 메타 ⚠, 캡션 꼬리·부록·요청 본문은 **사람의 눈** |
550
552
  | 결정 요청 | 결정에 **이용자 화면의 변화**(팝업·안내·칸의 유무)가 따르는데 고객 디자인 시스템 규격의 **도안**이 없는가 — **없음 — 사람의 눈**(절차는 visual-first 「화면 도안」) |
551
- | 결정 요청 · 선택지 | 선택지마다 **같은 틀·같은 잣대**인가(이름·수·순서가 한눈표·선택지 비교 행렬·의견 표·도판 칩·조건표에서 같은가). 한 선택지만 합성·실사·부연·크게·먼저가 아닌가. 조건표의 각 행이 **모든 도안 그림과 앱 코드**에 맞는가(대조 없이 「공통」이라 적지 않았는가) — 기계는 `asks` 절 표의 모든 행이 같은 열(`gazette.py` `brief_checks()` ⚠)과 도판 틀(`figure.mjs` R13)까지, 그 밖은 독자 검토 figures 관점 · **사람의 눈** |
553
+ | 결정 요청 · 선택지 | 선택지마다 **같은 틀·같은 잣대**인가(이름·수·순서가 한눈표·선택지 비교 행렬·의견 표·도판 칩·조건표에서 같은가). 한 선택지만 합성·실사·부연·크게·먼저가 아닌가. 조건표의 각 행이 **모든 도안 그림과 앱 코드**에 맞는가(대조 없이 「공통」이라 적지 않았는가) — 기계는 `asks` 절 표의 모든 행이 같은 열(`gazette.py` `brief_checks()` ⚠)과 도판 틀(`figure.mjs` R13)까지, 그 밖은 **사람의 눈** |
552
554
  | 확인 프로필 표 | 경계마다 포함·제외 두 행인가. 각 행을 판정 코드나 정의로 확인했는가(문서의 나이·키 정의가 앱의 정의와 같은가). 날짜 경계는 확인일 기준 상대값인가 — **없음 — 사람의 눈**(4단계 「확인 프로필 표」) |
553
555
  | 본문 전체 | 진행 상태 어휘(정해짐·회신 대기·N판)·개수로 상태를 세는 캡션·직전 판과의 비교(「~ 그대로」)가 남았는가. 정해진 것은 사실로 배경에, 결정 요청에는 지금 열린 것만 — 기계는 **낱말과 개수로 상태를 세는 표 제목**까지 잡는다(`gazette.py` 과정 어휘 ⚠ · readability R11h). 표 제목 밖의 개수 표현·「~ 그대로」 비교는 사람의 눈 |
554
556
  | 부록 | 본문에서 실제로 참조되는 것만 있는가 |
555
557
  | 판권지 | 문서가 여기서 닫히는가. 꼬리 카드가 붙어 있으면 구버전이다 |
556
- | 인쇄 미리보기 | 절마다 새 쪽에서 시작하는가. 표가 쪽 경계에서 잘리지 않는가 |
558
+ | 인쇄 미리보기 | 절마다 새 쪽에서 시작하는가. 표가 쪽 경계에서 잘리지 않는가. 결정 모드는 1쪽이 표지 단독(쪽번호 없음)인가, 결정 장 머리가 그 본문과 같은 쪽에 서는가, 표가 표로 서는가(칸마다 접히지 않는가) — 미리보기 대신 A4 PDF 를 뽑아 v1 본보기와 쪽 차례를 나란히 본다(`gazette-report` `scripts/pdfcheck.sh` → `pdftoppm`). 화면 요소 개수는 이 행의 확인이 아니다(§21) |
557
559
 
558
560
  이 표의 행 가운데 기계가 일부만 잡는 것은 행 끝에 그 한계를 적었다. 틀 · 의견 자리 · 도안 유무 · 원본을 쟀는지 · 선택지 사이 대칭 · 날짜는 여전히 이 표가 그물이다(경위: `references/history.md` §4·§7·§8·§12).
559
561
 
@@ -572,8 +574,8 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
572
574
  **기본은 초안이다.**
573
575
  도구가 `publish` 를 명시적으로 참으로 주지 않는 한 고객에게 안 보인다. 여는 것은 10단계다.
574
576
 
575
- 수정은 SKILL.md 8단계 「수정 절차」(받은 판 보관 → draft 를 `patch.py --freeze` 로 굳혀 새 판에 적용 → `render.py` 로 새 판을 그대로 로컬 렌더 → 받은 판의 `body_rev` 를 실은 dry_run(그 사이 본문 판이 바뀌었으면 여기서 409) → 판 갱신 검토 → 같은 `body_rev` 를 실어 `update_report` → 9단계).
576
- **같은 링크가 새 내용을 가리킨다.** 초안 `update_report` 도 **본문 판(`body_rev`)** 을 올리고 사용자가 그 판을 읽으므로 독자 검토를 통과한 본문 판만 올린다. 사용자가 「바로 반영」을 지시하면 먼저 올리고 검토를 곧바로 뒤따라 돌린다 — 발행 이력 행(`history`)은 공개 뒤에만 는다(SKILL 3c).
577
+ 수정은 SKILL.md 8단계 「수정 절차」(받은 판 보관 → draft 를 `patch.py --freeze` 로 굳혀 새 판에 적용 → `render.py` 로 새 판을 그대로 로컬 렌더 → 받은 판의 `body_rev` 를 실은 dry_run(그 사이 본문 판이 바뀌었으면 여기서 409) → 같은 `body_rev` 를 실어 `update_report` → 9단계).
578
+ **같은 링크가 새 내용을 가리킨다.** 초안 `update_report` 도 **본문 판(`body_rev`)** 을 올리고 사용자가 그 판을 읽으므로 로컬 렌더 ⚠ 와 dry_run 을 다 본 본문 판만 올린다 — 발행 이력 행(`history`)은 공개 뒤에만 는다(SKILL 3c).
577
579
  `list_reports` 줄에 「덮음: …」이 있으면(사람이 고친 초안·발행 본문) 덮기 전에 묻는다 — 받은 판의 `body_rev`(`get_report` 머리줄 값)를 실은 교체는 그 뒤 본문 판이 바뀌었으면 서버가 409 로 막지만, 편집기에 저장만 해 둔 사람 초안은 판을 안 올려 그 잠금에 안 걸린다. 목록의 「덮음」이 유일한 신호다.
578
580
 
579
581
  포털 셸이 문서 **둘레**에 놓는 것(검토 회신·핵심 요약·진척률 바)은 저작 대상이 아니다.
@@ -653,11 +655,11 @@ MCP 가 찍는 요약 줄은 **옛 서식의 셈**만 읽는다(`genetics.mjs ou
653
655
  공개 전 수정은 판이 아니다(SKILL 3c). 공개하기 직전에 한 번만 날짜를 맞춘다.
654
656
 
655
657
  1. 올라 있는 판을 받아(SKILL 8단계 「수정 절차」 1~3 — 로컬 `report.json` 은 그사이 수정 절차를 돈 문서면 낡았다) 작성일 세 자리 — `meta` 의 작성 · 판권지(`colophon`) 작성 · `history` 마지막 `date` — 를 공개하는 날 한 값으로 고친다. `history` 는 공개할 판 한 행(「최초 발행」)만 둔다.
656
- draft 는 있는 자리만 적는다 — `meta[label=작성][1]` · `colophon.rows[label=작성][1]`(판권지에 `rows` 가 있을 때만) · `history[0].date`. 칸에 날짜 말고 다른 글이 함께 있으면(「2026. 9. 27. · FCG」) `set` 대신 `replace` 로 날짜 조각만 바꾼다.
658
+ draft 는 있는 자리만 적는다 — `meta[label=작성][1]` · `colophon.rows[label=작성][1]`(판권지에 `rows` 가 있을 때만) · `history[0].date`. 칸에 날짜 말고 다른 글이 함께 있으면(「2026. 9. 27. · 우리회사」) `set` 대신 `replace` 로 날짜 조각만 바꾼다.
657
659
  `cover_date` 는 요약면 「기준」 날짜(수치의 기준일)라 이 셋에 묶지 않는다.
658
- 2. 로컬 렌더 → 받은 판의 `body_rev` 를 실은 dry_run → 같은 `body_rev` 로 `update_report` 한 번(수정 절차 4~6 — 날짜만 고친 판이라 판 갱신 검토는 돌리지 않는다) → 9단계 두 행.
660
+ 2. 로컬 렌더 → 받은 판의 `body_rev` 를 실은 dry_run → 같은 `body_rev` 로 `update_report` 한 번(수정 절차 4~6) → 9단계 두 행.
659
661
  3. 사용자 승인을 받고 `release_report(id)` 로 연다 — 그것이 사람의 승인 행위다.
660
- 승인 물음과 답에는 **이 판에서 건너뛴 단계**(0단계 사용자 확인 · 독자 검토 · 열람 확인 등)와 **증거 없는 관찰 주장 수**(로컬 `render.py` 의 `evidence_scan()` ⚠ 「화면을 말했는데 …」의 N곳 — 포털 dry_run 은 렌더러 운영 반영 뒤부터)를 반드시 싣는다 — 교체(`update_report`) 승인도 같다.
662
+ 승인 물음과 답에는 **이 판에서 건너뛴 단계**(0단계 사용자 확인 · 열람 확인 등)와 **증거 없는 관찰 주장 수**(로컬 `render.py` 의 `evidence_scan()` ⚠ 「화면을 말했는데 …」의 N곳 — 포털 dry_run 은 렌더러 운영 반영 뒤부터)를 반드시 싣는다 — 교체(`update_report`) 승인도 같다.
661
663
  볼 자리가 독자 자기 화면뿐인 확인 방법(「주문 목록을 열면 …」)도 2단계 정의에 맞는 꼴이지만 그 ⚠ 는 지워지지 않고 이 수에 든다 — 확인 방법 끝 「…에서 봄」은 증거로 치지 않는다(그 꼬리 한 줄이 캡처 대신 경고를 지우는 싼 길이 되므로, readability R14).
662
664
  「간단히」는 분량 지시이지 단계 면제가 아니다. 「바로 반영」(2026-09-15 사용자 결정)으로 뒤따라 돌릴 검토는 아직 안 돈 단계로 싣는다.
663
665
 
@@ -730,7 +732,7 @@ MCP 가 찍는 요약 줄은 **옛 서식의 셈**만 읽는다(`genetics.mjs ou
730
732
  | 14a | 도판 — 도판 HTML·PNG · 일괄 판정 매니페스트 | `assets` 의 `role:"figure"` + `sections[].plates` · 작업 폴더 `plates.json` | 6 |
731
733
  | 15 | (브리핑) 판단 항목마다 물음 제목과 기한 · 둘째 할 일이면 「… 확인 요청」 · 두 길 대칭 한눈표 · 선택지 전치 행렬 · 의견 절 하나 · 바꾸는 길의 위험 · 회신 뒤 일정 | `open_items` · `sections[].tables` · `note` 절 넷 | 4·6 |
732
734
  | 16 | (옛 결정 브리핑을 고칠 때) `doc_type` 에 「브리핑」 — `brief_checks()` 경고가 켜진다 | `doc_type` | 0 |
733
- | 17 | (코드 작업을 녹이면) 원고 밖 상태 표 | 작업 폴더(발행 안 함) · 독자 검토 `args.state` | 4 |
735
+ | 17 | (코드 작업을 녹이면) 원고 밖 상태 표 | 작업 폴더(발행 안 함) | 4 |
734
736
 
735
737
  건드리지 않는 것: `build.py`·`gazette.py`·`gazette.css`·`sentbreak.py`·`boundary.py`.
736
738
  `render.py` 가 사본이 생기면 멈춘다(`FORKABLE`, 경위: `references/history.md` §1).
@@ -48,21 +48,21 @@
48
48
  | R11f 판단 항목 | 본문 ≤ 220자 네 문장 — 첫 문장은 기한, 상세는 건으로. 보고 모드 한정 — 결정 모드는 칸이 네 문장의 뜻을 진다(`due`·`options[].name` / `now`·이용자가 겪는 일 / `options[].what` / 대칭 표·`no_reply`) | gazette.py `text_scan`(자수 · 문장 수는 R12b) | ⚠ |
49
49
  | R11g 부연 | 한 문장에 괄호 부연 ≤ 1, 괄호 안 ≤ 20자(공백 제외). 숫자 나열은 문장이 아니라 표 | gazette.py `text_scan`(괄호 수 · 괄호 안 자수) · 숫자 나열은 사람 눈 | ⚠ |
50
50
  | R11h 과정 어휘 | 본문에 **진행 상태 어휘 0** — 「정해짐 · 회신 대기 · 남은 물음 · 정해진 것 · N판」, 개수로 상태를 세는 표 제목(「정해진 것 셋과 남은 것 하나」), 주체 없는 결정 명사(「정한 사항」·「결정된 사항」). 독자는 앞 회차·회신·판을 모른다. 정해진 것은 **사실**로 배경(요지)에 — 다만 결정권이 고객에게 있는 항은 고객이 정한 기록을 원고 밖에서 확인한 뒤에만(SKILL 3b 「결정 주체」). 결정 요청에는 **지금 열린 것만**, 회차는 `history` 에만. 원고는 직전 판의 차분이 아니라 독자의 0 상태에서 다시 쓴다(2026-09-11 「뒷 내용을 나는 알고 너는 알아도 독자는 모름」) | gazette.py `text_scan` · 결정 기록 확인은 사람 눈 | ⚠ |
51
- | R12 덩어리 층 | 글 층(R11)이 문장·칸 하나의 길이를 재면 이 층은 **덩어리**(※ 주석 · 판단 항목 · 표·흐름도 · 요청 장치 · 도판 출처 · 같은 항의 되풀이)의 **문장 수와 자릿수**를 잰다. 값은 R12a~g. 전부 ⚠ 이고 거절이 아니다(실사례 2026-09-11, 고객사 결정 브리핑 — 문장은 짧아졌는데 같은 항이 여러 자리에 되풀이돼 반려 · 2026-09-12 회신 없는 정황 보고 — 같은 건이 두 PART 에 문장만 바꿔 섬) | a·b·e gazette.py `text_scan` · c·d·f·g 없음 — 사람 눈(g 는 독자 검토 「구조」 관점도) | ⚠ · — |
51
+ | R12 덩어리 층 | 글 층(R11)이 문장·칸 하나의 길이를 재면 이 층은 **덩어리**(※ 주석 · 판단 항목 · 표·흐름도 · 요청 장치 · 도판 출처 · 같은 항의 되풀이)의 **문장 수와 자릿수**를 잰다. 값은 R12a~g. 전부 ⚠ 이고 거절이 아니다(실사례 2026-09-11, 고객사 결정 브리핑 — 문장은 짧아졌는데 같은 항이 여러 자리에 되풀이돼 반려 · 2026-09-12 회신 없는 정황 보고 — 같은 건이 두 PART 에 문장만 바꿔 섬) | a·b·e gazette.py `text_scan` · c·d·f·g 없음 — 사람 눈 | ⚠ · — |
52
52
  | R12a 표 주석 | `tables[].note`(※ 주석) ≤ **2문장** — 문장은 렌더러가 문장 블록을 세우는 판별(`boundary.py`)로 센다 — 날짜 마침표(「2026. 9. 30.」·「9. 8.」)는 경계가 아니다. R11a 의 문장 길이도 같은 분할이다. 셋째 문장부터 ⚠ | gazette.py `text_scan` | ⚠ |
53
53
  | R12b 판단 항목 문장 | `open_items[].body` ≤ **4문장**(R11f 의 「네 문장」과 같은 값 — 자수 220 은 R11f, 문장 수는 여기서 센다). 다섯째 문장부터 ⚠. 보고 모드 한정 | gazette.py `text_scan` | ⚠ |
54
54
  | R12c 표 하나 | 한 절에 **같은 행 키**(같은 항·같은 선택지를 행으로 세운) 표·흐름도 ≤ **1** | 없음 — 사람 눈 | — |
55
55
  | R12d 요청 장치 | `cta` 기본 **[]** — 결론 한 줄은 `notice.text` 의 몫(결정 모드는 `cta` 를 받지 않는다) | 없음 — 사람 눈 | — |
56
56
  | R12e 도판 출처 | 출처 줄(`assets[].source_text`)은 **원본 위치 한 구절** — 쪽·행·주소·건 §·부록 N 가운데 하나(R11c 의 40자 안). 캡처는 「화면 이름 · 날짜」가 위치다(「주문 목록 화면 · 8. 23.」) — 형식을 맞추려고 부록 N 을 붙이지 않는다. 결정 절처럼 건보다 앞에 서는 도판은 뒤 절 § 대신 규격이 실린 부록 N 을 가리킨다(뒤 절 § 는 R12h 에 걸린다). 제3자 자료에서 낸 도판은 그 한 구절로 독자가 원본에 닿아야 한다(주소, 또는 `source_url` 이 있는 건 §). `source_url` 은 도판에 그려지지 않으므로 대신하지 못한다. **제작 메타**(제작 도구·배율·자르기 좌표·스크립트 이름)와 결정 경로는 `origin`(렌더 안 됨)과 도판 HTML 머리 주석에만 적는다. **증거 범위**는 캡처·영상 캡션 끝 한 구절로 보인다 — 찍은 환경(독자가 부르는 이름)·기기·날짜·옮겨 적은 부분(「… · 운영 관리자 웹 · 8. 23. 촬영」·「… · 알림 문구는 옮겨 적음 — 합성」), 캡션 60자 안(R11c). 바깥 원본이 없는 우리 도안·흐름은 출처 줄을 비우고, 정직성은 캡션 끝 한 낱말(「— 도안」·「— 재현」)이 말한다 — AI 로 만든 합성 그림도 「— 도안」이고, 「— 합성」은 실제 캡처에 글자를 옮겨 적은 것에만 단다(R14). 그림 번호는 출처 줄에 쓰지 않는다(번호는 옮겨 다닌다). 기계는 두 가지를 센다 — 위치 없음은 `provider:"user-provided"`(파일로 싣는 합성 포함)만(W2 — 「화면·창·페이지 이름 + 날짜」 꼴도 위치로 친다), 제작 설명·그림 번호는 `role:"figure"` 전부의 출처 줄. 캡션은 안 본다 | gazette.py `text_scan`(W2 · 제작 메타) · 캡션 꼬리의 증거 범위와 캡션·부록의 노이즈는 사람 눈 | ⚠ |
57
57
  | R12f 되풀이 | **같은 항의 이름·기한**이 문서 전체에서 서는 자리 ≤ **3** — 네 자리부터는 되풀이 | 없음 — 사람 눈 | — |
58
- | R12g PART 사이 | 같은 사실(시각·금액·건 제목·핵심 명제)이 **두 PART** 에 서면 한쪽은 건 번호로 가리키기만 한다. 요지·대조표·건(같은 건의 세 배율)은 한 PART — 요청 없는 문서에서 「경과 / 원인」으로 가르지 않는다(process.md 「PART 를 먼저 가른다」). 두 절 `marg.key` 가 낱말만 다르고 같은 명제면 되풀이다 — 글자 비교로는 안 잡힌다. 요약면 수치·요지 lead 가 문서 전체를 줄여 말하는 것은 예외(요지 문단이 건을 하나씩 옮겨 적으면 예외 아님). 실사례 2026-09-12: PART I 사실 27개 중 21개가 PART II 에 다시 섬, dry_run 경고 0 | 없음 — 독자 검토 「구조」 관점 · 사람 눈(렌더러 ⚠ 는 제안 단계) | — |
59
- | R12h 선참조 | 앞 절이 **뒤 절**을 가리키지 않는다(결정 모드는 번호 대신 이름 고리라 W5 가 돌지 않는다) — 요지 문단·판단 항목 본문의 `§n.n`(근거는 `refs[]` 로만 — 「해당 절」·「근거」 단추가 되므로 뜀이 아니다), 흐름도 「건」 열의 뒤 절 건 번호, 도판 출처 줄의 뒤 절 `§`, 「NN절」 낱말(남의 문서의 절 번호 「검수 보고 4차 제5절」처럼 「N차 … 제N절」 꼴은 이 문서의 뒤 절이 아니라 세지 않는다 — 2026-09-15). 낱말·규칙·예시 선언은 **첫 등장 자리에서 한 구절**(부록·앞 회차 보고에만 두지 않는다). 뒤 절이 앞 절을 되짚는 방향만 허용. 되풀이 금지(R12g)와 다른 축이다 — 되풀이를 빼되 그 자리에서 뜻이 서게 하는 한 구절은 남긴다. 실사례 2026-09-14 고객사 3차 보고 「읽다가 시험보는 줄 알 것 같음」: 2판 교차 참조 62 → 순서를 고친 3판에도 선형 읽기 뜀 지점 45(정의가 부록·원고 밖 / 앞 절의 뒤 절 번호) → 4판 0 | gazette.py `text_scan`(W5 — 절 i 의 산문(이름·부제·도입문·문단·표·흐름도 좌표·칸·여백 주석·같은 그룹의 건·판단 항목·강조문·도판 캡션·출처 줄)에서 앞 숫자가 i 보다 큰 `§n.n`·「NN절」을 센다. `summary[]`·`refs[]` 는 안 센다. 본보기 두 벌의 뒤 절 참조 10곳과 서식 문서 §12.5b 를 같은 날 같이 고쳤다) · 정의 위치(①)는 독자 검토 「선형 읽기」 관점(`reader-review.workflow.js` linear, jumps 0 목표) · 사람 눈 | ⚠ · — |
58
+ | R12g PART 사이 | 같은 사실(시각·금액·건 제목·핵심 명제)이 **두 PART** 에 서면 한쪽은 건 번호로 가리키기만 한다. 요지·대조표·건(같은 건의 세 배율)은 한 PART — 요청 없는 문서에서 「경과 / 원인」으로 가르지 않는다(process.md 「PART 를 먼저 가른다」). 두 절 `marg.key` 가 낱말만 다르고 같은 명제면 되풀이다 — 글자 비교로는 안 잡힌다. 요약면 수치·요지 lead 가 문서 전체를 줄여 말하는 것은 예외(요지 문단이 건을 하나씩 옮겨 적으면 예외 아님). 실사례 2026-09-12: PART I 사실 27개 중 21개가 PART II 에 다시 섬, dry_run 경고 0 | 없음 — 사람 눈(렌더러 ⚠ 는 제안 단계) | — |
59
+ | R12h 선참조 | 앞 절이 **뒤 절**을 가리키지 않는다(결정 모드는 번호 대신 이름 고리라 W5 가 돌지 않는다) — 요지 문단·판단 항목 본문의 `§n.n`(근거는 `refs[]` 로만 — 「해당 절」·「근거」 단추가 되므로 뜀이 아니다), 흐름도 「건」 열의 뒤 절 건 번호, 도판 출처 줄의 뒤 절 `§`, 「NN절」 낱말(남의 문서의 절 번호 「검수 보고 4차 제5절」처럼 「N차 … 제N절」 꼴은 이 문서의 뒤 절이 아니라 세지 않는다 — 2026-09-15). 낱말·규칙·예시 선언은 **첫 등장 자리에서 한 구절**(부록·앞 회차 보고에만 두지 않는다). 뒤 절이 앞 절을 되짚는 방향만 허용. 되풀이 금지(R12g)와 다른 축이다 — 되풀이를 빼되 그 자리에서 뜻이 서게 하는 한 구절은 남긴다. 실사례 2026-09-14 고객사 3차 보고 「읽다가 시험보는 줄 알 것 같음」: 2판 교차 참조 62 → 순서를 고친 3판에도 선형 읽기 뜀 지점 45(정의가 부록·원고 밖 / 앞 절의 뒤 절 번호) → 4판 0 | gazette.py `text_scan`(W5 — 절 i 의 산문(이름·부제·도입문·문단·표·흐름도 좌표·칸·여백 주석·같은 그룹의 건·판단 항목·강조문·도판 캡션·출처 줄)에서 앞 숫자가 i 보다 큰 `§n.n`·「NN절」을 센다. `summary[]`·`refs[]` 는 안 센다. 본보기 두 벌의 뒤 절 참조 10곳과 서식 문서 §12.5b 를 같은 날 같이 고쳤다) · 정의 위치(①)는 사람 눈 | ⚠ · — |
60
60
  | R13 캡처 틀 문법 | 캡처를 품은 **틀**을 선언 없이 찾는다 — img 에서 위로 올라가며 테두리가 보이는 첫 조상(자기 포함), 없으면 가장 바깥 overflow 자르개, 그것도 없으면 img 자신(`figure.mjs` `frameOf`). 틀이 둘 이상이면 「비교 컷」이다. 값은 R13a~d. 틀이 하나뿐인 도판(번호 표식 캡처·합성 한 장)에는 R13a 의 가로세로비·R13b·R13c 만 선다. 알려진 한계: 칩 이름표까지 품은 카드에 테두리를 두르면 그 카드가 틀로 잡혀 칩 글자가 R13b 로 걸린다 — 테두리는 캡처 상자에 둔다 | figure.mjs | a·b·c ✗ · d ⚠ |
61
61
  | R13a 좌우 같은 틀 | 비교 틀은 **좌우로 나란히** 선다 · 나란한 틀의 높이 차·폭 차 ≤ `R13.heightTol`·`widthTol`(2px) · 이미지 배율 차 ≤ 1% · 가로세로비 왜곡 ≤ 1%(왜곡은 틀 하나여도). 칸 폭 = (표시 폭 − 좌우 여백×2 − 사이) ÷ 2 — 숫자는 `PAIR`(전폭 `wide` · 본문 단 `column`)가 정본이고 `pair.mjs` 가 그대로 쓴다. 틀 높이는 두 칸 중 큰 쪽, 짧은 쪽은 흰 여백 — 늘리거나 따로 잘라 맞추지 않는다. 예외: 모든 틀이 가로 띠(폭 ≥ 높이×3)이고 같은 폭이면 위아래 허용 | figure.mjs · pair.mjs | ✗ |
62
62
  | R13b 틀 안 글자 0 | 틀 안(틀의 자손이거나 글리프 중심이 틀 안)에 HTML 글자 **0**. 빈 자리는 회색 점선이 말하고, 이름은 틀 위 칩(R13d)이 말한다. 예외는 원 번호 한 글자(①~⑳ — 읽는 순서) | figure.mjs | ✗ |
63
63
  | R13c 표식 색 | 틀 안 표식은 **검정 실선** = 있는·바뀔 자리, **회색 점선** = 빠진 자리, **원 번호** = 읽는 순서만(이름표로 쓰지 않는다). 틀 안 유채색 표식(배경·테두리·원 번호 글자색) 0 — 유채색은 캡처 틀이 없는 상태 개념도에만. 캡처에 구워 넣은 배지는 기계가 못 보므로 `shot.mjs` 기본값(검정 원·흰 링)이 집행자다 | figure.mjs · shot.mjs 기본값 | ✗ |
64
- | R13d 칩 이름표 | 비교 틀마다 틀 위(64px 안)에 **밝은 무채색 칩** 하나 — 칩 글자는 문서가 그 대상을 부르는 이름 그대로(기본 「그대로 두면」/「바꾸면」, 한눈표가 없으면 캡션의 이름). 칩 없음·검정·유채색 ⚠. `--caption "…"` 을 주면 칩 글자가 캡션에 없을 때 ⚠(alt·origin 은 대조 안 함). 칩 문구의 뜻과 도판 사이 대칭(선택지마다 같은 촬영 규격·같은 틀인가)은 기계가 못 가른다 | figure.mjs · 독자 검토 「도판」 관점 · 사람 눈 | ⚠ |
65
- | R14 관찰 주장 ↔ 독자가 볼 증거 | 화면·흐름·화면 문구·동작을 말하는 문장(관찰 주장)은 그 건·절에 **독자가 볼 증거**가 있어야 한다 — 실제 캡처·녹화·원문 인용·외부 문서, 또는 그 증거를 가리키는 `{{그림:id}}`. 센 대상이 있는 표는 수·대조 결과의 증거다 — 표는 우리가 옮겨 적은 글이라 화면 주장의 증거로는 렌더러가 치지 않고, 표로만 받친 화면 주장의 ⚠ 곳 수는 승인 물음에 싣는다(`lim-portal-format.md` §10 통과 기준 표). 도안(캡션 「실제 화면 아님」·「— 도안」·「— 재현」, AI 로 만든 합성 그림)은 설명이지 증거가 아니고, 「— 합성」(실제 캡처 일부 + 옮겨 적은 글자)은 증거다. 도판 갈래는 렌더러가 `role`·캡션·`provider`·`origin`·출처 줄로 가린다 — 캡션의 도안 표지가 먼저이고, 찍은 낱말(촬영·캡처·녹화·스크린샷·실기기·시뮬레이터 …)이 캡처를 가른다(순서와 낱말 목록은 `lim-portal-format.md` §10-1). 증거가 없으면 찍어 싣거나, 우리가 안 본 것이면 남은 것 칸으로 옮긴다. 헤지(「화면 미확인」·「(확인 전)」·「코드상」)와 확인 방법 끝 「…에서 봄」은 증거가 아니라 경고를 지우지 못한다 — 그 꼬리 한 줄이 캡처 대신 경고를 지우는 싼 길이 되기 때문이다. 그래서 볼 자리가 독자 자기 화면뿐인 확인 방법(SKILL 1·2단계 정의에 맞는 꼴)도 ⚠ 가 남고, 그 수는 공개·교체 승인 물음에 싣는다(SKILL 체크리스트 10단계). 건에 실물이 있어도 도안 토큰(도해·흐름도 포함)만 가리킨 문장과 「코드상·코드로 봄·설계상」처럼 화면 밖 근거를 스스로 밝힌 문장은 그 문장대로 센다. 관찰 주장으로 치지 않는 것: 확인 안 했음을 말하는 문장(「…보이는지는 확인하지 않았음」 — 단정 뒤에 붙인 고백 「…보임 — 화면은 확인하지 않았음」·「…나타나지만 실기기는 보지 않았음」은 센다) · 「수 있음·수 없음」 가능성 문장 · 표 칸(확인 프로필·조건표·계획처럼 기대 결과라 실물이 있을 수 없다). 「…나타나는 것까지 확인함」처럼 화면·동작을 품은 우리 확인 기록은 관찰 주장이다 | gazette.py `evidence_scan`(건 다섯 칸 · 절 문단·흐름도 칸 — 도안 밖 도판·원문 인용·그 가리킴·원문을 말한 문장의 건 원본 링크를 증거로 센다) · gazette.py `plate_scan`(캡처 갈래 도판의 실린 바이트가 긴 변 300px·짧은 변 100px 미만이면 자리 표시) · 표가 받치는 수·대조 주장과, 그 증거가 그 주장을 보이는지는 독자 검토 증거 가시성(visual-first §7)과 사람 눈 | ⚠ |
64
+ | R13d 칩 이름표 | 비교 틀마다 틀 위(64px 안)에 **밝은 무채색 칩** 하나 — 칩 글자는 문서가 그 대상을 부르는 이름 그대로(기본 「그대로 두면」/「바꾸면」, 한눈표가 없으면 캡션의 이름). 칩 없음·검정·유채색 ⚠. `--caption "…"` 을 주면 칩 글자가 캡션에 없을 때 ⚠(alt·origin 은 대조 안 함). 칩 문구의 뜻과 도판 사이 대칭(선택지마다 같은 촬영 규격·같은 틀인가)은 기계가 못 가른다 | figure.mjs · 사람 눈 | ⚠ |
65
+ | R14 관찰 주장 ↔ 독자가 볼 증거 | 화면·흐름·화면 문구·동작을 말하는 문장(관찰 주장)은 그 건·절에 **독자가 볼 증거**가 있어야 한다 — 실제 캡처·녹화·원문 인용·외부 문서, 또는 그 증거를 가리키는 `{{그림:id}}`. 센 대상이 있는 표는 수·대조 결과의 증거다 — 표는 우리가 옮겨 적은 글이라 화면 주장의 증거로는 렌더러가 치지 않고, 표로만 받친 화면 주장의 ⚠ 곳 수는 승인 물음에 싣는다(`lim-portal-format.md` §10 통과 기준 표). 도안(캡션 「실제 화면 아님」·「— 도안」·「— 재현」, AI 로 만든 합성 그림)은 설명이지 증거가 아니고, 「— 합성」(실제 캡처 일부 + 옮겨 적은 글자)은 증거다. 도판 갈래는 렌더러가 `role`·캡션·`provider`·`origin`·출처 줄로 가린다 — 캡션의 도안 표지가 먼저이고, 찍은 낱말(촬영·캡처·녹화·스크린샷·실기기·시뮬레이터 …)이 캡처를 가른다(순서와 낱말 목록은 `lim-portal-format.md` §10-1). 증거가 없으면 찍어 싣거나, 우리가 안 본 것이면 남은 것 칸으로 옮긴다. 헤지(「화면 미확인」·「(확인 전)」·「코드상」)와 확인 방법 끝 「…에서 봄」은 증거가 아니라 경고를 지우지 못한다 — 그 꼬리 한 줄이 캡처 대신 경고를 지우는 싼 길이 되기 때문이다. 그래서 볼 자리가 독자 자기 화면뿐인 확인 방법(SKILL 1·2단계 정의에 맞는 꼴)도 ⚠ 가 남고, 그 수는 공개·교체 승인 물음에 싣는다(SKILL 체크리스트 10단계). 건에 실물이 있어도 도안 토큰(도해·흐름도 포함)만 가리킨 문장과 「코드상·코드로 봄·설계상」처럼 화면 밖 근거를 스스로 밝힌 문장은 그 문장대로 센다. 관찰 주장으로 치지 않는 것: 확인 안 했음을 말하는 문장(「…보이는지는 확인하지 않았음」 — 단정 뒤에 붙인 고백 「…보임 — 화면은 확인하지 않았음」·「…나타나지만 실기기는 보지 않았음」은 센다) · 「수 있음·수 없음」 가능성 문장 · 표 칸(확인 프로필·조건표·계획처럼 기대 결과라 실물이 있을 수 없다). 「…나타나는 것까지 확인함」처럼 화면·동작을 품은 우리 확인 기록은 관찰 주장이다 | gazette.py `evidence_scan`(건 다섯 칸 · 절 문단·흐름도 칸 — 도안 밖 도판·원문 인용·그 가리킴·원문을 말한 문장의 건 원본 링크를 증거로 센다) · gazette.py `plate_scan`(캡처 갈래 도판의 실린 바이트가 긴 변 300px·짧은 변 100px 미만이면 자리 표시) · 표가 받치는 수·대조 주장과, 그 증거가 그 주장을 보이는지는 사람 눈 | ⚠ |
66
66
 
67
67
  ## 2. 사람 눈이 보는 것 (기계가 못 잰다)
68
68