genetics-mcp 2.18.0 → 2.18.2

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 (27) hide show
  1. package/bin/aarch64-apple-darwin/gcell +0 -0
  2. package/bin/manifest.json +2 -2
  3. package/bin/x86_64-apple-darwin/gcell +0 -0
  4. package/package.json +1 -1
  5. package/skills/genetics-report/SKILL.md +143 -134
  6. package/skills/genetics-report/assets/example/cases-briefing-designs.json +34 -0
  7. package/skills/genetics-report/assets/example/cases-briefing.json +4 -2
  8. package/skills/genetics-report/assets/example/plate-pair-after.png +0 -0
  9. package/skills/genetics-report/assets/example/plate-pair-before.png +0 -0
  10. package/skills/genetics-report/assets/example/plate-pair.html +25 -0
  11. package/skills/genetics-report/assets/example/report-briefing-designs.json +744 -0
  12. package/skills/genetics-report/assets/example/report-briefing.json +30 -24
  13. package/skills/genetics-report/assets/example/report.json +4 -4
  14. package/skills/genetics-report/assets/figure.mjs +390 -63
  15. package/skills/genetics-report/assets/mockshot.mjs +3 -2
  16. package/skills/genetics-report/assets/pair.mjs +138 -0
  17. package/skills/genetics-report/assets/shot.mjs +87 -19
  18. package/skills/genetics-report/references/content-pipeline.md +34 -33
  19. package/skills/genetics-report/references/edition-review.workflow.js +49 -0
  20. package/skills/genetics-report/references/history.md +121 -0
  21. package/skills/genetics-report/references/illustrations.md +16 -12
  22. package/skills/genetics-report/references/lim-portal-format.md +179 -93
  23. package/skills/genetics-report/references/linear-read-test.workflow.js +47 -0
  24. package/skills/genetics-report/references/process.md +141 -91
  25. package/skills/genetics-report/references/readability.md +46 -23
  26. package/skills/genetics-report/references/reader-review.workflow.js +157 -29
  27. package/skills/genetics-report/references/visual-first.md +95 -34
@@ -28,16 +28,35 @@ version: "4.0.0"
28
28
  이 둘은 같은 사실을 다루지만 완전히 다른 문서입니다. 이 스킬의 본체는
29
29
  **무엇을 빼고 무엇을 고쳐 쓰는가**(내용 설계)이고, 전달 형태는 그 다음입니다.
30
30
 
31
- ## 렌더러는 레포에 하나뿐이다 (2026-08-18)
32
-
33
- `assets/` 에 `build.py`·`report.css`·`palette.py`·`editor.js` 사본이 있었고 **지웠다.**
34
-
35
- 커밋 `f1a2725`(08-13) 가 SSOT 를 레포로 옮겼는데 옛 사본을 안 지웠다. 그 뒤 레포만
36
- 나흘 자라(20,361 → 51,754B · 887줄 차이) **이 스킬로 만든 고객 문서에 브랜드 서식이
37
- 통째로 빠졌다** — `cover-frame`·`ch-head`·`cindex`·`eof-endcard`·`Spoqa` 가 전부 0회.
38
- `lim-report.css` 는 스킬에 존재하지도 않았다. 둘을 대조하는 관문이 없어 아무도 몰랐다.
39
-
40
- **여기에 렌더러 파일을 다시 두지 마라.** `render.py` 가 그걸 감지하면 멈춘다.
31
+ ## 작업 체크리스트 — 단계 번호의 정본
32
+
33
+ 밟는 순서는 이 표 한 장이다. 이 스킬의 「N단계」는 모두 이 표의 번호다 — 단계마다 무엇을 쓰고 판단하는지는 `references/process.md`.
34
+ 행을 건너뛰면 그 행의 산출물이 없다는 뜻이다. 못 밟았으면 까닭을 핸드오프에 적는다. 「집행자」가 「사람」인 행은 기계가 막지 않는다.
35
+
36
+ | 단계 | 산출물 | 돌릴 명령 | 통과 기준 | 집행자 | 사용자에게 묻는 것 |
37
+ |---|---|---|---|---|---|
38
+ | 0 독자 | 독자 문장 1줄 + 할 일 목록(작업 메모) | — | 누가 · 무엇을 하나 · 무엇을 언제까지 정하나가 문장으로 섬 | 사람 — 사용자 확인 | **반드시** 0단계 물음 1~3 · FCG 의견을 낼지 |
39
+ | 0a 결정 장부 | 작업 폴더 `decisions.json`(발행 안 함) | — | 원고에 「정해진 것」으로 쓸 항마다 결정권 · 정한 주체 · 기록 · 확인 여부가 참 | 사람 눈 · 독자 검토 facts 관점(`args.decisions`) | 0단계 물음 4 — 미확인 항을 한 번에 |
40
+ | 0.5 시각 설계 | 절마다 시각 장치 · 예시 한 명 · 용어 잠금 표 | — | 0.5단계 표 1~6행이 정해짐 | 사람 눈 · 렌더러 ⚠(`lim-portal-format.md` 「10-1. 시각 우선 관문」) | 화면 변화가 따르면 도안으로 결재받을지 |
41
+ | 1·2 자료·건 | `cases.json` | — | 건마다 다섯 칸 · 근거 없는 칸은 「확인 필요」 | 서버 발행 검증(그룹 정합) · 사람 | 원자료 범위 · 고객이 아는 참조 · 「확인 필요」 칸 |
42
+ | 3 등급 | `grades` · 건별 `grade` | — | 4단 이하 · 최약 등급이 기본 | 사람 | 등급 이름·개수 |
43
+ | 4~6 원고 | `report.json` · 코드 작업을 녹이면 원고 밖 상태 표(반드시 지키는 것 3) | — | 요약 근거 · 요지 칸 수(4~6단계) · 절마다 `marg` | 서버 요약 근거 게이트(거절) · 사람 | 공통 원인이 실재하는가 |
44
+ | 6 도판 굽기 | 도판 HTML → PNG · `plates.json` | `node assets/figure.mjs --batch plates.json --report report.json` · 두 칸 비교는 `shot.mjs --after` → `pair.mjs` | exit 0(✗0 · 합계 400,000B 안) | `figure.mjs` R0~R10·R13 · `pair.mjs` · 칩 문구의 뜻은 사람 눈 | — |
45
+ | 7 로컬 렌더 | 단일 HTML | `python3 assets/render.py report.json` | ⚠0 · `forbid` 적중 0 | `gazette.py` `text_scan()`·`brief_checks()`·`tally_scan()` · `build.py guard()` | — |
46
+ | 7 dry_run | 경고 목록 | `publish_report`/`update_report` 에 `dry_run: true` | 작성자가 고칠 수 있는 ⚠0 — 못 없애는 경고는 까닭을 핸드오프에 | `report_publish.php report_build_checked()`(렌더러·입고·그림·문체) · 경고 기준선 대조는 사람 | — |
47
+ | 7 독자 검토 | 워크플로 결과(`merged`·`questions`·`dropped`) | `references/reader-review.workflow.js`(0.5단계 7행) · 구조를 안 바꾼 낱말 손질 판은 `references/edition-review.workflow.js`(결과 `kept`·`weak`) | 사실 틀림 반영 · 「⚠ 도판 N장 미열람」 없음 · 반영 뒤 로컬 렌더·dry_run 다시 | 워크플로 관점 + JS 거름 · `questions`·`dropped` 는 사람 | `questions[]` |
48
+ | 7 조판 검사 | 검사기 출력 | `gazette-report` 검사기 8종(단일 HTML 전달일 때) | 각 0건 · **표본 수를 함께 본다**(0표본 통과는 통과가 아니다) | 검사기 — 실행법은 `gazette-report` 스킬 | — |
49
+ | 7 사람 눈 | — | 인쇄 미리보기까지 연다 | `references/process.md` 「7단계 — 검수」 사람의 눈 표 | 사람 | — |
50
+ | 8 초안 발행·수정 | 초안 링크 | 새 문서 `publish_report` · 고치면 8단계 「수정 절차」 | 같은 링크 · 사람이 고친 초안을 모르고 덮지 않음 | 사람 — `update_report` 에 `body_rev` 잠금 칸이 아직 없음 | 사람이 고친 초안이면 덮어도 되는가 |
51
+ | 9 발행 뒤 대조 | 블록 목록 | `get_report(id, outline: true)` | `aside.marg` 수 = 절 수 · 옛 서식 블록 0 · 빈 블록 0 | 사람(블록 목록을 읽음) — 대조 기계 없음 | — |
52
+ | 9 열람 확인 | 캡처 | 열람 주소를 연다 | 칩·굵게·링크가 원문 글자가 아니라 서식으로 섬 · 도판 쌍·판단 절이 섬 | 사람 눈 — 못 열면 까닭을 핸드오프에 | — |
53
+ | 10 공개 직전 날짜 | `report.json` | `update_report` 한 번(날짜만 고치는 이 판은 독자 검토 없이 로컬 렌더·dry_run 만) | 작성일 세 자리가 한 값이고 공개하는 날(3c) | `gazette.py` `date_scan()` ⚠(세 자리가 다르면) · 공개하는 날인지는 사람 | 공개일 |
54
+ | 10 공개 | 공개된 링크 | `release_report(id)` | 사용자 승인 | 사람(승인 행위) | **반드시** 공개 승인 |
55
+
56
+ ## 렌더러는 레포에 하나뿐이다
57
+
58
+ `assets/` 에 렌더러 사본(`build.py`·`report.css`·`palette.py`·`editor.js`)을 **다시 두지 마라.** `render.py` 가 그걸 감지하면 멈춘다.
59
+ 사본을 두면 레포만 자라 고객 문서에서 서식이 조용히 빠진다(경위: `references/history.md` §1).
41
60
  고칠 것은 레포(`private/builder/`)에서 고치고 배포한다.
42
61
 
43
62
  ## 전달 경로 — 먼저 고른다
@@ -75,17 +94,21 @@ version: "4.0.0"
75
94
  `~함 / ~했음 / ~임`. **상대에게 말 거는 자리는 하십시오체**
76
95
  `~하여 주시기 바랍니다 / ~부탁드립니다 / ~하겠습니다`. 자세한 것은 아래 5·5a.
77
96
  경어체 `습니다|십시오|합니다|입니다|됩니다|주세요` 0건은 **기록 자리에만** 거는 기준이다.
