genetics-mcp 2.24.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 +49 -12
- package/package.json +2 -2
- package/skills/genetics-report/SKILL.md +35 -20
- package/skills/genetics-report/assets/mcp-call.mjs +61 -10
- package/skills/genetics-report/assets/patch.py +237 -22
- package/skills/genetics-report/assets/render.py +53 -2
- package/skills/genetics-report/references/edition-review.workflow.js +55 -13
- package/skills/genetics-report/references/font-embedding.md +1 -1
- package/skills/genetics-report/references/lim-portal-format.md +11 -5
- package/skills/genetics-report/references/process.md +7 -5
- package/skills/genetics-report/references/reader-review.workflow.js +13 -5
- package/skills/genetics-report/references/visual-first.md +6 -6
- package/skills/gazette-report/scripts/package-lock.json +0 -24
|
@@ -65,7 +65,7 @@ python3 assets/render.py <report.json>
|
|
|
65
65
|
`cfg.get('css', ['report.css'])`(`build.py styles()`)로 떨어져 옛 서식 시트가 실린다.
|
|
66
66
|
스타일 없는 문서가 대비 검사를 통과해 「거짓 초록」이 된다.
|
|
67
67
|
- 렌더러에 안 넘어가는 칸이 둘 있다: `out`(출력 파일명) · `forbid`(금칙 패턴).
|
|
68
|
-
서버는 `out` 을 스스로 `report.html` 로 박는다(`report_publish.php report_render()`).
|
|
68
|
+
서버는 `out` 을 스스로 `report.html` 로 박는다(`report_publish.php report_render()`). 로컬 `render.py` 는 원고에 `out` 이 없으면(`get_report` 로 받은 원고) 원고 이름 옆 `.html` 로 쓴다.
|
|
69
69
|
`forbid` 는 렌더러에 넘기지 않지만 버리지도 않는다 — 입구의 `report_publish.php report_forbid_warnings()` 가 경고로 센다(§10). 로컬 `render.py` 는 `build.py guard()` 가 렌더된 HTML 에 걸리면 멈춘다.
|
|
70
70
|
- `tenant`(소속처 slug)는 발행 데이터 칸이 아니라 `publish_report` 의 인자다 — 포털 입구는 렌더러 몫에서 깎는다.
|
|
71
71
|
소속처가 반려한 이름 목록은 그 소속처의 **반려 결정 장**(`remember_decision` 의 `rejected_names` 칸)에 산다. 포털은 발행·모의 발행 때
|
|
@@ -420,7 +420,7 @@ python3 assets/render.py <report.json>
|
|
|
420
420
|
| 열린 검토 회신 #N(이름 · 날짜) 「회신 본문」 — 집은 문장 「…」이 이 원문에 없습니다 — 원문이 바뀜 / 문장을 잃어 상위로 / 자리를 잃음 | `update_report` 만. **아직 반영 표시가 안 된** 회신이 집은 문장이 새 원문에 없다(3.5절 uid 항) — 이 판이 그 회신을 반영한 것이면 발행 뒤 `resolve_note(id, reply, rev)`, 아니면 회신 본문부터 읽는다(SKILL 9b). 핀을 살리려고 문장을 되돌리지 않는다 |
|
|
421
421
|
| 절 …의 도판 「…」를 assets 에서 못 찾았습니다 | `plates` 가 없는 `assets[].id` 를 가리킨다(건 `plates` 면 「건 NN-n 의 도판」) |
|
|
422
422
|
| 건 NN-n 에 묶인 도판 「…」는 전폭(wide)인데 건 안이라 본문 단 폭으로 섭니다 | `cases[].plates` 가 `wide:true` 자산을 가리킨다 — 건 안은 두 단 그리드라 전폭이 못 선다. 절 `plates` 로 옮기거나 `wide` 를 끈다(11-10절) |
|
|
423
|
-
| 도판 「…」에 그림 바이트가 없습니다 | `file`·`source` 없이 이름만 왔다. 로컬 `render.py` 는 `file` 을 바이트로 굳히지 않아 `file` 이 있어도 뜬다 — 로컬에서는 이 줄을 빼고 나머지 ⚠ 를
|
|
423
|
+
| 도판 「…」에 그림 바이트가 없습니다 | `file`·`source` 없이 이름만 왔다. 로컬 `render.py` 는 `file` 을 바이트로 굳히지 않아 `file` 이 있어도 뜬다 — 로컬에서는 이 줄을 빼고 나머지 ⚠ 를 읽는다. `get_report` 로 받은 표식(`(생략 — NB)`)은 치수가 있고 `file`·`source` 가 없으면 로컬 `render.py kept_stand_ins()` 가 서버 기록 치수의 자리 상자로 그리고 ⚠ 대신 「보관 그림 N장」 한 줄로 센다(원고에 `out` 이 있으면 — 받은 판이 아니라 작성 중인 원고라는 뜻 — 그 줄이 ⚠ 로 선다) — 그 HTML 은 검토본이다 |
|
|
424
424
|
| `chapters`·`figure`(**최상위 칸**) 는 자리가 없어 | 옛 서식 전용 칸. `assets[].role:"figure"` 와 다른 것이다 |
|
|
425
425
|
| 절 …의 `principles`/`logic` 은 자리가 없어 | 같음 |
|
|
426
426
|
| `wide`/`marg_width` 값이 길이 단위가 아니라 | CSS 값 검사 |
|
|
@@ -495,7 +495,7 @@ python3 assets/render.py <report.json>
|
|
|
495
495
|
| 도판 「%s」 출처 줄에 제작 설명이나 그림 번호가 있습니다(「%s」) — 위치 한 구절만, 제작 기록은 origin 으로 | `role:"figure"` 전부(provider 무관)의 `source_text` 를 주소를 지운 뒤 정규식 `(합성·재현)(이며·임·함·한 것·했) \| 예시(이며·임·라) \| (실제·실기기) 화면이 아님 \| 도안이 아님 \| 자리 표시 \| 규격(과 문구)?의 출처 \| 찍(음·은 것) \| 배율 \| N배 밀도 \| 크롭 \| 잘라 \| 자름 \| 그림 N-N` 으로 센다. **캡션은 보지 않는다** — 캡션의 한 낱말 「— 합성」·「재현」·「갈무리」는 정직성 이름표다. 출처 줄에서도 맨 낱말 「합성」·「재현」은 안 걸고 서술형만 건다. 「골밀도」 같은 값 이름은 「N배 밀도」가 아니라 안 걸린다 | 출처 줄에는 위치 한 구절만. 만든 방식·결정 경로는 `origin`(렌더 안 됨)과 도판 HTML 머리 주석에. 바깥 원본이 없는 우리 도안·흐름은 출처 줄을 비운다(readability R12e) |
|
|
496
496
|
| 표 「%s」 주석이 %d문장입니다 — ※ 주석은 %d문장 안 | `tables[].note` 문장 3 이상(둘째 `%d` 는 상한 2). 문장은 렌더러가 문장 블록을 세우는 판별(`boundary.py` — 날짜 마침표 「2026. 9. 30.」·「9. 8.」은 경계가 아님)로 센다. | 두 문장 안으로, 나머지는 본문·건으로(readability R12a) |
|
|
497
497
|
| 판단 항목 「%s」 본문이 %d문장입니다 — %d문장 안 | `open_items[].body` 문장 5 이상(둘째 `%d` 는 상한 4 · 자수 220 은 §10 의 R11f 행이 따로 센다) | 기한과 두 길 이름 → 길마다 달라지는 것 → 근거 절 번호까지 네 문장. 상세는 건에(readability R12b) |
|
|
498
|
-
| 앞 절이 뒤 절을 가리키는 곳이 %d개입니다(%s) — 낱말·규칙은 첫 등장 자리에서 풀고, 뒤 절이 앞 절을 되짚는 방향만 둡니다(readability R12h) | 절 i(배열 순서, 1부터)의 산문 — `sections[].name·sub·lede·paragraphs` · `tables[].caption·cols·rows·note` · `flow.caption·note`·`rows[].no`(건 좌표 꼴 `^§?\d{1,2}[-.]\d{1,2}$` 의 앞 숫자)·`cells[].text·note` · `marg(why/key/advice)` · 그 절이 `kind:"cases"` 면 같은 그룹 `cases[].symptom·cause·fix·how_to_check·remaining` · `kind:"asks"` 면 `cta[]`·`open_items[].title·body` · `sections[].plates` 가 가리키는 `assets[].caption·source_text` — 에서 정규식 `§\s*(\d+)\.\d+` 와 `(?<![\d.])(\d{1,2})절` 의 앞 숫자가 i 보다 큰 것을 센다. 「N차 … 제N절」(남의 문서의 절 번호, 예 「검수 보고 4차 제5절」)은 건너뛴다. `summary[].lead·body` 와 `refs[]` 는 세지 않는다 — 요약 근거 게이트(§8)가 `refs` 로 서고 「해당 절」·「근거」 단추가 되므로 뜀이 아니다. `%s` 는 자리와 걸린 낱말 최대 3개 | 낱말·규칙·예시 선언은 **첫 등장 자리에서 한 구절**로 풀고, 뒤 절 번호 대신 그 자리에서 뜻이 서는 말을 둔다. 근거 건은 `refs` 로만. 뒤 절이 앞 절을 되짚는 방향(05절에서 「03절 표」)은 둔다(readability R12h · SKILL 0.5단계 7행) |
|
|
498
|
+
| 앞 절이 뒤 절을 가리키는 곳이 %d개입니다(%s) — 낱말·규칙은 첫 등장 자리에서 풀고, 뒤 절이 앞 절을 되짚는 방향만 둡니다(readability R12h) | 절 i(배열 순서, 1부터)의 산문 — `sections[].name·sub·lede·paragraphs` · `tables[].caption·cols·rows·note` · `flow.caption·note`·`rows[].no`(건 좌표 꼴 `^§?\d{1,2}[-.]\d{1,2}$` 의 앞 숫자)·`cells[].text·note` · `marg(why/key/advice)` · 그 절이 `kind:"cases"` 면 같은 그룹 `cases[].symptom·cause·fix·how_to_check·remaining` 과 건에 묶인 표 `cases[].tables[].caption·cols·rows·note` · `kind:"asks"` 면 `cta[]`·`open_items[].title·body` · `sections[].plates` 가 가리키는 `assets[].caption·source_text` — 에서 정규식 `§\s*(\d+)\.\d+` 와 `(?<![\d.])(\d{1,2})절` 의 앞 숫자가 i 보다 큰 것을 센다. 「N차 … 제N절」(남의 문서의 절 번호, 예 「검수 보고 4차 제5절」)은 건너뛴다. `summary[].lead·body` 와 `refs[]` 는 세지 않는다 — 요약 근거 게이트(§8)가 `refs` 로 서고 「해당 절」·「근거」 단추가 되므로 뜀이 아니다. `%s` 는 자리와 걸린 낱말 최대 3개 | 낱말·규칙·예시 선언은 **첫 등장 자리에서 한 구절**로 풀고, 뒤 절 번호 대신 그 자리에서 뜻이 서는 말을 둔다. 근거 건은 `refs` 로만. 뒤 절이 앞 절을 되짚는 방향(05절에서 「03절 표」)은 둔다(readability R12h · SKILL 0.5단계 7행) |
|
|
499
499
|
| 표 「%s」의 「%s」 열은 모든 행이 같습니다 — 차이를 못 나르는 열은 주석으로 | `doc_type` 에 「브리핑」 · `kind:"asks"` 절의 `tables[]` 가운데 행이 셋 이상인 표에서, 첫 열을 뺀 한 열이 모든 행에서 같은 값(빈 칸 아님)이다. asks 밖 절(일정 표 「누가」 열 등)·행 둘 이하·빈 칸뿐인 열은 안 센다 | 그 열을 빼고 ※ 주석 한 줄로(visual-first §5). 선택지를 가르는 열만 한눈표에 둔다(§12.3b 대칭 불변식) |
|
|
500
500
|
| 건 행 이름 「%s」 낱말이 %d곳에도 쓰였습니다(%s) — 한 낱말은 한 장치에만, 다른 자리는 다른 낱말로 | 데이터가 준 `labels` 의 `symptom`·`cause`·`fix`·`check` 값이 `kind≠cases` 절의 `sub`·`tables[].caption`·`tables[].cols` 에 낱말로 선다(뒤에 조사 하나까지 같은 낱말 — 「판단력」·「판단이다」는 다른 낱말). 괄호 안은 자리 이름 최대 3개. `labels` 를 안 준 기본 이름·건 절 자신·절 이름·도입문·산문은 안 본다 | 의견 절의 열·부제는 「의견」으로(§3.5 · visual-first §3) |
|
|
501
501
|
| 선택지를 「길」로 부른 곳이 %d곳 있습니다(%s 「%s」 …) — 「길」은 스킬의 장치 이름입니다. 원고에서는 선택지를 그것이 실제로 무엇인지로 부릅니다 | 글자 자리 전부(과정 어휘와 같은 자리 — `history`·`labels`·`origin` 등 제외)에서 정규식 `RX_GIL`(gazette.py) — 「두 길의」「복제본 길」「고른 길별」「지나는 길과」, 앞말이 선택지를 세는 말인 「어느 길이」「두 길이」, 칸 하나가 「길」인 열 머리는 걸리고 「막대 길이」「길게」「길다」는 안 걸린다. `%s` 둘은 과정 어휘 행과 같은 꼴(자리 5곳까지 · 마지막 낱말) | 선택지는 그것이 실제로 무엇인지(고객이 부르는 이름)로 — 「복제본 전환」「직접 업그레이드」「현행 유지」. 「길」은 스킬 문서 안의 장치 이름일 뿐이다(SKILL 반드시 지키는 것 12) |
|
|
@@ -525,7 +525,7 @@ python3 assets/render.py <report.json>
|
|
|
525
525
|
| %s 머리의 개수가 %s 인데 실제는 %s 입니다 — count 를 비우면 자동으로 셉니다 | `kind` 가 `cases`·`asks` 인 절의 `count` 에 숫자를 적었는데 건 수·판단 항 수와 다르다. 그 밖의 절(`note` 등)은 무엇을 세는지 렌더러가 모르므로 안 본다 | `count` 를 지운다 — 렌더러가 센 값이 선다 |
|
|
526
526
|
| %s 의 표 「%s」에 %s 가 없어 싣지 못했습니다%s | 표에 제목·행·열 머리 가운데 무엇이든 있는데 `cols` 나 `rows` 가 비어 그릴 수 없다. 열 머리를 `head`·`headers`·`columns`·`header` 로 적었으면 그 이름을 짚는다. **표가 빠지면 뒤 표 번호가 전부 당겨진다** | 열 머리의 이름은 `cols` 다 |
|
|
527
527
|
| 절 %s 의 plates 배열 순서와 그림 번호가 다릅니다(전폭 「%s」 뒤에 본문 단 「%s」) — 차트·흐름도·본문 단 도판이 먼저 번호를 받습니다 | 한 절 `plates` 에서 `wide:true` 도판 뒤에 본문 단 도판이 적혔다 — 전폭은 그리드 밖이라 번호를 뒤에 받는다 | `plates` 를 본문 단 → 전폭 순서로 적는다 |
|
|
528
|
-
| 작성일이 한 값이 아닙니다(%s) — 표지 「작성」 · 판권지 「작성」 · 발행 이력 마지막 date 는 공개하는 날 한 값으로(공개 직전 update_report 한 번) | 표지 `meta` 의 「작성」 행 · 판권지 `colophon.rows` 의 「작성」 행(`rows` 가 없으면 표지를 그대로 쓰므로 안 셈) · `history` 마지막 `date` — 셋에서 년·월·일을 0 채움으로 읽어(「2026.08.24」 = 「2026. 8. 24.」, 범위는 첫 날짜) 값이 둘 이상이다. 자리가 둘 미만이면 안 센다. `cover_date` 는 수치의 기준일이라 대조하지 않는다(§3.1) | 공개
|
|
528
|
+
| 작성일이 한 값이 아닙니다(%s) — 표지 「작성」 · 판권지 「작성」 · 발행 이력 마지막 date 는 공개하는 날 한 값으로(공개 직전 update_report 한 번) | 표지 `meta` 의 「작성」 행 · 판권지 `colophon.rows` 의 「작성」 행(`rows` 가 없으면 표지를 그대로 쓰므로 안 셈) · `history` 마지막 `date` — 셋에서 년·월·일을 0 채움으로 읽어(「2026.08.24」 = 「2026. 8. 24.」, 범위는 첫 날짜) 값이 둘 이상이다. 자리가 둘 미만이면 안 센다. `cover_date` 는 수치의 기준일이라 대조하지 않는다(§3.1) | 공개 직전에 한 번, 세 자리를 공개하는 날로 맞춘다 — SKILL 8단계 「수정 절차」로(받은 판에서 출발 · `body_rev` 를 실어 교체 — SKILL 3c · 체크리스트 10단계). 표기를 한 꼴로 맞추는 것은 사람 눈(§3.5) |
|
|
529
529
|
|
|
530
530
|
위 표에서 여섯째 행(과정 어휘)부터 끝까지는 `gazette.py` 의 문구 **그대로**다(`%d`·`%s` 는 수·이름이 들어가는 자리) — 문구를 바꾸면 양쪽을 같이 바꾼다.
|
|
531
531
|
예외는 **서버**라고 적은 반려 이름 네 행이다 — 렌더러가 아니라 포털(`report_publish.php report_rejected_names()`·`report_build_checked()`)의 문구라 자리를 `%` 대신 「N」·「M」·「까닭」으로 적었다.
|
|
@@ -539,7 +539,7 @@ python3 assets/render.py <report.json>
|
|
|
539
539
|
- **로컬 `render.py`** — `--tenant <slug>`(없으면 원고의 `tenant`)로 옆 `mcp-call.mjs` 를 띄워 `list_rejected_names`(`format: "json"`)를 부른다.
|
|
540
540
|
받으면 「소속처 「slug」 반려 이름 N개로 셈」, 못 받으면 ⚠ 「반려 이름을 못 받았습니다(까닭) — 이 렌더는 소속처 「slug」의 반려 이름을 세지 않았습니다」,
|
|
541
541
|
소속처가 없으면 ⚠ 「소속처(--tenant 또는 원고의 tenant)가 없어 반려 이름을 세지 않았습니다」. 어느 쪽이든 렌더는 끝까지 한다.
|
|
542
|
-
`mcp-call.mjs`
|
|
542
|
+
MCP 서버는 `mcp-call.mjs` 가 찾아 띄운다 — 저장소 안 스킬이면 저장소의 `genetics.mjs`, 복사본으로 깔린 스킬이면 게시본이다(찾는 순서는 그 파일 머리 주석).
|
|
543
543
|
- **발행 직전 훅**(이 기계의 `~/.claude/hooks/report-gate.py` — 스킬과 함께 배급되지 않고, 설정에 등록됐을 때만 돈다) — 같은 길로 받아 `coined_scan()` 에 얹는다.
|
|
544
544
|
못 받으면 대화 이력·「탓」만 세고, 경고가 있을 때 「반려 이름 미확인(까닭)」 한 줄을 덧붙인다.
|
|
545
545
|
|
|
@@ -639,6 +639,12 @@ CSS 로는 못 한다. 우측 판독부에 남는 것은 문서 전체의 사실
|
|
|
639
639
|
모든 도판은 눌러서 **크게 보기**가 열린다(스크립트 없이 `:target`). 원본이 1400px 라 본문 단의 최대
|
|
640
640
|
1.8배다 — 하한을 못 넘긴 그림의 구제책이지 하한을 대신하지 않는다.
|
|
641
641
|
|
|
642
|
+
**접기(2026-09-30)** — 렌더러가 정한다(원고 칸 없음). 이미지 도판·영상은 절마다 첫 장만 펼치고 둘째부터
|
|
643
|
+
「그림 N-M 캡션」 한 줄로 접는다(도해 `.diagram` 은 안 접는다). 건 필드표는 증상·미결·원본은 늘 보이고
|
|
644
|
+
원인·조치·확인 방법만 접는다. 스크립트 없는 `<details>` 이고 인쇄는 전부 펼친다(`::details-content`).
|
|
645
|
+
본문의 `{{그림:id}}` 링크로 접힌 그림에 가면 브라우저가 펼친다(Chrome 실측 — Safari·Firefox 미측정).
|
|
646
|
+
그래서 **캡션 한 줄만으로 무슨 그림인지 서야 한다** — 접힌 동안 독자가 보는 것은 번호와 캡션뿐이다.
|
|
647
|
+
|
|
642
648
|
번호는 **그림 〈절 순번〉-〈그 절에서의 순서〉** 다. 절 4의 둘째 도판이면 `그림 4-2` 이고,
|
|
643
649
|
앵커는 `#fig-04-2` 다. 데이터로 바꿀 수 없다 — 절 번호와 같은 규약이다.
|
|
644
650
|
|
|
@@ -459,7 +459,7 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
459
459
|
|---|---|---|
|
|
460
460
|
| `dry_run` warnings(로컬 렌더 ⚠ 포함) | 무엇이 **안 실렸는가** · 규칙 낱말·모양 | 작성자가 고칠 수 있는 ⚠ 0건 |
|
|
461
461
|
| 검사기 8종 | 조판이 **성립했는가** | 각 검사기의 0건 |
|
|
462
|
-
| 독자 검토(`reader-review.workflow.js`) | 처음 읽는 사람·결정권자가 **읽히는가** · 도판을 열어 잰 틀 · 1차 자료와 맞는가 | Verify 를 통과한 발견 반영 · 「⚠ 도판 N장 미열람」 없음(SKILL
|
|
462
|
+
| 독자 검토(`reader-review.workflow.js`) | 처음 읽는 사람·결정권자가 **읽히는가** · 도판을 열어 잰 틀 · 1차 자료와 맞는가 | Verify 를 통과한 발견 반영 · 「⚠ 도판 N장 미열람」 없음(SKILL 체크리스트 7단계 독자 검토 행 — 미열람·「서버 보관」 줄의 id 가 모두 원고에서 보관 표식인 장이면 사람이 열람 주소에서 보고 핸드오프에 적어 통과) |
|
|
463
463
|
| 사람의 눈 | 이 문서가 **이 독자에게 맞는가** | 판단 |
|
|
464
464
|
|
|
465
465
|
### `dry_run` 이 실질적 유일한 품질 관문이다
|
|
@@ -570,9 +570,9 @@ RANK_TAG = ['live', 'data', 'done', 'soon'] # 배지 종류
|
|
|
570
570
|
**기본은 초안이다.**
|
|
571
571
|
도구가 `publish` 를 명시적으로 참으로 주지 않는 한 고객에게 안 보인다. 여는 것은 10단계다.
|
|
572
572
|
|
|
573
|
-
수정은 SKILL.md 8단계 「수정 절차」(`
|
|
573
|
+
수정은 SKILL.md 8단계 「수정 절차」(받은 판 보관 → draft 를 `patch.py --freeze` 로 굳혀 새 판에 적용 → `render.py` 로 새 판을 그대로 로컬 렌더 → 받은 판의 `body_rev` 를 실은 dry_run(그 사이 본문 판이 바뀌었으면 여기서 409) → 판 갱신 검토 → 같은 `body_rev` 를 실어 `update_report` → 9단계).
|
|
574
574
|
**같은 링크가 새 내용을 가리킨다.** 초안 `update_report` 도 **본문 판(`body_rev`)** 을 올리고 사용자가 그 판을 읽으므로 독자 검토를 통과한 본문 판만 올린다. 사용자가 「바로 반영」을 지시하면 먼저 올리고 검토를 곧바로 뒤따라 돌린다 — 발행 이력 행(`history`)은 공개 뒤에만 는다(SKILL 3c).
|
|
575
|
-
사람이 고친
|
|
575
|
+
`list_reports` 줄에 「덮음: …」이 있으면(사람이 고친 초안·발행 본문) 덮기 전에 묻는다 — 받은 판의 `body_rev`(`get_report` 머리줄 값)를 실은 교체는 그 뒤 본문 판이 바뀌었으면 서버가 409 로 막지만, 편집기에 저장만 해 둔 사람 초안은 판을 안 올려 그 잠금에 안 걸린다. 목록의 「덮음」이 유일한 신호다.
|
|
576
576
|
|
|
577
577
|
포털 셸이 문서 **둘레**에 놓는 것(검토 회신·핵심 요약·진척률 바)은 저작 대상이 아니다.
|
|
578
578
|
문서 안에 「댓글로 알려 주세요」를 쓰면 같은 것이 두 번 있게 된다.
|
|
@@ -597,6 +597,7 @@ python3 ~/.claude/skills/genetics-report/assets/render.py report.json
|
|
|
597
597
|
## 9단계 — 발행 뒤 판정
|
|
598
598
|
|
|
599
599
|
초안 발행·수정마다 돈다(공개 전에도). 이 블록 목록 대조와 열람 주소 열기가 SKILL.md 「작업 체크리스트」 9단계 두 행이다 — 둘 다 대조 기계는 아직 없고 사람이 한다.
|
|
600
|
+
고친 판이면 `get_report(id)` 로 되읽은 JSON 을 새 `body_rev` 를 파일 이름에 넣어 둔다 — 다음 수정이 받은 판과 내용으로 견줄 기록이다.
|
|
600
601
|
|
|
601
602
|
브라우저를 안 열고도 「무엇을 냈는가」를 확인하는 창구다.
|
|
602
603
|
|
|
@@ -649,9 +650,10 @@ MCP 가 찍는 요약 줄은 **옛 서식의 셈**만 읽는다(`genetics.mjs ou
|
|
|
649
650
|
|
|
650
651
|
공개 전 수정은 판이 아니다(SKILL 3c). 공개하기 직전에 한 번만 날짜를 맞춘다.
|
|
651
652
|
|
|
652
|
-
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` 로 날짜 조각만 바꾼다.
|
|
653
655
|
`cover_date` 는 요약면 「기준」 날짜(수치의 기준일)라 이 셋에 묶지 않는다.
|
|
654
|
-
2. `update_report` 한 번 → 9단계 두 행.
|
|
656
|
+
2. 로컬 렌더 → 받은 판의 `body_rev` 를 실은 dry_run → 같은 `body_rev` 로 `update_report` 한 번(수정 절차 4~6 — 날짜만 고친 판이라 판 갱신 검토는 돌리지 않는다) → 9단계 두 행.
|
|
655
657
|
3. 사용자 승인을 받고 `release_report(id)` 로 연다 — 그것이 사람의 승인 행위다.
|
|
656
658
|
|
|
657
659
|
공개 뒤 내용이 바뀐 update 에만 `history` 행을 더한다. 문서 밖 결정의 날짜는 본문에 적지 않는다(결정 장부).
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// text: "<렌더본 텍스트 절대경로(필수) — `python3 assets/render.py <report.json> --text <원고 폴더 밖 빈 폴더>/본문.txt`>",
|
|
5
5
|
// reader: "<독자 한 줄: 누구이며 무엇을 하나 — 할 일이 둘이면 둘 다>",
|
|
6
6
|
// example: "<예시 한 명 한 줄: 번호·측정일·실제 값>", bitmapBudget: 3,
|
|
7
|
-
// scratch: "<측정
|
|
7
|
+
// scratch: "<측정 스크립트를 둘 스크래치 절대경로>",
|
|
8
8
|
// plates: "<도판 HTML·PNG 작업 폴더(선택) — assets[].file 경로가 옮겨졌을 때 찾는 곳>",
|
|
9
9
|
// locked: ["<정해진 것 한 줄>", …], latest: "<사용자 최신 지적 원문>",
|
|
10
10
|
// sources: [{ name: "<자료 이름>", path: "<절대경로>", kind: "code|doc|pdf" }, …],
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
// merged.findings 앞에는 사실 틀림(class 사실틀림) 가운데 **Verify 가 참·부분으로 받은 것**이 합치지 않은 독립 항목으로 서고 개수 제한 밖이다.
|
|
26
26
|
// 미확인으로 판정된 사실 틀림은 합치는 쪽으로 가 problem 끝에 「(미확인)」이 붙는다. 뒤는 합친 상위 10.
|
|
27
27
|
// 발견을 버리는 조건은 진단 거짓 하나다. 처방이 규칙에 걸리면(정해진 것 되돌리기·노이즈·포인터·새 이름 짓기) 발견은 남기고 rx 에 「처방 다시 — 까닭」.
|
|
28
|
-
// 못 연 도판이 있으면 merged.overall 머리 줄이 「⚠ 도판 N장
|
|
28
|
+
// 못 연 도판이 있으면 merged.overall 머리 줄이 「⚠ 도판 N장 미열람」이다(서버 보관이라 열 길이 없던 장은 「도판 N장 서버 보관」 줄로 따로 선다 — 미열람이 아니다). severity<3·상한 초과·검증 실패는 반영하지 않고 raw.unverified 로.
|
|
29
29
|
// 2026-09-08 고객사 검수 보고 4차에서 이 검토가 용어 충돌(한 낱말 두 값)·수치 불일치·참조 오류·반올림 설명 오류를 잡았다.
|
|
30
30
|
// 2026-09-11 실사례(고객사 결정 브리핑) 반려 둘에서 더한 것 — decider 관점에 「권고가 제목·열·색·요약에 배어 동의만 받는 틀인지」,
|
|
31
31
|
// 새 관점 source(원본 대조: 링크를 실제로 열어 인용·쪽·값을 대조, 「흐리다」는 원본 해상도로 재측정). 원고에 확인 없이 「원본이 흐림」이 실렸었다.
|
|
@@ -91,9 +91,9 @@ const LOCKED = Array.isArray(A.locked) ? A.locked : (A.locked ? [String(A.locked
|
|
|
91
91
|
const SOURCES = Array.isArray(A.sources) ? A.sources : []
|
|
92
92
|
const STATE = A.state || ''
|
|
93
93
|
const VERIFY_MAX = 12
|
|
94
|
-
const CTX = `[원고·도판·저장소 파일은 수정하지 않는다. 측정
|
|
94
|
+
const CTX = `[원고·도판·저장소 파일은 수정하지 않는다. 측정 스크립트는 scratch 아래에만 쓴다. 한글로 답할 것.]
|
|
95
95
|
원고: ${FILE} (Lim 포털 관보 서식 보고서의 발행 JSON. parts[] PART(title·lede·questions — 그 PART 가 답하는 물음), sections[] 절(sections[].part 로 PART 에 속함), cases[] 건, open_items[] 판단 요청, summary, guide 읽는 법, appendix, assets 도판)
|
|
96
|
-
도판: assets[].file 은 열어 볼 로컬 PNG 다. 서버 보관 도판(
|
|
96
|
+
도판: assets[].file 은 열어 볼 로컬 PNG 다. 서버 보관 도판(data 가 「(생략 — NB)」 표식)은 get_report 로 바이트를 받을 수 없다 — 도판 작업 폴더에 같은 도판의 원본 PNG 가 있으면 그것을 열고(파일 이름이 id 와 달라도 캡션·내용으로 찾는다), 없으면 unopened 에 그 장의 id 하나씩, why 를 「서버 보관」으로 둔다. 로고(role 이 logo)는 도판이 아니다 — unopened 에 넣지 않는다. 도판 작업 폴더: ${PLATES}
|
|
97
97
|
scratch: ${SCRATCH}
|
|
98
98
|
독자: ${READER}
|
|
99
99
|
예시 한 명: ${EXAMPLE}
|
|
@@ -169,7 +169,15 @@ const unread = LENSES.filter(([k], i) => TEXT_LENSES.has(k) && res[i] && res[i].
|
|
|
169
169
|
const reads = res.map((r, i) => r && { lens: LENSES[i][0], ...r }).filter((r) => r && !unread.includes(r.lens))
|
|
170
170
|
log(`독자 관점 ${reads.length}/${LENSES.length} · 발견 ${reads.reduce((n, r) => n + r.findings.length, 0)}${failed.length ? ` · 실패 ${failed.join(', ')}` : ''}${unread.length ? ` · 렌더본 못 엶 ${unread.join(', ')}` : ''}`)
|
|
171
171
|
const fig = reads.find((r) => r.lens === 'figures')
|
|
172
|
-
|
|
172
|
+
// 서버 보관 도판(원본 PNG 가 이 기계에 없다)은 검토자가 열 길이 없다 — 열 수 있었는데 못 연 「미열람」과 갈라 적는다(그 장은 사람이 열람 주소에서 본다).
|
|
173
|
+
// 가르는 열쇠는 검토자가 적은 글(「서버 보관」)이라 판정이 아니라 **분류 표시**다 — 통과는 사람이 그 id 가 원고의 보관 표식인지 보고 정한다(SKILL 체크리스트 7행).
|
|
174
|
+
// 한 줄로 묶어 세면 보관 그림이 있는 문서를 고친 판은 통과 기준 「⚠ 도판 N장 미열람 없음」(SKILL 체크리스트 7행)을 채울 길이 없다(2026-09-30 검토).
|
|
175
|
+
const held = fig ? fig.unopened.filter((u) => /서버 보관/.test(`${u.why} ${u.id}`)) : []
|
|
176
|
+
const missed = fig ? fig.unopened.filter((u) => !held.includes(u)) : []
|
|
177
|
+
const figHead = !fig ? '⚠ 도판 관점 실패 — 도판 전부 미열람' : [
|
|
178
|
+
missed.length ? `⚠ 도판 ${missed.length}장 미열람(${missed.map((u) => u.id).join(', ')})` : '',
|
|
179
|
+
held.length ? `도판 ${held.length}장 서버 보관 — 검토자가 열지 못했다, 열람 주소에서 사람이 본다(${held.map((u) => u.id).join(', ')})` : '',
|
|
180
|
+
].filter(Boolean).join('\n')
|
|
173
181
|
if (figHead) log(figHead)
|
|
174
182
|
|
|
175
183
|
phase('Verify')
|
|
@@ -147,7 +147,7 @@ CSS 가 만드는 글자(장식 기호·인쇄 쪽 번호)는 없고, 클래스
|
|
|
147
147
|
{ file: "<report.json 절대경로>",
|
|
148
148
|
text: "<렌더본 텍스트 절대경로 — 필수>",
|
|
149
149
|
reader: "<독자 한 줄 — 할 일이 둘이면 둘 다>", example: "<예시 한 명 한 줄>", bitmapBudget: 3,
|
|
150
|
-
scratch: "<측정
|
|
150
|
+
scratch: "<측정 스크립트를 둘 스크래치 절대경로>", plates: "<도판 HTML·PNG 작업 폴더(선택)>",
|
|
151
151
|
locked: ["<정해진 것 한 줄>", …], latest: "<사용자 최신 지적 원문>",
|
|
152
152
|
sources: [{ name, path, kind: "code|doc|pdf" }, …],
|
|
153
153
|
decisions: "<0단계 결정 장부 decisions.json 경로(선택)>", state: "<코드 작업 상태 표 경로(선택)>" }
|
|
@@ -156,7 +156,7 @@ CSS 가 만드는 글자(장식 기호·인쇄 쪽 번호)는 없고, 클래스
|
|
|
156
156
|
`sources` 는 문서마다 달라서 스킬에 경로를 적지 않는다. `state` 를 주면 여덟째 관점이 켜진다.
|
|
157
157
|
`text` 가 없으면 워크플로가 멈춘다. 「처음 읽는 사람」·「선형 읽기」 두 관점은 이 파일 하나만 받고(정해진 것·결정 장부·최신 지적·상태 표·내부 자료는 안 받는다)
|
|
158
158
|
CLAUDE.md 를 싣지 않는 Explore 유형으로 돈다 — 자동 메모리(MEMORY.md)까지 빠지는지는 첫 실행 전사로 확인하기 전이다. 나머지 관점은 위 인자를 그대로 받는다.
|
|
159
|
-
판 갱신 검토(`edition-review.workflow.js`)와 선형 읽기 실측(`linear-read-test.workflow.js`)도 `args.text` 가 필수다 — 선형 읽기 실측은 `file`
|
|
159
|
+
판 갱신 검토(`edition-review.workflow.js`)와 선형 읽기 실측(`linear-read-test.workflow.js`)도 `args.text` 가 필수다 — 선형 읽기 실측은 `file` 도 받는다 — 렌더본이 원고보다 새로운지 재는 데만 쓰고, 읽는 넷에게는 주지 않는다.
|
|
160
160
|
|
|
161
161
|
| 관점 | 보는 것 | 경계 |
|
|
162
162
|
|---|---|---|
|
|
@@ -166,7 +166,7 @@ CLAUDE.md 를 싣지 않는 Explore 유형으로 돈다 — 자동 메모리(MEM
|
|
|
166
166
|
| visual 정보 디자이너 | 그림이면 한 번에 보일 곳 · 표 숫자를 되풀이하는 문단 | — |
|
|
167
167
|
| source 원본 대조 | 고객이 누를 수 있는 원본(`source_url`·출처 줄 주소·쪽·본문 링크)과 인용의 일치 | 앱 동작은 판정하지 않는다(facts 몫) — 다른 문서에 없다고 거짓이라 하지 않는다 |
|
|
168
168
|
| structure 구조 | PART 물음 ↔ 절 내용 · PART 사이 되풀이 · 요지·읽는 법 물음이 건의 관찰·판단을 바꿔 말한 곳(문장 쌍 전수) · 요지의 이야기 순서와 칸 수, 근거 문단 `body` 비움 | 처방은 빼기로 |
|
|
169
|
-
| figures 도판 | readability R13·§4 를 읽고 `assets[].file` PNG 를 **Read 로 연다**. 같은 이름 `.html` 이 있으면 머리 주석·CSS 를 읽는다. 두 칸이면 틀 윗선·아랫선 y 를 재어 px 차를 evidence 에. 짚을 곳 — R13 위반 · 틀 잘림(윗선 여백 0 포함) · 선택지 도안 가운데 하나만 합성·실사·크게·먼저 · 그림↔본문 반박 · 캡션 「왼쪽은…」 불일치 · 칩 이름과 캡션·표 이름 불일치 | 캡션·alt 만으로 판정하지 않는다. 서버 보관
|
|
169
|
+
| figures 도판 | readability R13·§4 를 읽고 `assets[].file` PNG 를 **Read 로 연다**. 같은 이름 `.html` 이 있으면 머리 주석·CSS 를 읽는다. 두 칸이면 틀 윗선·아랫선 y 를 재어 px 차를 evidence 에. 짚을 곳 — R13 위반 · 틀 잘림(윗선 여백 0 포함) · 선택지 도안 가운데 하나만 합성·실사·크게·먼저 · 그림↔본문 반박 · 캡션 「왼쪽은…」 불일치 · 칩 이름과 캡션·표 이름 불일치 | 캡션·alt 만으로 판정하지 않는다. 서버 보관 도판(「(생략 — NB)」 표식)은 `get_report` 로 바이트를 받을 수 없다 — 원본 PNG 가 도판 폴더에 있으면 그것을 열고(파일 이름이 id 와 달라도 캡션·내용으로 찾는다), 없으면 `unopened` 에 「서버 보관」으로. 로고(`role: logo`)는 도판이 아니다 — `unopened` 에 넣지 않는다. 못 연 도판은 `unopened` 에 |
|
|
170
170
|
| facts 사실 대조 | FCG 내부 1차 자료로 수치를 다시 계산 · 앱 동작은 `kind:"code"` 파일:줄로만 · 결정의 주체·자리·시점은 결정 장부·`locked` 와 대조 | 판정 못 하면 미확인 |
|
|
171
171
|
| state 상태 대조(`state` 있을 때) | 「반영·적용·고침·보이지 않음·빠짐」 같은 완료형 문장마다 상태 표의 확인 수준(코드·시험판·실기기·운영) | — |
|
|
172
172
|
|
|
@@ -182,7 +182,7 @@ CLAUDE.md 를 싣지 않는 Explore 유형으로 돈다 — 자동 메모리(MEM
|
|
|
182
182
|
`rx` 가 달린 발견은 규칙에 맞는 처방을 새로 적는다(이름 발견은 원래 이름으로 — 새 이름·뜻풀이 금지). 선형 읽기 뜀과 이름 발견은 상위 10 과 별개로 전부 돌아간다.
|
|
183
183
|
|
|
184
184
|
돌아오는 것: `{ head?, failed?, merged: { findings[](… · rx · verdicts), overall }, questions[], passed[], dropped[], jumps[], names[], raw: { reads, verdicts, unverified } }`.
|
|
185
|
-
`merged.findings` 앞에는 **참·부분으로 판정된** 사실 틀림이 합치지 않은 독립 항목으로 서고 개수 제한 밖이다. 못 연 도판이 있으면 `overall` 머리 줄이 「⚠ 도판 N장 미열람(id…)」 — 그 도판은 사람이 연다.
|
|
185
|
+
`merged.findings` 앞에는 **참·부분으로 판정된** 사실 틀림이 합치지 않은 독립 항목으로 서고 개수 제한 밖이다. 못 연 도판이 있으면 `overall` 머리 줄이 「⚠ 도판 N장 미열람(id…)」 — 그 도판은 사람이 연다. 검토자가 「서버 보관」이라 적은 도판은 「도판 N장 서버 보관」 줄로 따로 선다 — 그 id 가 원고에서 보관 표식(`data` 가 「(생략 — NB)」)인 장인지 확인하고 열람 주소에서 사람이 본다(체크리스트 7단계 독자 검토 행).
|
|
186
186
|
검증이 1건이라도 실패하거나 관점이 결과를 못 내면 `head` 「검토 미완 — 검증 N건 실패」(관점 실패는 이어 적는다)와 `failed: true` 가 붙고 `overall` 첫 줄도 같다 — 실패를 「발견 0」으로 읽지 않고 검토를 다시 돌린다.
|
|
187
187
|
통과 기준(SKILL 체크리스트 7단계 독자 검토 행): `jumps` 가운데 심각도 3 이상 0건 · `names` 0건 — 못 없앤 것은 까닭을 핸드오프에.
|
|
188
188
|
|
|
@@ -202,8 +202,8 @@ CLAUDE.md 를 싣지 않는 Explore 유형으로 돈다 — 자동 메모리(MEM
|
|
|
202
202
|
단 경고가 규칙의 뜻과 어긋나는 자리를 짚으면(남의 문서 절 번호를 이 문서의 뒤 절로 세는 것처럼) 원고를 깎지 않는다 — 오탐으로 판정해 렌더러를 고치고 대조군 시험을 둔다. 그 수리가 운영에 오르기 전이면 번호 대신 이름으로 위치를 살린다. 렌더러·서버 관문이 운영보다 앞선 동안 옛 규칙이 내는 경고는 `lim-portal-format.md` §10 통과 기준 표의 행으로 넘긴다.
|
|
203
203
|
2. 발행 뒤 **열람 주소를 실제로 연다**(Cursor 인앱 브라우저 `iab` 나 헤드리스 크롬). 그림 수·이미지 로드 수·표·흐름도·차트 수를 세고
|
|
204
204
|
판단 절과 그림 절을 캡처로 본다. 「구조 확인 outline」은 블록이 섰는지만 말하지 보이는지는 말하지 않는다.
|
|
205
|
-
3. 큰 원고(70KB 이상)는 채팅에 붙여넣지 말고
|
|
206
|
-
(
|
|
205
|
+
3. 큰 원고(70KB 이상)는 채팅에 붙여넣지 말고 파일 인자로 보낸다 — `node assets/mcp-call.mjs <도구> <인자.json> [결과 파일]`
|
|
206
|
+
(회차 폴더에 같은 도구를 다시 짓지 않는다 — 그렇게 지은 사본들이 64KiB 넘는 응답에서 한글을 깨뜨렸다).
|
|
207
207
|
|
|
208
208
|
## 9. 하지 않는 것
|
|
209
209
|
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "scripts",
|
|
3
|
-
"lockfileVersion": 3,
|
|
4
|
-
"requires": true,
|
|
5
|
-
"packages": {
|
|
6
|
-
"": {
|
|
7
|
-
"dependencies": {
|
|
8
|
-
"playwright-core": "^1.62.1"
|
|
9
|
-
}
|
|
10
|
-
},
|
|
11
|
-
"node_modules/playwright-core": {
|
|
12
|
-
"version": "1.62.1",
|
|
13
|
-
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.62.1.tgz",
|
|
14
|
-
"integrity": "sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==",
|
|
15
|
-
"license": "Apache-2.0",
|
|
16
|
-
"bin": {
|
|
17
|
-
"playwright-core": "cli.js"
|
|
18
|
-
},
|
|
19
|
-
"engines": {
|
|
20
|
-
"node": ">=20"
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|