genetics-mcp 2.9.1 → 2.9.3
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.
- package/bin/aarch64-apple-darwin/gcell +0 -0
- package/bin/aarch64-unknown-linux-musl/gcell +0 -0
- package/bin/manifest.json +4 -4
- package/bin/x86_64-apple-darwin/gcell +0 -0
- package/bin/x86_64-unknown-linux-musl/gcell +0 -0
- package/genetics.mjs +658 -26
- package/package.json +1 -1
- package/skills/genetics-cell-id/SKILL.md +204 -0
- package/skills/genetics-report/SKILL.md +217 -93
- package/skills/genetics-report/assets/example/cases.json +19 -22
- package/skills/genetics-report/assets/example/report.json +198 -53
- package/skills/genetics-report/assets/render.py +21 -10
- package/skills/genetics-report/assets/subset_font.py +24 -8
- package/skills/genetics-report/references/content-pipeline.md +316 -733
- package/skills/genetics-report/references/design-system.md +20 -723
- package/skills/genetics-report/references/font-embedding.md +132 -108
- package/skills/genetics-report/references/illustrations.md +20 -462
- package/skills/genetics-report/references/lim-portal-format.md +756 -182
- package/skills/genetics-report/references/process.md +414 -403
- package/skills/genetics-report/references/qa.md +28 -712
- package/skills/genetics-report/assets/generate-illustrations.py +0 -159
- package/skills/genetics-report/assets/qa.py +0 -198
- package/skills/genetics-report/assets/visual-baseline.py +0 -459
- package/skills/genetics-report/references/textbook-mode.md +0 -111
- package/skills/genetics-report/references/wysiwyg.md +0 -751
|
@@ -1,161 +1,168 @@
|
|
|
1
|
-
# 작업 절차
|
|
1
|
+
# 작업 절차 — 관보 기준 (2026-08-24 재작성)
|
|
2
2
|
|
|
3
|
-
SKILL.md 는
|
|
4
|
-
데이터 모델·조판 규칙은 `content-pipeline.md`, 토큰 역할은 `design-system.md`,
|
|
5
|
-
검수 항목 전체는 `qa.md`, 편집기 마크업 계약은 `wysiwyg.md`, 폰트는 `font-embedding.md` 가 맡는다.
|
|
6
|
-
여기서는 그것들을 **어떤 순서로 어떤 판단을 거쳐 채우는가**만 다룬다.
|
|
3
|
+
SKILL.md 는 「무엇을 만드는가」를 정하고, 이 문서는 **각 단계에서 실제로 무엇을 쓰고 무엇을 판단하는가**를 정한다.
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
칸 하나하나의 뜻은 `references/lim-portal-format.md`, 어휘·원고 규칙은 `references/content-pipeline.md` 가 맡는다.
|
|
6
|
+
**조판 규칙(활자 스케일·괘선·간격 격자·인쇄 페이지 문법·검사기 실행법)은 여기 안 적는다** — 원전은 `gazette-report` 스킬이다.
|
|
7
|
+
두 벌로 두면 갈라지고, 갈라지면 어느 쪽이 참인지 아무도 모른다.
|
|
8
|
+
|
|
9
|
+
이 문서의 수치와 동작은 전부 코드에서 확인했다.
|
|
10
|
+
확인 못 한 것은 맨 끝 「미확정」에 남겼다.
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
## 0. 전체 흐름
|
|
15
15
|
|
|
16
|
-
| 단계 | 하는 일 | 산출물 |
|
|
16
|
+
| 단계 | 하는 일 | 산출물 | 묻는가 | 자동 관문 |
|
|
17
17
|
|---|---|---|---|---|
|
|
18
18
|
| 0 | 독자 정의 | 독자 문장 1개 + 어휘 정책 | **반드시 묻는다** | — |
|
|
19
|
-
| 1 | 자료 수집 | 원자료(티켓·로그·대화) |
|
|
20
|
-
| 2 | 건별 정리 | `cases
|
|
21
|
-
| 3 | 등급 부여 | `
|
|
22
|
-
| 4 | 요약·확인 요청 | `
|
|
23
|
-
| 5 |
|
|
24
|
-
| 6 | 조립 |
|
|
25
|
-
| 7 |
|
|
26
|
-
| 8 | 전달 |
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
`
|
|
30
|
-
`
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
명령은 두 줄이다.
|
|
19
|
+
| 1 | 자료 수집 | 원자료(티켓·로그·대화) | 소스·범위·「고객이 아는 참조」 | — |
|
|
20
|
+
| 2 | 건별 정리 | `cases` 배열 | 안 묻는다. 단 「확인 필요」는 되돌린다 | 발행 검증(그룹 정합) |
|
|
21
|
+
| 3 | 등급 부여 | `grades` + 건별 `grade` | 등급 이름·개수만 | 없음 — 사람이 본다 |
|
|
22
|
+
| 4 | 요약·확인 요청 | `summary` · `open_items` · `cta` | 공통 원인의 실재 여부 | **요약 근거 게이트 — 발행 거절** |
|
|
23
|
+
| 5 | **여백 주석 채우기** | 절마다 `marg{why,key,advice}` | 안 묻는다 | ⚠ 경고(거절 아님) |
|
|
24
|
+
| 6 | 조립 | `parts` + `sections` + 골격 칸 | 원자료의 「확인 필요」 | 발행 검증 + 렌더러 assert 2종 |
|
|
25
|
+
| 7 | 검수 | 통과/실패 판정 | 안 묻는다 | dry_run warnings + 검사기 8종 + **사람의 눈** |
|
|
26
|
+
| 8 | 전달 | 열람 링크 또는 `.html` 하나 | **공개 직전 사람 승인** | 초안이 기본값 |
|
|
27
|
+
| 9 | 발행 뒤 판정 | outline 지문 | 안 묻는다 | `get_report(outline: true)` |
|
|
28
|
+
|
|
29
|
+
새 프로젝트에서 손대는 것은 **발행 데이터 하나**다(로컬 렌더라면 `report.json` + `cases.json`).
|
|
30
|
+
렌더러(`build.py`·`gazette.py`·`sentbreak.py`·`boundary.py`·`gazette.css`)는 레포에만 있고 프로젝트 고유 데이터를 하나도 안 갖는다.
|
|
31
|
+
|
|
32
|
+
로컬 렌더 명령은 한 줄이다.
|
|
34
33
|
|
|
35
34
|
```bash
|
|
36
|
-
python3 ~/.claude/skills/genetics-report/assets/
|
|
37
|
-
python3 ~/.claude/skills/genetics-report/assets/qa.py report.json # 실패 0 이어야 통과
|
|
35
|
+
python3 ~/.claude/skills/genetics-report/assets/render.py report.json
|
|
38
36
|
```
|
|
39
37
|
|
|
40
|
-
`
|
|
41
|
-
|
|
38
|
+
`render.py` 가 서버의 `REPORT_TEMPLATES` 를 읽어 `render`·`css`·폰트를 설정에 얹는다.
|
|
39
|
+
**`report.json` 에 `css`·`render`·`palette` 를 적지 마라** — 서버와 갈릴 수 있고, 갈리면 로컬에서 본 것과 고객이 본 것이 다르다.
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
**`build.py` 를 직접 부르지 마라.**
|
|
42
|
+
`cfg.get('css', ['report.css'])`(`build.py:285-286`)로 떨어져 옛 서식 시트가 실린다.
|
|
43
|
+
스타일이 안 맞는 문서가 검사를 통과해 「거짓 초록」이 된다.
|
|
44
|
+
|
|
45
|
+
실측(스킬 동봉 예시 · 절 5 · 건 2): 폰트 임베드 1면 409,044B → base64 545,392B · 산출물 659,164B · ⚠ 0건.
|
|
45
46
|
|
|
46
47
|
---
|
|
47
48
|
|
|
48
|
-
## 1. 0단계 —
|
|
49
|
+
## 1. 0단계 — 독자를 먼저 못 박는다
|
|
49
50
|
|
|
50
|
-
**이 스킬에서 유일하게 반드시 사용자에게 확인해야 하는 단계다.**
|
|
51
|
+
**이 스킬에서 유일하게 반드시 사용자에게 확인해야 하는 단계다.**
|
|
52
|
+
나머지는 스스로 판단해도 된다.
|
|
51
53
|
|
|
52
54
|
### 묻는 것
|
|
53
55
|
|
|
54
56
|
| 질문 | 왜 이걸 묻는가 | 예시 답 |
|
|
55
57
|
|---|---|---|
|
|
56
|
-
| 이 문서를 **읽고 판정하는 사람**은 누구인가 — 직함이 아니라 *하는 일*로 | 직함(
|
|
57
|
-
| 읽고 나서 **해야 할 행동**은 무엇인가 | `cta
|
|
58
|
-
| 문서에 실어도 되는 **참조 체계**는 무엇인가 | 독자가 확인할 수 없는 참조는 신뢰에 기여하지 않고 노이즈만 된다 |
|
|
59
|
-
|
|
|
58
|
+
| 이 문서를 **읽고 판정하는 사람**은 누구인가 — 직함이 아니라 *하는 일*로 | 직함(「팀장」)에서는 어휘 정책이 안 나온다. 행위(「검증한다」)에서는 나온다 | 「고객사 검수 담당 — 우리 작업이 실제로 해결됐는지 확인하는 사람」 |
|
|
59
|
+
| 읽고 나서 **해야 할 행동**은 무엇인가 | `cta`·`open_items`·건별 `how_to_check` 가 여기서 결정된다 | 「각 건을 한 번씩 열어 확인하고, 남은 판단 사항에 답을 준다」 |
|
|
60
|
+
| 문서에 실어도 되는 **참조 체계**는 무엇인가 | 독자가 확인할 수 없는 참조는 신뢰에 기여하지 않고 노이즈만 된다 | 「본인이 제보한 원본 링크만. 내부 티켓 번호는 안 됨」 |
|
|
61
|
+
| 전달 경로 — 포털 링크인가, 파일 하나인가, 인쇄도 도는가 | 포털은 셸이 문서 둘레에 요약·댓글을 놓는다. 파일 전달은 그것이 없다 | 「포털 링크 + 인쇄 가능해야 함」 |
|
|
60
62
|
|
|
61
63
|
### 이 답에서 곧바로 정해지는 것
|
|
62
64
|
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
-
|
|
66
|
-
|
|
65
|
+
- **금지 어휘 목록** — 독자가 검증할 수 없는 내부 어휘와 식별자.
|
|
66
|
+
로컬 렌더라면 `forbid` 정규식으로 적고, 포털 발행이라면 손으로 지킨다(7단계 참조).
|
|
67
|
+
- **PART 구성** — 독자가 바뀌면 읽기 순서가 바뀐다.
|
|
68
|
+
검수자에게는 「지금 부탁드리는 것」이 PART 1 이지만, 사후 열람자에게는 「경과」가 앞이다.
|
|
69
|
+
- **절 구성(`sections`)** — 독자가 바뀌면 절이 통째로 없어진다.
|
|
70
|
+
전 건 검수자에게는 `status` 절의 대조표가 핵심이지만, 결정권자 독자에게는 요약면 상태 막대만 남기고 대조표를 빼는 것이 맞다.
|
|
67
71
|
|
|
68
72
|
| 규칙 | 근거 | 어기면 |
|
|
69
73
|
|---|---|---|
|
|
70
|
-
| 독자를 문장 하나로 확정하기 전에는 한 건도 쓰지 않는다 | 어휘
|
|
71
|
-
| 독자를
|
|
74
|
+
| 독자를 문장 하나로 확정하기 전에는 한 건도 쓰지 않는다 | 어휘 정책·PART·절 구성이 전부 여기서 파생된다 | 전 건 재집필. 18건이면 18건 전부 |
|
|
75
|
+
| 독자를 「직함」이 아니라 「하는 일」로 받는다 | 하는 일이 정해져야 「이 사람이 확인할 수 있는가」를 매 문장에서 판정할 수 있다 | 매 건 즉흥 판단이 되고 문서 안에서 어휘가 흔들린다 |
|
|
72
76
|
|
|
73
|
-
독자를 안 정하고 만들면 **개발 로그에
|
|
74
|
-
|
|
77
|
+
독자를 안 정하고 만들면 **개발 로그에 조판만 입힌 물건**이 나온다.
|
|
78
|
+
실제로 한 번 그렇게 만들었고, 「개발팀 내부적인 작업 시나리오까지 섞어서 보고서로 보내고 있다」는 지적을 받았다.
|
|
75
79
|
|
|
76
80
|
---
|
|
77
81
|
|
|
78
82
|
## 2. 1단계 — 자료 수집
|
|
79
83
|
|
|
80
|
-
### 규칙
|
|
81
|
-
|
|
82
84
|
| 규칙 | 근거 | 어기면 |
|
|
83
85
|
|---|---|---|
|
|
84
|
-
| 티켓 본문만 읽지 않는다. **코멘트·스레드까지** 읽는다 | 실제 조치 내용은
|
|
85
|
-
| 건이 많으면 N건씩 묶어 병렬로 읽는다 |
|
|
86
|
-
| 제보 출처 링크가 있으면 **그대로** 보존한다 | `cases.
|
|
87
|
-
| 링크는 **독자가 아는 것만** 남긴다 |
|
|
86
|
+
| 티켓 본문만 읽지 않는다. **코멘트·스레드까지** 읽는다 | 실제 조치 내용은 본문이 아니라 코멘트에 적히는 것이 보통이다 | `fix` 칸이 통째로 빈다. 제목만 보고 쓴 건은 전부 「확인 필요」가 된다 |
|
|
87
|
+
| 건이 많으면 N건씩 묶어 병렬로 읽는다 | 품질이 아니라 속도 문제다 | (느릴 뿐) |
|
|
88
|
+
| 제보 출처 링크가 있으면 **그대로** 보존한다 | `cases[].source_url` → 건 필드표의 제보 원본 링크 | 접수 건과 자체 발견 건을 가르는 근거가 사라진다 |
|
|
89
|
+
| 링크는 **독자가 아는 것만** 남긴다 | 독자가 조회할 수 없는 주소는 확인 수단이 아니라 노이즈다 | 문서가 독자가 아니라 자기 조직을 향해 말한다 |
|
|
88
90
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
`source_url` 은 `http(s)` 로 시작해야 한다.
|
|
92
|
+
아니면 **발행이 거절된다**(`report_publish.php:194-197`).
|
|
91
93
|
|
|
92
|
-
**묻는다**: 원자료 소스와 범위(기간·상태 필터), 어떤 링크가
|
|
94
|
+
**묻는다**: 원자료 소스와 범위(기간·상태 필터), 어떤 링크가 「고객이 아는 참조」인지.
|
|
93
95
|
**판단한다**: 병렬 분할, 필드 추출, 어느 티켓이 한 건으로 합쳐지는지.
|
|
94
96
|
|
|
95
97
|
---
|
|
96
98
|
|
|
97
99
|
## 3. 2단계 — 건별 정리 (한 건 = 한 레코드)
|
|
98
100
|
|
|
99
|
-
`cases
|
|
101
|
+
`cases` 는 객체 배열이다.
|
|
100
102
|
|
|
101
103
|
```
|
|
102
|
-
group
|
|
104
|
+
group groups[].key 중 하나여야 한다 — 아니면 발행 거절
|
|
103
105
|
title 보고서 표제 (티켓 제목이 아니다 — 아래 참조)
|
|
104
|
-
grade
|
|
106
|
+
grade grades 키 중 하나
|
|
105
107
|
symptom 무엇이 잘못 보였는가
|
|
106
108
|
cause 왜 그랬는가 (한 문장)
|
|
107
109
|
fix 이제 어떻게 되는가
|
|
108
|
-
how_to_check 고객이 자기 화면에서 밟을 수 있는 순서
|
|
109
|
-
remaining 우리가 못 닫은 것 (없으면
|
|
110
|
-
source_url 제보 원본 링크 (없으면
|
|
110
|
+
how_to_check 고객이 자기 화면에서 밟을 수 있는 순서
|
|
111
|
+
remaining 우리가 못 닫은 것 (없으면 생략)
|
|
112
|
+
source_url 제보 원본 링크 (없으면 생략. http(s) 필수)
|
|
111
113
|
```
|
|
112
114
|
|
|
113
|
-
|
|
115
|
+
필드가 비어 있어도 렌더러는 안 죽는다(`build.py` 가 빈 문자열로 채운다).
|
|
116
|
+
**즉 빠뜨린 칸은 아무 데서도 안 잡힌다** — 사람이 세는 수밖에 없다.
|
|
114
117
|
|
|
115
118
|
### 작성 규칙 6개조
|
|
116
119
|
|
|
117
120
|
> · 파일명·함수명·커밋해시·SQL·클래스명을 쓰지 마라. 고객은 모른다.
|
|
118
|
-
> ·
|
|
121
|
+
> · 「무엇이 잘못 보였는가 → 왜 그랬는가 → 이제 어떻게 되는가」 순서로 쓴다.
|
|
119
122
|
> · 원인은 한 문장으로, 비유 없이, 사실만. 변명하지 마라.
|
|
120
123
|
> · 고객이 **직접 확인할 수 있는 방법**이 있으면 한 줄 덧붙인다.
|
|
121
|
-
> · 아직 안 끝난 게 있으면 숨기지 말고
|
|
122
|
-
> · 과장 금지.
|
|
124
|
+
> · 아직 안 끝난 게 있으면 숨기지 말고 「남은 것」으로 적는다.
|
|
125
|
+
> · 과장 금지. 「완벽히 해결」 대신 무엇을 확인했는지 쓴다.
|
|
123
126
|
>
|
|
124
|
-
> 근거가 없으면 지어내지 말고 그 필드를
|
|
127
|
+
> 근거가 없으면 지어내지 말고 그 필드를 **「확인 필요」** 로 남긴다.
|
|
125
128
|
|
|
126
129
|
| 규칙 | 근거 | 어기면 |
|
|
127
130
|
|---|---|---|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
| 근거 없는 필드는 **"확인 필요"** 로 남기고 사용자에게 되돌린다 | 추측이 사실 진술의 활자로 인쇄되면 회복 불가능하다 | 발송 후에는 회수할 수 없다 |
|
|
131
|
-
| `how_to_check` 는 **전 건 필수** | `qa.py` 구조 검사가 `class="row r-check"` 개수와 건 수를 대조한다. 한 건이라도 비면 실패 | 검수 요청이 아니라 통보가 된다 |
|
|
132
|
-
|
|
133
|
-
실측 확인: 18건 중 한 건의 `how_to_check` 를 비우고 빌드하면 QA 가 `❌ 확인 방법 17/18` 로 잡는다.
|
|
134
|
-
예시 프로젝트 최종 `cases.json` 에는 "확인 필요"가 0건이다 — 되돌려 전부 채운 뒤 조립에 들어갔다는 뜻이다.
|
|
131
|
+
| 근거 없는 필드는 「확인 필요」로 남기고 사용자에게 되돌린다 | 추측이 사실 진술의 활자로 인쇄되면 회복 불가능하다 | 발송 후에는 회수할 수 없다 |
|
|
132
|
+
| `how_to_check` 는 **전 건 필수** | 없으면 검수 요청이 아니라 통보다 | 기계가 안 잡는다. 사람이 건 수와 대조한다 |
|
|
135
133
|
|
|
136
134
|
### `title` 은 티켓 제목이 아니다
|
|
137
135
|
|
|
138
|
-
원자료 제목에는 `>` 구분자, `#2`, `[후속]`, `(심각)
|
|
139
|
-
|
|
136
|
+
원자료 제목에는 `>` 구분자, `#2`, `[후속]`, `(심각)` 처럼 티켓에서만 뜻이 통하는 표기와 내부 용어가 섞여 있다.
|
|
137
|
+
전 건 제목을 **보고서 표제로 다시 쓴 뒤** 데이터에 넣는다.
|
|
138
|
+
|
|
139
|
+
> 예: 「RN 앱 토큰 부활 경합」 → 「로그아웃 직후 이전 로그인 상태로 되돌아가던 상황」
|
|
140
|
+
|
|
141
|
+
### ⚠ `text_fix` 치환표는 관보에서 **안 돈다** (코드 확인 · 옛 문서와 어긋남)
|
|
140
142
|
|
|
141
|
-
|
|
143
|
+
`text_fix` 는 `build.py:516` 에만 있고, 그 줄은 **옛 「수정 내역 보고」 경로 안**이다.
|
|
144
|
+
관보 경로 `build_gazette()`(`build.py:421-454`)는 그 코드를 지나지 않고, `gazette.py` 에는 `text_fix` 라는 낱말이 아예 없다.
|
|
145
|
+
서버는 그 키를 화이트리스트에 넣어 **받기만 한다**(`report_publish.php:45`) — 설정에 실어 두고 아무도 안 읽는다.
|
|
142
146
|
|
|
143
|
-
|
|
144
|
-
|
|
147
|
+
실측(2026-08-24): `{"from":"레코드","to":"항목"}` 을 넣고 원고에 「레코드」를 심어 렌더했더니 **「레코드」가 그대로 산출물에 남았다.**
|
|
148
|
+
|
|
149
|
+
그러므로 **고객 언어 치환은 원고에서 직접 한다.**
|
|
150
|
+
치환 누락을 잡는 그물은 `forbid` 하나뿐이고, 그것도 로컬 렌더에서만 돈다(6단계).
|
|
145
151
|
|
|
146
152
|
---
|
|
147
153
|
|
|
148
154
|
## 4. 3단계 — 등급 부여 (독립 단계로 분리한다)
|
|
149
155
|
|
|
150
|
-
검수 독자가 가장 먼저 보는 축이다.
|
|
156
|
+
검수 독자가 가장 먼저 보는 축이다.
|
|
157
|
+
「이걸 너희는 어디까지 확인했는가」에 답하는 장치다.
|
|
151
158
|
|
|
152
159
|
### 분류 규율
|
|
153
160
|
|
|
154
|
-
각 건의 `fix
|
|
161
|
+
각 건의 `fix`·`how_to_check` 본문을 읽고, **본문에 실제로 적혀 있는 근거만으로** 분류한다.
|
|
155
162
|
|
|
156
|
-
예시
|
|
163
|
+
예시(4단계, 강한 순):
|
|
157
164
|
|
|
158
|
-
| 등급 | 뜻 (문서에
|
|
165
|
+
| 등급 | 뜻 (범례로 문서에 함께 실린다) | 붙는 조건 |
|
|
159
166
|
|---|---|---|
|
|
160
167
|
| 운영 환경 확인 | 운영 환경에서 실제로 동작시켜 결과까지 확인 | 실제 환경에서 재현·확인했다고 본문에 적혀 있음 |
|
|
161
168
|
| 실데이터 대조 | 운영 데이터를 건별로 대조해 확인 | 데이터를 조회·대조했다고 적혀 있음 |
|
|
@@ -164,473 +171,477 @@ source_url 제보 원본 링크 (없으면 생략)
|
|
|
164
171
|
|
|
165
172
|
| 규칙 | 근거 | 어기면 |
|
|
166
173
|
|---|---|---|
|
|
167
|
-
| **본문에 적힌 근거로만**
|
|
168
|
-
| 승급의
|
|
174
|
+
| **본문에 적힌 근거로만** 분류한다 | 독자는 문서 밖을 볼 수 없다. 등급은 *문서가 주장할 수 있는 것*이지 실제로 한 일이 아니다 | 등급이 자기 신고가 된다 |
|
|
175
|
+
| 승급의 근거를 **본문의 짧은 원문 인용**(30자 이내)으로 스스로 확인한다 | 인용이 안 잡히면 그 등급을 주장할 근거가 본문에 없다는 뜻이다 | 근거 없는 승급을 막을 수단이 사라진다 |
|
|
169
176
|
| **최약 등급이 기본값**이다 | 근거가 없으면 최약 등급 | 근거 없는 건이 중간 등급으로 흘러 등급 축 전체가 무의미해진다 |
|
|
170
|
-
| 최약 등급의 정의문에 **한계를 명시**한다 |
|
|
177
|
+
| 최약 등급의 정의문에 **한계를 명시**한다 | 등급 이름만으로는 무엇을 안 했는지 알 수 없다 | 검수 독자는 「전부 완료」보다 「여기까지만 확인함」을 훨씬 신뢰한다 |
|
|
171
178
|
| 등급 부여를 **요약 집필과 다른 판단으로** 분리한다(가능하면 다른 에이전트) | 요약을 쓰는 사람이 등급도 매기면 자기 요약을 뒷받침하도록 등급이 끌려간다 | 요약과 등급 축이 서로를 증명하는 순환이 된다 |
|
|
172
179
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
문장 중간에서 잘린 인용은 조치 본문과 중복이고 읽기만 방해한다.
|
|
180
|
+
등급 인용은 **작업 중 산출물**이고 발행 데이터에 남지 않는다.
|
|
181
|
+
문서에 발췌 인용을 넣지는 않는다 — 문장 중간에서 잘린 인용은 조치 본문과 중복이고 읽기만 방해한다.
|
|
176
182
|
|
|
177
|
-
### `grades`
|
|
183
|
+
### `grades` 는 **키 순서가 강도 순서**다
|
|
178
184
|
|
|
179
|
-
`
|
|
180
|
-
|
|
181
|
-
등급만 그리고(`build.py`: `for k in grades if mc.get(k)`), `qa.py` 는 `grades` 를 읽지 않으므로
|
|
182
|
-
안 쓰는 등급을 남겨 두어도 검사는 통과한다(실측 확인).
|
|
185
|
+
`gazette.py:80-83` 이 주석으로 「스킬 2단계가 계약」이라고 물고 있다.
|
|
186
|
+
자리로 세기를 정한다 — JSON 객체의 키 순서가 그대로 강한 순이다.
|
|
183
187
|
|
|
184
|
-
|
|
188
|
+
```
|
|
189
|
+
RANK_LVL = ['full', 'half', 'open', 'open'] # 대조표의 강도 표식
|
|
190
|
+
RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
실측으로 나오는 두 가지 한계(`gazette.py:751-762`).
|
|
194
|
+
|
|
195
|
+
- **강도 표식은 3단까지만 갈린다.** 3번째와 4번째가 둘 다 `open` 이다.
|
|
196
|
+
- **5번째 등급부터는 전부 최약 표식으로 눌린다**(`table[-1]`). `grades` 에 없는 이름을 건에 적어도 같다.
|
|
197
|
+
|
|
198
|
+
그래서 등급은 **4단 이하**로 짠다.
|
|
199
|
+
더 필요하면 `grades[k]` 의 3·4번째 자리에 표식·배지 이름을 직접 준다(같은 함수의 `slot` 분기).
|
|
185
200
|
|
|
186
201
|
**묻는다**: 등급 이름과 개수가 프로젝트에 맞는지.
|
|
187
|
-
**협상 대상이 아닌 것**:
|
|
202
|
+
**협상 대상이 아닌 것**: 「근거 없으면 최약 등급」, 「최약 등급 정의에 한계 명시」.
|
|
188
203
|
|
|
189
204
|
---
|
|
190
205
|
|
|
191
206
|
## 5. 4단계 — 요약·확인 요청 집필
|
|
192
207
|
|
|
193
|
-
건별 내용이 아니라 **문서의 판단 층**이다.
|
|
208
|
+
건별 내용이 아니라 **문서의 판단 층**이다.
|
|
209
|
+
|
|
210
|
+
### 문체
|
|
194
211
|
|
|
195
|
-
|
|
212
|
+
개조식이다 — `~함` / `~했음` / `~필요` / `~한 상황`.
|
|
213
|
+
대응표는 `references/lim-portal-format.md` §1.
|
|
196
214
|
|
|
197
215
|
> · 개발 용어(파일명·커밋해시·SQL·클래스명) 금지. **배포 단계 용어(스테이징/테스트환경) 금지.**
|
|
198
|
-
> · 결론을 먼저 쓴다. 각 문단은
|
|
216
|
+
> · 결론을 먼저 쓴다. 각 문단은 리드 문장 하나로 시작한다.
|
|
199
217
|
> · 과장 금지. 확인한 것과 확인하지 못한 것을 구분해서 쓴다.
|
|
200
|
-
> · 전 건이 이미 조치·반영을 마쳤다면 **"해결했으니 검토해 달라"가 기본 입장**이다.
|
|
201
218
|
|
|
202
|
-
|
|
219
|
+
문체를 안 바꾸면 낱말이 아니라 **조판의 문제**로 남는다 — 경어체 문장은 관보 문법 위에서 겉돈다.
|
|
220
|
+
`tone.mjs` 가 경어체 잔존을 센다.
|
|
203
221
|
|
|
204
|
-
`
|
|
205
|
-
|
|
222
|
+
### `summary` — 4개의 `{lead, body, refs}`
|
|
223
|
+
|
|
224
|
+
`lead` 는 결론 한 문장, `body` 는 2~4문장.
|
|
225
|
+
**건별 나열 금지** — 검수자가 요약면에서 판단을 끝낼 수 있어야 한다.
|
|
206
226
|
|
|
207
227
|
1. 접수된 N건이 어떤 성격이었고 지금 어떤 상태인가
|
|
208
228
|
2. 확인 과정에서 함께 발견해 고친 것 중 영향이 컸던 것
|
|
209
|
-
3. 여러 건을 관통하는 **공통 원인**이 있다면 그것
|
|
229
|
+
3. 여러 건을 관통하는 **공통 원인**이 있다면 그것 — **실재할 때만 쓴다.** 없는데 만들어 내면 그게 이 문서에서 가장 나쁜 슬롭이다
|
|
210
230
|
4. 검토 요청 — 무엇을 봐 주면 되는지
|
|
211
231
|
|
|
212
|
-
|
|
213
|
-
공통 원인이 실재할 때만 `report.json` 의 `figure` 로 도해(인라인 SVG)를 붙인다.
|
|
214
|
-
도해 색은 전부 `var(--…)` 토큰이어야 한다 — 인라인 SVG 는 사용자 정의 속성을 상속하므로
|
|
215
|
-
`fill="var(--primary-bg)"` 가 그대로 동작하고, 팔레트를 갈아끼워도 도해가 따라온다.
|
|
232
|
+
### 요약 근거 게이트 — 발행이 **거절**된다
|
|
216
233
|
|
|
217
|
-
|
|
234
|
+
`report_publish.php:260-287` 이 짝을 이룬 두 검사를 건다.
|
|
218
235
|
|
|
219
|
-
|
|
236
|
+
| 검사 | 무엇을 보는가 | 어기면 |
|
|
237
|
+
|---|---|---|
|
|
238
|
+
| 참조 존재 | 문단마다 근거 최소 하나 | 거절 |
|
|
239
|
+
| 참조 실재 | 그 번호가 실제로 있는 사례인가 | 거절 |
|
|
220
240
|
|
|
221
|
-
|
|
241
|
+
근거는 두 모양 다 받는다 — `refs: ["3.1"]` 또는 본문 안의 `§3.1`.
|
|
242
|
+
사례 번호는 입력에 없다 — `groups[].no` 아래로 1부터 서버가 **계산**한다.
|
|
222
243
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
`같은 원인으로 생긴 피해 범위를 끝까지 세지 못했습니다`.
|
|
244
|
+
> ⚠ **사례가 없는 문서는 `summary` 를 쓸 수 없다.**
|
|
245
|
+
> `cases` 가 비면 있는 번호가 0개라 모든 요약 문단이 「근거 없음」으로 거절된다.
|
|
246
|
+
> 요청·안내만 있는 문서라면 `summary` 를 비우고 요지를 `notice`·`bar_note`·`asks` 절 `lede` 로 옮긴다.
|
|
227
247
|
|
|
228
|
-
|
|
229
|
-
|---|---|---|
|
|
230
|
-
| 확인 요청 절의 주어는 **우리**다 | 위 규칙 | 마무리 못 한 쪽이 상대에게 일을 넘기는 문서가 된다 |
|
|
231
|
-
| 결론 먼저, 문단당 리드 1문장 | `.ex-lead` 가 있어야 요약 그리드의 시각 위계가 선다 | 굵게 렌더할 것이 없어 4칸이 균질한 회색 덩어리가 된다 |
|
|
232
|
-
| 확인한 것과 확인 못 한 것을 **문장 안에서 구분**한다 | 등급 축(3단계)과 본문이 어긋나면 안 된다 | 검수 독자는 그 어긋남을 가장 먼저 찾아낸다 |
|
|
233
|
-
| 파괴적 동작은 **결과를 같이 적고, 두 곳에 중복**한다 | 예시: `[발송] 버튼은 실제로 고객에게 알림톡이 나가므로 누르지 말아 주시기 바랍니다` — `summary` 4번과 `cta` 두 곳 | 한 곳에만 있으면 훑어 읽는 독자가 놓친다. 이 중복은 실수가 아니라 설계다 |
|
|
248
|
+
### `open_items` — 3~6개의 `{title, body, refs[]}`
|
|
234
249
|
|
|
235
|
-
|
|
250
|
+
건별 `remaining` 을 **성격별로 묶는다.**
|
|
251
|
+
건별로 다시 나열하지 않는다.
|
|
236
252
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
`figure` 로 지정한 파일도 통째로 삽입된다. 나머지 필드는 전부 `e()` 로 이스케이프된다.
|
|
253
|
+
> 이건 고객 숙제 목록이 아니라 **우리가 확정하지 못한 것을 밝히는** 절이다.
|
|
254
|
+
> 주어를 우리로 써라.
|
|
240
255
|
|
|
241
|
-
|
|
256
|
+
이 한 줄이 문서의 성격을 바꾼다.
|
|
257
|
+
같은 데이터를 「고객이 해야 할 일」로 쓰면 책임 전가 문서가 되고, 「우리가 아직 못 닫은 것」으로 쓰면 신뢰 문서가 된다.
|
|
258
|
+
그래서 `open_items[].title` 은 전부 1인칭이다 — `검증에 쓴 표본이 작음`, `같은 전화번호를 쓰는 계정의 주인은 우리가 판단할 수 없음`.
|
|
259
|
+
|
|
260
|
+
| 규칙 | 어기면 |
|
|
261
|
+
|---|---|
|
|
262
|
+
| 확인 요청 절의 주어는 **우리**다 | 마무리 못 한 쪽이 상대에게 일을 넘기는 문서가 된다 |
|
|
263
|
+
| 확인한 것과 확인 못 한 것을 **문장 안에서 구분**한다 | 등급 축과 본문이 어긋나고, 검수 독자는 그 어긋남을 가장 먼저 찾아낸다 |
|
|
264
|
+
| 파괴적 동작은 결과를 같이 적고 **두 곳에 중복**한다(요약 + `asks`) | 한 곳에만 있으면 훑어 읽는 독자가 놓친다. 이 중복은 실수가 아니라 설계다 |
|
|
242
265
|
|
|
243
|
-
|
|
244
|
-
`§` 기호를 버린다(§ 는 법령·논문 기호이지 보고서 활자가 아니다). 검수자는 건과 건을 오가며 대조하므로
|
|
245
|
-
손으로 찾게 두면 안 된다.
|
|
266
|
+
### `§` 는 원고 마커다
|
|
246
267
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
**통과하지 않는 자리**: 모든 제목(`title`, `open_items[].title`), 지표 라벨, 표지 메타.
|
|
268
|
+
절 참조는 원고에 `§3.1` 로 쓴다.
|
|
269
|
+
렌더러의 `link()` 가 앵커로 바꾸며 `§` 기호를 버린다 — `§` 는 법령·논문 기호이지 보고서 활자가 아니다.
|
|
250
270
|
|
|
251
|
-
|
|
271
|
+
`link()` 를 안 거친 자리에 `§n.n` 이 남으면 **렌더가 중단된다**(`build.py:390-393`).
|
|
272
|
+
제목·라벨·표지 메타는 `link()` 를 안 지난다 — 거기 절 참조를 쓰지 마라.
|
|
252
273
|
|
|
253
274
|
---
|
|
254
275
|
|
|
255
|
-
## 6. 5단계 —
|
|
276
|
+
## 6. 5단계 — 여백 주석(`marg`)을 채운다
|
|
277
|
+
|
|
278
|
+
**여기가 관보의 본체다.**
|
|
279
|
+
옛 절차의 이 자리에는 팔레트 고르기가 있었다.
|
|
280
|
+
관보에는 팔레트가 없다(`build_gazette` 가 `styles(..., tokens=False)` 로 부른다 — `build.py:441`).
|
|
281
|
+
고를 색이 없어진 자리를 **채울 문장**이 대신한다.
|
|
256
282
|
|
|
257
|
-
|
|
283
|
+
`marg` 가 비면 렌더러가 경고한다(`gazette.py:400-402`).
|
|
258
284
|
|
|
259
285
|
```
|
|
260
|
-
|
|
286
|
+
절 03 「처리 현황」에 여백 주석(marg.why/key/advice)이 없습니다 — 두 단 본문이 한 단으로 섭니다
|
|
261
287
|
```
|
|
262
288
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
289
|
+
거절이 아니라 경고다.
|
|
290
|
+
**즉 안 채워도 문서는 나온다** — 그리고 그 문서는 「문서처럼 꾸민 웹페이지」로 되돌아간다.
|
|
291
|
+
이 경고를 안고 고객에게 링크를 보내지 마라.
|
|
266
292
|
|
|
267
|
-
|
|
268
|
-
Korean Navy 의 Gold `#C9A961` 은 흰 바탕에서 **2.25:1** 이라 글자로 쓰면 WCAG 를 통과하지 못한다.
|
|
269
|
-
그래서 같은 색을 용도별로 쪼갠다 — `--accent`(배경·괘선 전용) / `--accent-mid`(24px+ Bold, 3:1) /
|
|
270
|
-
`--accent-ink`(작은 글자, 4.5:1) / `--accent-chip`+`--accent-on`(칩 배경과 그 위 글자, 쌍으로만 쓴다).
|
|
271
|
-
토큰 역할의 전모는 `design-system.md`.
|
|
293
|
+
### 세 줄이 각각 무엇인가
|
|
272
294
|
|
|
273
|
-
|
|
295
|
+
| 칸 | 무엇을 적는가 | 문형 |
|
|
296
|
+
|---|---|---|
|
|
297
|
+
| `why` | 그 절을 **왜** 읽는가. 독자가 실제로 던질 질문 그대로 | `~하는가?` / `~인가?` (`~합니까?` 아님) |
|
|
298
|
+
| `key` | 이 절에서 하나만 가져간다면 그것 | 개조식 단문 |
|
|
299
|
+
| `advice` | 어디를 참조해야 하는지. 근거의 출처를 가리킨다 | 개조식 단문 |
|
|
274
300
|
|
|
275
|
-
|
|
276
|
-
|
|
301
|
+
셋 중 채운 것만 그려진다.
|
|
302
|
+
하나도 없으면 `<aside class="marg">` 자체가 안 나오고 본문이 한 단이 된다.
|
|
277
303
|
|
|
278
|
-
|
|
304
|
+
### 나쁜 `marg` 의 모양 넷
|
|
305
|
+
|
|
306
|
+
| 모양 | 왜 나쁜가 |
|
|
279
307
|
|---|---|
|
|
280
|
-
|
|
|
281
|
-
|
|
|
282
|
-
|
|
|
283
|
-
|
|
|
284
|
-
| 한국 중견기업 B2B | `korean-brick` |
|
|
285
|
-
| 헬스·교육 | `korean-sage` |
|
|
286
|
-
| 임팩트 | `high-contrast` |
|
|
308
|
+
| 본문 첫 문장을 그대로 옮긴 `key` | 같은 것이 두 번 있게 된다. 여백 단은 요약란이 아니라 **다른 층위**다 |
|
|
309
|
+
| 「이 절에서는 …을 설명합니다」류의 `why` | 독자의 질문이 아니라 저자의 목차다. 독자는 그 질문을 던지지 않는다 |
|
|
310
|
+
| 어느 절에나 붙는 `advice` (「자세한 내용은 본문 참조」) | 가리키는 곳이 없으면 안 쓰느니만 못하다. **실제 절 번호**를 대라 |
|
|
311
|
+
| 채우려고 넣은 세 줄 | 세 칸을 다 채우는 것이 목표가 아니다. 할 말이 둘이면 둘만 쓴다 |
|
|
287
312
|
|
|
288
|
-
|
|
289
|
-
`python3 palette.py` 를 단독 실행하면 9개 전부의 감사 결과가 나온다. **9개 전부 OK 다**(실측).
|
|
290
|
-
Dark Editorial 은 다크 배경 팔레트라 흰 바탕 인쇄 전제와 맞지 않아 제외돼 있다.
|
|
313
|
+
### 절 종류별로 성격이 갈린다
|
|
291
314
|
|
|
292
|
-
|
|
315
|
+
| kind | `why` 가 답하는 질문 | `key` 가 담는 것 |
|
|
316
|
+
|---|---|---|
|
|
317
|
+
| `asks` | 무엇을 조치해야 하는가? | 그중 가장 시급한 것 하나 |
|
|
318
|
+
| `summary` | 이번 회차는 결국 어떻게 됐는가? | 판단에 필요한 한 문장 |
|
|
319
|
+
| `status` | 어디까지 믿어도 되는가? | 등급 축이 뜻하는 것 |
|
|
320
|
+
| `cases` | 무엇을 고쳤는가? | 이 묶음의 성격(접수 건인가 자체 발견인가) |
|
|
321
|
+
| `note` | 무엇을 아직 모르는가? | 확인 못 한 범위 |
|
|
293
322
|
|
|
294
|
-
|
|
323
|
+
### 분량
|
|
295
324
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
```
|
|
325
|
+
여백 주석 단은 좁다 — `--marg: 240px`(실측).
|
|
326
|
+
한글로 19자/줄쯤이다.
|
|
327
|
+
**한 칸을 두 문장 넘게 쓰지 마라** — 절반 넘게 접힌다.
|
|
300
328
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
다만 `ink` 를 흐린 회색으로 주면 유도로 구제할 수 없어 **빌드가 중단된다**(실측):
|
|
329
|
+
글줄 폭 근거와 자폭 실측치는 `gazette-report` 스킬에 있다.
|
|
330
|
+
여기 옮겨 적지 않는다.
|
|
304
331
|
|
|
305
|
-
|
|
306
|
-
AssertionError: 팔레트 대비 미달: [('본문 ink/paper', 3.45), ('본문 ink/surface', 3.38), …]
|
|
307
|
-
```
|
|
332
|
+
---
|
|
308
333
|
|
|
309
|
-
|
|
334
|
+
## 7. 6단계 — 조립
|
|
310
335
|
|
|
311
|
-
|
|
312
|
-
|---|---|---|
|
|
313
|
-
| 한 문서 한 팔레트 | `:root` 는 하나만 주입된다 | — |
|
|
314
|
-
| **`--accent` 를 글자색으로 쓰지 않는다** | `qa.py` 가 `color:var(--accent)` 를 실패로 잡는다(하이픈 접두 속성은 제외하므로 `border-color` 는 정상) | 2.25:1. "좀 연하네"로만 보이고 대비 미달인 줄 모른다 |
|
|
315
|
-
| `--mid` 는 괘선 전용 | 같은 검사가 `color:var(--mid)` 도 실패로 잡는다 | 2.3:1 |
|
|
316
|
-
| 색을 손으로 추가하지 않는다 | 하드코딩 hex 는 QA 경고로 잡히고, 팔레트를 갈아끼울 때 그 색만 남는다 | 팔레트 교체가 반쪽이 된다 |
|
|
336
|
+
### 골격 순서는 바꾸지 않는다
|
|
317
337
|
|
|
318
|
-
|
|
319
|
-
빌드·QA 를 돌리면 셋 다 `통과 48 · 경고 1 · 실패 0` 이다(실측).
|
|
338
|
+
`gazette.py:898-906` 이 순서를 고정한다.
|
|
320
339
|
|
|
321
|
-
|
|
340
|
+
```
|
|
341
|
+
표지 → 발행 이력 → 차례 → 이 문서 읽는 법 → 요약
|
|
342
|
+
→ PART 간지 → 절 → … → 부록 → 판권지
|
|
343
|
+
```
|
|
322
344
|
|
|
323
|
-
|
|
345
|
+
칸 하나하나의 뜻과 예시는 `references/lim-portal-format.md`.
|
|
324
346
|
|
|
325
|
-
|
|
347
|
+
### PART 를 먼저 가른다
|
|
326
348
|
|
|
327
|
-
|
|
349
|
+
`parts` 가 없으면 경고 뒤 절 전체가 한 묶음으로 선다(`gazette.py:843-847`).
|
|
350
|
+
그러면 「먼저 읽을 것 / 경과 / 남은 것」이라는 **읽기 순서가 사라진다.**
|
|
328
351
|
|
|
329
|
-
|
|
352
|
+
가르는 기준은 절의 성격이 아니라 **독자가 무엇을 해야 하는가**다.
|
|
330
353
|
|
|
331
|
-
|
|
|
354
|
+
| PART | 독자의 몫 | 대개 들어가는 kind |
|
|
332
355
|
|---|---|---|
|
|
333
|
-
|
|
|
334
|
-
|
|
|
335
|
-
|
|
|
336
|
-
| `asks` | CTA 박스 + 확인 요청 카드 2열 | `cta`, `open_items` |
|
|
337
|
-
| `note` | 꼬리 문단 | `paragraphs` |
|
|
356
|
+
| 1 요청 | 지금 해야 할 것 | `asks` |
|
|
357
|
+
| 2 경과 | 읽고 확인할 것 | `summary` · `status` · `cases` |
|
|
358
|
+
| 3 남은 것 | 알아 둘 것 | `note` |
|
|
338
359
|
|
|
339
|
-
|
|
340
|
-
목차는 좌측 고정 열이다 — 본문 위에 얹으면 웹앱처럼 보인다.
|
|
360
|
+
절이 하나뿐인 묶음도 간지를 둔다 — 간지는 장식이 아니라 층위 표시다.
|
|
341
361
|
|
|
342
|
-
|
|
362
|
+
### `kind` 는 다섯뿐이다
|
|
343
363
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
364
|
+
`summary` · `status` · `cases` · `asks` · `note`.
|
|
365
|
+
그 밖의 값은 **서버가 거절한다**(`REPORT_RENDER_KINDS`, `report_publish.php:96·172-175`).
|
|
366
|
+
거절하는 이유는 완성도가 아니라 손실이다 — 모르는 `kind` 의 절은 렌더러가 아무 말 없이 통째로 빠뜨린다.
|
|
367
|
+
|
|
368
|
+
`tone` 은 여섯이다(`you`·`deep`·`neutral`·`done`·`wait`·`hold`).
|
|
369
|
+
목록 밖의 값은 **조용히 `neutral` 로 강등된다**(`gazette.py:801-802`) — 기계가 안 잡으니 눈으로 본다.
|
|
370
|
+
생략하면 `kind` 가 정한다.
|
|
347
371
|
|
|
348
|
-
|
|
349
|
-
확인 요청이 없는 건은 `.ck.one` 으로 한 칸이 된다.
|
|
372
|
+
### 렌더러가 자동으로 하는 것
|
|
350
373
|
|
|
351
|
-
|
|
374
|
+
| 무엇 | 어디서 | 원고에서 할 일 |
|
|
375
|
+
|---|---|---|
|
|
376
|
+
| 문장 단위 줄바꿈 (`<span class="sn">`) | `sentbreak.py` + `boundary.py` 를 렌더러가 부른다 | **문장을 짧게 끊는다.** 낱말은 하나도 안 바뀐다 |
|
|
377
|
+
| `§3.1` → 앵커 링크 | `link()` | 절 참조를 `§n.n` 으로 적는다 |
|
|
378
|
+
| 사례 번호 계산 | `groups[].no` 아래로 1부터 | 번호를 손으로 적지 않는다 |
|
|
352
379
|
|
|
353
|
-
|
|
354
|
-
|
|
380
|
+
**긴 산문의 문단 분절은 자동으로 안 된다.**
|
|
381
|
+
옛 경로의 `chunk()` 는 관보 렌더러에 안 넘어간다(`build.py:440` 이 `{'e', 'link'}` 만 준다).
|
|
382
|
+
문단은 원고에서 끊는다.
|
|
355
383
|
|
|
356
|
-
|
|
357
|
-
AssertionError: 그룹에 배정되지 않은 건이 있다: 17/18 — cases 의 group 값이 ['reported', 'own'] 중 하나여야 한다
|
|
358
|
-
```
|
|
384
|
+
### 관보에 자리가 없는 칸
|
|
359
385
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
386
|
+
`chapters`(챕터 오프닝) · `figure`(요약 도형) · `principles` · `logic` · `assets` 중 `role != "logo"` 인 것.
|
|
387
|
+
전부 **세고 버린다**(`gazette.py:878-896`).
|
|
388
|
+
보낸 사람이 실린 줄 알면 안 되므로 ⚠ 로 소리 내어 센다.
|
|
363
389
|
|
|
364
|
-
|
|
390
|
+
`assets[].brief` 를 주면 **서버가 진짜로 그린다** — 크레딧이 타고 렌더러가 버린다.
|
|
391
|
+
자세한 것은 `references/illustrations.md`.
|
|
365
392
|
|
|
366
|
-
|
|
393
|
+
### 방어선
|
|
394
|
+
|
|
395
|
+
| 층 | 무엇을 잡는가 | 결과 |
|
|
367
396
|
|---|---|---|
|
|
368
|
-
| `
|
|
369
|
-
| `link()`
|
|
370
|
-
|
|
|
397
|
+
| 서버 검증 | 모르는 `kind` · 없는 그룹 · 없는 PART · 요약 근거 · `source_url` 모양 · 목록/객체 모양 | **발행 거절** |
|
|
398
|
+
| 렌더러 assert | `link()` 를 안 거친 `§n.n` · `forbid` 정규식 적중 | **렌더 중단(파일 안 씀)** |
|
|
399
|
+
| 렌더러 ⚠ | `marg` 없음 · `parts` 없음 · 그룹 미배정 건 · 자리 없는 그림 | 경고만 |
|
|
371
400
|
|
|
372
|
-
|
|
401
|
+
### ⚠ `forbid` 는 **로컬 렌더에서만** 돈다 (코드 확인)
|
|
373
402
|
|
|
374
|
-
|
|
375
|
-
- `
|
|
376
|
-
- 열거가 아니면서 `길이 > 180자` 이고 `문장 > 2개` 면 두 문장 단위로 `<p>` 분절. 문장 분리는 한국어 종결어 기준(`(?<=다\.)`, `(?<=요\.)`, `(?<=오\.)`).
|
|
403
|
+
`guard()`(`build.py:394-396`)가 `cfg['forbid']` 를 읽어 산출물을 훑고, 걸리면 assert 로 죽는다.
|
|
404
|
+
실측(2026-08-24): 금지어 「티켓」을 원고에 심고 `render.py` 를 돌리면 `AssertionError: 금지 표현 유출: 티켓 → ['티켓']` 으로 멈추고 파일이 안 써진다.
|
|
377
405
|
|
|
378
|
-
|
|
406
|
+
그런데 포털 발행에서는 이 그물이 없다.
|
|
407
|
+
`forbid` 는 `REPORT_CLIENT_KEYS` 에 없어서 `report_client_fields()` 가 **깎아 낸다**(`report_publish.php:76` 이 「서버만 정한다」고 명시).
|
|
408
|
+
서버는 그 값을 따로 안 채운다 — 빈 채로 렌더러에 닿는다.
|
|
379
409
|
|
|
380
|
-
|
|
381
|
-
|
|
410
|
+
포털 발행이 최종 경로라도 **발행 전에 같은 데이터를 로컬로 한 번 구워서 `forbid` 그물을 통과시켜라.**
|
|
411
|
+
그것이 지금 유일한 자동 어휘 관문이다.
|
|
382
412
|
|
|
383
|
-
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## 8. 7단계 — 검수
|
|
416
|
+
|
|
417
|
+
관문은 셋이고, 셋 다 다른 것을 본다.
|
|
418
|
+
|
|
419
|
+
| 층 | 무엇을 보는가 | 통과 기준 |
|
|
384
420
|
|---|---|---|
|
|
385
|
-
|
|
|
386
|
-
|
|
|
387
|
-
|
|
|
388
|
-
| 내부 산출물 규모 | `저장 경로 6곳을 수정했고` | `저장이 일어나는 모든 경로를 수정했고` |
|
|
389
|
-
| 내부 검증 산출물 | `자동 검증 2건을 추가했습니다` | `같은 문제가 다시 나타나면 곧바로 걸러지도록 상시 점검을 걸어 두었습니다` |
|
|
390
|
-
| 앱 배포 경로 | `다음 스토어 빌드부터` | `다음 앱 업데이트부터` |
|
|
391
|
-
| 설계 검토 이력 | `처음 검토안 중 '…'은 …위험이 있어 제외했습니다.` | **삭제(`""`)** |
|
|
392
|
-
| 화면에 영향 없는 내부 잔여 | `이 밖에 지금은 쓰이지 않는 잔여 기능 정리가 별도 건으로 남아 있습니다(화면 동작에는 영향 없음).` | **삭제(`""`)** |
|
|
421
|
+
| `dry_run` warnings | 무엇이 **안 실렸는가** | ⚠ 0건 |
|
|
422
|
+
| 검사기 8종 | 조판이 **성립했는가** | 각 검사기의 0건 |
|
|
423
|
+
| 사람의 눈 | 이 문서가 **이 독자에게 맞는가** | 판단 |
|
|
393
424
|
|
|
394
|
-
|
|
395
|
-
> "저장 경로 6곳" → "저장이 일어나는 모든 경로"는 **같은 사실의 다른 세는 단위**다(6곳이 전부였다).
|
|
396
|
-
> 이 선을 넘으면 치환표가 아니라 은폐가 된다.
|
|
425
|
+
### `dry_run` 이 실질적 유일한 품질 관문이다
|
|
397
426
|
|
|
398
|
-
|
|
399
|
-
|
|
427
|
+
`publish_report(dry_run: true)` 는 렌더까지 돌리고 아무것도 저장하지 않는다.
|
|
428
|
+
돌아오는 `warnings` 는 세 곳에서 모인다(`report_publish.php:1100-1108`).
|
|
400
429
|
|
|
401
|
-
|
|
430
|
+
1. **렌더러가 센 것** — `marg` 없음 · `parts` 없음 · 그룹 미배정 건 · 자리 없는 그림. 이것이 먼저 온다.
|
|
431
|
+
2. **입고 검사** — 렌더 산출물이 발행 규격을 지켰는가.
|
|
432
|
+
3. **그림 관문** — 자산 재사용 등.
|
|
402
433
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
| 1 | 그룹 미배정 건 | `그룹에 배정되지 않은 건이 있다: N/M` |
|
|
406
|
-
| 2 | 팔레트 대비 미달 | `팔레트 대비 미달: [...]` |
|
|
407
|
-
| 3 | `§` 잔존 | `§ 가 산출물에 남았다 — link() 를 거치지 않은 텍스트가 있다` |
|
|
408
|
-
| 4 | `forbid` 정규식 적중 | `금지 표현 유출: <패턴> → [...]` |
|
|
434
|
+
2026-08-18 이전에는 이 값이 **한 번도 도구에 도달하지 않았다**(서버가 `error_log` 로만 흘렸다) — 에이전트는 「경고 없음」으로 읽었고 확인할 방법이 없었다.
|
|
435
|
+
지금은 dry_run 과 실제 발행 응답 **양쪽에** 실린다.
|
|
409
436
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
예시 프로젝트의 `forbid`:
|
|
437
|
+
⚠ 가 하나라도 있으면 그것부터 고친다.
|
|
438
|
+
경고를 안고 고객에게 링크를 보내지 마라.
|
|
413
439
|
|
|
414
|
-
|
|
415
|
-
["1217\\d{12}", "[Aa]sana", "운영 배포", "별도 티켓", "자동 검증 \\d건"]
|
|
416
|
-
```
|
|
440
|
+
### 검사기 8종
|
|
417
441
|
|
|
418
|
-
|
|
419
|
-
|
|
442
|
+
`~/.claude/skills/gazette-report/scripts/` 에 있다.
|
|
443
|
+
**실행법과 설계 원리는 `gazette-report` 스킬에 있다** — 여기 두 벌로 두지 않는다.
|
|
420
444
|
|
|
421
|
-
|
|
422
|
-
|
|
445
|
+
| 파일 | 무엇을 잡는가 |
|
|
446
|
+
|---|---|
|
|
447
|
+
| `kcheck.mjs` | 대비(알파·조상 opacity 합성) · 제목 레벨 · 표 접근명 · 앵커 · 7폭 넘침 |
|
|
448
|
+
| `read.mjs` | 한글 자폭 실측 글자/줄 · 행간 · 본문 대비 |
|
|
449
|
+
| `tone.mjs` | 경어체 잔존 · 늘어짐 지표 · 한 문장 한 줄 |
|
|
450
|
+
| `fontchk.mjs` | 렌더된 활자 크기·굵기 분포 |
|
|
451
|
+
| `flexcheck.mjs` | flex/grid 안에서 문장이 토막 나는 곳 |
|
|
452
|
+
| `cssaudit.sh` | 활자 스케일 · 간격 격자 · 표 마감 · 미봉책 |
|
|
453
|
+
| `pdfcheck.sh` | 실제 PDF 쪽 구조 |
|
|
454
|
+
| `contentdiff.sh` | 조판이 본문·id·앵커를 바꿨는지 |
|
|
423
455
|
|
|
424
|
-
|
|
456
|
+
**0표본 통과는 통과가 아니다.**
|
|
457
|
+
표본 수를 함께 본다 — 잴 것이 없어서 0건인지, 재서 0건인지가 다르다.
|
|
425
458
|
|
|
426
|
-
|
|
459
|
+
**재는 판이 실제 판과 다르면 인과가 거짓으로 잡힌다.**
|
|
460
|
+
로컬 검증은 `render.py` 산출물로 한다(서버와 같은 서식·같은 폰트).
|
|
461
|
+
`build.py` 를 직접 부른 산출물로 재면 옛 시트가 실려 거짓 초록이 나온다.
|
|
427
462
|
|
|
428
|
-
|
|
429
|
-
python3 ~/.claude/skills/genetics-report/assets/qa.py report.json
|
|
430
|
-
```
|
|
463
|
+
### 자동 검사가 다 통과해도 **반드시 눈으로 연다**
|
|
431
464
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
**편집기 소스를 본문으로 오인하지 않기 위해서**다.
|
|
465
|
+
자동 검사는 **안 보이는 결함**을 잡고, 눈은 **보이는 결함**을 잡는다.
|
|
466
|
+
둘은 겹치지 않는다.
|
|
435
467
|
|
|
436
|
-
|
|
468
|
+
실제로 자동 검사를 다 통과한 문서에서 눈으로만 잡힌 것들.
|
|
437
469
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
|
450
|
-
|
|
451
|
-
|
|
|
452
|
-
|
|
|
453
|
-
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
### 자동 검수가 통과해도 반드시 브라우저로 연다
|
|
469
|
-
|
|
470
|
-
`qa.py` docstring 이 못박고 있다 — 사람이 봐야 하는 것(톤·독자 적합성·실제 렌더)은 이 검사기가 대신하지 못한다.
|
|
471
|
-
실제로 자동 검수를 다 통과한 문서에서 눈으로만 잡힌 것들: **안 보이는 배지, 빈 목록 항목,
|
|
472
|
-
한국어 낱말 중간 줄바꿈, 편집기가 판정표를 지워버리는 버그.**
|
|
473
|
-
시각 검수 목록은 `qa.md`.
|
|
474
|
-
|
|
475
|
-
### 남아 있는 경고 1건
|
|
476
|
-
|
|
477
|
-
예시 프로젝트에서 `⚠️ rgb/rgba 리터럴 2건` 이 뜬다. `report.css` 의
|
|
478
|
-
표지 `dl` 구분선 `rgba(255,255,255,.22)` 와 `.r-open .xref` 밑줄 `rgba(111,87,33,.35)` 다.
|
|
479
|
-
앞의 것은 어느 팔레트에서나 Primary 위 흰 반투명이라 문제없지만, **뒤의 것은 Korean Navy 의 골드에서
|
|
480
|
-
유래한 갈색 리터럴이라 팔레트를 바꿔도 그 색이 남는다.** 밑줄 1px 이라 대비 기준과는 무관하고
|
|
481
|
-
현재는 경고로 넘기고 있다. 팔레트를 바꿔 쓸 때 눈으로 한 번 볼 자리다.
|
|
470
|
+
- **안 보이는 배지** — 대비는 통과하는데 시각적으로 바탕에 묻혔다.
|
|
471
|
+
- **빈 목록 항목** — 데이터가 빈 문자열이라 마크업은 정상이고 화면에는 빈 줄만 남았다.
|
|
472
|
+
- **한국어 낱말 중간 줄바꿈** — `keep-all` 이 안 걸린 자리. 기계는 넘침만 보고 낱말 경계는 안 본다.
|
|
473
|
+
- **편집기가 대조표를 지워버리는 버그** — 렌더는 정상이고 저장 뒤에 사라졌다.
|
|
474
|
+
- **문서 안 편집 층의 흔적** — 관보는 안 싣지만(`cfg['editor'] = False`), 옛 데이터를 물려받으면 스위치만 남는다.
|
|
475
|
+
|
|
476
|
+
### 사람의 눈 검수 목록
|
|
477
|
+
|
|
478
|
+
브라우저로 열고 **인쇄 미리보기까지** 연다.
|
|
479
|
+
관보는 인쇄되는 문서다 — 화면만 보면 절반만 본 것이다.
|
|
480
|
+
|
|
481
|
+
| 자리 | 무엇을 보는가 |
|
|
482
|
+
|---|---|
|
|
483
|
+
| 표지 | 대제목 첫 행이 한 줄에 서는가. `title_sub` 에 문장이 들어가 조판이 무너지지 않았는가 |
|
|
484
|
+
| 표지 우상단 | 고객사 마크 자리가 비어 있지 않은가(로고 없으면 활자로 서 있는가) |
|
|
485
|
+
| 표지 가운데 | 빈 마당이 그대로인가. **채우지 마라** — 그것이 문법이다 |
|
|
486
|
+
| 차례 | 항목 수가 절 수와 맞는가. 죽은 링크가 없는가 |
|
|
487
|
+
| 이 문서 읽는 법 | 질문형이 `~합니까?` 로 새지 않았는가 |
|
|
488
|
+
| 요약면 | `notice.state` 가 실제 상태와 맞는가. 상태 막대 라벨이 무엇을 세는지 `bar_note` 가 밝히는가 |
|
|
489
|
+
| PART 간지 | 인쇄에서 각각 1쪽 단독으로 서는가 |
|
|
490
|
+
| 절 첫 화면 | 두 단으로 서는가. 한 단이면 `marg` 가 빈 것이다 |
|
|
491
|
+
| 여백 주석 | 본문 첫 문장의 복사본이 아닌가. 셋을 채우려고 넣은 줄이 없는가 |
|
|
492
|
+
| 건 필드표 | 증상→원인→조치→확인 방법 순서가 전 건 같은가 |
|
|
493
|
+
| 대조표 | 등급 표식이 강한 순으로 서는가. 5번째 등급이 눌려 있지 않은가 |
|
|
494
|
+
| 본문 전체 | 경어체 잔존 0건인가(`습니다|십시오|합니다|입니다|됩니다|주세요`) |
|
|
495
|
+
| 본문 전체 | 낱말 중간에서 줄이 바뀐 곳이 없는가 |
|
|
496
|
+
| 본문 전체 | 독자가 조회할 수 없는 식별자가 남아 있지 않은가(포털 발행이면 이 그물이 없다 — 여기가 마지막 관문이다) |
|
|
497
|
+
| 부록 | 본문에서 실제로 참조되는 것만 있는가 |
|
|
498
|
+
| 판권지 | 문서가 여기서 닫히는가. 꼬리 카드가 붙어 있으면 구버전이다 |
|
|
499
|
+
| 인쇄 미리보기 | 절마다 새 쪽에서 시작하는가. 표가 쪽 경계에서 잘리지 않는가 |
|
|
482
500
|
|
|
483
501
|
---
|
|
484
502
|
|
|
485
503
|
## 9. 8단계 — 전달
|
|
486
504
|
|
|
487
|
-
|
|
505
|
+
서식은 서버가 정하므로 고를 것이 없다.
|
|
506
|
+
경로만 고른다.
|
|
488
507
|
|
|
489
|
-
|
|
490
|
-
고객본은 하단 바의 **`고객본 내보내기`** 버튼으로 **별도 파일**(`<원본이름>_고객본.html`)로 뽑는다.
|
|
508
|
+
### 포털 발행 (기본)
|
|
491
509
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
| 최종 발송 직전에 **사람이 버튼을 누른다**(= 승인 행위) | `exportCustomer()` 의 `confirm` 이 제거 내역을 숫자로 명시한다: `내부 전용 블록 N개가 제거됩니다 / 편집 기능이 파일에서 완전히 삭제됩니다 / 원본은 그대로 둡니다` | 내부 전용 블록이 남았는지 사람이 확인할 마지막 기회가 사라진다 |
|
|
495
|
-
| 고객본은 별도 파일, **원본은 건드리지 않는다** | 같은 `confirm` 문구 | 내부 검토본이 사라져 다음 회차에 다시 만들어야 한다 |
|
|
496
|
-
| 문구 수정 요청은 **다시 빌드하지 말고** 문서에서 고친다 | `저장`(Cmd+S)이 **이 파일 자체**에 덮어쓴다. 사본을 만들면 어느 파일이 최신인지 알 수 없다 | `report.json` 과 HTML 이 갈라진다 |
|
|
497
|
-
| 편집기로 손댄 뒤 내보냈다면 **결과 파일을 열어 본다** | QA #13 은 빌드 산출물에서 시뮬레이션한 것이지 사람이 편집한 뒤의 파일이 아니다 | 절번호·판정표가 어긋난 채 나갈 수 있다(편집기가 재생성하지만 확인은 사람이 한다) |
|
|
510
|
+
`publish_report` 에 데이터를 준다 — `tenant`·`slug` 필수.
|
|
511
|
+
서버가 렌더하므로 **HTML 을 만들지 않는다.**
|
|
498
512
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
`
|
|
502
|
-
앞뒤에 `<!-- REPORT-EDITOR:BEGIN -->` / `<!-- REPORT-EDITOR:END -->` 주석을 출력하며,
|
|
503
|
-
`serialize(true)` 가 정확히 그 표식을 찾아 들어낸다. 꺼두는 것만으로는 흔적이 남는다.
|
|
513
|
+
**기본은 초안이다.**
|
|
514
|
+
도구가 `publish` 를 명시적으로 참으로 주지 않는 한 고객에게 안 보인다.
|
|
515
|
+
확인한 뒤 `release_report(id)` 로 연다 — 그것이 사람의 승인 행위다.
|
|
504
516
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
---
|
|
517
|
+
수정은 `get_report` → 데이터 수정 → `update_report`.
|
|
518
|
+
**같은 링크가 새 내용을 가리킨다.**
|
|
508
519
|
|
|
509
|
-
|
|
520
|
+
포털 셸이 문서 **둘레**에 놓는 것(검토 회신·핵심 요약·진척률 바)은 저작 대상이 아니다.
|
|
521
|
+
문서 안에 「댓글로 알려 주세요」를 쓰면 같은 것이 두 번 있게 된다.
|
|
510
522
|
|
|
511
|
-
|
|
512
|
-
보고서에서는 **1·3번은 그대로 살리고 2번만 조건부로 완화한다.**
|
|
523
|
+
### 단일 HTML
|
|
513
524
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
| 2 | 조사·체언 종결 조각문 | **레지스터로 갈라서 적용** (아래) | 없음 — 사람이 본다 |
|
|
518
|
-
| 3 | "A에서 B로" 전환 공식 | 헤딩에서는 금지. 본문은 **수치와 측정 주체가 있을 때만** | 없음 — 사람이 본다 |
|
|
525
|
+
```bash
|
|
526
|
+
python3 ~/.claude/skills/genetics-report/assets/render.py report.json
|
|
527
|
+
```
|
|
519
528
|
|
|
520
|
-
|
|
529
|
+
파일 하나를 그대로 보낸다.
|
|
530
|
+
상대는 더블클릭만 하면 된다.
|
|
521
531
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
길이가 들쭉날쭉해지고 **색인으로서 기능을 잃는다.**
|
|
532
|
+
관보 문서에는 **문서 안 편집 층이 없다**(`cfg['editor'] = False`, `build.py:439`).
|
|
533
|
+
편집기의 블록 모델이 옛 마크업에 묶여 있어 관보 위에서는 차례를 빈 값으로 덮는다 — 고장이 아니라 파괴다.
|
|
534
|
+
문구 수정은 데이터를 고쳐 다시 굽는다.
|
|
526
535
|
|
|
527
|
-
|
|
536
|
+
**묻는다**: 최종 승인, 파일명 규칙.
|
|
528
537
|
|
|
529
|
-
|
|
538
|
+
---
|
|
530
539
|
|
|
531
|
-
|
|
532
|
-
- `h3` 건 제목(`cases[].title`): `사전상담 링크에서 다른 고객의 정보가 열리던 문제` …
|
|
533
|
-
- 표 헤더·태그·범례: `증상` `원인` `조치` `확인 방법` `확인 요청`
|
|
540
|
+
## 10. 9단계 — 발행 뒤 판정
|
|
534
541
|
|
|
535
|
-
|
|
542
|
+
브라우저를 안 열고도 「무엇을 냈는가」를 확인하는 창구다.
|
|
536
543
|
|
|
537
|
-
|
|
538
|
-
|
|
544
|
+
```
|
|
545
|
+
get_report(id: N, outline: true)
|
|
546
|
+
```
|
|
539
547
|
|
|
540
|
-
|
|
548
|
+
### v2 지문 — 블록 목록에 이 일곱이 있어야 한다
|
|
541
549
|
|
|
542
|
-
|
|
543
|
-
|
|
550
|
+
| 블록 | 무엇 |
|
|
551
|
+
|---|---|
|
|
552
|
+
| `header.cover` | 표지 |
|
|
553
|
+
| `section.hist` | 발행 이력 |
|
|
554
|
+
| `nav.toc` | 차례 |
|
|
555
|
+
| `section.guide` | 이 문서 읽는 법 |
|
|
556
|
+
| `section.pt` | PART 간지 |
|
|
557
|
+
| `aside.marg` | 여백 주석 단 — **절 수만큼 있어야 한다** |
|
|
558
|
+
| `div.colophon` | 판권지 |
|
|
544
559
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
라벨은 애초에 주장이 아니므로 이 위험이 없다. 그래서 면제된다.
|
|
560
|
+
`figure.eof-endcard` 가 보이면 **구버전**이다.
|
|
561
|
+
관보는 꼬리 카드를 안 붙인다(`REPORT_EOF_TEMPLATES = []`, `report_publish.php:1249`).
|
|
548
562
|
|
|
549
|
-
|
|
563
|
+
`aside.marg` 개수가 절 수보다 적으면 그만큼의 절이 한 단으로 서 있다는 뜻이다.
|
|
550
564
|
|
|
551
|
-
|
|
552
|
-
- **조사로 끝나는 조각문은 어느 레지스터에서도 금지**("…의", "…에서"). 이건 라벨도 문장도 아니다.
|
|
565
|
+
### ⚠ 머리줄의 `절 0 · 건 0 · 장 0 · 그림 0` 은 **정상값**이다
|
|
553
566
|
|
|
554
|
-
|
|
567
|
+
MCP 가 찍는 요약 줄은 **옛 서식의 셈**만 읽는다(`mcp/genetics.mjs:2718-2726`).
|
|
568
|
+
그 값들은 `h2.sec` · `.case` · `.ch-open` · `<img>` 를 세는데, 관보는 그중 무엇도 안 쓴다.
|
|
569
|
+
실측(예시 문서): 절 0 · 건 0 · 장 0 · 그림 0 이고 실제로는 `ask` 1 · `sheet` 2 · `board` 1 이었다.
|
|
555
570
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
**대시를 문서에서 추방한 게 아니라 헤딩에서만 추방했다.**
|
|
559
|
-
라벨-값 구분자로서의 대시(`레이블 — 값`)는 캡션·마이크로카피에서 정상 활자다.
|
|
560
|
-
금지 대상은 *대비 수사*로서의 대시다. 검사기를 `h1/h2/h3` 로 한정한 것이 이 구분의 구현이다.
|
|
561
|
-
(주의: 검사는 **공백을 낀** ` — ` 만 잡는다. `X—Y` 처럼 붙여 쓰면 통과하므로 사람이 본다.)
|
|
571
|
+
**0 을 보고 「문서가 비었다」로 읽지 마라.**
|
|
572
|
+
판정은 그 아래 **블록 목록**으로 한다.
|
|
562
573
|
|
|
563
|
-
|
|
574
|
+
서버는 관보 셈(`ask`·`sheet`·`board`·`sum`·`part` 등)을 실제로 계산해 `?outline=1` 에 실어 준다.
|
|
575
|
+
**MCP 요약 줄이 그것을 안 찍을 뿐이다** — 지금 도구로는 블록 목록으로만 본다.
|
|
564
576
|
|
|
565
|
-
|
|
577
|
+
### 빈 블록
|
|
566
578
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
`qa.py` 의 AI 슬롭 어휘 목록(`혁신적인`, `차세대`, `재정의하는`, `한 차원 높은`, `최적화된 솔루션`,
|
|
570
|
-
`완벽한 경험`, `새로운 패러다임`, `고도화된`)은 스킬에 고정이고, `forbid` 만 프로젝트가 채운다.
|
|
579
|
+
응답 끝의 `⚠ 빈 블록 N건` 은 **렌더러가 조각을 빠뜨렸다는 뜻**이다.
|
|
580
|
+
데이터 문제가 아니라 렌더러 문제이므로, 그대로 두지 말고 원인을 찾는다.
|
|
571
581
|
|
|
572
582
|
---
|
|
573
583
|
|
|
574
584
|
## 11. 같은 사실이 두 문서로 갈리는 지점
|
|
575
585
|
|
|
576
|
-
|
|
586
|
+
내부 기록 ↔ 고객 문서 대조표는 SKILL.md 0단계에 있다.
|
|
587
|
+
여기서는 그 표를 만든 **원리 셋**만 적는다.
|
|
577
588
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
| 스토어 빌드 이후 반영된다 | "다음 스토어 빌드부터" | "다음 앱 업데이트부터" |
|
|
586
|
-
| 검수용 계정/매장을 썼다 | "테스트 매장의 테스트 고객" | "검수용 매장·고객" |
|
|
587
|
-
| 화면 재현 없이 반영만 확인했다 | "코드 확인" | "반영 확인 — 수정이 운영에 반영된 것까지 확인 (화면 재현은 미실시)" |
|
|
588
|
-
| 티켓 번호 `1217296144360763` | 식별자로 씀 | **싣지 않는다** |
|
|
589
|
-
|
|
590
|
-
관통하는 원리 셋:
|
|
591
|
-
|
|
592
|
-
1. **독자가 검증할 수 없는 참조는 싣지 않는다.** 티켓 번호·내부 시스템명은 확인 수단이 없어 노이즈만 된다. 반대로 제보 원본 링크는 독자가 자기 제보를 대조할 수 있으므로 남긴다.
|
|
593
|
-
2. **우리 조직의 내부 구조를 드러내는 명사는 전부 치환 대상이다.** 배포·티켓·테스트·경로 수 — 전부 "우리 팀이 어떻게 일하는가"이지 "당신 문제가 어떻게 됐는가"가 아니다.
|
|
594
|
-
3. **약한 근거는 숨기지 말고 이름을 붙여 노출한다.** 최약 등급을 지우는 게 아니라 정의를 달아 보여준다.
|
|
589
|
+
1. **독자가 검증할 수 없는 참조는 싣지 않는다.**
|
|
590
|
+
티켓 번호·내부 시스템명은 확인 수단이 없어 노이즈만 된다.
|
|
591
|
+
반대로 제보 원본 링크는 독자가 자기 제보를 대조할 수 있으므로 남긴다.
|
|
592
|
+
2. **우리 조직의 내부 구조를 드러내는 명사는 전부 바꿀 대상이다.**
|
|
593
|
+
배포·티켓·테스트·경로 수 — 전부 「우리 팀이 어떻게 일하는가」이지 「당신 문제가 어떻게 됐는가」가 아니다.
|
|
594
|
+
3. **약한 근거는 숨기지 말고 이름을 붙여 노출한다.**
|
|
595
|
+
최약 등급을 지우는 게 아니라 정의를 달아 보여준다.
|
|
595
596
|
|
|
596
597
|
독자가 바뀌면 구조까지 바뀐다.
|
|
597
598
|
|
|
598
599
|
| 독자에서 나온 결정 | 구현 | 다른 독자였다면 |
|
|
599
600
|
|---|---|---|
|
|
600
|
-
| 전 건을 검증한다 | `status` 절의 전 건
|
|
601
|
-
| 건과 건을 오가며 대조한다 | 절 참조가 전부
|
|
602
|
-
| 우리 작업의 완결성을 본다 |
|
|
603
|
-
| 실제로 화면을 눌러본다 | 위험 행동 경고를 요약과
|
|
601
|
+
| 전 건을 검증한다 | `status` 절의 전 건 대조표 | 결정권자 독자였다면 대조표를 빼고 상태 막대만 남긴다 |
|
|
602
|
+
| 건과 건을 오가며 대조한다 | 절 참조가 전부 앵커 링크 | 순차 낭독용 문서였다면 링크는 불필요하다 |
|
|
603
|
+
| 우리 작업의 완결성을 본다 | `asks` 절이 「고객 숙제」가 아니라 「우리가 확정 못 한 것」 | 계약 정산 문서였다면 같은 데이터가 「잔여 작업 목록」이 된다 |
|
|
604
|
+
| 실제로 화면을 눌러본다 | 위험 행동 경고를 요약과 `asks` 두 곳에 중복 | 읽기만 하는 독자였다면 이 문장 자체가 불필요하다 |
|
|
604
605
|
|
|
605
606
|
---
|
|
606
607
|
|
|
607
608
|
## 12. 새 프로젝트 체크리스트
|
|
608
609
|
|
|
609
|
-
| # | 채울 것 | 어디에 |
|
|
610
|
+
| # | 채울 것 | 어디에 | 단계 |
|
|
610
611
|
|---|---|---|---|
|
|
611
612
|
| 1 | 독자 문장 1개 (하는 일로) | (문서 아님 — 작업 전제) | 0 |
|
|
612
|
-
| 2 |
|
|
613
|
-
| 3 |
|
|
614
|
-
| 4 | 절 구성과 순서 | `
|
|
615
|
-
| 5 | 건별
|
|
616
|
-
| 6 | 보고서 표제로 재작성한 전 건 제목 | `cases.
|
|
617
|
-
| 7 | 등급
|
|
618
|
-
| 8 | 요약 4
|
|
619
|
-
| 9 |
|
|
620
|
-
| 10 |
|
|
621
|
-
| 11 |
|
|
622
|
-
| 12 |
|
|
623
|
-
| 13 |
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
613
|
+
| 2 | 금지 어휘·식별자 정규식 | `forbid` (로컬 렌더에서만 돈다) | 0·6 |
|
|
614
|
+
| 3 | PART 구성 | `parts` | 0·6 |
|
|
615
|
+
| 4 | 절 구성과 순서 | `sections` + `groups` | 0·6 |
|
|
616
|
+
| 5 | 건별 필드 | `cases` | 1·2 |
|
|
617
|
+
| 6 | 보고서 표제로 재작성한 전 건 제목 | `cases[].title` | 2 |
|
|
618
|
+
| 7 | 등급 이름·정의문 (**4단 이하** · 최약 등급에 한계 명시) | `grades` | 3 |
|
|
619
|
+
| 8 | 요약 4문단 + **문단마다 근거** | `summary` (+ `refs`) | 4 |
|
|
620
|
+
| 9 | 확인 요청 3~6개 (주어는 우리) | `open_items` | 4 |
|
|
621
|
+
| 10 | **절마다 여백 주석** | `sections[].marg` | 5 |
|
|
622
|
+
| 11 | 표지·발행 이력·활용법 | `doc_no`·`client`·`title`·`title_sub`·`subtitle`·`meta`·`issuer`·`history`·`guide` | 6 |
|
|
623
|
+
| 12 | 요약면 | `notice`·`bar`·`bar_note`·`stats` | 6 |
|
|
624
|
+
| 13 | 부록·판권지 | `appendix`·`colophon` | 6 |
|
|
625
|
+
| 14 | 고객사 로고 (있으면) | `assets` — `role:"logo"` 하나만 실린다 | 6 |
|
|
626
|
+
|
|
627
|
+
건드리지 않는 것: `build.py`·`gazette.py`·`gazette.css`·`sentbreak.py`·`boundary.py`.
|
|
628
|
+
`render.py` 가 사본이 생기면 멈춘다(`FORKABLE`) — 2026-08-18 에 나흘 만에 887줄이 갈라졌고 그동안 고객 문서가 서식 없이 나갔기 때문이다.
|
|
627
629
|
|
|
628
630
|
---
|
|
629
631
|
|
|
630
632
|
## 13. 미확정
|
|
631
633
|
|
|
632
|
-
1. **`open_items` 개수 3~6 의 근거.**
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
4
|
|
636
|
-
|
|
634
|
+
1. **`open_items` 개수 3~6 의 근거.**
|
|
635
|
+
상한·하한을 정한 실측 근거는 없다.
|
|
636
|
+
2. **등급 4단이 최적인가.**
|
|
637
|
+
4단이 표식의 한계라는 것은 코드로 확인했다.
|
|
638
|
+
3단이 나은 프로젝트가 있는지는 검증하지 않았다.
|
|
639
|
+
3. **관보 셈(`ask`·`sheet`·`board`·`marg` 등)을 MCP `outline` 요약 줄이 안 찍는 것.**
|
|
640
|
+
서버는 계산해서 실어 준다.
|
|
641
|
+
도구를 고칠지, 블록 목록으로 판정하는 지금 방식을 유지할지 판단하지 않았다.
|
|
642
|
+
4. **포털 발행에 `forbid` 그물이 없는 것.**
|
|
643
|
+
서버가 의도적으로 뺀 키인지(파일을 읽는 키와 같은 취급), 관보 전환에서 빠진 것인지 확인 못 했다.
|
|
644
|
+
현재 처방은 「발행 전에 로컬로 한 번 굽는다」이고, 이것은 우회이지 해결이 아니다.
|
|
645
|
+
5. **`text_fix` 를 서버가 계속 받는 것.**
|
|
646
|
+
관보 렌더러가 안 읽는데 화이트리스트에 남아 있다.
|
|
647
|
+
지울지, 관보 경로에 붙일지 판단하지 않았다.
|