78
- - ⚠ **톤 게이트는 경고이지 거절이 아니다.** `lib/report_tone.php` 가 `dry_run` 경고로 셀 뿐
79
- 발행을 막지 않는다 — 실측(2026-09-11): 경어체 경고를 안은 `update_report` 2회 모두 발행 성공.
80
- **요청 자리에서 나는 경어체 경고는 의도된 것이므로 고치지 않는다**(`references/visual-first.md` §8).
81
- 이 경고를 하드 규칙으로 오인해 종결을 비튼 것이 2026-09-02부터 **네 번 반복된 반려의 원인**이다.
82
- - `tenant` 는 키가 가리키는 고객사와 일치해야 한다(오발행 방지 가드). 값은 소속처 slug 우선·이름 폴백 — 아래 :228 의 `slug` 는 **보고서** slug 라 다른 것이다.
97
+ - ⚠ **톤 게이트는 경고이지 거절이 아니다.** `report_tone.php report_tone_warnings()` 가 `dry_run` 경고로 셀 뿐 발행을 막지 않는다.
98
+ 서버는 요청 자리(`open_items` 본문·`cta`·판권지 `note`·`asks` 절 여백 주석)와 「」 인용을 안 세고, 로컬 `tone.mjs` 는 판단 항목 본문과 「」 인용만 뺀다.
99
+ ⚠ **서버 쪽 자리 가림과 2026-09-14 에 더한 렌더러 ⚠ 행들은 운영 반영 확인 전이다** — 배포 전의 운영 `dry_run` 은 옛 셈으로 돌아 요청 자리에서도 경어체를 세고 새 행은 안 뜬다.
100
+ 그때 뜬 요청 자리 경어체 경고는 **의도**이므로 자리를 확인하고 넘긴다(`lim-portal-format.md` §10 통과 기준 표). 그 전까지 새 행의 유일한 기계 그물은 로컬 `render.py` 다.
101
+ 그래서 남는 경어체 경고 가운데 PART I 간지의 요청 문장(두 경로)과 로컬의 `cta`·판권지 회신 안내는 **의도된 것이므로 고치지 않는다**.
102
+ 이 경고를 하드 규칙으로 오인해 종결을 비튼 것이 **네 번 반복된 반려의 원인**이다(경위: `references/history.md` §5).
103
+ - `tenant` 는 키가 가리키는 고객사와 일치해야 한다(오발행 방지 가드). 값은 소속처 slug 우선·이름 폴백 — 8단계의 `slug` 는 **보고서** slug 라 다른 것이다.
83
104
  - `sections[].kind` 는 `summary|status|cases|asks|note` 다섯 가지뿐 — 그 밖의 값은 절이 통째로 사라지므로 서버가 거절한다.
84
105
  - `cases[].grade` 는 `grades` 에 정의된 이름이어야 한다.
85
106
  - **`update_report` 는 같은 주소를 덮어쓴다** — 이미 고객에게 나간 링크가 새 내용을 가리키므로, 발행 후 수정은 재발행이 아니라 update 로 한다. 기존 문서는 `list_reports`/`get_report` 로 받아 고쳐 되돌려 보낸다.
86
107
  - **그림 계약**: `update_report` 에서 `assets` 를 **빼고** 보내면 서버가 저장된 그림을 그대로 유지한다. 전부 지우려면 `assets: []` 를 명시하고 `sections[].plates`·`chapters[].asset` 에서도 그 id 를 빼야 한다 — 가리키는 곳이 없는 id 는 422. 한 장만 바꾸려면 그 id 에 새 `source`/`file`, 나머지는 `get_report` 가 준 표식 그대로.
87
- - 초안 상태로 올려 두고 다듬어도 된다(발행이 막히지 않는다). 단, 고객에게 링크를 보내기 전에 완성할 것.
88
- - 내용 설계 규칙(아래 0~2단계, 고객 언어 치환, 카피 게이트)은 **전달 경로와 무관하게 동일하게** 적용된다 — 서버가 렌더한다고 해서 원고 품질 단계를 건너뛰지 않는다.
108
+ - 초안 상태로 올려 두고 다듬어도 발행은 막히지 않는다. 단 초안 `update_report` 도 **본문 판(`body_rev`)** 을 올리고 사용자가 그 판을 읽으므로 **독자 검토를 통과한 본문 판만 올린다** — 다듬는 중간 판은 로컬 렌더·dry_run 으로 본다.
109
+ ⚠ **운영 반영 확인 전 — 운영 서버는 초안에 `update_report` 를 보내면 그 순간 공개로 바꾼다**(저장된 공개일이 비었으면 오늘로 채운다, 수리는 레포 main 에만 있다). 배포 전까지 초안은 `dry_run` 으로만 다듬고, 굳은 뒤 `publish_report` 한 번 → 사람 확인 → `release_report`. 이미 썼으면 `list_reports` 대괄호가 「데이터로 발행된 문서」인지 보고 `unpublish_report(id)` 로 되돌린다 — 교체 응답 문구(「이미 나간 열람 링크가 그대로…」)는 초안에도 같아 그것만으로는 못 가른다. 결정 브리핑 한 편이 첫 교체로 공개돼 여러 판을 고치는 엿새 동안 열려 있었다(2026-09-09~15).
110
+ **발행 이력 행(`history`)은 다른 것이다** — 공개 전 수정은 이력 행을 만들지 않는다(3c).
111
+ - 내용 설계 규칙(아래 0~3단계, 고객 언어 치환, 카피 게이트)은 **전달 경로와 무관하게 동일하게** 적용된다 — 서버가 렌더한다고 해서 원고 품질 단계를 건너뛰지 않는다.
89
112
 
90
113
  단일 HTML 산출물의 성질:
91
114
 
@@ -107,11 +130,11 @@ version: "4.0.0"
107
130
  |---|---|---|
108
131
  | 판정한다 (검수·회신·결재) | 요청 / 경과 / 잔여 | `asks` → `summary` → `status` → `cases` → `note` |
109
132
  | **배운다** (유지보수·인수·온보딩·사후분석) | 원리 / 붕괴와 처방 / 적용과 남은 것 | 같은 다섯 kind 를 그 순서로 쓴다 |
110
- | **결정한다** (도입 여부·옵션 선택·예산·일정) | 결정 / 근거 / 이행 | `asks` → `summary` → `note`(선택지 전치 행렬) → `cases` → `note`(FCG 의견 표 한 장) → `note`(바꾸는 길의 위험) → `note`(회신 뒤 일정) |
133
+ | **결정한다** (도입 여부·옵션 선택·예산·일정) | 결정 / 근거 / 이행 | `asks`(결정 물음 + 둘째 할 일이 있으면 「… 확인 요청」) → `summary` → `note`(선택지 전치 행렬) → `cases` → `note`(FCG 의견 표 한 장 — 절 이름에 「의견」을 넣는다, W1 이 세지 않는 조건. 다른 절·건 행 이름에는 「의견」을 쓰지 않는다) → `note`(바꾸는 길의 위험) → `note`(회신 뒤 일정) |
111
134
 
112
135
  **회신·결정이 없는 정황 공유 보고는 판정한다 뼈대에서 요청 PART 만 뺀다.** PART 는 「경과 / 남은 것」이고,
113
136
  요지·대조표·건은 경과 PART 하나에 함께 선다(`references/process.md` 「PART 를 먼저 가른다」).
114
- 절의 성격(시각표·원인·앞날)으로 PART 를 새로 짓지 않는다 — 「경과 / 원인」으로 가르면 같은 건이 두 PART 에 문장만 바꿔 선다(실사례 2026-09-12).
137
+ 절의 성격(시각표·원인·앞날)으로 PART 를 새로 짓지 않는다 — 「경과 / 원인」으로 가르면 같은 건이 두 PART 에 문장만 바꿔 선다(경위: `references/history.md` §9).
115
138
  독자가 결정권자면 `status` 대조표를 빼고 요약면 상태 막대만 남긴다(`references/process.md` 「이 답에서 곧바로 정해지는 것」).
116
139
 
117
140
  결정한다 모드에 「하지 않기로 한 것」 절은 **따로 두지 않는다** — 선택지 표의 「정할 자리」·「다시 볼 때」 행이
@@ -125,9 +148,8 @@ version: "4.0.0"
125
148
  `kind:"lesson"` 같은 것은 **없다.** 서버가 발행 단계에서 거절한다.
126
149
  가르치는 문서도 다섯 kind 로 푼다 — 자세한 것은 `references/lim-portal-format.md` §12.
127
150
 
128
- 가르치는 문서에서 검수 뼈대에 스타일만 입히는 것은 반려된 실패 사례다.
129
- **부분마다 좋아졌는데 전체는 그대로였다** — 심슨의 역설이다.
130
- 독자 정의(0단계) 직후 PART 구성부터 정하고, **절 구성이 확정되기 전에 문구를 다듬지 않는다.**
151
+ 가르치는 문서를 검수 뼈대에 스타일만 입혀 내지 않는다 — 독자 정의(0단계) 직후 PART 구성부터 정하고,
152
+ **절 구성이 확정되기 전에 문구를 다듬지 않는다**(경위: `references/history.md` §11).
131
153
 
132
154
  ## 트리거 키워드
133
155
 
@@ -140,7 +162,7 @@ Lim 보고서, Lim 에 올려줘, 고객 보고서, 수정 내역, 검수 요청
140
162
 
141
163
  ## 0단계 — 독자를 먼저 못 박는다 (건너뛰지 말 것)
142
164
 
143
- **이 스킬에서 유일하게 반드시 사용자에게 확인해야 하는 것.** 나머지는 스스로 판단해도 된다.
165
+ **이 스킬에서 반드시 사용자에게 확인해야 하는 것은 이 단계와 공개 승인(10단계) 둘이다.** 나머지는 스스로 판단해도 된다.
144
166
 
145
167
  물어볼 것:
146
168
 
@@ -149,6 +171,8 @@ Lim 보고서, Lim 에 올려줘, 고객 보고서, 수정 내역, 검수 요청
149
171
  3. **읽고 나서 무엇을 결정하는가** — 선택지는 무엇이고, 선택지마다 무엇이 달라지는가, **언제까지** 정해야 하는가.
150
172
  **FCG 의견을 낼지는 따로 묻는다** — 내면 한 절 한 자리.
151
173
  (「결정한다」 모드에서는 필수. 답이 「특별히 결정할 것은 없다」면 그 문서는 브리핑이 아니라 보고다.)
174
+ 4. **이미 정해진 것은 무엇이고, 누가·어디서 정했는가** — 작업 폴더 `decisions.json`(발행 안 함)에 항 · 내용 · 결정권(고객/FCG) · 정한 주체 ·
175
+ 기록(회신 원문·회의록·결정문의 이름과 날짜) · 사용자 확인 여부를 적는다(체크리스트 0a). 미확인 항은 원고에 쓰기 전에 **한 번에** 묻는다. 쓰는 법은 3b 「결정 주체」.
152
176
 
153
177
  독자가 정해지면 나머지가 전부 따라 정해진다. 같은 사실이 이렇게 갈린다.
154
178
 
