genetics-mcp 2.23.0 → 2.25.0
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 +5 -5
- package/bin/x86_64-apple-darwin/gcell +0 -0
- package/bin/x86_64-pc-windows-gnu/gcell.exe +0 -0
- package/bin/x86_64-unknown-linux-musl/gcell +0 -0
- package/genetics.mjs +2068 -239
- package/package.json +2 -2
- package/skills/gazette-report/SKILL.md +11 -10
- package/skills/gazette-report/scripts/tone.mjs +17 -5
- package/skills/gazette-report/scripts/tone.test.mjs +15 -2
- package/skills/gazette-report/template/skeleton.html +10 -10
- package/skills/genetics-define/SKILL.md +2 -0
- package/skills/genetics-report/SKILL.md +123 -102
- package/skills/genetics-report/assets/example/cases-briefing.json +1 -1
- package/skills/genetics-report/assets/example/cases.json +3 -3
- package/skills/genetics-report/assets/example/report-briefing-designs.json +26 -26
- package/skills/genetics-report/assets/example/report-briefing.json +3 -3
- package/skills/genetics-report/assets/example/report.json +11 -11
- package/skills/genetics-report/assets/mcp-call.mjs +160 -0
- package/skills/genetics-report/assets/patch.py +411 -0
- package/skills/genetics-report/assets/render.py +223 -0
- package/skills/genetics-report/assets/xlsx-plate.py +203 -0
- package/skills/genetics-report/references/content-pipeline.md +26 -26
- package/skills/genetics-report/references/edition-review.workflow.js +120 -23
- package/skills/genetics-report/references/font-embedding.md +1 -1
- package/skills/genetics-report/references/history.md +76 -2
- package/skills/genetics-report/references/lim-portal-format.md +109 -48
- package/skills/genetics-report/references/linear-read-test.workflow.js +50 -14
- package/skills/genetics-report/references/process.md +54 -48
- package/skills/genetics-report/references/reader-review.workflow.js +118 -33
- package/skills/genetics-report/references/visual-first.md +34 -17
- package/skills/gazette-report/scripts/package-lock.json +0 -24
|
@@ -26,6 +26,8 @@ python3 ~/.claude/skills/genetics-report/assets/render.py report.json
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
`render.py` 가 서버의 `REPORT_TEMPLATES` 를 읽어 `render`·`css`·폰트를 설정에 얹는다.
|
|
29
|
+
소속처 문서면 그 소속처가 반려한 이름도 함께 센다 — `--tenant <slug>`(원고에 `tenant` 가 있으면 생략)로 MCP `list_rejected_names` 를 불러 받은 목록을 얹는다.
|
|
30
|
+
못 받으면 ⚠ 한 줄을 내고 반려 이름만 빼고 굽는다(`lim-portal-format.md` §10-1 「목록을 얻는 길」).
|
|
29
31
|
**`report.json` 에 `css`·`render`·`palette` 를 적지 마라** — 서버와 갈릴 수 있고, 갈리면 로컬에서 본 것과 고객이 본 것이 다르다.
|
|
30
32
|
|
|
31
33
|
**`build.py` 를 직접 부르지 마라.**
|
|
@@ -46,23 +48,25 @@ python3 ~/.claude/skills/genetics-report/assets/render.py report.json
|
|
|
46
48
|
| 질문 | 왜 이걸 묻는가 | 예시 답 |
|
|
47
49
|
|---|---|---|
|
|
48
50
|
| 이 문서를 **읽고 판정하는 사람**은 누구인가 — 직함이 아니라 *하는 일*로 | 직함(「팀장」)에서는 어휘 정책이 안 나온다. 행위(「검증한다」)에서는 나온다 | 「고객사 검수 담당 — 우리 작업이 실제로 해결됐는지 확인하는 사람」 |
|
|
49
|
-
| 읽고 나서 **해야 할 행동**은 무엇인가 — 할 일이 둘이면 둘 다 목록으로 | `cta`·`open_items`·건별 `how_to_check` 가 여기서 결정된다. 할 일 목록은 독자 검토 `args.reader` 에 그대로 싣는다 | 「① 결정 물음에 회신한다 ②
|
|
51
|
+
| 읽고 나서 **해야 할 행동**은 무엇인가 — 할 일이 둘이면 둘 다 목록으로 | `cta`·`open_items`·건별 `how_to_check` 가 여기서 결정된다. 할 일 목록은 독자 검토 `args.reader` 에 그대로 싣는다 | 「① 결정 물음에 회신한다 ② <독자 화면의 채널 이름> 앱에서 확인한다」 |
|
|
50
52
|
| 문서에 실어도 되는 **참조 체계**는 무엇인가 | 독자가 확인할 수 없는 참조는 신뢰에 기여하지 않고 노이즈만 된다 | 「본인이 제보한 원본 링크만. 내부 티켓 번호는 안 됨」 |
|
|
51
53
|
| 전달 경로 — 포털 링크인가, 파일 하나인가, 인쇄도 도는가 | 포털은 셸이 문서 둘레에 요약·댓글을 놓는다. 파일 전달은 그것이 없다 | 「포털 링크 + 인쇄 가능해야 함」 |
|
|
52
54
|
| 읽고 나서 **무엇을 결정하는가** — 선택지·선택지마다 달라지는 것·기한. 우리 의견을 낼지는 따로 묻는다 | 답이 있으면 「결정한다」 모드다. `open_items` 가 고객이 고를 **물음**이 되고 기한 ⚠ 가 걸린다. 의견은 내면 한 절 한 자리(lim-portal-format §12.3b) | 「[방식 A] 를 들일지, 그대로 둘지 — 12월 31일까지」 |
|
|
53
55
|
| **이미 정해진 것**은 무엇이고 **누가·어디서** 정했는가(체크리스트 0a) | 정해진 것은 사실로 배경에 서고 결정 요청에서 빠진다 — 주체와 기록을 확인하지 않고 쓰면 열린 항이 닫힌 사실로 실리거나, FCG 가 대화에서 정한 것이 고객 결정처럼 읽힌다(SKILL 3b 「결정 주체」). 작업 폴더 `decisions.json`(발행 안 함): 항 · 내용 · 결정권(고객/FCG) · 정한 주체 · 기록(회신 원문·회의록·결정문의 이름과 날짜) · 사용자 확인 여부. 미확인 항은 원고에 쓰기 전에 한 번에 묻는다 | 「화면 문구 교체 — 결정권 고객 · 고객 회신 메일(날짜) · 확인함」 |
|
|
56
|
+
| 원고에서 부를 대상(판·환경·인스턴스·설정·요금·문서)마다 **독자가 보는 이름**은 무엇인가(SKILL 0단계 물음 5) | 작업하며 지은 이름은 문서 안에서 정의해도 독자가 모른다 — 대응표 없이 쓰기 시작하면 설명형 새 이름을 짓게 된다(SKILL 반드시 지키는 것 12). 작업 폴더 `names.md`(발행 안 함): 우리가 부르던 이름 / 독자 화면·문서의 이름 / 그 이름이 보이는 자리. 자료(화면 캡처·콘솔·원본 문서)에서 먼저 찾고 못 찾은 것만 한 번에 묻는다 | 「예비판 → <독자 화면의 채널 이름> 앱 · 고객 관리자 화면의 채널 목록」 |
|
|
54
57
|
|
|
55
58
|
### 이 답에서 곧바로 정해지는 것
|
|
56
59
|
|
|
57
60
|
- **모드** — 판정한다 / 배운다 / 결정한다 셋 중 하나(SKILL.md 「세 가지 독자」). 결정한다면 `doc_type` 에 「브리핑」을 적어 렌더러 ⚠ 를 켠다.
|
|
58
61
|
- **금지 어휘 목록** — 독자가 검증할 수 없는 내부 어휘와 식별자.
|
|
59
|
-
|
|
62
|
+
`forbid` 정규식으로 적는다 — 로컬 렌더는 걸리면 멈추고, 포털 발행은 경고로 센다(6단계 「`forbid`」).
|
|
63
|
+
- **부를 이름** — 원고에서 부를 대상마다 독자 화면·문서의 이름(위 표 마지막 물음의 대응표). 원고와 용어 잠금 표는 이 이름만 쓴다.
|
|
60
64
|
- **PART 구성** — 독자가 바뀌면 읽기 순서가 바뀐다.
|
|
61
65
|
검수자에게는 「지금 부탁드리는 것」이 PART 1 이지만, 사후 열람자에게는 「경과」가 앞이다.
|
|
62
66
|
- **절 구성(`sections`)** — 독자가 바뀌면 절이 통째로 없어진다.
|
|
63
67
|
전 건 검수자에게는 `status` 절의 대조표가 핵심이지만, 결정권자 독자에게는 요약면 상태 막대만 남기고 대조표를 빼는 것이 맞다.
|
|
64
68
|
- **말을 거는 자리의 종결** — 독자가 **사람**이면 그 사람에게 직접 하는 말은 하십시오체로 맺는다
|
|
65
|
-
(`cta`·`open_items`·PART I
|
|
69
|
+
(`cta`·`open_items`·PART I 간지(요청·결정 PART 일 때)·판권지 회신 안내·요청 절 항을 부탁하는 읽는 법 한 줄 — 사실 문장까지, 목록의 정본은 SKILL 5). 그 밖의 자리에는 우리·사물이 주어인 개조식만 쓰고, 독자가 할 일은 두지 않는다(SKILL 5).
|
|
66
70
|
독자를 사람으로 정해 놓고 문체는 상수로 두면, 문서가 사람이 아니라 대장에게 말한다.
|
|
67
71
|
자세한 것은 SKILL 5·5a(경위: `references/history.md` §5).
|
|
68
72
|
|
|
@@ -79,7 +83,7 @@ python3 ~/.claude/skills/genetics-report/assets/render.py report.json
|
|
|
79
83
|
|
|
80
84
|
| 규칙 | 근거 | 어기면 |
|
|
81
85
|
|---|---|---|
|
|
82
|
-
| 티켓 본문만 읽지 않는다. **코멘트·스레드까지** 읽는다 | 실제 조치 내용은 본문이 아니라 코멘트에 적히는 것이 보통이다 | `fix` 칸이 통째로 빈다. 제목만 보고 쓴 건은 전부
|
|
86
|
+
| 티켓 본문만 읽지 않는다. **코멘트·스레드까지** 읽는다 | 실제 조치 내용은 본문이 아니라 코멘트에 적히는 것이 보통이다 | `fix` 칸이 통째로 빈다. 제목만 보고 쓴 건은 전부 「[미확인]」이 된다 |
|
|
83
87
|
| 건이 많으면 N건씩 묶어 병렬로 읽는다 | 품질이 아니라 속도 문제다 | (느릴 뿐) |
|
|
84
88
|
| 제보 출처 링크가 있으면 **그대로** 보존한다 | `cases[].source_url` → 건 필드표의 제보 원본 링크 | 접수 건과 자체 발견 건을 가르는 근거가 사라진다 |
|
|
85
89
|
| 링크는 **독자가 아는 것만** 남긴다 | 독자가 조회할 수 없는 주소는 확인 수단이 아니라 노이즈다 | 문서가 독자가 아니라 자기 조직을 향해 말한다 |
|
|
@@ -103,8 +107,8 @@ grade grades 키 중 하나
|
|
|
103
107
|
symptom 무엇이 잘못 보였는가
|
|
104
108
|
cause 왜 그랬는가 (한 문장)
|
|
105
109
|
fix 이제 어떻게 되는가
|
|
106
|
-
how_to_check 고객이 자기 화면에서
|
|
107
|
-
remaining 우리가 못 닫은 것 (없으면 생략)
|
|
110
|
+
how_to_check 고객이 자기 화면에서 볼 수 있는 결과 (주어는 화면·값)
|
|
111
|
+
remaining 우리가 못 닫은 것 — 미확인·미결인 사실 (부탁은 요청 절. 없으면 생략)
|
|
108
112
|
source_url 제보 원본 링크 (없으면 생략. http(s) 필수)
|
|
109
113
|
```
|
|
110
114
|
|
|
@@ -116,15 +120,15 @@ source_url 제보 원본 링크 (없으면 생략. http(s) 필수)
|
|
|
116
120
|
> · 파일명·함수명·커밋해시·SQL·클래스명을 쓰지 마라. 고객은 모른다.
|
|
117
121
|
> · 「무엇이 잘못 보였는가 → 왜 그랬는가 → 이제 어떻게 되는가」 순서로 쓴다.
|
|
118
122
|
> · 원인은 한 문장으로, 비유 없이, 사실만. 변명하지 마라.
|
|
119
|
-
> · 고객이
|
|
123
|
+
> · 모든 건에 고객이 **자기 화면에서 볼 수 있는 결과**를 한 줄 적는다 — 어디를 열면 무엇이 보이는지, 주어는 화면·값.
|
|
120
124
|
> · 아직 안 끝난 게 있으면 숨기지 말고 「남은 것」으로 적는다.
|
|
121
125
|
> · 과장 금지. 「완벽히 해결」 대신 무엇을 확인했는지 쓴다.
|
|
122
126
|
>
|
|
123
|
-
> 근거가 없으면 지어내지 말고 그 필드를
|
|
127
|
+
> 근거가 없으면 지어내지 말고 그 필드를 **「[미확인]」** 으로 남기고 사용자에게 되묻는다(발행 전 0 — 문서 `forbid` 에 `\[미확인\]` 을 넣으면 로컬 렌더가 멈춘다).
|
|
124
128
|
|
|
125
129
|
| 규칙 | 근거 | 어기면 |
|
|
126
130
|
|---|---|---|
|
|
127
|
-
| 근거 없는 필드는
|
|
131
|
+
| 근거 없는 필드는 「[미확인]」으로 남기고 사용자에게 되돌린다 | 추측이 사실 진술의 활자로 인쇄되면 회복 불가능하다 | 발송 후에는 회수할 수 없다 |
|
|
128
132
|
| `how_to_check` 는 **전 건 필수** | 없으면 검수 요청이 아니라 통보다 | 기계가 안 잡는다. 사람이 건 수와 대조한다 |
|
|
129
133
|
|
|
130
134
|
### `title` 은 티켓 제목이 아니다
|
|
@@ -143,7 +147,7 @@ source_url 제보 원본 링크 (없으면 생략. http(s) 필수)
|
|
|
143
147
|
실측(2026-08-24): `{"from":"레코드","to":"항목"}` 을 넣고 원고에 「레코드」를 심어 렌더했더니 **「레코드」가 그대로 산출물에 남았다.**
|
|
144
148
|
|
|
145
149
|
그러므로 **고객 언어 치환은 원고에서 직접 한다.**
|
|
146
|
-
치환 누락을 잡는 그물은 `forbid`
|
|
150
|
+
치환 누락을 잡는 그물은 `forbid` 하나뿐이다 — 로컬 렌더는 걸리면 멈추고, 포털 발행은 경고로 센다(6단계 「`forbid`」).
|
|
147
151
|
|
|
148
152
|
---
|
|
149
153
|
|
|
@@ -208,25 +212,24 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
208
212
|
원고를 쓰기 전에 핸드오프에 **상태 표**(무엇 · 코드 반영 · 시험판 전달 · 실기기 · 운영, 칸마다 근거)를 만들고, 문서의 동사는 이 표의 확인 수준을 넘지 않게 고른다.
|
|
209
213
|
반영 단계 어휘는 `references/content-pipeline.md` 「4.2 치환 유형」 B 행을 따른다. 실기기 확인이 없으면 같은 문장에 그렇다고 적는다.
|
|
210
214
|
판정 규칙은 이용자가 확인할 수 있는 동작으로만 적고, 구현 규칙(어느 키로 판정하는지)은 싣지 않는다.
|
|
211
|
-
**커밋·브랜치·파일·시험 도구·시험 건수는 이 표에만** 둔다 — 원고에 새면 `gazette.py` `text_scan()` 개발 식별자 ⚠(두 경로
|
|
215
|
+
**커밋·브랜치·파일·시험 도구·시험 건수는 이 표에만** 둔다 — 원고에 새면 `gazette.py` `text_scan()` 개발 식별자 ⚠(두 경로).
|
|
212
216
|
확인 수준보다 앞선 완료형 동사는 기계가 못 가린다 — 독자 검토에 `args.state` 로 이 표를 주면 state 관점이 대조하고, 나머지는 사람의 눈(SKILL 반드시 지키는 것 3).
|
|
213
217
|
|
|
214
218
|
### 문체
|
|
215
219
|
|
|
216
|
-
|
|
217
|
-
(`~함` / `~했음` / `~임`). **요청 자리**(`cta`·`open_items`·PART I
|
|
220
|
+
**주어와 자리가 정한다.** 요청 자리 밖(요약·건·절 도입문·여백 주석·문단·표·부록)에는 우리·사물·화면이 주어인 문장만 두고 개조식
|
|
221
|
+
(`~함` / `~했음` / `~임`). 독자가 할 일은 **요청 자리**(`cta`·`open_items`·PART I 간지(요청·결정 PART 일 때)·판권지 회신 안내·요청 절 항을 부탁하는 읽는 법 한 줄)에만 두고 사실 문장까지
|
|
218
222
|
**하십시오체**(`~하여 주시기 바랍니다` / `~부탁드립니다` / `~하겠습니다`).
|
|
219
|
-
|
|
223
|
+
규율은 SKILL 5·5a, 대응표는 `references/lim-portal-format.md` §14-1·§14-2.
|
|
220
224
|
|
|
221
225
|
> · 개발 용어(파일명·커밋해시·SQL·클래스명) 금지. **배포 단계 용어(스테이징/테스트환경) 금지** — 반영 단계는 위 「코드 작업을 녹일 때」의 어휘로.
|
|
222
226
|
> · 결론을 먼저 쓴다. 각 문단은 리드 문장 하나로 시작한다.
|
|
223
227
|
> · 과장 금지. 확인한 것과 확인하지 못한 것을 구분해서 쓴다.
|
|
224
228
|
|
|
225
|
-
|
|
229
|
+
요청 자리 밖에서 문체를 안 바꾸면 낱말이 아니라 **조판의 문제**로 남는다 — 경어체 서술문은
|
|
226
230
|
관보 문법 위에서 겉돈다. 반대로 요청 자리에서 개조식을 고집하면 **하대로 읽힌다** — 이쪽이
|
|
227
|
-
|
|
228
|
-
로컬 `tone.mjs` 는 판단 항목
|
|
229
|
-
⚠ 서버 쪽 자리 가림은 **운영 반영 확인 전**이다 — 배포 전의 운영 `dry_run` 은 요청 자리에서도 경어체를 세므로, 그 경고는 자리를 확인하고 넘긴다(lim-portal-format §10 통과 기준 표 셋째 행).
|
|
231
|
+
거듭 반려된 자리다(SKILL 5·5a · 경위 history.md §5). 서버 `report_tone.php report_tone_warnings()` 는 요청 자리(`open_items` 본문·`cta`·판권지 `note`·`asks` 절 여백 주석)와 「」 인용을 안 세고,
|
|
232
|
+
로컬 `tone.mjs` 는 요청 자리 가운데 넷(판단 항목 본문·`cta`·요청 PART 의 PART I 간지·판권지 회신 안내)과 「」 인용을 뺀다(2026-09-26). 읽는 법(`guide`)의 요청 한 줄은 두 경로 모두 센다. 그래서 남는 경어체 경고는 서버의 PART I 간지(요청 PART 일 때) 문장과 두 경로의 읽는 법 요청 한 줄이고, 둘 다 의도이므로 **사람이 걸러 읽고 그대로 둔다**.
|
|
230
233
|
|
|
231
234
|
### `summary` — 검수·보고판 4개의 `{lead, body, refs}`
|
|
232
235
|
|
|
@@ -237,7 +240,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
237
240
|
1. 접수된 N건이 어떤 성격이었고 지금 어떤 상태인가
|
|
238
241
|
2. 확인 과정에서 함께 발견해 고친 것 중 영향이 컸던 것
|
|
239
242
|
3. 여러 건을 관통하는 **공통 원인**이 있다면 그것 — **실재할 때만 쓴다.** 없는데 만들어 내면 그게 이 문서에서 가장 나쁜 슬롭이다
|
|
240
|
-
4. 검토 요청 —
|
|
243
|
+
4. 검토 요청 — 요청 절에 남은 항 이름과 기한
|
|
241
244
|
|
|
242
245
|
「결정한다」판은 4~6문단이고 순서가 다르다 — 무엇을 언제까지 결정하는가 / 검토한 선택지와 편익·비용·불확실성 /
|
|
243
246
|
확인한 사실과 근거의 등급·성숙도(권고 없음 — 의견은 별도 절 한 자리) / 결정 뒤 이어지는 것(SKILL.md 4~6단계 브리핑판).
|
|
@@ -275,19 +278,18 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
275
278
|
요청 절이 없는 문서가 확인 못 한 것을 `note` 절에 모을 때도 같다 — 건의 `remaining` 을 문단마다 옮겨 적지 않고
|
|
276
279
|
성격(작업자 미상 · 기록 없음 · 현장에서만 가려짐 같은)으로 묶고, 건은 번호로 가리킨다.
|
|
277
280
|
|
|
278
|
-
>
|
|
279
|
-
> 주어를 우리로 써라.
|
|
281
|
+
> 요청 절은 독자가 할 일이 서는 유일한 자리다. 검수·보고 문서의 확인 요청 항은 **우리가 확정하지 못한 사실을 먼저** 적고, 부탁은 하십시오체로 맺는다(결정 문서의 판단 항목은 본문 첫 문장이 기한 — SKILL 0.5단계 5행).
|
|
280
282
|
|
|
281
|
-
이
|
|
282
|
-
같은 데이터를 「고객이 해야 할
|
|
283
|
-
|
|
283
|
+
이 순서가 문서의 성격을 바꾼다.
|
|
284
|
+
같은 데이터를 「고객이 해야 할 일」만으로 쓰면 책임 전가 문서가 되고, 「우리가 아직 못 닫은 것」을 먼저 밝히면 신뢰 문서가 된다.
|
|
285
|
+
검수·보고 문서의 `open_items[].title` 은 「~ 요청」+기한 괄호(SKILL 5a)이고, 본문 첫 문장이 우리가 못 닫은 사실이다 — 「검증에 쓴 표본이 작습니다」·「같은 전화번호를 쓰는 계정의 주인은 저희가 판단할 수 없습니다」.
|
|
284
286
|
결정 문서(브리핑)의 판단 항목은 다르다 — 고객이 고를 **물음**이다(SKILL 0.5단계 5행 · lim-portal-format §12.5b).
|
|
285
287
|
독자의 할 일이 둘이면(결정 + 시험판 확인) 둘째는 `open_items` 두 번째 건 「… 확인 요청」으로 두고 본문 첫 문장에 상대 기한을 넣는다 —
|
|
286
|
-
표지·현황 줄에는 사실문으로만 올린다. 읽는 법(`guide`)에는 요청 절의 확인 요청을 가리키는 요청 한 줄을 둘 수 있다(2026-09-15 사용자 결정) — 그 밖의 요청문은 두지 않는다(
|
|
288
|
+
표지·현황 줄에는 사실문으로만 올린다. 읽는 법(`guide`)에는 요청 절의 확인 요청을 가리키는 요청 한 줄을 둘 수 있다(2026-09-15 사용자 결정) — 그 밖의 요청문은 두지 않는다(요청 자리 밖, SKILL 5). 집행자: `gazette.py` `brief_checks()` 기한 ⚠(「확인 요청」 문구로 갈림) · 독자 검토 decider 관점.
|
|
287
289
|
|
|
288
290
|
| 규칙 | 어기면 |
|
|
289
291
|
|---|---|
|
|
290
|
-
| 확인 요청
|
|
292
|
+
| 검수·보고 문서의 확인 요청 항은 **우리가 못 닫은 사실**을 먼저 적는다 | 까닭 없이 할 일만 넘기면 마무리 못 한 쪽이 상대에게 일을 넘기는 문서가 된다 |
|
|
291
293
|
| 확인한 것과 확인 못 한 것을 **문장 안에서 구분**한다 | 등급 축과 본문이 어긋나고, 검수 독자는 그 어긋남을 가장 먼저 찾아낸다 |
|
|
292
294
|
| 파괴적 동작은 결과를 같이 적고 **두 곳에 중복**한다(요약 + `asks`) | 한 곳에만 있으면 훑어 읽는 독자가 놓친다. 이 중복은 실수가 아니라 설계다 |
|
|
293
295
|
|
|
@@ -324,7 +326,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
324
326
|
|---|---|---|
|
|
325
327
|
| `why` | 그 절을 **왜** 읽는가. 독자가 실제로 던질 질문 그대로 | `~하는가?` / `~인가?` (`~합니까?` 아님) |
|
|
326
328
|
| `key` | 이 절에서 하나만 가져간다면 그것 | 개조식 단문 |
|
|
327
|
-
| `advice` |
|
|
329
|
+
| `advice` | 더 볼 곳. 근거의 출처를 가리킨다 | 명사구(「03절 대조표」) 또는 사물이 주어인 단문(「판정 기준은 부록 1에 있음」) — 「~할 것」「~ 참조」 아님 |
|
|
328
330
|
|
|
329
331
|
셋 중 채운 것만 그려진다.
|
|
330
332
|
하나도 없으면 `<aside class="marg">` 자체가 안 나오고 본문이 한 단이 된다.
|
|
@@ -431,20 +433,21 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
431
433
|
| 층 | 무엇을 잡는가 | 결과 |
|
|
432
434
|
|---|---|---|
|
|
433
435
|
| 서버 검증 | 모르는 `kind` · 없는 그룹 · 없는 PART · 요약 근거 · `source_url` 모양 · 목록/객체 모양 | **발행 거절** |
|
|
434
|
-
| 렌더러 assert | `link()` 를 안 거친 `§n.n` · `forbid` 정규식 적중 | **렌더 중단(파일 안 씀)** |
|
|
435
|
-
|
|
|
436
|
+
| 렌더러 assert(로컬 렌더) | `link()` 를 안 거친 `§n.n` · `forbid` 정규식 적중 | **렌더 중단(파일 안 씀)** |
|
|
437
|
+
| 서버 ⚠(포털 발행) | 문서의 `forbid` 적중 · 세지 못한 패턴(`report_publish.php report_forbid_warnings()`) · 소속처 반려 이름 목록을 못 읽음·깨진 결정 장·상한 초과(`report_publish.php report_rejected_names()`) | 경고만 |
|
|
438
|
+
| 렌더러 ⚠ | `marg` 없음 · `parts` 없음 · 그룹 미배정 건 · 자리 없는 그림 · 시각 우선·글 층·도판 출처 줄·그림 번호·개발 식별자 · 대화 이력·「탓」·소속처 반려 이름(목록은 포털이면 서버가, 로컬이면 `render.py` 가 `list_rejected_names` 로 받아 얹는다 — `lim-portal-format.md` 「10. 경고 조건」) | 경고만 |
|
|
436
439
|
|
|
437
|
-
### ⚠ `forbid`
|
|
440
|
+
### ⚠ `forbid` — 로컬 렌더는 멈추고, 포털 발행은 경고로 센다 (코드 확인)
|
|
438
441
|
|
|
439
442
|
`build.py guard()` 가 `cfg['forbid']` 를 읽어 산출물을 훑고, 걸리면 assert 로 죽는다.
|
|
440
443
|
실측(2026-08-24): 금지어 「티켓」을 원고에 심고 `render.py` 를 돌리면 `AssertionError: 금지 표현 유출: 티켓 → ['티켓']` 으로 멈추고 파일이 안 써진다.
|
|
441
444
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
+
포털 발행에서는 이 칸이 렌더러에 안 넘어간다 — `REPORT_CLIENT_KEYS` 에 없어 `report_publish.php report_client_fields()` 가 렌더러 몫에서 뺀다.
|
|
446
|
+
대신 그 앞에서 `report_publish.php report_forbid_warnings()` 가 깎기 전 목록을 떠서 발행 데이터의 글자 칸마다 맞추고, 걸린 자리를 5곳까지 짚어 **경고**로 싣는다 — 모의 발행과 실발행이 같이 지나고, 막지 않는다(2026-09-26).
|
|
447
|
+
두 경로의 판정은 갈릴 수 있다 — 로컬은 렌더된 HTML 을, 포털은 원고 글자 칸(`data` 한 칸만 뺌 — 렌더러가 안 그리는 `generated_by`·`work` 포함)을 본다.
|
|
448
|
+
포털은 PCRE 로 맞추고, 세지 못한 패턴(정규식이 아님·빈 문자열에 맞음·실행 상한·200자 넘음·50개 넘음)은 「세지 못한 패턴이 N개」 경고로 알린다 — 그 패턴의 적중은 0 이 아니라 미확인이다.
|
|
445
449
|
|
|
446
|
-
|
|
447
|
-
고객사·제품명처럼 문서마다 다른 금칙 값의 자동 관문은 지금 이것뿐이다 — 개발 식별자·과정 어휘는 두 경로 다 `gazette.py` `text_scan()` ⚠ 가 센다(⚠ 2026-09-14 에 더한 행은 운영 반영 확인 전 — 배포 전에는 로컬 렌더만, lim-portal-format §10-1 머리).
|
|
450
|
+
고객사·제품명처럼 문서마다 다른 금칙 값의 자동 관문은 이 목록뿐이다 — 개발 식별자·과정 어휘는 두 경로 다 `gazette.py` `text_scan()` ⚠ 가 센다.
|
|
448
451
|
|
|
449
452
|
---
|
|
450
453
|
|
|
@@ -456,7 +459,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
456
459
|
|---|---|---|
|
|
457
460
|
| `dry_run` warnings(로컬 렌더 ⚠ 포함) | 무엇이 **안 실렸는가** · 규칙 낱말·모양 | 작성자가 고칠 수 있는 ⚠ 0건 |
|
|
458
461
|
| 검사기 8종 | 조판이 **성립했는가** | 각 검사기의 0건 |
|
|
459
|
-
| 독자 검토(`reader-review.workflow.js`) | 처음 읽는 사람·결정권자가 **읽히는가** · 도판을 열어 잰 틀 · 1차 자료와 맞는가 | Verify 를 통과한 발견 반영 · 「⚠ 도판 N장 미열람」 없음(SKILL
|
|
462
|
+
| 독자 검토(`reader-review.workflow.js`) | 처음 읽는 사람·결정권자가 **읽히는가** · 도판을 열어 잰 틀 · 1차 자료와 맞는가 | Verify 를 통과한 발견 반영 · 「⚠ 도판 N장 미열람」 없음(SKILL 체크리스트 7단계 독자 검토 행 — 미열람·「서버 보관」 줄의 id 가 모두 원고에서 보관 표식인 장이면 사람이 열람 주소에서 보고 핸드오프에 적어 통과) |
|
|
460
463
|
| 사람의 눈 | 이 문서가 **이 독자에게 맞는가** | 판단 |
|
|
461
464
|
|
|
462
465
|
### `dry_run` 이 실질적 유일한 품질 관문이다
|
|
@@ -467,7 +470,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
467
470
|
1. **렌더러가 센 것** — `marg` 없음 · `parts` 없음 · 그룹 미배정 건 · 자리 없는 그림 · `text_scan()`·`brief_checks()`·`tally_scan()` 경고. 이것이 먼저 온다.
|
|
468
471
|
2. **입고 검사** — 렌더 산출물이 발행 규격을 지켰는가(본문 링크의 바깥 호스트도 여기서 센다).
|
|
469
472
|
3. **그림 관문** — 자산 재사용 등.
|
|
470
|
-
4. **문체 관문** — `report_tone.php report_tone_warnings()`:
|
|
473
|
+
4. **문체 관문** — `report_tone.php report_tone_warnings()`: 요청 자리 밖 경어체 · 상대 행위의 명령형 · 보고 칸의 요청문. 맨 뒤에 온다.
|
|
471
474
|
|
|
472
475
|
2026-08-18 이전에는 이 값이 **한 번도 도구에 도달하지 않았다**(서버가 `error_log` 로만 흘렸다) — 에이전트는 「경고 없음」으로 읽었고 확인할 방법이 없었다.
|
|
473
476
|
지금은 dry_run 과 실제 발행 응답 **양쪽에** 실린다.
|
|
@@ -530,8 +533,8 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
530
533
|
| 여백 주석 | 본문 첫 문장의 복사본이 아닌가. 셋을 채우려고 넣은 줄이 없는가 |
|
|
531
534
|
| 건 필드표 | 증상→원인→조치→확인 방법 순서가 전 건 같은가 |
|
|
532
535
|
| 대조표 | 등급 표식이 강한 순으로 서는가. 5번째 등급이 눌려 있지 않은가 |
|
|
533
|
-
|
|
|
534
|
-
| 요청 자리 | 반대다 — `cta`·`open_items`·PART I 간지·판권지 회신 안내가
|
|
536
|
+
| 요청 자리 밖 | 경어체 잔존 0건인가(`습니다|십시오|합니다|입니다|됩니다|주세요`). 독자가 주어인 문장(「~할 것」「~해야 함」「~면 됨」「~몫임」「확인 필요」「~ 참조」)이 없는가 — 기계는 `how_to_check` 의 명령·당위까지만(SKILL 5) |
|
|
537
|
+
| 요청 자리 | 반대다 — `cta`·`open_items`·PART I 간지·판권지 회신 안내가 **사실 문장까지 하십시오체로 맺는가**. 명사형 종결(`부탁드림`·`바람`·`하시면 됨`)이 남아 있지 않은가 |
|
|
535
538
|
| 본문 전체 | 낱말 중간에서 줄이 바뀐 곳이 없는가 |
|
|
536
539
|
| 본문 전체 | 독자가 조회할 수 없는 식별자가 남아 있지 않은가 — 해시·코드 파일·개발 도구·커밋·브랜치 같은 개발 식별자는 `gazette.py` `text_scan()` ⚠(두 경로), 고객사·제품명 같은 문서마다 다른 금칙 값은 포털 발행에 그물이 없어 **여기가 마지막 관문이다** |
|
|
537
540
|
| 본문 전체 | (코드 작업을 녹인 문서) 「반영함·보이지 않음·빠짐」 같은 완료형 동사가 원고 밖 상태 표의 확인 수준(코드·시험판·실기기·운영)을 넘지 않는가 — 기계 없음, 독자 검토 state 관점(`args.state`) · 사람의 눈(4단계 「코드 작업을 녹일 때」) |
|
|
@@ -567,9 +570,9 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
567
570
|
**기본은 초안이다.**
|
|
568
571
|
도구가 `publish` 를 명시적으로 참으로 주지 않는 한 고객에게 안 보인다. 여는 것은 10단계다.
|
|
569
572
|
|
|
570
|
-
수정은 SKILL.md 8단계 「수정 절차」(`
|
|
573
|
+
수정은 SKILL.md 8단계 「수정 절차」(받은 판 보관 → draft 를 `patch.py --freeze` 로 굳혀 새 판에 적용 → `render.py` 로 새 판을 그대로 로컬 렌더 → 받은 판의 `body_rev` 를 실은 dry_run(그 사이 본문 판이 바뀌었으면 여기서 409) → 판 갱신 검토 → 같은 `body_rev` 를 실어 `update_report` → 9단계).
|
|
571
574
|
**같은 링크가 새 내용을 가리킨다.** 초안 `update_report` 도 **본문 판(`body_rev`)** 을 올리고 사용자가 그 판을 읽으므로 독자 검토를 통과한 본문 판만 올린다. 사용자가 「바로 반영」을 지시하면 먼저 올리고 검토를 곧바로 뒤따라 돌린다 — 발행 이력 행(`history`)은 공개 뒤에만 는다(SKILL 3c).
|
|
572
|
-
사람이 고친
|
|
575
|
+
`list_reports` 줄에 「덮음: …」이 있으면(사람이 고친 초안·발행 본문) 덮기 전에 묻는다 — 받은 판의 `body_rev`(`get_report` 머리줄 값)를 실은 교체는 그 뒤 본문 판이 바뀌었으면 서버가 409 로 막지만, 편집기에 저장만 해 둔 사람 초안은 판을 안 올려 그 잠금에 안 걸린다. 목록의 「덮음」이 유일한 신호다.
|
|
573
576
|
|
|
574
577
|
포털 셸이 문서 **둘레**에 놓는 것(검토 회신·핵심 요약·진척률 바)은 저작 대상이 아니다.
|
|
575
578
|
문서 안에 「댓글로 알려 주세요」를 쓰면 같은 것이 두 번 있게 된다.
|
|
@@ -594,6 +597,7 @@ python3 ~/.claude/skills/genetics-report/assets/render.py report.json
|
|
|
594
597
|
## 9단계 — 발행 뒤 판정
|
|
595
598
|
|
|
596
599
|
초안 발행·수정마다 돈다(공개 전에도). 이 블록 목록 대조와 열람 주소 열기가 SKILL.md 「작업 체크리스트」 9단계 두 행이다 — 둘 다 대조 기계는 아직 없고 사람이 한다.
|
|
600
|
+
고친 판이면 `get_report(id)` 로 되읽은 JSON 을 새 `body_rev` 를 파일 이름에 넣어 둔다 — 다음 수정이 받은 판과 내용으로 견줄 기록이다.
|
|
597
601
|
|
|
598
602
|
브라우저를 안 열고도 「무엇을 냈는가」를 확인하는 창구다.
|
|
599
603
|
|
|
@@ -646,9 +650,10 @@ MCP 가 찍는 요약 줄은 **옛 서식의 셈**만 읽는다(`genetics.mjs ou
|
|
|
646
650
|
|
|
647
651
|
공개 전 수정은 판이 아니다(SKILL 3c). 공개하기 직전에 한 번만 날짜를 맞춘다.
|
|
648
652
|
|
|
649
|
-
1. 작성일 세 자리 — `meta` 의 작성 · 판권지(`colophon`) 작성 · `history` 마지막 `date` — 를 공개하는 날 한 값으로 고친다. `history` 는 공개할 판 한 행(「최초 발행」)만 둔다.
|
|
653
|
+
1. 올라 있는 판을 받아(SKILL 8단계 「수정 절차」 1~3 — 로컬 `report.json` 은 그사이 수정 절차를 돈 문서면 낡았다) 작성일 세 자리 — `meta` 의 작성 · 판권지(`colophon`) 작성 · `history` 마지막 `date` — 를 공개하는 날 한 값으로 고친다. `history` 는 공개할 판 한 행(「최초 발행」)만 둔다.
|
|
654
|
+
draft 는 있는 자리만 적는다 — `meta[label=작성][1]` · `colophon.rows[label=작성][1]`(판권지에 `rows` 가 있을 때만) · `history[0].date`. 칸에 날짜 말고 다른 글이 함께 있으면(「2026. 9. 27. · FCG」) `set` 대신 `replace` 로 날짜 조각만 바꾼다.
|
|
650
655
|
`cover_date` 는 요약면 「기준」 날짜(수치의 기준일)라 이 셋에 묶지 않는다.
|
|
651
|
-
2. `update_report` 한 번 → 9단계 두 행.
|
|
656
|
+
2. 로컬 렌더 → 받은 판의 `body_rev` 를 실은 dry_run → 같은 `body_rev` 로 `update_report` 한 번(수정 절차 4~6 — 날짜만 고친 판이라 판 갱신 검토는 돌리지 않는다) → 9단계 두 행.
|
|
652
657
|
3. 사용자 승인을 받고 `release_report(id)` 로 연다 — 그것이 사람의 승인 행위다.
|
|
653
658
|
|
|
654
659
|
공개 뒤 내용이 바뀐 update 에만 `history` 행을 더한다. 문서 밖 결정의 날짜는 본문에 적지 않는다(결정 장부).
|
|
@@ -701,14 +706,15 @@ MCP 가 찍는 요약 줄은 **옛 서식의 셈**만 읽는다(`genetics.mjs ou
|
|
|
701
706
|
|---|---|---|---|
|
|
702
707
|
| 1 | 독자 문장 1개 (하는 일로) + 할 일 목록 | (문서 아님 — 작업 전제) | 0 |
|
|
703
708
|
| 1a | 정해진 것의 결정권·정한 주체·기록·확인 여부 | 작업 폴더 `decisions.json`(발행 안 함) | 0a |
|
|
704
|
-
| 2 | 금지 어휘·식별자 정규식 | `forbid` (로컬
|
|
709
|
+
| 2 | 금지 어휘·식별자 정규식 | `forbid` (로컬 렌더는 멈춤 · 포털 발행은 경고) | 0·6 |
|
|
710
|
+
| 2a | 부를 이름 대응표(우리가 부르던 이름 / 독자 화면·문서의 이름 / 보이는 자리) | 작업 폴더 `names.md`(발행 안 함) | 0 |
|
|
705
711
|
| 3 | PART 구성 | `parts` | 0·6 |
|
|
706
712
|
| 4 | 절 구성과 순서 | `sections` + `groups` | 0·6 |
|
|
707
713
|
| 5 | 건별 필드 | `cases` | 1·2 |
|
|
708
714
|
| 6 | 보고서 표제로 재작성한 전 건 제목 | `cases[].title` | 2 |
|
|
709
715
|
| 7 | 등급 이름·정의문 (**4단 이하** · 최약 등급에 한계 명시) | `grades` | 3 |
|
|
710
716
|
| 8 | 요지(칸 수는 SKILL 4~6단계) + **문단마다 근거** | `summary` (+ `refs`) | 4 |
|
|
711
|
-
| 9 | 확인 요청 3~6개
|
|
717
|
+
| 9 | 확인 요청 3~6개(검수·보고는 우리가 못 닫은 사실을 먼저, 부탁은 하십시오체) | `open_items` | 4 |
|
|
712
718
|
| 10 | **절마다 여백 주석** | `sections[].marg` | 5 |
|
|
713
719
|
| 11 | 표지·발행 이력·활용법 | `doc_no`·`client`·`title`·`title_sub`·`subtitle`·`meta`·`issuer`·`history`·`guide` | 6 |
|
|
714
720
|
| 12 | 요약면 | `notice`·`bar`·`bar_note`·`stats` | 6 |
|
|
@@ -734,9 +740,9 @@ MCP 가 찍는 요약 줄은 **옛 서식의 셈**만 읽는다(`genetics.mjs ou
|
|
|
734
740
|
3. **관보 셈(`ask`·`sheet`·`board`·`marg` 등)을 MCP `outline` 요약 줄이 안 찍는 것.**
|
|
735
741
|
서버는 계산해서 실어 준다.
|
|
736
742
|
도구를 고칠지, 블록 목록으로 판정하는 지금 방식을 유지할지 판단하지 않았다.
|
|
737
|
-
4. **포털
|
|
738
|
-
|
|
739
|
-
|
|
743
|
+
4. **포털 발행의 `forbid` 는 경고이고 로컬은 멈춘다.**
|
|
744
|
+
2026-09-26 전에는 포털 입구가 이 칸을 깎기만 해서 그물이 없었다. 지금은 `report_publish.php report_forbid_warnings()` 가 경고로 센다.
|
|
745
|
+
두 경로의 태도(멈춤 · 경고)와 훑는 자리(렌더된 HTML · 원고 글자 칸)가 달라 판정이 갈릴 수 있다. 하나로 맞출지는 판단하지 않았다.
|
|
740
746
|
5. **`text_fix` 를 서버가 계속 받는 것.**
|
|
741
747
|
관보 렌더러가 안 읽는데 화이트리스트에 남아 있다.
|
|
742
748
|
지울지, 관보 경로에 붙일지 판단하지 않았다.
|