@@ -163,65 +187,54 @@ Lim 보고서, Lim 에 올려줘, 고객 보고서, 수정 내역, 검수 요청
163
187
  | "회귀 테스트 2건 추가" | "같은 문제가 다시 나타나면 걸러지도록 상시 점검 **적용**" |
164
188
  | "RN 앱 토큰 부활 경합" | "로그아웃 직후 이전 로그인 상태로 되돌아가던 **상황**" |
165
189
  | "인증서를 설치해 주셔야 합니다" | "인증서 설치 **필요**" |
166
- | 티켓 번호 `1217296144360763` | (싣지 않는다. 고객이 아는 참조는 본인이 제보한 원본 링크뿐) |
190
+ | 티켓 번호(16자리 숫자) | (싣지 않는다. 고객이 아는 참조는 본인이 제보한 원본 링크뿐) |
167
191
 
168
192
  문체를 안 바꾸면 관보 문법 위에서 겉돈다 — **낱말이 아니라 조판의 문제**이고, 검수기가 센다.
169
193
 
170
- 독자를 안 정하고 만들면 개발 로그에 색만 칠한 물건이 나온다. 실제로 그렇게 한 번 만들었고,
171
- "개발팀 내부적인 작업 시나리오까지 섞어서 보고서로 보내고 있다"는 지적을 받았다.
194
+ 독자를 안 정하고 만들면 개발 로그에 색만 칠한 물건이 나온다(경위: `references/history.md` §2).
172
195
 
173
196
  ---
174
197
 
175
198
  ## 0.5단계 — 시각 우선: 글보다 먼저 정한다 [MUST] (2026-09-08)
176
199
 
177
- > 반려 원문 셋(앳플리 체중 조절 권장량 4차, 같은 날): 「글만 적어서는 이해가 어려움 — 그림 자료」 →
178
- > 「신입은 읽다가 자겠다」 → 「색상 다변화, 핵심은 굵게, 배지·그래프 보강」. 셋 다 원고를 쓴
179
- > 에이전트가 「글이면 충분하다」고 판단한 자리였다. **판단을 에이전트에게 남겨 두지 않는다** —
180
- > 렌더러가 센다(dry_run ⚠, `lim-portal-format.md` §10-1). 여기는 그 앞의 집필 공식이다.
200
+ > 「글이면 충분하다」는 판단을 원고를 쓰는 에이전트에게 남기지 않는다 — 렌더러가 센다(dry_run ⚠, `lim-portal-format.md` 「10-1. 시각 우선 관문」).
201
+ > 여기는 그 앞의 집필 공식이다(경위: `references/history.md` §3).
181
202
 
182
203
  원고를 쓰기 전에, 절마다 이 순서로 정한다. 글은 마지막이다.
183
204
 
184
205
  | 순서 | 정할 것 | 기준 |
185
206
  |---|---|---|
186
- | 1 | **한 장 이야기** | 문제 → 원인 → 해법 → 지금 상태 → 정할 것. 요약면 다섯 칸이 이 순서이고, 다루는 일의 **사건 경과** 표 한 장을 1절에 둔다(이 문서의 판 이력은 `history` — 3b) |
207
+ | 1 | **한 장 이야기** | 문제 → 원인 → 해법(지금 상태 포함) → 정할 것. 칸 수가 아니라 이야기 순서다 — 요지 칸 수는 4~6단계 「요지」 한 곳이 정본. 다루는 일의 **사건 경과** 표 한 장을 1절에 둔다(이 문서의 판 이력은 `history` — 3c) |
187
208
  | 2 | **예시 한 명** | 실존 이용자 하나의 실제 숫자로 문서 전체를 관통시킨다(같은 사람이 그림·표·건에 반복) |
188
- | 3 | **용어 잠금 표** | 같은 낱말이 두 값을 가리키면 그 자리에서 문서가 죽는다. 뜻이 갈리는 낱말은 표 한 장으로 값·정의·보이는 자리를 박는다 |
189
- | 4 | **절마다 시각 장치 먼저** | 개념은 그림(HTML 개념도 → `assets/figure.mjs`), 실제 화면은 번호 표식을 얹은 캡처(`assets/shot.mjs`), 견주기는 표, 「A 면 B」는 흐름도, 분포는 막대 차트. 글은 그 옆 3줄. 도판은 `references/readability.md` 의 규칙표(R1~R10)를 `figure.mjs` 로 통과시킨다 — 글자 17/15px·행간 1.4·뜻 색 3·그림 안 문장 0·무손실. **글 층도 같은 문서의 R11** — 한 문장 60자(한 줄은 45자)·표 칸 20자(5열 이상 12자)·캡션 60자·괄호 문장당 1·숫자 나열은 표 행. 렌더러 dry_run 과 로컬 `render.py` 가 ⚠ 로 센다. 9/10 「도판은 좋아졌는데 가독성은 아직」 반려 |
190
- | 5 | **판단 요청** | 요청은 **고객이 고를 물음**이다 — 제목은 물음, 본문 첫 문장은 기한과 두 길의 이름. 결과는 한눈표 **한 곳에만**, 열은 「항 · 지금 · 그대로 두면 · 바꾸면」으로 **대칭**. 6항 이상이면 관문 흐름도(정하면 어느 길로)를 곁에 둔다. 권고 열·시한 칩·한 길의 결과만 있는 열은 쓰지 않고 `priority:"must"` 도 쓰지 않는다. **화면 변화**(팝업·안내·칸의 유무)가 따르면 글과 표만으로 묻지 않고 **고객 디자인 시스템 규격의 도안**을 붙여 결재를 청한다 — `references/visual-first.md` 「화면 도안」 절. 집행자: 기한은 `gazette.py` ⚠(`doc_type` 에 「브리핑」), 권고 낱말은 `gazette.py` ⚠ W1(카피 게이트 표), 도안 유무는 없음 — 사람의 눈(`references/process.md` 7단계 표) |
191
- | 5a | **원본 확인** | 주장·그림마다 **원본 이름 · 쪽(행) · 찾을 낱말**과 「건 §n.n」을 적는다. 「흐리다」「못 연다」고 쓰기 전에 **잰다** — PDF 는 `pdfimages -list` 전체, 웹은 실제로 열어 찾는다. 고객이 운영에서 **실제로 누를 수 있는 링크**만 근거로 친다 — 건 `source_url`, 그리고 글자 안의 맨 주소·`[글자](주소)`(도판 출처 줄 `source_text` 포함). 집행자: `references/reader-review.workflow.js` 「원본 대조」 관점(7행) · 도판 출처 줄은 `gazette.py` ⚠ W2 — 그 밖은 없음, 사람의 눈 |
192
- | 6 | **표기** | 인라인 표기(`**굵게**`·`==강조==`·`{{ok|칩}}`·`[글자](주소)`·**맨 주소**)와 절·PART 의 `tone`, 차트 행 `tone`, 건의 `source_url`, 요약면 `notice.state`. 색은 뜻으로(`lim-portal-format.md` §11-6) |
193
- | 7 | **독자 검토** | 발행 전 `references/reader-review.workflow.js` 로 다섯 관점(처음 읽는 사람·결정권자·정보 디자이너·원본 대조·구조) 검토를 돌리고 상위 발견을 반영한다. **구조 발견(PART·절 합치기·빼기)을 먼저** 반영한다 — 문장·표를 더하는 처방이 절 구성보다 앞서면 겹침이 커진다(2026-09-12 실측: 처방 반영 뒤 PART 사이에 다시 선 시각표 행 8→12) |
194
- | 8 | **실물 확인** | 발행 뒤 열람 주소를 열어 그림·표·칩이 섰는지 캡처로 본다. dry_run 경고 0 이 목표 |
209
+ | 3 | **용어 잠금 표** | 같은 낱말이 두 값을 가리키면 그 자리에서 문서가 죽는다. 뜻이 갈리는 낱말은 표 한 장으로 값·정의·보이는 자리를 박는다. 장치 이름(건 행 `labels` 값)은 절 이름·부제·표 열·캡션에 다시 쓰지 않고, 선택지 기호(A·B·C)는 한 목록에만 붙인다. 집행자: `gazette.py` `text_scan()` ⚠(건 행 이름 충돌·선택지 기호 충돌) · 독자 검토 first-time 관점(한 낱말 두 값) · 뜻이 같은지는 사람 눈 |
210
+ | 4 | **절마다 시각 장치 먼저** | 개념은 그림, 실제 화면은 번호 표식 캡처, 견주기는 표, 「A 면 B」는 흐름도, 분포는 막대 차트. 글은 그 옆 3줄. 도판 층 R0~R10·R13 은 `figure.mjs`(비교 컷은 `shot.mjs --after` → `pair.mjs`), 글 층 R11 은 렌더러 ⚠ — 값은 `references/readability.md` 「1. 규칙표」 한 곳(경위: `references/history.md` §3) |
211
+ | 5 | **판단 요청** | 요청은 **고객이 고를 물음**이다 — 제목은 물음, 본문 첫 문장은 기한과 두 길의 이름, 결과는 한눈표 **한 곳에만** 대칭으로. 모양·선택지 대칭 불변식·화면 도안 절차는 `references/visual-first.md` §5 와 `lim-portal-format.md` §12.3b. 집행자: `gazette.py` `brief_checks()` ⚠(기한·동일값 열) · ⚠ W1(권고 낱말) · 선택지 사이 대칭은 독자 검토 figures 관점 · 도안 유무는 **없음 — 사람의 눈**(`references/process.md` 7단계 표) |
212
+ | 5a | **원본 확인** | 주장·그림마다 원본을 **댈 수 있어야** 한다. 출처 줄은 위치 한 구절(`references/readability.md` R12e — 우리 도안은 비움), 원본 이름·찾을 낱말은 건(`source_url`·`how_to_check`)이나 부록에, 제작 메타는 `origin` 으로(11번). 집행자: 독자 검토 source 관점(누를 수 있는 원본) · facts 관점(앱 동작·내부 수치·결정 주체) · `gazette.py` ⚠ W2 · `text_scan()` 제작 메타 ⚠ — 그 밖은 사람 눈 |
213
+ | 6 | **표기** | 인라인 표기(`**굵게**`·`==강조==`·`{{ok|칩}}`·`[글자](주소)`·**맨 주소**)와 절·PART 의 `tone`, 차트 행 `tone`, 건의 `source_url`, 요약면 `notice.state`. 그림 가리킴은 손으로 번호를 치지 않고 `{{그림:<assets id>}}` 토큰으로(번호·조사를 렌더러가 셈) — ⚠ **운영 반영 확인 전**이라 배포 뒤 열람 DOM 에서 `a.ref[href^="#fig-"]` 를 세어 확인하기 전에는 쓰지 않는다(`lim-portal-format.md` §11-6). 색은 뜻으로(`lim-portal-format.md` 「11-6. 인라인 표기」) |
214
+ | 7 | **독자 검토** | 발행 전 `references/reader-review.workflow.js` — 관점 여덟(상태 표 `args.state` 를 주면 아홉). **Verify 를 통과한 발견만 반영한다 — 검토자 주장도 틀린다.** 반영 순서는 사실 틀림 → 구조(합치기·빼기) → 나머지. **빼기가 포인터를 남기면 안 된다** — 「N절을 보라」「건 §n.n」「부록에 있다」로 대신하면 독자가 장을 오가는 시험지가 된다. 낱말·규칙·예시 선언은 **첫 등장 자리에서 한 구절**, 뒤 절의 번호·표 이름·§ 는 앞 절에서 쓰지 않는다(요약 근거는 `refs[]` 로). 선형 읽기 관점의 **뜀 지점(`jumps`) 0 이 목표**(실측은 `references/linear-read-test.workflow.js`, 독자 셋+결정권자). 관점·인자·JS 거름 규칙은 `references/visual-first.md` §7. 집행자: 워크플로 관점 + JS 거름 · 뒤 절 번호는 렌더러 ⚠ 「앞 절이 뒤 절을 가리키는 곳」(`gazette.py text_scan` W5 · readability R12h) · 정의 위치와 `questions`·`dropped` 는 사람 눈(경위: `references/history.md` §9·§12). **낱말만 고친 판도 검토 없이 내지 않는다** — 변경 자리만 보는 `references/edition-review.workflow.js`(세 관점 + 반박)로 돌린다. 렌더러 경고 0 만 보고 낸 15판이 다음 판 8자리 손질을 낳았다(2026-09-15) |
215
+ | 8 | **실물 확인** | 발행할 때마다 체크리스트 9단계 두 행 — 블록 목록 대조와 열람 주소 열기. 집행자: 사람 — 발행 뒤 대조 기계는 아직 없다 |
195
216
 
196
217
  상세와 도판 예산(장당 80KB · 합계 400KB), 그림 만드는 법, 반려 사례는 `references/visual-first.md`.
197
218
 
198
219
  ## 워크플로우
199
220
 
200
- ### 1. 자료 모으기 → `cases.json`
221
+ ### 1·2단계 — 자료 모으기 → `cases.json`
201
222
 
202
223
  건별로 **증상 · 원인 · 조치 · 확인 방법 · 확인 요청** 다섯 칸을 채운다.
203
224
  `확인 방법`은 **고객이 자기 화면에서 직접 밟을 수 있는 순서**여야 한다. 이게 없으면 검수 요청이 아니라 통보다.
204
- `확인 요청`은 우리가 끝낼 수 없어 상대의 판단·확인이 필요한 것만 적는다. 없으면 비운다.
225
+ `확인 요청`(`remaining`)은 **아직 닫히지 않은 것**만 적는다 — 상대의 판단·확인이 필요한 것과 운영에 아직 안 나간 우리 작업(`references/content-pipeline.md` §1.1). 없으면 비운다.
205
226
 
206
227
  → 필드 정의와 작성 규칙: `references/content-pipeline.md`
207
228
 
208
- ### 2. 등급 체계 정하기
229
+ ### 3단계 — 등급 체계 정하기
209
230
 
210
231
  각 건을 **어디까지 확인했는지**로 등급을 매긴다. 이건 고객에게 "얼마나 믿어도 되는가"를 알려주는 장치다.
211
232
  등급 이름은 고객 언어로 쓴다 — "코드 확인", "자동 검사" 같은 내부 절차 용어를 그대로 쓰지 않는다.
212
-
213
- 예시(4단계, 강한 순):
214
-
215
- | 등급 | 뜻 |
216
- |---|---|
217
- | 운영 환경 확인 | 운영 환경에서 실제로 동작시켜 결과까지 확인 |
218
- | 실데이터 대조 | 운영 데이터를 건별로 대조해 확인 |
219
- | 재발 점검 적용 | 같은 문제가 다시 생기면 걸러지도록 상시 점검 적용 |
220
- | 반영 확인 | 수정이 운영에 반영된 것까지 확인 (화면 재현은 미실시) |
233
+ 예시 네 등급(운영 환경 확인 · 실데이터 대조 · 재발 점검 적용 · 반영 확인)와 붙는 조건은 `references/process.md` 「3단계 — 등급 부여」.
221
234
 
222
235
  **확인 못 한 것을 확인한 것처럼 쓰지 않는다.** 등급이 낮아 보이는 게 싫어서 올리면, 나중에 그 한 건이 문서 전체의 신뢰를 깎는다.
223
236
 
224
- ### 3. 색은 고르지 않는다 — 뜻으로 정해진다
237
+ ### 색은 고르지 않는다 — 뜻으로 정해진다
225
238
 
226
239
  **포털 발행에는 팔레트 인자가 없다.** 관보 서식은 자기 색 체계를 통째로 갖고,
227
240
  장 색은 그 절이 무엇인가로 정해진다(`sections[].tone`).
@@ -242,7 +255,7 @@ Lim 보고서, Lim 에 올려줘, 고객 보고서, 수정 내역, 검수 요청
242
255
  (`report_publish.php`), 렌더러도 `styles(..., tokens=False)` 로 부른다 — 유도 토큰이
243
256
  문서에 안 실린다. 고를 자리가 없으니 고르려 하지 마라.
244
257
 
245
- ### 4. 뼈대 쓰기 → `report.json`
258
+ ### 4~6단계 — 뼈대 쓰기 → `report.json`
246
259
 
247
260
  **관보 골격은 순서가 정해져 있다.** 바꾸지 않는다.
248
261
 
@@ -252,14 +265,18 @@ Lim 보고서, Lim 에 올려줘, 고객 보고서, 수정 내역, 검수 요청
252
265
  ```
253
266
 
254
267
  절은 다섯 kind 로 쓴다(`summary`·`status`·`cases`·`asks`·`note`).
255
- 요약면의 요지는 **4칸**으로 쓴다 — 검수자가 첫 화면에서 판단을 끝낼 수 있어야 한다.
268
+ **요지 칸 수의 정본은 여기 한 곳이다.** 검수·보고판은 **4칸**, 칸마다 `lead` 한 문장 + `body` 2~4문장 — 검수자가 첫 화면에서 판단을 끝낼 수 있어야 한다.
256
269
 
257
270
  1. 접수한 것은 어떻게 됐는가
258
271
  2. 우리가 추가로 찾은 것 중 중요한 것
259
272
  3. 여러 건을 관통하는 공통 원인
260
273
  4. 상대가 무엇을 하면 되는가
261
274
 
262
- 「결정한다」 모드의 요약 4칸은 다르다 — 결정권자가 첫 화면에서 yes/no 를 고를 수 있어야 한다.
275
+ 「결정한다」판은 **4~6문단**이다 — 결정권자가 첫 화면에서 yes/no 를 고를 수 있어야 한다. **순서의 정본은 여기 한 곳이다**(`references/visual-first.md` §1 의 이야기 순서는 검수·보고판의 것).
276
+ 아래 넷이 뼈대다. 앞선 결정·화면 규격·실측 같은 **배경 문단**은 1 앞에 올 수 있고, 4(결정 뒤)는 1 문단의 `body` 로 붙일 수 있다.
277
+ 2(선택지 편익·비용)는 그 절에 선택지 비교 행렬이 있으면 배경 문단이 대신한다 — 요지에서 표를 옮겨 적지 않는다(R12c). 본보기가 그 모양이다(`assets/example/report-briefing-designs.json`).
278
+ 결정에 직접 닿는 문단만 `body`(세 문장 안)를 쓰고, 근거 문단은 `lead` 한 줄 + `refs` 로 두고 `body` 를 비운다 — 본문은 건이 가진다(readability R12g).
279
+ 집행자: 독자 검토 structure 관점 · 사람 눈 — 기계 없음.
263
280
 
264
281
  1. 무엇을 **언제까지** 결정해야 하는가 — 「무엇을 언제까지」 그 한 줄은 요약면 현황 줄(`notice`)의 몫이다
265
282
  2. 검토한 선택지와 각각의 편익·비용·불확실성
@@ -274,16 +291,16 @@ Lim 보고서, Lim 에 올려줘, 고객 보고서, 수정 내역, 검수 요청
274
291
  - `marg.advice` — 어디를 참조해야 하는지
275
292
 
276
293
  **번호는 데이터가 아니라 자리가 정한다.** `sections[].no`·`id` 를 적어도 렌더러가 안 읽고
277
- 배열 순서로 `ch`·앵커를 만든다(`gazette.py:794·811`). 찍히는 것은 `label` 하나다.
294
+ 배열 순서로 `ch`·앵커를 만든다(`gazette.py Doc.build()`). 찍히는 것은 `label` 하나다.
278
295
  `summary` 의 `§n.n` 은 서버가 `groups[].no` 로 검사하므로 **`groups[].no` 를 그 절의 자리와
279
296
  같게** 맞춘다 — 어긋나면 게이트는 통과하고 링크가 헛짚는다.
280
297
 
281
- **등급은 4단 이하.** 5번째부터 최약 표식으로 눌린다(`gazette.py:751-762`).
298
+ **등급은 4단 이하.** 5번째부터 최약 표식으로 눌린다(`gazette.py Doc._grade()`).
282
299
  그리고 `cases` 가 비면 `summary` 를 못 쓴다 — 근거 게이트가 전 문단을 거절한다.
283
300
 
284
301
  → 칸 하나하나: `references/lim-portal-format.md`
285
302
 
286
- ### 5. 전달 — Lim 발행 (기본 경로)
303
+ ### 8단계 — 전달: Lim 발행 (기본 경로)
287
304
 
288
305
  report.json + cases.json 을 하나로 합쳐 `publish_report` 에 준다
289
306
  (스키마가 곧 이 스킬의 데이터 모델이다 — `tenant`·`slug` 필수).
@@ -295,13 +312,15 @@ report.json + cases.json 을 하나로 합쳐 `publish_report` 에 준다
295
312
  서버는 「빈 칸」을 안 막는다 — 막는 것은 **조용히 사라지는 것**뿐이고, 관보의 본체가
296
313
  빠지면 ⚠ 로 소리 내어 센다. `marg` 가 비었다는 경고를 못 보고 넘기면 두 단이 한 단으로 선다.
297
314
 
298
- **기본은 초안이다.** 도구가 `publish` 를 참으로 주지 않는 한 고객에게 안 보인다.
299
- 확인한 뒤 `release_report(id)` 로 연다 — 그것이 사람의 승인 행위다.
315
+ **기본은 초안이다.** 도구가 `publish` 를 참으로 주지 않는 한 고객에게 안 보인다. ⚠ 단 운영 반영 확인 전에는 초안에 보낸 `update_report` 가 공개로 바꾼다(위 「Lim 발행 규칙」).
316
+ 공개 직전 날짜를 맞춘 뒤(3c) `release_report(id)` 로 연다 — 그것이 사람의 승인 행위다(체크리스트 10단계).
300
317
 
301
- 수정은 `get_report` → 데이터 수정 → `update_report` — **같은 링크가 새 내용을 가리킨다.**
318
+ **수정 절차** — `get_report` 머리줄에서 판번호(`body_rev`)와 사람 편집 초안 여부를 본다 → 받은 JSON 을 백업 → 자리마다 지금 값이
319
+ 기대와 같은지 확인하며 고친다 → 로컬 렌더 ⚠0 → dry_run → 독자 검토 → `update_report` → 9단계 두 행. **같은 링크가 새 내용을 가리킨다.**
320
+ 사람이 고친 초안이면 덮기 전에 묻는다 — `update_report` 에 `body_rev` 잠금 칸이 아직 없어 기계가 막지 않는다.
302
321
  그림은 서버가 보관한다 — `assets` 를 빼고 보내면 유지, `assets: []` 면 삭제(plates 에서도 빼야 422 가 안 난다), 바꿀 장만 새 `source`/`file`.
303
322
 
304
- ### 5-1. 발행 뒤 판정 — 블록 목록으로 본다
323
+ ### 9단계 — 발행 뒤 판정: 블록 목록으로 본다
305
324
 
306
325
  브라우저를 안 열고 「무엇을 냈는가」를 확인하는 창구는 `get_report(id, outline: true)` 다.
307
326
 
@@ -312,16 +331,11 @@ report.json + cases.json 을 하나로 합쳐 `publish_report` 에 준다
312
331
 
313
332
  `aside.marg` 개수가 **절 수와 같아야 한다.** 모자라면 그만큼의 절이 한 단으로 서 있다.
314
333
 
315
- ⚠ **머리줄의 `절 0 · 건 0 · 장 0` 은 정상값이다.** MCP 요약 줄이 옛 서식 클래스
316
- (`h2.sec`·`.case`·`.ch-open`)만 세는데 관보는 그중 무엇도 안 쓴다. 실측(예시 문서):
317
- 전부 0 이면서 실제로는 `ask` 1 · `sheet` 2 · `board` 1 이었다. **0 을 「비었다」로 읽지 마라.**
318
-
319
- **「그림 N(표지마크 M)」은 다르다 — 이건 진짜 셈이다**(2026-08-25). 위 62줄대로 관보에는
320
- 비트맵이 두 자리 실리고, 그중 표지 마크는 **서버가 넣는다**(고객사에 로고가 등록돼 있으면).
321
- 그래서 로고를 등록한 고객사의 문서는 `M = 1` 이 정상이고, 본문 도판은 `N − M` 이다.
334
+ ⚠ **머리줄의 `절 0 · 건 0 · 장 0` 은 정상값이다.** MCP 요약 줄이 옛 서식 클래스(`h2.sec`·`.case`·`.ch-open`)만 센다 — **0 을 「비었다」로 읽지 마라.**
335
+ **「그림 N(표지마크 M)」은 진짜 셈이다.** 표지 마크는 고객사에 로고가 등록돼 있으면 **서버가 넣으므로** `M = 1` 이 정상이고 본문 도판은 `N − M` 이다.
322
336
  **`그림 0` 을 합격 기준으로 삼지 마라** — 도판을 실은 문서에서 그 기준은 자기 근거를 지운다.
323
337
 
324
- ### 5′. 전달 — 단일 HTML (Lim 밖 고객·메일 첨부)
338
+ ### 8단계′ — 전달: 단일 HTML (Lim 밖 고객·메일 첨부)
325
339
 
326
340
  ```bash
327
341
  python3 ~/.claude/skills/genetics-report/assets/render.py report.json
@@ -338,20 +352,10 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
338
352
 
339
353
  파일 하나를 그대로 보낸다. 상대는 더블클릭만 하면 된다.
340
354
 
341
- ### 5″. 조판 검사 — `gazette-report` 스킬의 8종
342
-
343
- | 검사기 | 무엇을 잡는가 |
344
- |---|---|
345
- | `kcheck.mjs` | 대비(알파·조상 opacity 합성) · 제목 레벨 · 표 접근명 · 앵커 · 7폭 넘침 |
346
- | `read.mjs` | 한글 자폭 실측 글자/줄 · 행간 · 본문 대비 |
347
- | `tone.mjs` | 경어체 잔존 · 늘어짐 지표 · **한 문장 한 줄** · 문체 유형 4종(학생 보고서투·완충어·근거 없는 총평·단독 부정 종결) |
348
- | `fontchk.mjs` | 렌더된 활자 크기·굵기 분포 |
349
- | `flexcheck.mjs` | flex/grid 안에서 문장이 토막 나는 곳 |
350
- | `cssaudit.sh` | 활자 스케일 · 간격 격자 · 표 마감 · 미봉책 |
351
- | `pdfcheck.sh` | 실제 PDF 쪽 구조 |
352
- | `contentdiff.sh` | 조판이 본문·id·앵커를 바꿨는지 |
355
+ ### 7단계 — 조판 검사: `gazette-report` 스킬의 8종
353
356
 
354
- 실행법은 `gazette-report` 스킬에 있다. 여기 두 벌로 두지 않는다.
357
+ 검사기 8종(`kcheck.mjs`·`read.mjs`·`tone.mjs`·`fontchk.mjs`·`flexcheck.mjs`·`cssaudit.sh`·`pdfcheck.sh`·`contentdiff.sh`)이 무엇을 잡는지는
358
+ `references/process.md` 「7단계 — 검수」 표, 실행법은 `gazette-report` 스킬에 있다. 여기 세 벌로 두지 않는다.
355
359
 
356
360
  **0표본 통과는 통과가 아니다.** 표본 수를 함께 본다.
357
361
  그리고 **폰트가 큰 문서는 두 번 재라** — 409KB 폰트 적재 경합으로 첫 실행이 오탐을 낸다(실측).
@@ -365,8 +369,11 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
365
369
  | `assets/render.py` | `report.json` → 단일 HTML. **서버 등록부에서 서식을 읽어** 레포 `private/builder/build.py` 를 부른다 — 여기 사본을 두지 마라 |
366
370
  | `assets/subset_font.py` | 폰트 서브셋 생성 (보통 실행 불필요) |
367
371
  | `assets/example/report.json` · `cases.json` | 관보 필드를 전부 채운 본보기. 새 문서는 여기서 베낀다 |
368
- | `assets/figure.mjs` · `shot.mjs` · `mockshot.mjs` | 도판 도구 — 개념도를 굽고 가독성 관문을 잰다(`figure.mjs`) · 웹 화면을 번호 표식과 함께 찍는다(`shot.mjs`) · 고객 앱 화면 도안을 2배 밀도로 찍는다(`mockshot.mjs`, `references/visual-first.md` 「화면 도안」) |
372
+ | `assets/figure.mjs` · `shot.mjs` · `mockshot.mjs` · `pair.mjs` | 도판 도구 — 도판 HTML 을 굽고 가독성·틀 문법 관문(R0~R10·R13)을 잰다, `--batch plates.json` 은 일괄 판정과 예산 합계, `--spec` 은 계약 상수(`figure.mjs`) · 웹 화면을 검정 원 번호 표식과 함께 찍고 `--after` 로 블록을 숨긴 전후 두 장을 같은 구간으로 찍는다(`shot.mjs`) · 고객 앱 화면 도안을 2배 밀도로 찍는다(`mockshot.mjs`, `references/visual-first.md` 「화면 도안」) · 전후 두 컷을 좌우 같은 틀·같은 배율로 조립하고 판정까지 찍는다(`pair.mjs`, 본보기 `assets/example/plate-pair.html`) |
373
+ | `references/linear-read-test.workflow.js` | 선형 읽기 **실측** — 처음 읽는 사람 셋 + 결정권자가 앞에서 뒤로 한 번 읽으며 뛰어야 하는 자리를 전부 센다(`args: {file, reader, round}` — 재측정은 `round` 를 바꿔야 캐시를 안 탄다). 뜀 0 이 목표. 독자 검토(`reader-review.workflow.js`)의 linear 관점이 같은 읽기를 하나로 한다 |
374
+ | `references/edition-review.workflow.js` | **판 갱신 검토** — 구조는 그대로이고 낱말·출처 줄·여백 주석만 고친 판의 **변경 자리**(edit-N.py 의 put/sub 호출)만 선형 독자·규칙 대조·사실 대조 세 관점으로 읽고 심각도 3 이상은 반박한다(`args: {file, backup, edit_script, doc}`). 사실 관점이 백업↔새 판 JSON diff 에 스크립트가 바꾼 자리가 빠짐없이 있는지(삽입·삭제가 섞이면 줄 수가 아니라 자리로)·수치 무변경을 검산한다. 구조가 바뀐 판은 `reader-review.workflow.js`. 낱말 손질 판을 검토 없이 발행하자 다음 판 8자리 손질이 생겼다(2026-09-15) |
369
375
  | `assets/example/report-briefing.json` · `cases-briefing.json` | 「결정한다(R&D 브리핑)」 모드 본보기 — 물음 제목 · 두 길 대칭 한눈표 · 선택지 전치 행렬 · FCG 의견 표 한 장 · 바꾸는 길의 위험 · 고른 길별 일정 · `cta` 기본 `[]` |
376
+ | `assets/example/report-briefing-designs.json` · `cases-briefing-designs.json` | 「결정한다」 도안 결재형 본보기 — 세 길 · 전폭 선택지 도판(자리 표시) · 조건표 · 선택지마다 한 행인 의견 표 · 판단 항목 둘(물음 + 「… 확인 요청」) · 확인 프로필 표(`references/lim-portal-format.md` §12.3b) |
370
377
  | 폰트 | **레포** `private/builder/fonts/pretendard-gazette.woff2` — 가변 1면 |
371
378
 
372
379
  **스킬에는 렌더러도 스타일시트도 검사기도 없다.** 셋 다 레포와 `gazette-report` 스킬에 있고,
@@ -381,22 +388,26 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
381
388
  1. **티켓 번호·이슈 트래커 이름을 싣지 않는다.** 고객이 아는 참조는 본인이 제보한 원본 링크다.
382
389
  2. **`§` 같은 기호를 본문에 노출하지 않는다.** 원고에서는 참조 마커로 쓰되 렌더에서 지운다(빌드가 처리).
383
390
  3. **개발 절차 서술을 빼거나 고쳐 쓴다.** 배포·티켓 분리·테스트 추가·설계 검토안은 고객의 관심사가 아니다.
391
+ **코드 작업을 녹일 때**는 원고를 쓰기 전에 원고 밖 상태 표(무엇 · 코드 반영 · 시험판 전달 · 실기기 · 운영, 칸마다 근거)를 만들고, 문서의 동사는 그 표의 확인 수준을 넘지 않게 고른다(`references/content-pipeline.md` 「4.2 치환 유형」).
392
+ 커밋·브랜치·파일·시험 도구·시험 건수는 그 표에만 둔다. 원고에 새면 `gazette.py` `text_scan()` 개발 식별자 ⚠, 확인 수준을 넘는 동사는 독자 검토 state 관점(`args.state`)과 사람 눈.
384
393
  3b. **회차 서술을 본문 절에 두지 않는다.** 「이번 회차에 추가함」·「이번 회차 미확인 사항」은
385
394
  우리 작업 순서이지 그 절의 내용이 아니다. 고객은 이 문서를 **처음 읽는 사람**이고,
386
395
  그에게 필요한 것은 무엇이 적혀 있느냐이지 우리가 언제 적었느냐가 아니다.
387
- 회차 변경점을 말하는 자리는 **발행 이력(`history`)** 이고, 「이번 회차에서 새로 추가된 것은?」을
388
- 활용법(`guide`)에 한 줄 둘 수 있다. 절 `lede`·본문 문단·표 주석·건·요청에는 두지 않는다.
389
- 실측(2026-09-01): 3차 회차 문서에서 절 셋·문단 둘·건 하나·요청 하나, **일곱 자리**에 샜다.
390
- 위 3번 규칙이 이미 있었으나 예시가 배포·티켓·테스트뿐이라 이 형태가 빠져나갔다.
396
+ 회차 변경점을 말하는 자리는 **발행 이력(`history`, 3c)** 이고, 「이번 회차에서 새로 추가된 것은?」을
397
+ 활용법(`guide`)에 한 줄 둘 수 있다. 절 `lede`·본문 문단·표 주석·건·요청에는 두지 않는다(경위: `references/history.md` §4).
391
398
  **회차 낱말만이 아니다 — 진행 상태 어휘와 구조도 금한다.** 「정해짐 · 회신 대기 · 남은 물음 · 정해진 것 · N판」,
392
399
  상태 열(「상태: 정해짐/회신 대기」), 개수로 상태를 세는 표 제목(「정해진 것 셋과 남은 것 하나」),
393
400
  「~ 그대로(변화 없음)」. 독자는 앞 회차·회신·판을 모른다. 정해진 것은 **사실**로 요지(배경)에 적고,
394
401
  결정 요청 절에는 **지금 열린 것만** 둔다. 회차의 자리는 `history` 하나. 원고는 직전 판의 차분이 아니라
395
402
  **독자의 0 상태에서 다시 쓴다** — 판마다 「처음 읽는 사람이 이 절에서 무엇을 알아야 하나」를 다시 묻는다.
396
- 집행자: `gazette.py` `text_scan()` 과정 어휘 ⚠(2026-09-11 추가, `tests/builder.test.py` 시험 3건) ·
403
+ 집행자: `gazette.py` `text_scan()` 과정 어휘 ⚠(`tests/builder.test.py`) ·
397
404
  `references/readability.md` R11h. 상태 열·「그대로(변화 없음)」는 기계가 못 본다 — 사람의 눈.
398
- 까닭 — 실사례(2026-09-11, 고객사 결정 브리핑): 사용자 결정을 판마다 차분으로 반영하다 1절이
399
- 「정해진 것 셋과 남은 것 하나」 상태판이 됐음. 「뒷 내용을 나는 알고 너는 알아도, 독자는 모름. 이해관계자 입장 고려 안 해?」
405
+ **결정 주체** — 결정권이 고객에게 있는 항은 고객이 정한 기록이 있고 그 항이 원문에서 실제로 닫혀 있을 때만(「정해야 함·차기」로 남아 있지 않을 때) 사실로 배경에 쓴다.
406
+ 기록이 없거나 FCG·내부 대화에서 정했으면 사실로 쓰지 않고 결정 물음이나 FCG 의견 절로 둔다. FCG 권한 안의 작업 결정(작업 순서·일정)은 「FCG 작업」으로 사실 서술한다.
407
+ 본문에는 결정 출처·날짜를 적지 않는다 — 확인은 결정 장부(0단계 물음 4)에서 한다. 집행자: 사람 눈(0a) · 독자 검토 facts 관점 · 주체 없는 결정 명사(「정한 사항」·「결정된 사항」·「결정임」)는 `text_scan()` 과정 어휘 ⚠.
408
+ 3c. **공개 전 수정은 판이 아니다.** `history` 는 공개할 판 한 행(「최초 발행」)이고, `meta` 의 작성 · 판권지 작성 · `history` 마지막 `date` 는 **한 값**이며 공개하는 날로 맞춘다(체크리스트 10단계 — 공개 직전 `update_report` 한 번).
409
+ 공개 뒤 내용이 바뀐 update 에만 `history` 행을 더한다. 문서 밖 결정의 날짜는 본문에 적지 않는다. `cover_date` 는 요약면 「기준」 날짜(수치의 기준일)라 이 셋과 대조하지 않는다.
410
+ 집행자: `gazette.py` `date_scan()` ⚠ — 세 자리를 년·월·일로 견줘 다르면 센다(두 경로 · `lim-portal-format.md` §10-1). 공개하는 날인지와 `history` 행 수는 사람(체크리스트 행) · 공개 때 날짜 안내(`release_report`)는 아직 기계가 없다(경위: `references/history.md` §12).
400
411
  4. **확인 못 한 범위를 반드시 적는다.** 감추면 다음 보고서까지 못 믿게 된다.
401
412
  5. **개조식은 「우리가 한 일」에만 쓴다.** `~함 / ~했음 / ~임`.
402
413
  그 자리는 우리·사물이 주어인 **기록 자리**다 — `cases` 의 증상·원인·조치·확인 방법,
@@ -418,35 +429,24 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
418
429
  청자 높임이 0 이다. 중립이 아니라 **기록체**이고, 사람에게 직접 말하는 자리에 쓰면
419
430
  하대로 읽힌다. 그래서 겸양 어간 `-드리-` 가 든 「부탁드림」도 존대가 아니다.
420
431
 
421
- ⚠ **이 규칙은 네 번 반려당하고서야 고쳐졌다.** 앞의 세 처방이 모두 종결을 못 건드린 채
422
- 어휘만 갈았기 때문이다. 같은 실수를 반복하지 않도록 경위를 남긴다.
423
-
424
- | 회차 | 나간 글자 | 고객 반응 | 당시 처방 |
425
- |---|---|---|---|
426
- | 2026-09-02 #32 | ~해 주셔야 함 · 회신 필요 | 이거 너무 싸가지없는 거 아니야? | `-시-` 되살리기 |
427
- | 2026-09-03 #112 | 동의해 주시면 됨 | 이런 말투 존나 싸가지 없지 않아? | 「부탁드림」으로 교체 |
428
- | 2026-09-03 #112 | 보고 칸의 요청문 | 보고와 요청의 차이를 잘 모르는거야? | 요청문은 요청 절에만 |
429
- | 2026-09-11 #176 | 부탁드**림** · 진행하겠**음** | 존나 마음에 안듦 · 관보가 원래 이런말투임? | **종결을 하십시오체로** |
430
-
431
- 네 번째 반려가 겨눈 것은 **2·3차 처방 그 자체**였다. 종결을 못 바꾼 이유는
432
- 「톤 게이트가 `습니다` 를 세므로 이쪽은 바꿀 수 없다」는 전제였는데 **그 전제가 틀렸다** —
433
- 게이트는 경고이지 거절이 아니다(위 「Lim 발행 규칙」).
432
+ ⚠ **이 규칙은 네 번 반려당하고서야 고쳐졌다.** 앞의 처방들이 종결을 못 건드린 채 어휘만 갈았고,
433
+ 「톤 게이트가 `습니다` 를 세므로 바꿀 수 없다」는 전제는 틀렸다 — 게이트는 경고이지 거절이 아니다(위 「Lim 발행 규칙」). 경위 표: `references/history.md` §5.
434
434
 
435
435
  ⚠ **관형 명사구는 고치지 마라** — 「회신이 필요한 것은 4가지임」의 주어는 「것」이라
436
436
  이름이지 명령이 아니다. 「자격이 필요함」처럼 주어가 사물인 「필요」도 그대로 둔다.
437
437
  여기까지 높이면 표지 통계·색인 라벨이 말을 거는 문장이 되어 오히려 어색해진다.
438
- 정본은 genetics 결정문 `decisions/고객-문서-요청-자리는-하십시오체로-맺는다-명사형-종결은-하대로-읽힌다.md`(hnl) —
438
+ 정본은 genetics 결정문 `decisions/고객-문서-요청-자리는-하십시오체로-맺는다-명사형-종결은-하대로-읽힌다.md`(결정문 보관 소속처) —
439
439
  이 스킬은 패키지로 덮어써지므로 여기 적은 것은 사본이다.
440
440
  앞 결정문 `…상대가-주어인-문장은-요청드림-부탁드림으로-맺는다.md` 는 **뒤집혔다**.
441
441
 
442
- ⚠ **보고 칸에 요청문을 두지 마라 — 세 번째 반려**(2026-09-03 저녁, 같은 보고서).
443
- 건의 `how_to_check`·`fix`·`remaining`, 절 `paragraphs`, `summary` 는 **보고 자리**다.
444
- 거기에 「…을 수용하실 수 있는지 의견을 부탁드림」「…를 보시면 확인됨」을 넣자
445
- **「보고와 요청의 차이를 잘 모르는거야?」**로 반려됐다. 보고 칸은 사실과 계획만 —
442
+ ⚠ **보고 칸에 요청문을 두지 마라**(셋째 반려 — 경위: `references/history.md` §5).
443
+ 건의 `how_to_check`·`fix`·`remaining`, 절 `paragraphs`, `summary`, 읽는 법(`guide`)은 **보고 자리**다. 보고 칸은 사실과 계획만 —
446
444
  「검수 기준. A가 됨. B가 뜸.」「셈법은 01절 ③ 회신에 따라 확정함」. 요청은 `asks` 절의
447
445
  `open_items`·`cta` 와 PART I 간지에만 둔다. 계사 「~임」으로 끝나는 판정문
448
- (「순서는 다른 항목 뒤임」)도 무성의하게 읽힌다 — 우리 행위 동사로 적는다
449
- (「다른 항목을 마친 뒤 착수함」). 정본: genetics `decisions/고객-문서-보고-칸에는-요청문을-두지-않는다-요청은-요청-절에만.md`(hnl).
446
+ (「순서는 다른 항목 뒤임」)도 무성의하게 읽힌다 — 우리 행위 동사로 적는다(「다른 항목을 마친 뒤 착수함」).
447
+ 출시 전 수정처럼 아직 안 나간 것도 `remaining` 에 적는다(칸의 뜻은 `references/content-pipeline.md` §1.1 한 곳) — 비어 있으면 대조표·일감이 완료로 센다. 집행자: **없음 — 사람 눈**.
448
+ 집행자: `report_tone.php report_tone_warnings()`(dry_run) 「보고 칸에 요청문이 N곳 있습니다」 — `how_to_check` 의 **명령형·당위**(「확인 필요」·「주셔야 함」)만 센다. 「부탁드립니다」·「보시면 확인됨」 꼴 요청문과 그 밖의 칸은 **사람 눈** · `tone.mjs` 명령형.
449
+ 정본: genetics `decisions/고객-문서-보고-칸에는-요청문을-두지-않는다-요청은-요청-절에만.md`(결정문 보관 소속처).
450
450
  이 규칙은 **여전히 유효하다** — 5a 와 짝이다. 5a 가 요청 자리를 하십시오체로 올리는 만큼,
451
451
  요청문이 보고 칸으로 새면 관보가 통째로 편지가 된다. **자리를 먼저 가르고, 그 다음 문체다.**
452
452
  5b. **한글은 마침표에서 줄을 바꾼다.** 문장을 이어 붙인 한글 문단은 개조식으로 고쳐도
@@ -483,9 +483,7 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
483
483
  | 「독자가 실제로 던질 질문을 적어라」는 **규칙** | 그 질문들 |
484
484
  | 등급을 **가르는 기준** | 어느 건이 어느 등급인가 |
485
485
 
486
- 실패 사례(2026-08-17): 스킬 표에 체중계·팔근육 같은 특정 업종 아이콘을 적어 두었고,
487
- 검수기에는 그 테넌트의 강조색 hex 를 상수로 박아 두었다. 강조색이 다른 테넌트에서
488
- **전량 오판정**했다. 스킬에 값을 박으면 다음 고객에서 터진다.
486
+ 스킬에 값을 박으면 다음 고객에서 터진다(경위: `references/history.md` §6).
489
487
  10. **부정 서술은 조건을 주어로 세우고, 한 절에서 한 번만 말한다.** 「할 수 없다·제외된다·지원하지
490
488
  않는다」로 문장을 끝내지 않는다 — 그 문장은 독자에게 「당신은 못 한다」로 읽히고, 이유·기준·다음이
491
489
  없으면 배제 통보가 된다(사회적 배제 연구의 귀결: 이유 없는 거절은 통제감·소속감을 깎고, 이유가 붙은
@@ -496,8 +494,7 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
496
494
  결정권이 고객에게 있는 문서에서 그 자리는 「하지 않기로 한 것」 절이 아니라 선택지 표의 「정할 자리」·「다시 볼 때」 행이다.
497
495
  - 나쁜 소식 앞에 **상대가 이미 잘 둔 것 한 문장**. 위로가 아니라 기준점이다 — 그 다음 문장의 기준이 된다.
498
496
  - 「해야 합니다」를 쓰지 않는다. **결정권이 고객에게 있는 문서에서는 「하지 않기로 함」「권고함」「기각」도 쓰지 않는다** —
499
- 선택은 상대에게 둔다. FCG 의견은 별도 절 한 자리에만(세 가지 독자 표·4단계).
500
- 실사례(2026-09-11, 고객사 결정 브리핑): 「보고서에 답정너 형식 좀 없애」.
497
+ 선택은 상대에게 둔다. FCG 의견은 별도 절 한 자리에만(세 가지 독자 표·4~6단계, 경위: `references/history.md` §7).
501
498
  - 구체적인 값(지역명·회사명·제품명)은 스킬이 아니라 **그 문서의 `forbid`** 로 막는다(9번).
502
499
  기계가 잡는 것은 「조건·이유 없이 부정으로 끝난 문장」까지다(`tone.mjs` 단독 부정 종결). **주어가 사람·조직·
503
500
  국가인지는 기계가 못 본다** — 사람의 눈 검수 표에 그 행이 있다(`references/process.md` 7단계).
@@ -506,9 +503,7 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
506
503
  짐작으로 판정하지 않고, 못 열었으면 「미확인」이라 적는다. **인용은 원문 문구 그대로**, 위치는 절·쪽(행)까지.
507
504
  고객이 눌러 열 수 없는 참조는 근거가 아니다(0.5단계 5a행).
508
505
  집행자: `references/reader-review.workflow.js` 「원본 대조」 관점(발행 전 독자 검토) · 도판 출처 줄의 원본 위치 누락은
509
- `gazette.py` ⚠ W2 — 그 밖은 없음, 사람의 눈.
510
- 실사례(2026-09-11, 고객사 결정 브리핑): 확인 없이 「원본이 흐림」이 실렸고 재보니 원본은 충분히 컸다 —
511
- 「고객은 직접 원본을 보고 싶은데 볼 수 없잖아」.
506
+ `gazette.py` ⚠ W2 · 앱 동작·내부 수치는 독자 검토 facts 관점 — 그 밖은 사람의 눈(경위: `references/history.md` §8).
512
507
 
513
508
  ## 흔한 실패 모드
514
509
 
@@ -519,7 +514,7 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
519
514
  | "웹앱 같다" | 목차를 본문 위에 얹음 | 목차는 **옆으로** 뺀다. 좌측 고정 내비 |
520
515
  | 낱말이 한가운데서 갈라짐 | `word-break` 기본값 | `word-break:keep-all` (구조 CSS 에 이미 있음) |
521
516
  | 인용문이 문장 중간에서 잘림 | 근거를 자동 발췌 | 발췌 인용을 **아예 넣지 않는다.** 조치 본문에 이미 있다 |
522
- | 개발 서술이 새어 들어감 | 원고를 그대로 씀 | **사람이 원고에서 고친다.** ⚠ `text_fix` 는 관보 경로에서 **안 돈다**(`build_gazette` 가 안 부른다 — 실측: 치환 0회). `forbid` 는 로컬 렌더에서만 살고 포털 발행은 입구에서 깎아 낸다(`report_publish.php:76`) |
517
+ | 개발 서술이 새어 들어감 | 원고를 그대로 씀 | **사람이 원고에서 고친다.** ⚠ `text_fix` 는 관보 경로에서 **안 돈다**(`build_gazette` 가 안 부른다 — 실측: 치환 0회). `forbid` 는 로컬 렌더에서만 살고 포털 발행은 입구에서 깎아 낸다(`report_publish.php report_client_fields()`). 개발 식별자는 두 경로 다 `text_scan()` ⚠ 가 센다 |
523
518
  | `forbid` 가 멀쩡한 문장을 막는다 | **한국어에는 낱말 경계가 없다** — `머지` 가 「**나**머지 절은」을 잡는다. `\b` 도 전방탐색도 안 듣는다(뒤에 공백이 오니까) | **앞**을 막는다: `(?<!나)머지`. 앞 글자로 갈리는 것이라 후방탐색이 답이다 |
524
519
  | 두 단이 한 단으로 선다 | `marg` 를 안 채웠다 | `dry_run` 이 ⚠ 로 세어 준다. **경고를 읽어라** |
525
520
  | 발행했는데 옛 서식이 나온다 | 관보 필드를 하나도 안 실었다 | 실측(2026-08-24): v2 최상위 16종 중 **0종**·절 키 11종 중 **0종** 사용. `assets/example/report.json` 을 베껴 시작한다 |
@@ -531,25 +526,38 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
531
526
  doc-pptx 의 슬롭 3종 중 **대시 대비 헤드라인**("복붙에서 위임으로 — 목표만 주면")과
532
527
  **"A에서 B로" 전환 공식**은 이 문서에서도 그대로 금지다.
533
528
 
534
- **집행자가 없는 규칙은 규칙이 아니다.** 이 절은 2026-08-27 까지 「검수기가 잡는다」 한 줄로 끝났는데,
535
- 그 검수기(`qa.py`)는 폐기됐고 남은 `tone.mjs` 는 대시 밀도만 셌다 — 넉 달 동안 아무도 「A에서 B로」를
536
- 기계로 잡지 않았다. 규칙마다 누가 잡는지를 적고, **없으면 없음이라고 적는다**(`references/qa.md`).
529
+ **집행자가 없는 규칙은 규칙이 아니다.** 규칙마다 누가 잡는지를 적고, **없으면 없음이라고 적는다**(경위: `references/history.md` §10).
530
+ 「두 경로」는 dry_run 과 로컬 렌더다 — ⚠ 단 **2026-09-14 에 더한 행은 운영 반영 확인 전**이라, 배포 전에는 로컬 렌더에서만 뜬다(`lim-portal-format.md` §10-1 머리). 렌더러 경고 문구 원문·정규식 대상·탈출구는 `lim-portal-format.md` 「10. 경고 조건」·「10-1. 시각 우선 관문」 표 한 곳에만 둔다 — 이 표는 규칙 · 집행자 · 경로만 적는다.
537
531
 
538
532
  | 규칙 | 집행자 | 어느 경로에서 |
539
533
  |---|---|---|
540
534
  | 대시 `—` 밀도 | `tone.mjs` S2(0.5/천자) | 로컬 렌더 산출물 |
541
535
  | 「A에서 B로」 전환 공식 | **없음** — 사람의 눈 검수(`process.md` 7단계 표) | — |
542
- | 경어체 잔존(기록 자리) · 한 문장 한 줄 | `tone.mjs` S1 — 판단 항목 본문(`p.ask__body`)과 「」 인용은 세지 않는다(5a · 11) | 로컬 렌더 산출물 |
543
- | 학생 보고서투 · 완충어 · 근거 없는 총평 · 단독 부정 종결 | `tone.mjs` S1/S2(2026-08-27 추가) | 로컬 렌더 산출물 |
544
- | 금칙 값(고객사·지역·제품명·티켓) | `build.py` `forbid` | **로컬 렌더만** — 포털 발행은 안 돈다(`report_publish.php:76`) |
545
- | 판단 항목에 기한 없음 · `asks` 절 없음 · 선택지 표에 근거 등급 열이나 행 없음(브리핑) | `gazette.py` `brief_checks()` ⚠ | **두 경로 다**(dry_run·로컬) |
546
- | 본문 절의 회차 서술(「이번 회차…」) | `gazette.py` `round_talk_scan()` ⚠ | **두 경로 다**(dry_run·로컬) |
547
- | 본문의 진행 상태 어휘(정해짐·회신 대기·N판) · 개수로 상태를 세는 표 제목(3b) | `gazette.py` `text_scan()` 과정 어휘 ⚠(2026-09-11) | **두 경로 다**(dry_run·로컬) |
548
- | 권고 낱말(제목·표 열·절 이름·여백 주석·요약면) — 결정권이 고객에게 있는 문서(10번) | `gazette.py` ⚠ **W1** | **두 경로 다**(dry_run·로컬) |
549
- | 고객·제3자 자료에서 낸 도판(`user-provided`)의 출처 줄에 원본 위치(쪽·행·주소·건 §) 누락(11번) | `gazette.py` ⚠ **W2** | **두 경로 다**(dry_run·로컬) |
536
+ | 경어체 잔존(기록 자리) · 한 문장 한 줄 | `tone.mjs` S1 · `report_tone.php report_tone_warnings()` — 둘이 빼는 요청 자리는 「Lim 발행 규칙」 톤 줄(5a · 11) | 로컬 렌더 산출물 · dry_run |
537
+ | 보고 칸(`how_to_check`)의 **명령형·당위**(「확인 필요」·「주셔야 함」) · 상대 행위를 명령형으로 맺은 문장(5a) | `report_tone.php report_tone_warnings()` 「보고 칸에 요청문이 N곳」·명령형 줄 · `tone.mjs` 명령형 — 「부탁드립니다」 꼴은 **사람 눈** | dry_run · 로컬 렌더 산출물 |
538
+ | 학생 보고서투 · 완충어 · 근거 없는 총평 · 단독 부정 종결 | `tone.mjs` S1/S2 | 로컬 렌더 산출물 |
539
+ | 금칙 값(고객사·지역·제품명·티켓) | `build.py` `forbid` | **로컬 렌더만** — 포털 발행은 `report_publish.php report_client_fields()` 가 깎아 낸다 |
540
+ | 개발 식별자(3 — 대상 목록은 `lim-portal-format.md` §10-1) | `gazette.py` `text_scan()` ⚠ | **두 경로 다** |
541
+ | 판단 항목·확인 요청에 기한 없음 · `asks` 절 없음 · 선택지 표에 근거 등급 없음 · `asks` 절 표의 동일값 열(브리핑) | `gazette.py` `brief_checks()` ⚠ | **두 경로 다** |
542
+ | 본문 절의 회차 서술(「이번 회차…」) | `gazette.py` `round_talk_scan()` ⚠ | **두 경로 다** |
543
+ | 본문의 진행 상태 어휘(정해짐·회신 대기·N판) · 개수로 상태를 세는 표 제목 · 주체 없는 결정 명사(3b) | `gazette.py` `text_scan()` 과정 어휘 ⚠ | **두 경로 다** |
544
+ | 결정권이 고객에게 있는 항을 기록 없이 사실로 씀(3b 결정 주체) | 독자 검토 facts 관점(`args.decisions`) · 사람 눈(0a) — 기계는 위 명사까지 | 발행 전 |
545
+ | 권고 낱말(제목·표 열·절 이름·여백 주석·요약면)(10번) | `gazette.py` ⚠ **W1** — 이름에 「의견」이 든 절은 안 셈 | **두 경로 다** |
546
+ | 고객·제3자 자료에서 낸 도판(`user-provided`)의 출처 줄에 원본 위치(쪽·행·주소·건 §) 누락(11번) | `gazette.py` ⚠ **W2** | **두 경로 다** |
547
+ | 도판 출처 줄의 제작 설명·그림 번호 · 출처 줄 길이(0.5단계 5a행) | `gazette.py` `text_scan()` ⚠ — 캡션은 안 봄 | **두 경로 다** |
548
+ | 건 행 이름(`labels`) 낱말이 다른 절 부제·표 제목·열 머리에 다시 섬 · 선택지 기호 한 글자에 이름 둘(0.5단계 3행) | `gazette.py` `text_scan()` ⚠ · 뜻이 같은지는 사람 눈 | **두 경로 다** |
549
+ | 그림·표 번호 가리킴 — 없는 번호 · 조사 · 서지 못한/서지 않는 칸의 토큰 · `plates` 순서(0.5단계 6행) | `gazette.py` `text_scan()`·`build()` ⚠ — 번호 셈은 `fig_order()` 한 곳 | **두 경로 다** |
550
+ | 괄호 안 부연 · 흐름도 칸 `note` · 도판 캡션 문장 수(readability R11) | `gazette.py` `text_scan()` ⚠ — 한 줄 45자·요약·도입문 문장 수는 사람 눈 | **두 경로 다** |
551
+ | 요약면 막대·머리띠 요청 잔여가 문서의 셈과 어긋남 | `gazette.py` `tally_scan()` ⚠ — 대조만(탈출구 `bar_note`·빈 `remain` 은 `lim-portal-format.md` §10 표). **막대가 판단 항목 수를 세면 `remaining` 누락은 못 잡는다 — 사람 눈** | **두 경로 다** |
552
+ | 도판 문법 — R0·R0b·R1c·R13a~d 와 도판 예산(장당·합계) | `figure.mjs` ✗(R13d·예산 90% 는 ⚠, 면제는 `--allow <규칙>`) · `--batch` 예산 합계 · 두 칸 규격은 `pair.mjs` · 칩 문구의 뜻은 사람 눈 | 도판 굽기(6단계) |
553
+ | 선택지 사이 대칭 · 조건표가 모든 도안과 맞는가 · 그림이 본문을 반박하는가(0.5단계 5행) | 독자 검토 figures 관점(PNG 를 열어 잼) · 사람 눈(`process.md` 7단계 표) | 발행 전 |
554
+ | 확인 수준보다 앞선 완료형 동사(코드만 고쳤는데 「앱에서 보이지 않음」)(3) | 독자 검토 state 관점(`args.state`) · 사람 눈 | 발행 전 |
555
+ | 작성일 세 자리 불일치(3c) | `gazette.py` `date_scan()` ⚠ — 0 채움으로 견줌, `cover_date` 는 안 봄 | **두 경로 다** |
556
+ | 공개 전 판을 `history` 에 쌓음 · 공개하는 날과 다름(3c) | **없음** — 사람(체크리스트 10단계) | — |
550
557
  | 확인 포기 문구(「흐리다」「못 연다」)를 원본을 재지 않고 쓴 것(11번) | **없음** — 사람의 눈(`process.md` 7단계 표 · 독자 검토 「원본 대조」 관점) | — |
551
558
  | 부정 서술의 주어가 사람·조직·국가 | **없음** — 사람의 눈 검수 | — |
552
- | 같은 건 묶음(요지·대조표·건)이 요청 없이 두 PART 로 갈림 · 앞 PART 가 뒤 PART 물음에 먼저 답함 · 두 절 `marg.key` 가 같은 명제(readability R12g) | 독자 검토 「구조」 관점(`references/reader-review.workflow.js`) · 사람의 눈(`references/process.md` 7단계 「PART 간지」 행) — **기계 없음** | 발행 전 |
559
+ | 같은 건 묶음이 요청 없이 두 PART 로 갈림 · 앞 PART 가 뒤 PART 물음에 먼저 답함 · 두 절 `marg.key` 가 같은 명제 · 요지 칸 수·근거 문단 `body` 비움(R12g) | 독자 검토 「구조」 관점 · 사람의 눈(`references/process.md` 7단계 「PART 간지」 행) — **기계 없음** | 발행 전 |
560
+ | 스킬 문서의 줄 번호 인용(`파일.py` 뒤 쌍점과 줄 번호) · 정의가 없는 심볼 닻(`파일 이름()`) — 스킬을 고칠 때 | `tools/contract-drift.py --skill` — 기준선보다 늘면 실패, 닻은 저장소에서 정의를 찾음. 배포 관문은 아직 `--skill` 없이 돈다 | 스킬 수정 뒤 |
553
561
 
554
562
  다만 **조사·체언 종결 조각문** 규칙은 보고서 문맥에서 완화한다. 목차 항목과 건 제목은
555
563
  "…던 문제", "…내역 정리"처럼 명사구로 끝나는 것이 한국어 보고서의 관례다. 슬라이드 헤드라인과
@@ -559,7 +567,7 @@ doc-pptx 의 슬롭 3종 중 **대시 대비 헤드라인**("복붙에서 위임
559
567
  ## 폰트
560
568
 
561
569
  **폰트를 고를 자리가 없다.** 서식이 정한다 — `report.json` 에 `font` 를 적어도
562
- 두 경로 모두에서 버려진다(로컬은 `render.py:157-158` 이 블록째 교체, 포털은
570
+ 두 경로 모두에서 버려진다(로컬은 `render.py main()` 이 서식 설정으로 블록째 교체, 포털은
563
571
  `report_publish.php` 가 깎아 낸다). 그래서 `font.embed: false` 도 **안 먹는다.**
564
572
 
565
573
  지금 실리는 것: `pretendard-gazette.woff2` · **409,044B** · 가변 **wght 300–700** · 1면 ·
@@ -572,7 +580,8 @@ KS X 1001 완성형 2,350자. 관보 서식이 `--w-light: 300` 을 쓰므로 40
572
580
 
573
581
  | 파일 | 로드 조건 |
574
582
  |---|---|
575
- | `references/process.md` | **작업 순서 전체** — 0~8단계. 문서를 만들기 시작할 때 먼저 읽는다 |
583
+ | `references/process.md` | **단계마다 무엇을 쓰고 판단하는가** — 0~10단계(번호의 정본은 위 「작업 체크리스트」). 문서를 만들기 시작할 때 먼저 읽는다 |
584
+ | `references/history.md` | 규칙이 생긴 반려 경위·원문·실측 — 규칙이 아니다. 규칙 자리의 「(경위: §n)」이 가리킨다 |
576
585
  | `references/lim-portal-format.md` | **포털 발행할 때** — 관보 골격·여백 주석·PART·톤·요약 근거 게이트·운영 제약 |
577
586
  | `references/content-pipeline.md` | 데이터 모델 전수 — 절 `kind` 5종, 등급, 한국어 조판 규칙, 고객 언어 치환 |
578
587
  | `references/font-embedding.md` | 폰트를 바꾸거나 커버리지를 조정할 때 |
@@ -582,6 +591,6 @@ KS X 1001 완성형 2,350자. 관보 서식이 `--w-light: 300` 을 쓰므로 40
582
591
 
583
592
  | 파일 | 왜 남겨 두었나 |
584
593
  |---|---|
585
- | `references/illustrations.md` | `assets[].brief` 를 주면 **서버가 진짜로 그린다** — 크레딧이 타고 렌더러가 버린다(`gazette.py:878-887`). 위험이 실재해서 남긴다 |
594
+ | `references/illustrations.md` | `assets[].brief` 를 주면 **서버가 진짜로 그린다** — 크레딧이 타고 렌더러가 버린다(`gazette.py Doc.build()` 가 role 이 logo·figure 밖인 그림을 세고 버리고, `plate_block()` 은 바이트 없는 도판에 「그림 바이트가 없습니다」를 센다). 위험이 실재해서 남긴다 |
586
595
  | `references/design-system.md` | 팔레트 층이 없어졌다. 토큰을 고르려 들면 서버와 갈린다 |
587
596
  | `references/qa.md` | 검수기가 `gazette-report` 로 옮겨 갔다. 여기 목록은 옛 검사기다 |