genetics-mcp 2.27.0 → 2.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/genetics.mjs +154 -455
- package/package.json +4 -5
- package/skills/gazette-report/scripts/boundary.py +8 -1
- package/skills/gazette-report/scripts/tone.mjs +1 -1
- package/skills/gazette-report/scripts/tone.test.mjs +3 -0
- package/skills/genetics-cell-id/SKILL.md +4 -5
- package/skills/genetics-report/SKILL.md +59 -39
- package/skills/genetics-report/assets/example/cases-briefing-designs.json +11 -11
- package/skills/genetics-report/assets/example/cases-briefing.json +3 -3
- package/skills/genetics-report/assets/example/cases.json +3 -3
- package/skills/genetics-report/assets/example/decision.json +43 -43
- package/skills/genetics-report/assets/example/report-briefing-designs.json +61 -61
- package/skills/genetics-report/assets/example/report-briefing.json +54 -54
- package/skills/genetics-report/assets/example/report.json +34 -45
- package/skills/genetics-report/assets/render.py +4 -6
- package/skills/genetics-report/assets/subset_font.py +1 -1
- package/skills/genetics-report/references/content-pipeline.md +1 -1
- package/skills/genetics-report/references/decision-format.md +90 -24
- package/skills/genetics-report/references/font-embedding.md +1 -1
- package/skills/genetics-report/references/history.md +38 -5
- package/skills/genetics-report/references/lim-portal-format.md +48 -24
- package/skills/genetics-report/references/process.md +28 -26
- package/skills/genetics-report/references/readability.md +5 -5
- package/skills/genetics-report/references/visual-first.md +18 -79
- package/bin/aarch64-apple-darwin/gcell +0 -0
- package/bin/aarch64-unknown-linux-musl/gcell +0 -0
- package/bin/manifest.json +0 -7
- 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/skills/genetics-report/references/edition-review.workflow.js +0 -196
- package/skills/genetics-report/references/linear-read-test.workflow.js +0 -106
- package/skills/genetics-report/references/reader-review.workflow.js +0 -404
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genetics-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.29.1",
|
|
4
4
|
"description": "문서 포털 발행·세션 이식·사례 기억 MCP — 데이터를 주면 규격 문서가 나온다 (짝인 스킬 동봉)",
|
|
5
5
|
"author": "주식회사 LIM (LIM Inc.)",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -14,16 +14,15 @@
|
|
|
14
14
|
"codex-session-cli.mjs",
|
|
15
15
|
"NATIVE-CODEX-SESSION.md",
|
|
16
16
|
"LICENSE",
|
|
17
|
-
"skills"
|
|
18
|
-
"bin"
|
|
17
|
+
"skills"
|
|
19
18
|
],
|
|
20
19
|
"engines": {
|
|
21
20
|
"node": ">=18"
|
|
22
21
|
},
|
|
23
22
|
"scripts": {
|
|
24
|
-
"test": "node smoke.mjs && node append.test.mjs && node codex-session.test.mjs && node task-results-stdio.test.mjs && node notify.test.mjs && node schedule.test.mjs && node windows.test.mjs &&
|
|
23
|
+
"test": "node smoke.mjs && node append.test.mjs && node codex-session.test.mjs && node task-results-stdio.test.mjs && node notify.test.mjs && node schedule.test.mjs && node windows.test.mjs && python3 ../tests/report-patch.test.py",
|
|
25
24
|
"test:task-results": "node task-results.test.mjs && node task-results-stdio.test.mjs",
|
|
26
|
-
"prepack": "find skills -name __pycache__ -type d -prune -exec rm -rf {} + 2>/dev/null
|
|
25
|
+
"prepack": "find skills -name __pycache__ -type d -prune -exec rm -rf {} + 2>/dev/null",
|
|
27
26
|
"prepublishOnly": "npm test",
|
|
28
27
|
"release": "bash release.sh"
|
|
29
28
|
}
|
|
@@ -19,9 +19,12 @@ import re
|
|
|
19
19
|
# · `전환 완료. 4건은 …` 은 `4` 뒤가 마침표가 아니라 안 걸린다.
|
|
20
20
|
# · `1. 첫째. 2. 둘째.` 처럼 사이에 글이 낀 열거도 안 걸린다.
|
|
21
21
|
# · 앞이 숫자·마침표면 제외해 온전한 연도 꼴의 뒷부분을 물지 않는다(연도 꼴이 먼저 걸리므로 이중 방어).
|
|
22
|
+
# · 뒤에 시각(`10. 8. 09:40 켬`)이 와도 날짜다 — 「뒤에 숫자 금지」가 시각까지 막아 `10.` / `8.` / `09:40 켬`
|
|
23
|
+
# 세 줄로 쪼개졌다(2026-10-08, 관보 v3 시험 문서 #238 표 칸). 뒤 숫자가 `H:MM`·`HH:MM` 의 머리일 때만 풀고,
|
|
24
|
+
# `9. 8. 7.` 처럼 수가 하나 더 붙는 꼴은 그대로 날짜로 안 본다.
|
|
22
25
|
DATE = re.compile(
|
|
23
26
|
r'\d{4}\.\s*\d{1,2}\.(?:\s*\d{1,2}\.)?' # 2026. 8. 21. / 2026. 8.
|
|
24
|
-
r'|(?<![\d.])\d{1,2}\.\s*\d{1,2}\.(?!\s*\d)' # 9. 8. (연도 없는 달·일)
|
|
27
|
+
r'|(?<![\d.])\d{1,2}\.\s*\d{1,2}\.(?!\s*\d(?!\d?:\d))' # 9. 8. · 10. 8. 09:40 (연도 없는 달·일 — 뒤 시각은 허용)
|
|
25
28
|
)
|
|
26
29
|
TAG = re.compile(r'<[^>]*>')
|
|
27
30
|
|
|
@@ -115,6 +118,10 @@ if __name__ == '__main__':
|
|
|
115
118
|
("9. 10. 출시됨", 0),
|
|
116
119
|
("9. 8.", 0),
|
|
117
120
|
("전체 출시가 9. 10. 에 끝났음. 아이폰은 대기임.", 1),
|
|
121
|
+
# 연도 없는 날짜 뒤 시각 — 2026-10-08 실측. 고치기 전엔 여기서 0 대신 2 가 나왔다
|
|
122
|
+
# (관보 v3 시험 문서 #238 표 칸 「10. 8. 09:40 켬」이 세 줄로 쪼개진 자국).
|
|
123
|
+
("10. 8. 09:40 켬", 0),
|
|
124
|
+
("스위치는 10. 8. 9:40 에 켬. 그 뒤 실패는 0 임.", 1),
|
|
118
125
|
# 그 마스크가 삼키면 안 되는 것들 — 위 넷을 고치면서 깨지기 쉬운 자리.
|
|
119
126
|
# 둘 다 옛 정규식과 **경계 수가 같음**을 대조로 확인함(2026-09-11, 8표본 중
|
|
120
127
|
# 달라진 것은 연도 없는 날짜 하나뿐).
|
|
@@ -194,7 +194,7 @@ export function analyze(raw0) {
|
|
|
194
194
|
// 날짜(2026. 8. 21.)·버전(iOS 26.4)·경로(api.php)는 문장 끝이 아니므로 먼저 가린다.
|
|
195
195
|
const BLOCK = /<(p|li|td|dd|figcaption)\b[^>]*>([\s\S]*?)<\/\1>/g;
|
|
196
196
|
// 연도 없는 점 날짜(8. 21.)도 문장 끝이 아니다 — 안 가리면 부정 종결의 문맥 창이 밀린다.
|
|
197
|
-
const DATE = /\d{4}\.\s*\d{1,2}\.(?:\s*\d{1,2}\.)?|(?<!\d)\d{1,2}\.\s*\d{1,2}\.(?!\s*\d)/g;
|
|
197
|
+
const DATE = /\d{4}\.\s*\d{1,2}\.(?:\s*\d{1,2}\.)?|(?<!\d)\d{1,2}\.\s*\d{1,2}\.(?!\s*\d(?!\d?:\d))/g; // 뒤 시각(10. 8. 09:40)은 날짜 — boundary.py DATE 와 같은 식
|
|
198
198
|
const BOUND = /(?<=[가-힣0-9)\]」』”'"A-Za-z])[.!?]\s+(?=[가-힣0-9「『※(\[]|[A-Z])/g;
|
|
199
199
|
const runOn = [];
|
|
200
200
|
const blockTexts = []; // ②b-3 이 같은 블록 단위를 다시 쓴다
|
|
@@ -33,6 +33,9 @@ test('한 문장 한 줄 — 회귀(기존 검사 유지)', () => {
|
|
|
33
33
|
assert.equal(pos(bad.runOn.length), 1);
|
|
34
34
|
const good = analyze('<p><span class="sn">첫 문장임.</span> <span class="sn">둘째 문장임.</span></p>');
|
|
35
35
|
assert.equal(good.runOn.length, 0);
|
|
36
|
+
// 연도 없는 날짜 뒤 시각(10. 8. 09:40)은 문장 끝이 아니다 — 표 칸 하나를 「두 문장 한 덩어리」로 세지 않는다(2026-10-08 관보 v3 표 칸이
|
|
37
|
+
// 렌더러에서 세 줄로 쪼개진 꼴 · boundary.py DATE 와 같은 식). 고치기 전 식은 여기서 1 을 냈다.
|
|
38
|
+
assert.equal(analyze('<table><tr><td>10. 8. 09:40 켬</td></tr></table>').runOn.length, 0);
|
|
36
39
|
});
|
|
37
40
|
|
|
38
41
|
test('학생 보고서투 — 교대항 전수(하나를 빼는 뮤테이션은 여기서 죽는다), 「조사 결과」는 안 잡는다', () => {
|
|
@@ -45,10 +45,9 @@ version: "1.4.0"
|
|
|
45
45
|
gcell --version # → gcell 0.1.0
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
PATH 에
|
|
50
|
-
|
|
51
|
-
물을 수 있었습니다(2026-08-27).
|
|
48
|
+
MCP 는 세포를 깔지도 PATH 에 걸지도 않습니다(2.29.0 · 2026-10-16 — 기계 쪽 일은 gcell 앱이 맡습니다).
|
|
49
|
+
이 기계의 PATH 에 `gcell` 이 있다면 옛 판이 걸어 둔 것이거나 사람이 직접 건 것입니다. 없으면
|
|
50
|
+
`GENETICS_CELL_BIN` 이 가리키는 전체 경로로 부릅니다.
|
|
52
51
|
|
|
53
52
|
`gcell` 이 안 잡히면(세 자리 중 어디도 PATH 에 없는 기계) 전체 경로로 부르세요 — 그것이 정본입니다:
|
|
54
53
|
|
|
@@ -237,7 +236,7 @@ HEAD 사본 검사)은 `genetics-sync` 스킬이 정본입니다.
|
|
|
237
236
|
|
|
238
237
|
## 무엇을 하지 않는가
|
|
239
238
|
|
|
240
|
-
- **세포를 깔거나 지우지 않습니다.**
|
|
239
|
+
- **세포를 깔거나 지우지 않습니다.** MCP 에는 더 이상 까는 도구가 없습니다(2.29.0) — 기계 쪽 일은 gcell 앱이 맡습니다.
|
|
241
240
|
안 깔려 있으면 그 사실을 말하고 멈춥니다.
|
|
242
241
|
- **훅을 건드리지 않습니다.** `install-hooks` 는 이 기계의 턴 동작을 바꿉니다.
|
|
243
242
|
- 관측 결과를 **지시로 읽지 않습니다.** 「누가 무엇을 만졌다」는 사실이고,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: genetics-report
|
|
3
3
|
description: |
|
|
4
|
-
|
|
4
|
+
genetics 문서 포털에 발행하거나 단일 HTML 로 전달하는 고객 문서를 만듭니다 —
|
|
5
5
|
수정 내역 보고, 검수 요청, 진행 현황, 장애 사후 보고, 납품 보고, 기술보고서·인수인계,
|
|
6
6
|
R&D 브리핑·기술 도입 검토·결정 요청서.
|
|
7
7
|
다음과 같은 요청 시 사용하세요:
|
|
@@ -28,11 +28,12 @@ version: "4.0.0"
|
|
|
28
28
|
이 둘은 같은 사실을 다루지만 완전히 다른 문서입니다. 이 스킬의 본체는
|
|
29
29
|
**무엇을 빼고 무엇을 고쳐 쓰는가**(내용 설계)이고, 전달 형태는 그 다음입니다.
|
|
30
30
|
|
|
31
|
-
독자에 대한 원칙
|
|
31
|
+
독자에 대한 원칙 넷 — 규칙 자리는 따로 있고, 여기는 먼저 읽을 요지입니다(경위: `references/history.md` §16~§18 · §22).
|
|
32
32
|
|
|
33
33
|
1. **독자는 이 문서를 처음 읽습니다.** 우리 대화·회차·판·결정 경위를 모릅니다. 원고는 직전 판의 차분이 아니라 독자의 0 상태에서 씁니다(반드시 지키는 것 3b).
|
|
34
34
|
2. **대상은 독자가 문서 밖에서 보는 원래 이름으로 부릅니다** — 자기 화면·콘솔·계약서·원본 문서의 글자입니다. 작업하며 지은 이름은 문서 안에서 정의해도 쓰지 않습니다(반드시 지키는 것 12 · 0단계 물음 5).
|
|
35
35
|
3. **뜻은 그 자리에서 섭니다.** 낱말은 첫 등장 자리에서 풀고, 뒤 절 번호나 「N절 참고」로 독자를 오가게 하지 않습니다(0.5단계 7행).
|
|
36
|
+
4. **문서는 발행처가 직접 말합니다.** 발행처 이름은 표지 · 판권지 같은 정체 자리에만 쓰고, 본문은 서술 「당사」 · 요청 자리 「저희」입니다. 「(우리회사 확인)」 · 「이 문서를 보낸 우리회사 담당자」처럼 제 이름을 3인칭으로 부르면 두 회사 사이를 잇는 중개자의 글로 읽힙니다 — 포털이 받지 않습니다(반드시 지키는 것 15).
|
|
36
37
|
|
|
37
38
|
## 작업 체크리스트 — 단계 번호의 정본
|
|
38
39
|
|
|
@@ -41,8 +42,8 @@ version: "4.0.0"
|
|
|
41
42
|
|
|
42
43
|
| 단계 | 산출물 | 돌릴 명령 | 통과 기준 | 집행자 | 사용자에게 묻는 것 |
|
|
43
44
|
|---|---|---|---|---|---|
|
|
44
|
-
| 0 독자 | 독자 문장 1줄 + 할 일 목록(작업 메모) · 이름 대응표 `names.md` · 증거 계획 `evidence.md`(둘 다 작업 폴더, 발행 안 함 — 0단계 물음 5·6) | — | 누가 · 무엇을 하나 · 무엇을 언제까지 정하나가 문장으로 섬 · 원고에서 부를 대상마다 독자 화면·문서의 이름이 섬(새 개념이면 「원래 이름 없음」) · 관찰 주장마다 보여 줄 것 · 찍는 사람 · 필요한 접근이 섬 | 사람 — 사용자 확인 | **반드시** 0단계 물음 1~3 · 「결정 요청으로 낼까요, 보고로 낼까요」 ·
|
|
45
|
-
| 0a 결정 장부 | 작업 폴더 `decisions.json`(발행 안 함) | — | 원고에 「정해진 것」으로 쓸 항마다 결정권 · 정한 주체 · 기록 · 확인 여부가 참 | 사람 눈
|
|
45
|
+
| 0 독자 | 독자 문장 1줄 + 할 일 목록(작업 메모) · 이름 대응표 `names.md` · 증거 계획 `evidence.md`(둘 다 작업 폴더, 발행 안 함 — 0단계 물음 5·6) | `whoami`(운영사 줄 — 물음 7) | 누가 · 무엇을 하나 · 무엇을 언제까지 정하나가 문장으로 섬 · 원고에서 부를 대상마다 독자 화면·문서의 이름이 섬(새 개념이면 「원래 이름 없음」) · 관찰 주장마다 보여 줄 것 · 찍는 사람 · 필요한 접근이 섬 | 사람 — 사용자 확인 | **반드시** 0단계 물음 1~3 · 「결정 요청으로 낼까요, 보고로 낼까요」 · 보내는 쪽 의견을 낼지 · 자료에서 못 찾은 독자 쪽 이름(물음 5) · 모자란 접근(물음 6) · `whoami` 에 운영사 이름이 없으면 보내는 쪽 이름(물음 7) |
|
|
46
|
+
| 0a 결정 장부 | 작업 폴더 `decisions.json`(발행 안 함) | — | 원고에 「정해진 것」으로 쓸 항마다 결정권 · 정한 주체 · 기록 · 확인 여부가 참 | 사람 눈 | 0단계 물음 4 — 미확인 항을 한 번에 |
|
|
46
47
|
| 0.5 시각 설계 | 절마다 시각 장치 · 예시 한 명 · 용어 잠금 표 | — | 0.5단계 표 1~6행이 정해짐 | 사람 눈 · 렌더러 ⚠(`lim-portal-format.md` 「10-1. 시각 우선 관문」) | 화면 변화가 따르면 도안으로 결재받을지 |
|
|
47
48
|
| 1·2 자료·건 | `cases.json` | — | 건마다 다섯 칸 · 근거 없는 칸은 「[미확인]」(사용자에게 되물을 칸 — 발행 전 0) · 확인 방법마다 볼 자리와 우리가 본 때·환경(안 본 결과는 `remaining`) | 서버 발행 검증(그룹 정합) · `gazette.py` `evidence_scan()` ⚠(볼 자리) · 사람 | 원자료 범위 · 고객이 아는 참조 · 「[미확인]」 칸 |
|
|
48
49
|
| 3 등급 | `grades` · 건별 `grade` | — | 4단 이하 · 최약 등급이 기본 | 사람 | 등급 이름·개수 |
|
|
@@ -50,8 +51,6 @@ version: "4.0.0"
|
|
|
50
51
|
| 6 도판 굽기 | 도판 HTML → PNG · `plates.json` | `node assets/figure.mjs --batch plates.json --report report.json` · 두 칸 비교는 `shot.mjs --after` → `pair.mjs` | exit 0(✗0 · 합계 2,400,000B 안) | `figure.mjs` R0~R10·R13 · `pair.mjs` · 칩 문구의 뜻은 사람 눈 | — |
|
|
51
52
|
| 7 로컬 렌더 | 단일 HTML | `python3 assets/render.py report.json`(소속처 문서면 `--tenant <slug>` — 원고에 `tenant` 가 있으면 생략) | ⚠0 · `forbid` 적중 0 · 단일 HTML 로 전달할 판이면 「보관 그림 N장」 줄 0(그 HTML 은 그림 자리가 상자인 검토본 — 원고에 `out` 이 있으면 그 줄이 ⚠ 로 선다) | `gazette.py` `text_scan()`·`brief_checks()`·`tally_scan()`·`evidence_scan()` · `build.py guard()` · `render.py kept_stand_ins()` | — |
|
|
52
53
|
| 7 dry_run | 경고 목록 | `publish_report`/`update_report` 에 `dry_run: true` | 작성자가 고칠 수 있는 ⚠0 — 못 없애는 경고는 까닭을 핸드오프에(10단계 행) | `report_publish.php report_build_checked()`(렌더러·입고·그림·문체 · 금칙어는 `report_publish.php report_forbid_warnings()`) · `update_report` 는 `comments.php comment_anchor_forecast()`(회신 핀 자리) · 경고 기준선 대조는 사람 | — |
|
|
53
|
-
| 7 독자 검토 | 렌더본 텍스트(원고 폴더 밖 빈 폴더) · 워크플로 결과(`merged`·`questions`·`dropped`·`jumps`·`names` — 판 갱신 검토는 `kept`·`refuted`·`weak`·`unverified`) | `python3 assets/render.py report.json --text <원고 폴더 밖 빈 폴더>/본문.txt` → `references/reader-review.workflow.js`(`args.text` 필수 · `args.evidence_plan` 에 0단계 `<작업 폴더>/evidence.md`, 0.5단계 7행) · 구조를 안 바꾼 낱말 손질 판은 `references/edition-review.workflow.js`(역시 `args.text`) | 사실 틀림 반영 · 선형 읽기 뜀(`jumps`) 가운데 심각도 3 이상 0건 · 만든 이름(`names`) 0건 · 증거 없는 관찰 주장 `judgement.evidence_missing` 0 — 못 없앤 것은 까닭을 핸드오프에(10단계 행) · 결과 머리 「검토 미완」 없음(있으면 다시 돌림) · 「⚠ 도판 N장 미열람」 없음 — 다만 미열람·「서버 보관」 줄에 찍힌 id 가 모두 원고에서 `data` 가 「(생략 — NB)」 표식인 장이면, 사람이 열람 주소에서 그 장을 열어 보고 id 를 핸드오프에 적으면 통과다(그 밖의 미열람은 다시 돌린다) · 반영 뒤 로컬 렌더·dry_run 다시 | 워크플로 관점 + JS 거름 · `questions`·`dropped`·`refuted`·`rx`(처방 다시) 는 사람 | `questions[]` |
|
|
54
|
-
| 7 독자 검토(결정 모드) | 결정 장마다 작성자 한 문장 ↔ 독자 한 문장 · 갈린 자리 | 같은 렌더본 → `references/reader-review.workflow.js`(`args.mode: "decision"` · `args.intents`) | 공개 문서마다 원고를 모르는 독자 한 번, 점수 없이 막힌 자리만 — 갈린 자리와 고친 것, 원고에서 지운 사실의 차분을 사용자 보고에 싣는다(관점 아홉·뜀 0·이름 0 은 결정 모드의 완료 조건이 아니다) | 워크플로 독자 한 번 · 갈린 자리를 칸 이름으로 옮기는 것은 사람 | — |
|
|
55
54
|
| 7 조판 검사 | 검사기 출력 | `gazette-report` 검사기 8종(단일 HTML 전달일 때) | 각 0건 · **표본 수를 함께 본다**(0표본 통과는 통과가 아니다) | 검사기 — 실행법은 `gazette-report` 스킬 | — |
|
|
56
55
|
| 7 사람 눈 | — | 인쇄 미리보기까지 연다 | `references/process.md` 「7단계 — 검수」 사람의 눈 표 | 사람 | — |
|
|
57
56
|
| 8 초안 발행·수정 | 초안 링크 · 고친 판이면 받은 판 JSON 과 `edits.json`(작업 폴더, 발행 안 함) | 새 문서 `publish_report` · 고치면 8단계 「수정 절차」 | 같은 링크 · `patch.py --freeze` 가 `edits.json` 을 씀(받은 판 사본에 두 번째 바꿈 0) · 교체와 그 앞 dry_run 에 받은 판의 `body_rev`(`get_report` 머리줄 값)를 실음 · 사람이 고친 초안을 모르고 덮지 않음 | `patch.py`(옛 값이 다르면 멈춤 · 굳힐 때 멱등 검사) · `update_report` 의 `body_rev` 잠금(받은 뒤 본문 판이 바뀌었으면 서버 409) · 편집기에 저장만 된 사람 초안은 판을 안 올려 잠금에 안 걸림 — 목록의 「덮음」을 사람이 본다 | 사람이 고친 초안이면 덮어도 되는가 · 교체 승인(10단계 행) |
|
|
@@ -59,8 +58,8 @@ version: "4.0.0"
|
|
|
59
58
|
| 9 열람 확인 | 캡처 | 열람 주소를 연다 | 칩·굵게·링크가 원문 글자가 아니라 서식으로 섬 · 도판 쌍·판단 절이 섬 | 사람 눈 — 못 열면 까닭을 핸드오프에(10단계 행) | — |
|
|
60
59
|
| 9a 첨삭 메모 반영 | 반영된 판 · 닫힌 메모 · 까닭을 단 답글 | `list_reports` → `list_notes` → 8단계 「수정 절차」 → `resolve_note`·`reply_note`(9a단계) | 미반영 메모 0 — 남은 것은 전부 답글로 까닭이 달림 | 사람이 메모를 닮 · 서버는 미반영 수만 셈(`open_notes`, 우리 팀에게만) | 사람이 「메모 해놨다」고 할 때만 돈다 — 무엇을 고칠지 되묻지 않음 · 증빙을 찍는 데 모자란 접근은 청함 |
|
|
61
60
|
| 9b 검토 회신 반영 | 회신마다 「어느 물음의 답인가」 대조 · 반영된 판 · 반영 표시 | **개정 전에** `list_notes(id)`(검토 회신이 본문과 함께 실린다) → 8단계 「수정 절차」로 반영 → `resolve_note(id, reply, rev)`(9b단계) | 열린 회신 0 — 남은 것은 사람에게 넘긴 까닭이 있음 · 원고에 「회신 없음」이라고 쓴 자리가 회신과 어긋나지 않음 | 서버는 열린 회신 수(`open_replies`)를 목록·되읽기·교체 응답에 싣고, 열린 회신의 문장이 바뀌면 교체 경고로 말함 · 본문 읽기와 대조는 사람·에이전트 | 고객에게 보이는 답글 문안(에이전트는 달지 않는다) |
|
|
62
|
-
| 10 공개 직전 날짜 | 받은 판 JSON 과 `edits.json`(날짜 세 칸) | 8단계 「수정 절차」로 한 번 — 받은 판에서 날짜 세 칸만 고쳐 `body_rev` 를 실어 교체
|
|
63
|
-
| 10 공개 | 공개된 링크 | `release_report(id)` | 사용자 승인 — 공개·교체 승인을 묻거나 공개해도 되는지 답할 때 이 판에서 건너뛴 단계(0단계 사용자 확인 ·
|
|
61
|
+
| 10 공개 직전 날짜 | 받은 판 JSON 과 `edits.json`(날짜 세 칸) | 8단계 「수정 절차」로 한 번 — 받은 판에서 날짜 세 칸만 고쳐 `body_rev` 를 실어 교체 | 작성일 세 자리가 한 값이고 공개하는 날(3c) | `gazette.py` `date_scan()` ⚠(세 자리가 다르면) · 공개하는 날인지는 사람 | 공개일 |
|
|
62
|
+
| 10 공개 | 공개된 링크 | `release_report(id)` | 사용자 승인 — 공개·교체 승인을 묻거나 공개해도 되는지 답할 때 이 판에서 건너뛴 단계(0단계 사용자 확인 · 열람 확인 등)와 증거 없는 관찰 주장 수(로컬 렌더 ⚠ 「화면을 말했는데 …」의 N곳 — 포털 dry_run 은 렌더러 운영 반영 뒤부터)를 싣는다 | 사람(승인 행위) — 실렸는지 대조하는 기계는 없음 | **반드시** 공개 승인 |
|
|
64
63
|
|
|
65
64
|
## 렌더러는 레포에 하나뿐이다
|
|
66
65
|
|
|
@@ -107,12 +106,16 @@ version: "4.0.0"
|
|
|
107
106
|
서버와 로컬 `tone.mjs` 는 같은 요청 자리 넷(판단 항목 본문·`cta`·판권지 회신 안내·요청 PART 의 PART I 간지 도입문·물음)과 「」 인용을 빼고 센다(2026-09-29 — 요청 절 여백 주석·PART 제목은 센다). 결정 모드의 요청 자리는 확인의 `ask`·`steps` · 「고객 쪽이 하실 일」 칸 · 회신 줄 · 판권지 회신 안내다(렌더본의 `data-zone="ask"`).
|
|
108
107
|
읽는 법(`guide`)의 요청 한 줄만 자리로 못 가려 두 경로 모두 센다 — 그 한 줄의 경어체 경고는 **의도이므로 고치지 않는다.** 간지에서 나면 요청 PART I 이 아닌 간지이니 개조식으로 고친다.
|
|
109
108
|
이 경고를 하드 규칙으로 오인해 종결을 비튼 것이 **거듭된 반려의 원인**이다(경위: `references/history.md` §5).
|
|
109
|
+
- **수는 아라비아 숫자로 쓴다**(대표 2026-10-13 「숫자는 고유어 대신 진짜 숫자로 표기하는 게 좋음」).
|
|
110
|
+
「다섯 건」 → 「5건」 · 「두 번째」 → 「2번째」 · 「두 값」 → 「2개 값」 · 「두 기기」 → 「기기 2대」 · 「열두 달」 → 「12개월」 · 「둘째 표」 → 「2번째 표」 · 「후보 셋을」 → 「후보 3개를」.
|
|
111
|
+
그대로 두는 것은 굳은 말(한눈에 · 한꺼번에 · 한 번에 · 둘 다 · 가운데 하나), 동사 「골라 둘 것」, 「」 안에 옮긴 앱 화면 문구다.
|
|
112
|
+
이름을 키로 쓰는 칸(`grades`)의 이름을 고치면 그 이름을 쓰는 값(건의 `grade`)도 함께 고친다. 렌더러가 고유어 수를 자리마다 「다섯 건 → 5건」으로 짚는다(⚠ · `references/lim-portal-format.md` §10-1).
|
|
110
113
|
- `tenant` 는 키가 가리키는 고객사와 일치해야 한다(오발행 방지 가드). 값은 소속처 slug 우선·이름 폴백 — 8단계의 `slug` 는 **보고서** slug 라 다른 것이다.
|
|
111
114
|
- `sections[].kind` 는 `summary|status|cases|asks|note` 다섯 가지뿐 — 그 밖의 값은 절이 통째로 사라지므로 서버가 거절한다.
|
|
112
115
|
- `cases[].grade` 는 `grades` 에 정의된 이름이어야 한다.
|
|
113
116
|
- **`update_report` 는 같은 주소를 덮어쓴다** — 이미 고객에게 나간 링크가 새 내용을 가리키므로, 발행 후 수정은 재발행이 아니라 update 로 한다. 기존 문서는 `list_reports`/`get_report` 로 받아 고쳐 되돌려 보낸다.
|
|
114
117
|
- **그림 계약**: `update_report` 에서 `assets` 를 **빼고** 보내면 서버가 저장된 그림을 그대로 유지한다 — 캡션·출처 줄·alt 같은 도판 글 칸도 저장값 그대로다. 글 칸을 고쳤으면 `assets` 를 `get_report` 표식째 목록으로 보낸다(서버가 id 로 바이트를 잇고 글 칸은 보낸 값을 쓴다). 전부 지우려면 `assets: []` 를 명시하고 `sections[].plates`·`chapters[].asset` 에서도 그 id 를 빼야 한다 — 가리키는 곳이 없는 id 는 422. 한 장만 바꾸려면 그 id 에 새 `source`/`file`, 나머지는 `get_report` 가 준 표식 그대로.
|
|
115
|
-
- 초안 상태로 올려 두고 다듬어도 발행은 막히지 않는다. 단 초안 `update_report` 도 **본문 판(`body_rev`)** 을 올리고 사용자가 그 판을 읽으므로
|
|
118
|
+
- 초안 상태로 올려 두고 다듬어도 발행은 막히지 않는다. 단 초안 `update_report` 도 **본문 판(`body_rev`)** 을 올리고 사용자가 그 판을 읽으므로 **로컬 렌더 ⚠ 와 dry_run 을 다 본 본문 판만 올린다** — 다듬는 중간 판은 올리지 않는다.
|
|
116
119
|
**발행 이력 행(`history`)은 다른 것이다** — 공개 전 수정은 이력 행을 만들지 않는다(3c).
|
|
117
120
|
- 내용 설계 규칙(아래 0~3단계, 고객 언어 치환, 카피 게이트)은 **전달 경로와 무관하게 동일하게** 적용된다 — 서버가 렌더한다고 해서 원고 품질 단계를 건너뛰지 않는다.
|
|
118
121
|
|
|
@@ -143,7 +146,7 @@ version: "4.0.0"
|
|
|
143
146
|
절의 성격(시각표·원인·앞날)으로 PART 를 새로 짓지 않는다 — 「경과 / 원인」으로 가르면 같은 건이 두 PART 에 문장만 바꿔 선다(경위: `references/history.md` §9).
|
|
144
147
|
독자가 결정권자면 `status` 대조표를 빼고 요약면 상태 막대만 남긴다(`references/process.md` 「이 답에서 곧바로 정해지는 것」).
|
|
145
148
|
|
|
146
|
-
결정 블록의
|
|
149
|
+
결정 블록의 보내는 쪽 의견은 결정마다 `opinion` 칸 하나다 — 첫 화면·제목·표는 그 칸을 읽지 않는다. 옛 결정 브리핑(결정 블록 전 보고 모드)을 고칠 때만 의견 절 한 자리.
|
|
147
150
|
**결정 문서와 R&D 블로그 글은 다른 물건이다** — 블로그 글은 독자가 할 일이 없다. 결정 블록은 결정마다 이름 · 물음 · 선택지 둘 이상(이름 · 한 줄)이 없으면 서버가 거절한다(기한은 권함 — 없으면 ⚠).
|
|
148
151
|
|
|
149
152
|
`kind:"lesson"` 같은 것은 **없다.** 서버가 발행 단계에서 거절한다.
|
|
@@ -171,14 +174,26 @@ Lim 보고서, Lim 에 올려줘, 고객 보고서, 수정 내역, 검수 요청
|
|
|
171
174
|
2. **읽고 나서 무엇을 해야 하는가** — 확인만? 판단해서 회신? 결재?
|
|
172
175
|
3. **읽고 나서 무엇을 결정하는가** — 선택지는 무엇이고, 선택지마다 무엇이 달라지는가, **언제까지** 정해야 하는가.
|
|
173
176
|
답에 정할 것이 기한과 함께 있으면 결정 블록(`decision_brief.decisions`)을 쓴다 — 문서가 결정 모드로 선다. 「특별히 결정할 것은 없다」면 보고다.
|
|
174
|
-
사용자 확인에 한 줄을 넣는다 — 「결정 요청으로 낼까요, 보고로 낼까요」.
|
|
175
|
-
|
|
177
|
+
사용자 확인에 한 줄을 넣는다 — 「결정 요청으로 낼까요, 보고로 낼까요」. **보내는 쪽 의견을 낼지는 따로 묻는다** — 내면 결정마다 `opinion` 칸 하나.
|
|
178
|
+
결정 요청이면 **받는 쪽이 이미 가진 뼈대**를 먼저 찾는다 — 고객이 보낸 문서의 장 · 회의 안건 · 문의의 갈래. 문서는 그 뼈대를 그대로 진다
|
|
179
|
+
(`decision_brief.frame` + 결정마다 `from` — `references/decision-format.md` §1). 우리가 묶은 차례(원고 id · 일 단위)로 세우면 받는 쪽은
|
|
180
|
+
58쪽을 검증하지 못하고 「뼈대가 같았으니 정할 것도 같겠지」로 넘어간다(대표 2026-10-13 「이쁜 쓰레기」 · 합의 착각). 자료에서 못 찾으면 한 번에 묻는다.
|
|
181
|
+
보고도 같다 — 묶음(`groups`)을 받는 쪽 뼈대의 항목으로(「QA 자료 3쪽 ①」) 세우고 최상위 `frame` 에 그 뼈대 이름을 적는다. 요약 종이에
|
|
182
|
+
「{뼈대}와 한 일」 뼈대 표가 서고 한눈에 절(`status`)은 두지 않는다(그 절의 표 · 그림은 알맞은 절에). 뼈대 밖에서 함께 고친 묶음은 `outside`, 하실 일은 `refs` 로 그 일이 나온 건에
|
|
183
|
+
잇는다(`references/lim-portal-format.md` 3.2b).
|
|
184
|
+
4. **이미 정해진 것은 무엇이고, 누가·어디서 정했는가** — 작업 폴더 `decisions.json`(발행 안 함)에 항 · 내용 · 결정권(고객/우리) · 정한 주체 ·
|
|
176
185
|
기록(회신 원문·회의록·결정문의 이름과 날짜) · 사용자 확인 여부를 적는다(체크리스트 0a). 미확인 항은 원고에 쓰기 전에 **한 번에** 묻는다. 쓰는 법은 3b 「결정 주체」.
|
|
177
186
|
5. **원고에서 부를 대상마다 독자가 보는 이름은 무엇인가** — 판·환경·인스턴스·설정·요금·문서처럼 우리가 작업하며 부르던 이름마다, 독자가 자기 화면·콘솔·계약서·원본 문서에서 보는 글자를 찾는다.
|
|
178
187
|
작업 폴더 이름 대응표 `names.md`(발행 안 함)에 「우리가 부르던 이름 / 독자 화면·문서의 이름 / 그 이름이 보이는 자리」 세 열로 적고, 자료에서 못 찾은 것만 **한 번에** 묻는다.
|
|
179
188
|
원고의 이름과 0.5단계 용어 잠금 표의 이름 열은 이 표의 둘째 열에서만 가져온다. 둘째 열이 빈 새 개념만 설명형으로 부르고 「원래 이름 없음」이라 적는다(반드시 지키는 것 12).
|
|
180
189
|
6. **독자가 믿어야 할 관찰 주장(화면·흐름·화면 문구·동작)마다 무엇을 보여 주는가** — 「보여 줄 것(캡처·녹화·원문·센 대상이 있는 표) / 누가 찍나 / 필요한 접근(계정·기기·창·메일함·자동 조작 허락)」을 작업 폴더 `evidence.md`(발행 안 함)에 표로 적고, 모자란 접근은 원고를 쓰기 전에 대화창에서 **한 번에** 청한다.
|
|
181
190
|
「X 하면 항상 Y」 같은 구조 주장은 관찰 하나로 단정하지 않는다 — 팀 지식(`search_cases`)을 먼저 뒤지고 코드 분기로 확인한다.
|
|
191
|
+
7. **보내는 쪽 이름은 무엇인가** — 발행처(`issuer` 첫 칸 · 결정 모드의 표지 「보낸 곳」)에는 `whoami` 가 보이는 운영사 이름(「운영사: …」 줄)을 그대로 적는다.
|
|
192
|
+
그 줄이 없거나(키 자격 · 구성원 · 옛 서버 — 운영사 줄은 관리자 · 편집자 로그인에만 선다) 「운영사 이름 미설정」이면 사용자에게 **한 번** 묻고, 사용자에게 「전체 관리자가 설정 › 보고서 브랜드 › 운영사 이름에 넣으면 다음부터 `whoami` 에 섭니다」라고 알린다. 회사 이름을 대화 맥락에서 짐작해 적지 않는다 — 이 스킬은 다른 운영사의 설치본에서도 돈다(경위: `references/history.md` §6).
|
|
193
|
+
이름을 끝내 모르면 첫 칸을 빈 글자 `""` 로 두고 **칸을 빼지 않는다** — `issuer` 는 [발행처, 대상, 날짜] 자리라, 첫 칸을 빼면 대상(받는 쪽)이 첫 칸으로 당겨져 보내는 쪽으로 선다.
|
|
194
|
+
표지 머리글(`kicker`) · 문서번호(`doc_no`) · 판권지(`colophon`)에도 회사 이름 · 약호를 지어 넣지 않는다. 보내는 쪽 이름은 이 한 이름만 쓰고, 문서번호는 사용자가 쓰는 번호 체계가 있을 때만 적는다.
|
|
195
|
+
결정 문서는 원고에 이름이 없으면 발행 때 설정의 운영사 이름으로 채워지고(관리자 · 편집자가 사람 로그인으로 낸 문서만 — 키 발행 · 로컬 렌더는 채우지 않는다), 그것도 없으면 「당사」로 서며 알림이 뜬다(`references/decision-format.md` 3절).
|
|
196
|
+
**이 이름은 정체 자리에만 선다** — 표지(`issuer` 첫 칸 · `kicker` · 결정 표지 「보낸 곳」) · 문서번호 · 판권지 행. 본문에서 발행처는 서술 「당사」, 요청 자리 「저희」다(반드시 지키는 것 15). 결정 모드의 행 이름 · 의견 머리 · 권함 칩도 렌더러가 「당사」로 짓는다(「당사가 할 일」 · 「당사 의견」 · 「당사 권함」).
|
|
182
197
|
|
|
183
198
|
독자가 정해지면 나머지가 전부 따라 정해진다. 같은 사실이 이렇게 갈린다.
|
|
184
199
|
|
|
@@ -212,12 +227,12 @@ Lim 보고서, Lim 에 올려줘, 고객 보고서, 수정 내역, 검수 요청
|
|
|
212
227
|
|---|---|---|
|
|
213
228
|
| 1 | **한 장 이야기** | 문제 → 원인 → 해법(지금 상태 포함) → 정할 것. 칸 수가 아니라 이야기 순서다 — 요지 칸 수는 4~6단계 「요지」 한 곳이 정본. 다루는 일의 **사건 경과** 표 한 장을 1절에 둔다(이 문서의 판 이력은 `history` — 3c) |
|
|
214
229
|
| 2 | **예시 한 명** | 실존 이용자 하나의 실제 숫자로 문서 전체를 관통시킨다(같은 사람이 그림·표·건에 반복) |
|
|
215
|
-
| 3 | **용어 잠금 표** | 같은 낱말이 두 값을 가리키면 그 자리에서 문서가 죽는다. 뜻이 갈리는 낱말은 표 한 장으로 값·정의·보이는 자리를 박는다. **이름 열은 0단계 이름 대응표(물음 5)의 독자 화면·문서 이름에서만 가져온다** — 표에 정의했다고 작업하며 지은 이름이 독자의 말이 되지는 않는다(경위: `references/history.md` §16). 장치 이름(건 행 `labels` 값)은 절 이름·부제·표 열·캡션에 다시 쓰지 않고, 선택지 기호(A·B·C)는 한 목록에만 붙인다. **이 스킬이 선택지를 부르는 「길」·「바꾸면/그대로 두면」도 장치 이름이다** — 원고에서는 선택지를 그것이 실제로 무엇인지(고객이 부르는 이름)로 부르고, 물건을 비유로 부르지 않는다(반드시 지키는 것 12). 집행자: `gazette.py` `text_scan()` ⚠(건 행 이름 충돌·선택지 기호 충돌·「길」) ·
|
|
216
|
-
| 4 | **절마다 시각 장치 먼저** | <!-- 장치 목록에서 굽는 글 «skill-row» — 손으로 고치지 않는다: python3 tools/contract-devices.py --write -->내용 모양이 장치를 고른다 — 구조는 구성도·도판(개념도), 흐름은 흐름도·절차도·데이터 흐름도, 순서는
|
|
230
|
+
| 3 | **용어 잠금 표** | 같은 낱말이 두 값을 가리키면 그 자리에서 문서가 죽는다. 뜻이 갈리는 낱말은 표 한 장으로 값·정의·보이는 자리를 박는다. **이름 열은 0단계 이름 대응표(물음 5)의 독자 화면·문서 이름에서만 가져온다** — 표에 정의했다고 작업하며 지은 이름이 독자의 말이 되지는 않는다(경위: `references/history.md` §16). 장치 이름(건 행 `labels` 값)은 절 이름·부제·표 열·캡션에 다시 쓰지 않고, 선택지 기호(A·B·C)는 한 목록에만 붙인다. **이 스킬이 선택지를 부르는 「길」·「바꾸면/그대로 두면」도 장치 이름이다** — 원고에서는 선택지를 그것이 실제로 무엇인지(고객이 부르는 이름)로 부르고, 물건을 비유로 부르지 않는다(반드시 지키는 것 12). 집행자: `gazette.py` `text_scan()` ⚠(건 행 이름 충돌·선택지 기호 충돌·「길」) · 한 낱말 두 값 · 뜻이 같은지·비유인지는 사람 눈 |
|
|
231
|
+
| 4 | **절마다 시각 장치 먼저** | <!-- 장치 목록에서 굽는 글 «skill-row» — 손으로 고치지 않는다: python3 tools/contract-devices.py --write -->내용 모양이 장치를 고른다 — 구조는 구성도·도판(개념도), 흐름은 흐름도·절차도·데이터 흐름도, 순서는 표(사건 경과)·순서도, 상태는 상태 변화도, 변화는 기울기·두 판 비교·도판(두 컷 비교), 분포는 막대 차트·구성 띠, 시간에 따른 값은 시계열, 견주기는 막대 차트(수일 때)·점 차트·표(글이 섞일 때), 원문은 원문 인용·도판, 화면은 도판·화면 녹화. 둘 수 있는 칸 · 서버 조건 · 한도 · 만드는 법은 `references/visual-first.md` §4 장치 표(정본 `private/builder/devices.py`). 글은 그 옆 3줄<!-- /장치 목록 «skill-row» --> |
|
|
217
232
|
| 5 | **판단 요청** | 결정 요청은 결정 블록의 칸(물음·기한·선택지·대칭 표)이 진다 — `references/decision-format.md`. 보고 모드의 판단 항목(검수 확인 요청)은 제목 「~ 요청」 · 본문 첫 문장 기한(5a) · 모양은 `references/visual-first.md` §5. 화면이 바뀌는 결정은 어느 모드든 도안까지(같은 §5 「화면 도안」). 집행자: `gazette.py` `brief_checks()` ⚠(기한) · ⚠ W1(권고 낱말) · 도안 유무는 **없음 — 사람의 눈**(`references/process.md` 7단계 표) |
|
|
218
|
-
| 5a | **원본·증거 확인** | 주장·그림마다 원본을 **댈 수 있어야** 한다. 화면·흐름·화면 문구·동작을 말하는 문장(관찰 주장)은 **독자가 문서 안에서 볼 증거**를 그 건·절에 둔다 — 실제 캡처·녹화·원문 인용·외부 문서(센 대상이 있는 표는 수·대조 결과의 증거 — 화면 주장은 표만으로 받치지 않는다). 도안(「— 도안」·「— 재현」·「실제 화면 아님」, AI 로 만든 합성 그림)은 설명이지 증거가 아니고, 「— 합성」(실제 캡처 + 옮겨 적은 글자)은 증거다. 없으면 찍어 싣거나, 우리가 안 본 것이면 `remaining` 으로 옮긴다 — 「화면 미확인」「코드상」 같은 헤지 낱말과 확인 방법 끝 「…에서 봄」은 증거가 아니다. 출처 줄은 위치 한 구절(우리 도안은 비움 — 캡처는 8b), 원본 이름·찾을 낱말은 건(`source_url`·`how_to_check`)이나 부록에, 제작 메타는 `origin` 으로(`references/readability.md` R12e·R14 · 11번). 집행자: `gazette.py` `evidence_scan()` ⚠ · `gazette.py` `plate_scan()` ⚠(작은 캡처) ·
|
|
233
|
+
| 5a | **원본·증거 확인** | 주장·그림마다 원본을 **댈 수 있어야** 한다. 화면·흐름·화면 문구·동작을 말하는 문장(관찰 주장)은 **독자가 문서 안에서 볼 증거**를 그 건·절에 둔다 — 실제 캡처·녹화·원문 인용·외부 문서(센 대상이 있는 표는 수·대조 결과의 증거 — 화면 주장은 표만으로 받치지 않는다). 도안(「— 도안」·「— 재현」·「실제 화면 아님」, AI 로 만든 합성 그림)은 설명이지 증거가 아니고, 「— 합성」(실제 캡처 + 옮겨 적은 글자)은 증거다. 없으면 찍어 싣거나, 우리가 안 본 것이면 `remaining` 으로 옮긴다 — 「화면 미확인」「코드상」 같은 헤지 낱말과 확인 방법 끝 「…에서 봄」은 증거가 아니다. 출처 줄은 위치 한 구절(우리 도안은 비움 — 캡처는 8b), 원본 이름·찾을 낱말은 건(`source_url`·`how_to_check`)이나 부록에, 제작 메타는 `origin` 으로(`references/readability.md` R12e·R14 · 11번). 집행자: `gazette.py` `evidence_scan()` ⚠ · `gazette.py` `plate_scan()` ⚠(작은 캡처) · `gazette.py` ⚠ W2 · `text_scan()` 제작 메타 ⚠ — 그 밖은 사람 눈 |
|
|
219
234
|
| 6 | **표기** | 인라인 표기(`**굵게**`·`==강조==`·`{{ok|칩}}`·`[글자](주소)`·**맨 주소**)와 절·PART 의 `tone`, 차트 행 `tone`, 건의 `source_url`, 요약면 `notice.state`. 그림 가리킴은 손으로 번호를 치지 않고 `{{그림:<assets id>}}` 토큰으로(번호·조사를 렌더러가 셈 — `lim-portal-format.md` §11-6). 색은 뜻으로(`lim-portal-format.md` 「11-6. 인라인 표기」) |
|
|
220
|
-
| 7 |
|
|
235
|
+
| 7 | **앞에서 뒤로 읽히게 쓴다** | 발행 전 독자 검토 단계는 없다 — 2026-10-19 사용자 결정 「독자 검토를 걷기」(경위: `references/history.md` §23). 이 줄은 쓰는 사람이 지킨다. **빼기가 포인터를 남기면 안 된다** — 「N절을 보라」「건 §n.n」「부록에 있다」로 대신하면 독자가 장을 오가는 시험지가 된다. 낱말·규칙·예시 선언은 **첫 등장 자리에서 한 구절**, 뒤 절의 번호·표 이름·§ 는 앞 절에서 쓰지 않는다(요약 근거는 `refs[]` 로). 대상·판·상태·선택지는 독자가 문서 밖(자기 화면 글자 · 원본 문서 · 공급사 공식 명칭)에서 본 이름으로 부른다 — 문서가 붙인 이름은 정의를 달아도 통과가 아니다. 집행자: 뒤 절 번호는 렌더러 ⚠ 「앞 절이 뒤 절을 가리키는 곳」(`gazette.py text_scan` W5 · readability R12h) · 소속처가 반려한 이름은 `text_scan()` ⚠ · 정의 위치와 그 밖의 만든 이름은 사람 눈(경위: `references/history.md` §9·§12) |
|
|
221
236
|
| 8 | **실물 확인** | 발행할 때마다 체크리스트 9단계 두 행 — 블록 목록 대조와 열람 주소 열기. 집행자: 사람 — 발행 뒤 대조 기계는 아직 없다 |
|
|
222
237
|
|
|
223
238
|
상세와 도판 예산(장당 300KB · 합계 2,400KB), 그림 만드는 법, 반려 사례는 `references/visual-first.md`.
|
|
@@ -288,7 +303,7 @@ Lim 보고서, Lim 에 올려줘, 고객 보고서, 수정 내역, 검수 요청
|
|
|
288
303
|
- `marg.advice` — 더 볼 곳. 명사구(「03절 대조표」)나 사물이 주어인 단문(「판정 기준은 부록 1에 있음」) — 「~할 것」「~을 보라」「~ 참조」처럼 독자에게 시키지 않는다
|
|
289
304
|
|
|
290
305
|
**번호는 데이터가 아니라 자리가 정한다.** `sections[].no`·`id` 를 적어도 렌더러가 안 읽고
|
|
291
|
-
배열 순서로 `ch`·앵커를 만든다(`gazette.py Doc.build()`). 찍히는 것은 `label`
|
|
306
|
+
배열 순서로 `ch`·앵커를 만든다(`gazette.py Doc.build()`). 찍히는 것은 `label` 하나다(없으면 절 머리 「제N절」 · 쪽 머리말 칸에는 번호 N 만).
|
|
292
307
|
`summary` 의 `§n.n` 은 서버가 `groups[].no` 로 검사하므로 **`groups[].no` 를 그 절의 자리와
|
|
293
308
|
같게** 맞춘다 — 어긋나면 게이트는 통과하고 링크가 헛짚는다.
|
|
294
309
|
|
|
@@ -305,7 +320,7 @@ report.json + cases.json 을 하나로 합쳐 `publish_report` 에 준다
|
|
|
305
320
|
|
|
306
321
|
**`dry_run: true` 로 먼저 태우고 `warnings` 를 읽는다.** 그것이 실질적 유일한 품질 관문이다.
|
|
307
322
|
단 **구조는 세지 않는다** — PART·절 사이에서 같은 사실을 다시 푸는 되풀이를 재는 경고는 렌더러에도 서버에도 없다.
|
|
308
|
-
경고 0 은 구조 통과가 아니다. 그 몫은
|
|
323
|
+
경고 0 은 구조 통과가 아니다. 그 몫은 사람의 눈(`references/process.md` 7단계 「PART 간지」 행)이다.
|
|
309
324
|
서버는 「빈 칸」을 안 막는다 — 막는 것은 **조용히 사라지는 것**뿐이고, 관보의 본체가
|
|
310
325
|
빠지면 ⚠ 로 소리 내어 센다. `marg` 가 비었다는 경고를 못 보고 넘기면 두 단이 한 단으로 선다.
|
|
311
326
|
|
|
@@ -322,7 +337,6 @@ report.json + cases.json 을 하나로 합쳐 `publish_report` 에 준다
|
|
|
322
337
|
5. 교체 인자는 새 판으로 만든다. `patch.py` 가 「도판 칸을 고친 편집」을 알리지 않았으면 `assets` 를 뺀다(서버가 저장된 도판을 그대로 잇는다). 알렸으면(캡션·출처 줄·alt 를 고쳤거나 그림을 바꿈) `assets` 를 새 판 그대로 싣는다 —
|
|
323
338
|
표식은 표식째 두면 서버가 id 로 바이트를 잇고 글 칸은 보낸 값을 쓴다. 그림을 바꿀 장은 `set assets[id=…]` 에 객체를 통째로(`file` 포함) 준다(`file` 칸만 `set` 하면 없는 칸이라 멈춘다). 늘 싣지 않는 까닭: 목록으로 보내면 아직 그리는 중인 그림 자리가 처음부터 다시 걸린다.
|
|
324
339
|
→ `update_report(dry_run: true, body_rev: <받은 판>)` — 받은 뒤 본문 판이 바뀌었으면 여기서 409 다(6단계의 409 절차로). 「이 서버는 받은 판 잠금을 모릅니다」 줄이 나오면 교체가 판을 견주지 않는다는 뜻이니 교체 전에 사용자에게 알린다.
|
|
325
|
-
→ 판 갱신 검토(`edition-review.workflow.js` — `edits` 에 `edits.json`, `backup` 에 1의 파일, `file` 에 3의 새 판, `text` 에 4의 본문.txt, `patch` 에 2·3단계에서 쓴 그 `patch.py` 의 절대경로, 수치를 고친 판이면 `canon` 에 정본을 가리키는 한 줄 — 파일과 자리). 구조를 바꾼 판이면 독자 검토다.
|
|
326
340
|
6. 교체는 `update_report` 에 받은 판의 `body_rev` 를 실어 한다(1에서 머리줄에 보이고 파일 이름에 넣은 값 — 시험 실행이 알려 주는 「지금 판」이 아니다) — 받은 뒤 본문 판이 바뀌었으면(다른 교체 · 편집기 발행 · 그림이 앉아 다시 구운 것) 서버가 409 로 멈추고 아무것도 안 쓴다(2026-09-30 받은 판 잠금).
|
|
327
341
|
409 면 새로 받은 판을 1의 파일 자리에 두고(이름에 새 `body_rev`) `edits.json` 을 다시 적용해 3~5 를 다시 돈다(`backup` 도 그 판) — `set`·`replace` 자리는 남이 고쳤으면 멈추지만, 줄 op 는 남의 고침을 못 가린다(`drop_rows`·`remove_row` 는 라벨만 보고 남이 고친 행도 빼고, `append_row`·`insert_row` 는 남이 붙인 행 곁에 또 붙인다). 그래서 다시 적용하기 전에 옛 1의 파일과 새로 받은 판을 diff 해 그 표부터 본다.
|
|
328
342
|
교체되면 출력에 「본문 판 body_rev=N」(새 판)이 찍혔는지 본다 — 없으면 판을 견주지 않고 덮인 것이니(잠금을 모르는 옛 서버이거나, `body_rev` 인자를 모르는 옛 MCP 가 떠 있다) 되읽어 1의 파일과 견준다.
|
|
@@ -352,8 +366,8 @@ report.json + cases.json 을 하나로 합쳐 `publish_report` 에 준다
|
|
|
352
366
|
| 순서 | 도구 | 할 일 |
|
|
353
367
|
|---|---|---|
|
|
354
368
|
| 1 | `list_reports` | 줄 끝에 `첨삭 메모 N건 미반영` 이 붙은 문서를 찾는다. 문서 번호를 들었어도 그 줄의 「덮음: …」은 본다(사람의 편집 초안은 이 목록만 알린다) |
|
|
355
|
-
| 2 | `list_notes(id)` | 미반영 메모를 읽는다. `anchor.path`(예 `case:k7m2p9/fix`)가 **고칠 칸**, `anchor.quote_exact` 가 사람이 **본 글**이다. 답글은 사람이 덧붙인
|
|
356
|
-
| 3 | 8단계 「수정 절차」 1~5 | 받은 판을 받아 두고, 메모마다 고칠 칸을 draft 에 적어 `--freeze` 로 굳혀 새 판을 만들고, 로컬 렌더 · dry_run(받은 판의 `body_rev` 를 실어)
|
|
369
|
+
| 2 | `list_notes(id)` | 미반영 메모를 읽는다. `anchor.path`(예 `case:k7m2p9/fix`)가 **고칠 칸**, `anchor.quote_exact` 가 사람이 **본 글**이다. 답글은 사람이 덧붙인 설명이다. 결정 문서 대칭 표 행의 옛 닻 `…/row_fcg_does` 는 지금 열쇠 `rows.sender_does`(옛 이름 `fcg_does`)다 — 옛 칸을 따로 더하지 말고 `sender_does` 를 고친다(둘 다 있으면 옛 칸은 안 그려지고 알림이 뜬다) |
|
|
370
|
+
| 3 | 8단계 「수정 절차」 1~5 | 받은 판을 받아 두고, 메모마다 고칠 칸을 draft 에 적어 `--freeze` 로 굳혀 새 판을 만들고, 로컬 렌더 · dry_run(받은 판의 `body_rev` 를 실어)까지 돈다 |
|
|
357
371
|
| 4 | 8단계 「수정 절차」 6 | 메모를 모두 반영한 판을 **한 번에** `update_report(body_rev: …)` 로 보낸다. `uid` 는 받은 값 그대로 남는다(`patch.py` 는 고친 칸만 바꾼다) — 흘리면 메모가 자리를 잃는다. 초안은 초안 그대로 남는다 |
|
|
358
372
|
| 5 | `resolve_note(id, note, rev)` | **고친 뒤에만.** 반영이 실린 `body_rev` 를 함께 준다. 먼저 부르면 미반영 목록에서 빠져 다시 안 보인다. 증빙(화면·영상·근거)을 요구한 메모는 실물이 실린 판에서만 닫는다 — 도해·설명을 더한 판으로 닫지 않는다 |
|
|
359
373
|
| 6 | `reply_note(id, note, body)` | 못 고치거나 다르게 본 메모는 **닫지 말고** 그 메모에 이유를 답글로 단다. 못 찍은 증빙이면 「못 함」 답글 전에 필요한 접근을 대화창에서 청한다(0단계 물음 6) |
|
|
@@ -369,7 +383,7 @@ report.json + cases.json 을 하나로 합쳐 `publish_report` 에 준다
|
|
|
369
383
|
|---|---|---|
|
|
370
384
|
| 1 | `list_notes(id)` | 검토 회신이 **본문과 함께** 실린다. `[회신 N]` 줄의 자리(「판단 항 「…」」·건·절·도판)가 **어느 물음에 대한 말인지**, 그 아래가 누가(고객/우리) 무슨 말을 했는지다. 답글은 뿌리 밑에 붙는다 |
|
|
371
385
|
| 2 | (대조) | 회신마다 원고와 맞춰 본다 — 이미 답이 온 판단 항을 **열린 항으로 다시 묻고 있지 않은가**, 원고가 「회신에 언급이 없어 미결」이라고 쓴 자리가 회신과 어긋나지 않는가, 회신의 낱말과 정본(고객 문서)의 낱말이 갈리면 정본 낱말로 맞췄는가 |
|
|
372
|
-
| 3 | 8단계 「수정 절차」 1~6 | 반영한다(받은 판 → draft · `--freeze` → 새 판 → 로컬 렌더 · dry_run(`body_rev` 를 실어)
|
|
386
|
+
| 3 | 8단계 「수정 절차」 1~6 | 반영한다(받은 판 → draft · `--freeze` → 새 판 → 로컬 렌더 · dry_run(`body_rev` 를 실어) → `update_report(body_rev: …)`). 답이 온 판단 항은 닫힌 항 표로 옮기고 출처에 회신 날짜를 적는다. 교체 경고의 「열린 검토 회신 …」 줄은 회신의 본문과 함께 온다 — 그 회신을 이 판이 반영한 것이면 그대로 발행한다 |
|
|
373
387
|
| 4 | `resolve_note(id, reply, rev)` | **반영한 뒤에만.** 표시해도 회신은 고객에게 그대로 보인다. 문서에 반영할 것이 없는 회신(인사·이미 답한 물음)도 읽었으면 표시한다 |
|
|
374
388
|
| 5 | `remember_case`·`remember_decision`(회신이 반려일 때) | 9a단계 7행과 같다 — 팀 기억에 「스킬 반영: `references/history.md` §n / 미반영(까닭)」 한 줄, 작업하며 지은 이름을 짚은 반려면 그 반려 결정의 `rejected_names` 칸에 그 이름과 원래 이름을 적는다 |
|
|
375
389
|
|
|
@@ -410,13 +424,11 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
|
|
|
410
424
|
|
|
411
425
|
| 파일 | 역할 |
|
|
412
426
|
|---|---|
|
|
413
|
-
| `assets/render.py` | `report.json` → 단일 HTML. **서버 등록부에서 서식을 읽어** 레포 `private/builder/build.py` 를 부른다 — 여기 사본을 두지 마라. `render.py --text <출력.txt>` 는 렌더가 성공한 뒤 화면에 보이는 글만 화면 순서대로 텍스트로 뽑는다(그림 자리 「[그림] <id> · <갈래>」 · 글 끝 「[그림 파일]」 목록 — 실린 바이트는 옆 `<이름>-그림/` 에 풀림 · 표 칸 「 \| 」 · `origin`·alt·스크립트 없음) —
|
|
427
|
+
| `assets/render.py` | `report.json` → 단일 HTML. **서버 등록부에서 서식을 읽어** 레포 `private/builder/build.py` 를 부른다 — 여기 사본을 두지 마라. `render.py --text <출력.txt>` 는 렌더가 성공한 뒤 화면에 보이는 글만 화면 순서대로 텍스트로 뽑는다(그림 자리 「[그림] <id> · <갈래>」 · 글 끝 「[그림 파일]」 목록 — 실린 바이트는 옆 `<이름>-그림/` 에 풀림 · 표 칸 「 \| 」 · `origin`·alt·스크립트 없음) — 원고 폴더 안에 쓰면 ⚠ 가 뜬다. `get_report` 로 받은 원고도 그대로 굽는다(받을 때는 `mcp-call.mjs --json` — 머리줄이 붙으면 못 읽는다) — `out` 이 없으면 원고 이름 옆 `.html` 로 쓰고, 도판(figure) 표식은 서버 기록 치수의 자리 상자로 그린다(`render.py kept_stand_ins()` — ⚠ 대신 「보관 그림 N장」 한 줄, 그 HTML 은 검토본). 로고 표식은 표지에서 고객사 이름 활자로 선다. 원고에 `out` 이 있으면(작성 원고 — 전달 경로) 그 한 줄은 ⚠ 로 선다. `--tenant <slug>`(없으면 원고의 `tenant`)는 그 소속처가 반려한 이름을 옆 `mcp-call.mjs` 로 MCP `list_rejected_names` 를 불러 받아 함께 센다 — 못 받으면 ⚠ 한 줄을 내고 반려 이름만 빼고 굽는다(`references/lim-portal-format.md` §10-1) |
|
|
414
428
|
| `assets/patch.py` | 원고 **부분 고치기(멱등)** — `python3 assets/patch.py report.json edits.json`. 회차마다 고치는 파이썬을 새로 짓지 말고 **데이터(edits.json)만** 남긴다. op 일곱: `set`·`replace`·`drop_rows`·`remove_row`·`append_row`·`insert_row`·`forbid`(칸과 뜻은 머리 주석 op 표). 표 줄은 번호 대신 첫 칸 글자로 가리킨다 — `rows[label=…]` 는 앞 op 가 줄을 끼우거나 빼도 같은 줄을 찾고, 그 글자인 줄이 하나가 아니면 멈춘다(2026-09-30 — 9/29 수정 판에서 통째로 바꾼 표 여섯을 줄 op 로 다시 써도 공개본과 같았다). 그 줄의 **첫 칸을 바꾸는** 편집은 `[label=…]` 로 적지 않고 번호 경로로 적는다 — 첫 실행 뒤 그 글자가 없어져 두 번째 실행이 줄을 못 찾으므로 돌리기 전에 멈춘다. 배열 원소는 `assets[id=…]` 처럼 `id` 로도 가리키고(끝자리여도 된다), 없는 칸은 만들지 않고 멈춘다. 두 번 돌려 「바꿈 0」이 계약이고, 값이 `old` 도 `new` 도 아니면 **멈춘다**(그 사이 누가 고쳤다는 뜻). `set` 의 `old` 는 손으로 옮기지 않는다 — draft 에 `new` 만 적고 `python3 assets/patch.py <받은 판> draft.json --freeze edits.json` 이 받은 판에서 채운다. 받은 판 사본에 두 번 돌려 첫째 건너뜀 0 · 둘째 바꿈 0 일 때만 OUT 을 쓰고, 줄을 끼우거나 뺀 표의 칸을 번호로 가리키는 `old` 없는 `set` 은 굳히지 않으며(`[label=…]` 로 가리킨다), 적용에 `old` 없는 `set` 이 오면 멈춘다. 편집이 도판 칸(`assets…`)을 고치면 「교체 인자에 assets 를 표식째 싣는다」를 알린다(`patch.py freeze()` — 2026-09-29 수정 판에서 긴 표 행의 `old` 를 스크래치 스크립트로 채웠던 자리). 회차 스크립트가 쌓여 고객사 문서 폴더가 플랫폼이 되던 것을 멈추려고 들였다(2026-09-22 — 한 폴더 2,563줄·다른 폴더 4,285줄 실측) |
|
|
415
429
|
| `assets/subset_font.py` | 폰트 서브셋 생성 (보통 실행 불필요) |
|
|
416
430
|
| `assets/example/report.json` · `cases.json` | 관보 필드를 전부 채운 본보기. 새 문서는 여기서 베낀다 — 본보기의 캡처는 가상 고객사의 가상 화면이고, 실제 문서에는 실물 캡처를 싣는다 |
|
|
417
431
|
| `assets/figure.mjs` · `shot.mjs` · `pair.mjs` · `mockshot.mjs` · `xlsx-plate.py` | 도판을 만드는 도구 — 무엇을 언제 쓰는지와 문서에서 말해도 되는 옵션은 장치 표(`references/visual-first.md` §4 — 정본 `private/builder/devices.py`), 도판 규칙의 값은 `references/readability.md` §1. 계약 상수는 `figure.mjs --spec` 이 낸다. `xlsx-plate.py` 는 원본을 읽기만 하고 사본에서 인쇄 범위를 잘라 굽는다 — LibreOffice 가 한글 폰트를 못 보는 기계에서는 PDF 에 한글이 없음을 재고 멈춘다(2026-09-22 macOS 실측) |
|
|
418
|
-
| `references/linear-read-test.workflow.js` | 선형 읽기 **실측** — 처음 읽는 사람 셋 + 결정권자가 앞에서 뒤로 한 번 읽으며 뛰어야 하는 자리를 전부 센다(`args: {text, file, reader, round}` — `text`(필수)는 `render.py --text` 로 뽑은 렌더본 텍스트이고 읽는 넷은 이 파일 하나만 읽는다. `file`(필수)은 그 렌더본을 뽑은 `report.json` 이고 렌더본이 원고보다 새로운지 재는 데만 쓴다 — 읽는 넷에게는 주지 않는다. 둘 중 하나가 없거나 렌더본이 비었거나 원고보다 오래되면 읽기 전에 멈춘다. 재측정은 `round` 를 바꿔야 캐시를 안 탄다). 뜀 0 이 목표. 독자 검토(`reader-review.workflow.js`)의 linear 관점이 같은 읽기를 하나로 한다 |
|
|
419
|
-
| `references/edition-review.workflow.js` | **판 갱신 검토** — 구조는 그대로이고 낱말·출처 줄·여백 주석만 고친 판의 **변경 자리**(`assets/patch.py` 의 편집 목록 `edits.json` — 옛 `edit-N.py` 의 put/sub 호출도 받는다)를 규칙 대조·사실 대조로, 새 판 렌더본 전체를 선형 독자로 읽고 심각도 3 이상은 진단과 처방을 따로 반박한다(`args: {file, backup, edits, doc, text}`, 편집 스크립트면 `edits` 대신 `edit_script` · `patch` 는 편집 목록을 굳힌 그 patch.py 의 경로(기본 스킬 설치본 — 없거나, 그 목록을 못 읽는 판이거나, 새 판에 편집이 아직 적용돼 있지 않으면 시작 전 검사에서 멈춘다) · `canon` 은 수치 편집을 대조할 정본을 가리키는 한 줄(안 주면 검토자가 `doc` 글·`handoff` 에서 찾고, 어디에도 없으면 「정본 없음」으로 적는다) · `renderer` 는 규칙 관점과 반박이 읽을 렌더러 — 결과 `kept`(진단이 거짓 아님, 처방이 규칙에 걸리면 `rx`)·`refuted`(진단 거짓)·`weak`·`unverified`(상한 밖·검증 실패), 실패가 있으면 `head` 「검토 미완」). 사실 관점이 백업↔새 판 JSON diff 에 바뀐 자리가 모두 기록에 있는지(줄 수가 아니라 자리로) 검산한다 — 편집 목록이면 백업 사본에 `patch.py` 를 적용한 결과가 새 판과 같은지와 수치를 바꾼 편집 전부, 편집 스크립트면 수치 무변경. 구조가 바뀐 판은 `reader-review.workflow.js`. 낱말 손질 판을 검토 없이 발행하자 다음 판 8자리 손질이 생겼다(2026-09-15) |
|
|
420
432
|
| `assets/example/decision.json` | 결정 블록 본보기(결정 모드) — 지어낸 예시 고객사의 결정 둘(선택지 둘·확인·위험 크기 / 선택지 셋·결정 뒤 확인) |
|
|
421
433
|
| `assets/example/report-briefing*.json` · `cases-briefing*.json` | 옛 결정 브리핑(결정 블록 전 보고 모드) — 이미 나간 문서를 고칠 때만 본다, 새 결정 문서에 베끼지 않는다(렌더러 바이트 시험 자료라 지우지 않는다) |
|
|
422
434
|
| 폰트 | **레포** `private/builder/fonts/pretendard-gazette.woff2` — 가변 1면 |
|
|
@@ -435,7 +447,7 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
|
|
|
435
447
|
3. **개발 절차 서술을 빼거나 고쳐 쓴다.** 배포·티켓 분리·테스트 추가·설계 검토안은 고객의 관심사가 아니다.
|
|
436
448
|
**코드 작업을 녹일 때**는 원고를 쓰기 전에 원고 밖 상태 표(무엇 · 코드 반영 · 시험판 전달 · 실기기 · 운영, 칸마다 근거)를 만들고, 문서의 동사는 그 표의 확인 수준을 넘지 않게 고른다(`references/content-pipeline.md` 「4.2 치환 유형」).
|
|
437
449
|
공수·견적·측정 방법(조건·도구)도 싣지 않는다 — 고객의 고충이 아니라 우리 과정이다(돈은 드는지·언제 아는지·누가 내는지만, `references/decision-format.md` 2절).
|
|
438
|
-
커밋·브랜치·파일·시험 도구·시험 건수는 그 표에만 둔다 — 다만 어디서 봤는지(화면에서 봄 · 운영 서버에 물어봄 · 시험으로 봄 · 코드로 봄)는 문장에 남긴다(치환 G). 원고에 새면 `gazette.py` `text_scan()` 개발 식별자 ⚠, 확인 수준을 넘는 동사는
|
|
450
|
+
커밋·브랜치·파일·시험 도구·시험 건수는 그 표에만 둔다 — 다만 어디서 봤는지(화면에서 봄 · 운영 서버에 물어봄 · 시험으로 봄 · 코드로 봄)는 문장에 남긴다(치환 G). 원고에 새면 `gazette.py` `text_scan()` 개발 식별자 ⚠, 확인 수준을 넘는 동사는 사람 눈.
|
|
439
451
|
3b. **회차 서술을 본문 절에 두지 않는다.** 「이번 회차에 추가함」·「이번 회차 미확인 사항」은
|
|
440
452
|
우리 작업 순서이지 그 절의 내용이 아니다. 고객은 이 문서를 **처음 읽는 사람**이고,
|
|
441
453
|
그에게 필요한 것은 무엇이 적혀 있느냐이지 우리가 언제 적었느냐가 아니다.
|
|
@@ -449,8 +461,8 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
|
|
|
449
461
|
집행자: `gazette.py` `text_scan()` 과정 어휘 ⚠(`tests/builder.test.py`) · 대화 이력 낱말 ⚠(「앞서 합의한」「요청하신 대로」 — 2026-09-26) ·
|
|
450
462
|
`references/readability.md` R11h. 상태 열·「그대로(변화 없음)」는 기계가 못 본다 — 사람의 눈.
|
|
451
463
|
**결정 주체** — 결정권이 고객에게 있는 항은 고객이 정한 기록이 있고 그 항이 원문에서 실제로 닫혀 있을 때만(「정해야 함·차기」로 남아 있지 않을 때) 사실로 배경에 쓴다.
|
|
452
|
-
기록이 없거나
|
|
453
|
-
본문에는 결정 출처·날짜를 적지 않는다 — 확인은 결정 장부(0단계 물음 4)에서 한다. 집행자: 사람 눈(0a) ·
|
|
464
|
+
기록이 없거나 우리 쪽·내부 대화에서 정했으면 사실로 쓰지 않고 결정 물음이나 보내는 쪽 의견 절로 둔다. 우리 권한 안의 작업 결정(작업 순서·일정)은 「우리 작업」으로 사실 서술한다.
|
|
465
|
+
본문에는 결정 출처·날짜를 적지 않는다 — 확인은 결정 장부(0단계 물음 4)에서 한다. 집행자: 사람 눈(0a) · 주체 없는 결정 명사(「정한 사항」·「결정된 사항」·「결정임」)는 `text_scan()` 과정 어휘 ⚠.
|
|
454
466
|
3c. **공개 전 수정은 판이 아니다.** `history` 는 공개할 판 한 행(「최초 발행」)이고, `meta` 의 작성 · 판권지 작성 · `history` 마지막 `date` 는 **한 값**이며 공개하는 날로 맞춘다(체크리스트 10단계 — 공개 직전 8단계 「수정 절차」로 한 번).
|
|
455
467
|
공개 뒤 내용이 바뀐 update 에만 `history` 행을 더한다. 문서 밖 결정의 날짜는 본문에 적지 않는다. `cover_date` 는 요약면 「기준」 날짜(수치의 기준일)라 이 셋과 대조하지 않는다.
|
|
456
468
|
집행자: `gazette.py` `date_scan()` ⚠ — 세 자리를 년·월·일로 견줘 다르면 센다(두 경로 · `lim-portal-format.md` §10-1). 공개하는 날인지와 `history` 행 수는 사람(체크리스트 행) · 공개 때 날짜 안내(`release_report`)는 아직 기계가 없다(경위: `references/history.md` §12).
|
|
@@ -533,7 +545,7 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
|
|
|
533
545
|
결정권이 고객에게 있는 문서에서 그 자리는 「하지 않기로 한 것」 절이 아니라 선택지 표의 「정할 자리」·「다시 볼 때」 행이다.
|
|
534
546
|
- 나쁜 소식 앞에 **상대가 이미 잘 둔 것 한 문장**. 위로가 아니라 기준점이다 — 그 다음 문장의 기준이 된다.
|
|
535
547
|
- 「해야 합니다」를 쓰지 않는다. **결정권이 고객에게 있는 문서에서는 「하지 않기로 함」「권고함」「기각」도 쓰지 않는다** —
|
|
536
|
-
선택은 상대에게 둔다.
|
|
548
|
+
선택은 상대에게 둔다. 보내는 쪽 의견은 결정 블록의 `opinion` 칸 하나에만 — 옛 결정 브리핑을 고칠 때만 의견 절 한 자리(경위: `references/history.md` §7).
|
|
537
549
|
- 구체적인 값(지역명·회사명·제품명)은 스킬이 아니라 **그 문서의 `forbid`** 로 막는다(9번).
|
|
538
550
|
기계가 잡는 것은 「조건·이유 없이 부정으로 끝난 문장」까지다(`tone.mjs` 단독 부정 종결). **주어가 사람·조직·
|
|
539
551
|
국가인지는 기계가 못 본다** — 사람의 눈 검수 표에 그 행이 있다(`references/process.md` 7단계).
|
|
@@ -541,8 +553,7 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
|
|
|
541
553
|
11. **원본을 「흐리다」「못 연다」고 쓰기 전에 잰다.** PDF 는 `pdfimages -list` 전체, 웹은 실제로 열어 찾는다 —
|
|
542
554
|
짐작으로 판정하지 않고, 못 열었으면 「미확인」이라 적는다. **인용은 원문 문구 그대로**, 위치는 절·쪽(행)까지.
|
|
543
555
|
고객이 눌러 열 수 없는 참조는 근거가 아니다(0.5단계 5a행).
|
|
544
|
-
집행자: `
|
|
545
|
-
`gazette.py` ⚠ W2 · 앱 동작·내부 수치는 독자 검토 facts 관점 — 그 밖은 사람의 눈(경위: `references/history.md` §8).
|
|
556
|
+
집행자: 도판 출처 줄의 원본 위치 누락은 `gazette.py` ⚠ W2 — 그 밖(인용 · 원본 대조 · 앱 동작 · 내부 수치)은 사람의 눈(경위: `references/history.md` §8).
|
|
546
557
|
12. **물건은 이름으로 부른다 — 이 스킬의 장치 이름과 비유를 원고에 옮기지 않는다.** 이 문서가 선택지를 「길」(두 길·바꾸는 길·그대로 두는 길),
|
|
547
558
|
상태를 「지금·그대로 두면·바꾸면」이라 부르는 것은 **스킬 안의 장치 이름**이다. 원고에서 선택지는 그것이 실제로 무엇인지 — 고객이 부르는 이름 —
|
|
548
559
|
로 부른다(「복제본 전환」「직접 업그레이드」「현행 유지」). 「복제본 길」「그 자리 길」「고른 길별 일정」은 장치 이름을 줄여 만든 조어이고,
|
|
@@ -558,17 +569,25 @@ render·css·폰트를 함께 얹는다. 직접 부르면 옛 서식 시트가
|
|
|
558
569
|
독자가 주어인 문장은 요청 자리에만 하십시오체로, 나머지는 우리·사물이 주어인 개조식이고, 해라체 명령은 어디에도 없다(5).
|
|
559
570
|
집행자: `gazette.py` `text_scan()` ⚠ 「선택지를 「길」로 부른 곳」·「해라체 명령이 N곳」(두 경로 — 운영 반영 확인 2026-09-17) ·
|
|
560
571
|
「책임 낱말 「탓」」·「대화 이력 낱말」·「소속처가 반려한 이름」(목록은 소속처 반려 결정의 `rejected_names` 칸 — 2026-09-26, 카피 게이트 표) ·
|
|
561
|
-
|
|
572
|
+
목록 밖의 비유·조어·직역 일반은 **없음 — 사람의 눈**(경위: `references/history.md` §13·§16·§17).
|
|
562
573
|
13. **우리 쪽 보안·운영 실수와 자격증명 취급 사실을 문서에 적지 않는다 — 구두로 전한다.**
|
|
563
574
|
「비밀번호가 메신저로 오갔음」「키를 메일로 보냈음」은 교체 권고의 근거로 옳아도 고객 문서의 자리가 아니다 —
|
|
564
575
|
박제되고 책임 소재를 글로 남긴다. 권고는 사용자에게 채팅으로만, 문서에는 그 사건의 원인·조치·확인만(`references/content-pipeline.md` 유형 L).
|
|
565
576
|
경계: 그 사건 범위 안의 조언(심사에 넘긴 시험 계정을 「외부에 알려진 것으로 봄」)은 남긴다.
|
|
566
577
|
집행자: `gazette.py` `text_scan()` ⚠ 「자격증명 노출」 — 자격증명 명사와 노출 경로·동사(메신저·메일·평문·오갔·보냈…)가 한 문장 30자 안에 같이 선 곳만. 명사 하나(「비밀번호 재설정」)는 안 셈 ·
|
|
567
|
-
「우리 실수」 일반(「늦게 알았음」 류)은 **없음 — 사람
|
|
578
|
+
「우리 실수」 일반(「늦게 알았음」 류)은 **없음 — 사람 눈**(경위: `references/history.md` §14).
|
|
568
579
|
14. **건이 둘 이상인 절의 표·도판·인용은 절이 아니라 그 건에 묶는다** — `cases[].tables`·`plates`·`quotes`(`references/lim-portal-format.md` §11-10). 결정 장의 근거는 `facts[].source` 가 진다(결정 모드).
|
|
569
580
|
절 칸에 두면 렌더러가 건 목록 **뒤**에 한꺼번에 세워, 독자는 건 다섯을 글로만 읽고 나서 표 다섯·그림 넷을 만나고 어느 건의 근거인지는 캡션 글자로만 잇는다.
|
|
570
581
|
절 칸은 절 전체에 걸치는 근거(조치 전후 대조표)만. 전폭 도판은 건 안에 못 서니 절에 둔다(건에 두면 ⚠).
|
|
571
582
|
집행자: 렌더러 `gazette.py` `case_evidence()` — 자리를 만들 뿐 「절에 둔 것이 사실은 한 건의 것」인지는 **사람 눈**(경위: `references/history.md` §15).
|
|
583
|
+
15. **문서는 발행처가 직접 말한다 — 발행처 이름을 3인칭으로 쓰지 않는다**(대표 2026-10-18 「발행처 3인칭 전부 금지」).
|
|
584
|
+
서술은 「당사」(「우리회사가 확인함」 → 「당사가 확인함」), 요청 자리(요청 절 · `cta` · 판권지 회신 안내 · 물음 · 요청 PART 간지 도입문)는 「저희」(「이 문서를 보낸 우리회사 담당자에게」 → 「저희 검색 개선 담당자에게」).
|
|
585
|
+
「(우리회사 확인)」 · 「우리회사 설명」 같은 꼬리표는 떼고 그 사실의 근거를 1인칭으로 적는다(「당사 사무실의 시험용 POS 에서 확인함」) — 꼬리표는 남이 한 말을 옮겨 주는 중개자의 글이다.
|
|
586
|
+
이름이 서는 자리는 정체 자리뿐이다: 표지 칸(`issuer` · `kicker` · `title` · `doc_no` · `running_footer`) · 판권지 행 · 결정 회신 받는 곳(연락처 — 「우리회사 검색 개선 담당」). 그 자리에서도 「보낸 {이름}」 꼴은 쓰지 않는다.
|
|
587
|
+
그대로 두는 것: 「」 · 『』 안 원문 · 화면 글자, 원문 인용(`quotes`)의 남의 말, 라틴 제품 이름(「Acme POS Daemon」). 한글 이름이 든 제품 · 화면 이름은 「」 안에 둔다.
|
|
588
|
+
작성자가 발행처 밖의 회사(개발사 · 대행사)여도 같다 — 문서는 발행처의 이름으로 나가므로 작성자의 자리에서 발행처를 부르지 않는다(경위: `references/history.md` §22).
|
|
589
|
+
집행자: 렌더러 `gazette.py` `voice_scan()` ⚠(두 경로 · 재굽기 포함) · **포털은 새로 내기 · 고치기 · 편집기 발행에서 거절**(`report_publish.php report_voice_hits` — 같은 표 `tests/fixtures/issuer-voice.json`, dry_run 도 422) ·
|
|
590
|
+
발행 직전 훅 `coined_scan()`. 이름의 별칭(한글 발행처의 영문 이름 등)과 「그쪽 · 이쪽」 같은 우회는 **사람 눈**.
|
|
572
591
|
|
|
573
592
|
## 흔한 실패 모드
|
|
574
593
|
|
|
@@ -611,7 +630,7 @@ doc-pptx 의 슬롭 3종 중 **대시 대비 헤드라인**("복붙에서 위임
|
|
|
611
630
|
| 요청 절 판단 항목에 기한과 선택지가 있는데 결정 블록이 없음(0단계 물음 3) | `gazette.py` `decision_hint()` ⚠ 「결정 블록으로 쓰면 결정 모드로 섭니다」 | **두 경로 다** |
|
|
612
631
|
| 본문 절의 회차 서술(「이번 회차…」) | `gazette.py` `round_talk_scan()` ⚠ | **두 경로 다** |
|
|
613
632
|
| 본문의 진행 상태 어휘(정해짐·회신 대기·N판) · 개수로 상태를 세는 표 제목 · 주체 없는 결정 명사(3b) | `gazette.py` `text_scan()` 과정 어휘 ⚠ | **두 경로 다** |
|
|
614
|
-
| 결정권이 고객에게 있는 항을 기록 없이 사실로 씀(3b 결정 주체) |
|
|
633
|
+
| 결정권이 고객에게 있는 항을 기록 없이 사실로 씀(3b 결정 주체) | 사람 눈(0a) — 기계는 위 명사까지 | 발행 전 |
|
|
615
634
|
| 권고 낱말(제목·표 열·절 이름·여백 주석·요약면)(10번) | `gazette.py` ⚠ **W1** — 이름에 「의견」이 든 절은 안 셈 | **두 경로 다** |
|
|
616
635
|
| 고객·제3자 자료에서 낸 도판(`user-provided`)의 출처 줄에 원본 위치(쪽·행·주소·건 §, 캡처면 「화면 이름 · 날짜」) 누락(11번 · 8b) | `gazette.py` ⚠ **W2** | **두 경로 다** |
|
|
617
636
|
| 관찰 주장에 독자가 볼 실물 증거가 없음(0.5단계 5a행) | `gazette.py` `evidence_scan()` ⚠ — 나머지 집행자는 0.5단계 5a행 | **두 경로 다** — 포털 dry_run 은 렌더러 운영 반영 뒤 |
|
|
@@ -619,19 +638,20 @@ doc-pptx 의 슬롭 3종 중 **대시 대비 헤드라인**("복붙에서 위임
|
|
|
619
638
|
| 선택지를 「길」로 부른 곳(스킬 장치 이름의 유출, 12번) | `gazette.py` `text_scan()` ⚠ — 「막대 길이」「길게」는 안 세고 「어느 길이」·열 머리 「길」은 셈. 「사진」「단추」 같은 비유는 **없음 — 사람의 눈** | **두 경로 다** |
|
|
620
639
|
| 해라체 명령(「…을 보라」「…하라」, 12번) | `gazette.py` `text_scan()` ⚠ — 「보라색」「정할 것」은 안 셈. 공급사 용어 직역(「지원료」)은 **없음 — 사람의 눈** | **두 경로 다** |
|
|
621
640
|
| 대화 이력 낱말(「앞서 합의한」「요청하신 대로」 — 3b) · 책임 낱말 「탓」(12번) | `gazette.py` `text_scan()` ⚠ — 과정 어휘와 같은 칸을 칸마다 한 번 센다. 「사전에 협의」「남탓」「탓하다」는 안 셈 | **두 경로 다** |
|
|
622
|
-
| 소속처가 이미 반려한 작업 이름(12번) | `gazette.py` `text_scan()` ⚠ — 목록은 그 소속처 반려 결정들의 `rejected_names` 칸(이름 → 원래 이름, 이름마다 가장 새 결정). 포털은 서버가, 로컬은 `render.py --tenant <slug>` 가 `list_rejected_names` 로 받아 렌더러에 넘긴다. 렌더 없이 부르는 `gazette.py coined_scan()`(이 기계의 발행 직전 훅이 부르는 자리)도 같은 길로 받은 목록으로 같은 경고를 낸다. 목록 밖의 새 이름은 **없음 —
|
|
641
|
+
| 소속처가 이미 반려한 작업 이름(12번) | `gazette.py` `text_scan()` ⚠ — 목록은 그 소속처 반려 결정들의 `rejected_names` 칸(이름 → 원래 이름, 이름마다 가장 새 결정). 포털은 서버가, 로컬은 `render.py --tenant <slug>` 가 `list_rejected_names` 로 받아 렌더러에 넘긴다. 렌더 없이 부르는 `gazette.py coined_scan()`(이 기계의 발행 직전 훅이 부르는 자리)도 같은 길로 받은 목록으로 같은 경고를 낸다. 목록 밖의 새 이름은 **없음 — 사람 눈** | **두 경로 다** — 목록을 못 받으면 `render.py` 는 ⚠ 「반려 이름을 못 받았습니다」, 훅은 경고가 있을 때 「반려 이름 미확인」을 덧붙인다(둘 다 세지 않음) |
|
|
623
642
|
| 건 행 이름(`labels`) 낱말이 다른 절 부제·표 제목·열 머리에 다시 섬 · 선택지 기호 한 글자에 이름 둘(0.5단계 3행) | `gazette.py` `text_scan()` ⚠ · 뜻이 같은지는 사람 눈 | **두 경로 다** |
|
|
643
|
+
| 발행처 이름을 3인칭으로 씀 · 「(발행처 확인)」 꼬리표 · 「이 문서를 보낸 발행처 담당자」(15번) | `gazette.py` `voice_scan()` ⚠ · **포털 거절**(`report_publish.php report_voice_hits` — 새로 내기 · 고치기 · 편집기 발행, dry_run 도 422) — 별칭 · 우회는 **사람 눈** | **두 경로 다** — 로컬은 경고, 포털은 거절 |
|
|
624
644
|
| 그림·표 번호 가리킴 — 없는 번호 · 조사 · 서지 못한/서지 않는 칸의 토큰 · `plates` 순서(0.5단계 6행) | `gazette.py` `text_scan()`·`build()` ⚠ — 번호 셈은 `fig_order()` 한 곳 | **두 경로 다** |
|
|
625
645
|
| 괄호 안 부연 · 흐름도 칸 `note` · 도판 캡션 문장 수(readability R11) | `gazette.py` `text_scan()` ⚠ — 한 줄 45자·요약·도입문 문장 수는 사람 눈 | **두 경로 다** |
|
|
626
646
|
| 요약면 막대·머리띠 요청 잔여가 문서의 셈과 어긋남 | `gazette.py` `tally_scan()` ⚠ — 대조만(탈출구 `bar_note`·빈 `remain` 은 `lim-portal-format.md` §10 표). **막대가 판단 항목 수를 세면 `remaining` 누락은 못 잡는다 — 사람 눈** | **두 경로 다** |
|
|
627
647
|
| 도판 문법 — R0·R0b·R1c·R13a~d 와 도판 예산(장당·합계) | `figure.mjs` ✗(R13d·예산 90% 는 ⚠, 면제는 `--allow <규칙>`) · `--batch` 예산 합계 · 두 칸 규격은 `pair.mjs` · 칩 문구의 뜻은 사람 눈 | 도판 굽기(6단계) |
|
|
628
|
-
| 선택지 사이 대칭 · 조건표가 모든 도안과 맞는가 · 그림이 본문을 반박하는가(0.5단계 5행) |
|
|
629
|
-
| 확인 수준보다 앞선 완료형 동사(코드만 고쳤는데 「앱에서 보이지 않음」)(3) |
|
|
648
|
+
| 선택지 사이 대칭 · 조건표가 모든 도안과 맞는가 · 그림이 본문을 반박하는가(0.5단계 5행) | 사람 눈(`process.md` 7단계 표) | 발행 전 |
|
|
649
|
+
| 확인 수준보다 앞선 완료형 동사(코드만 고쳤는데 「앱에서 보이지 않음」)(3) | 사람 눈 | 발행 전 |
|
|
630
650
|
| 작성일 세 자리 불일치(3c) | `gazette.py` `date_scan()` ⚠ — 0 채움으로 견줌, `cover_date` 는 안 봄 | **두 경로 다** |
|
|
631
651
|
| 공개 전 판을 `history` 에 쌓음 · 공개하는 날과 다름(3c) | **없음** — 사람(체크리스트 10단계) | — |
|
|
632
|
-
| 확인 포기 문구(「흐리다」「못 연다」)를 원본을 재지 않고 쓴 것(11번) | **없음** — 사람의 눈(`process.md` 7단계 표
|
|
652
|
+
| 확인 포기 문구(「흐리다」「못 연다」)를 원본을 재지 않고 쓴 것(11번) | **없음** — 사람의 눈(`process.md` 7단계 표) | — |
|
|
633
653
|
| 부정 서술의 주어가 사람·조직·국가 | **없음** — 사람의 눈 검수 | — |
|
|
634
|
-
| 같은 건 묶음이 요청 없이 두 PART 로 갈림 · 앞 PART 가 뒤 PART 물음에 먼저 답함 · 두 절 `marg.key` 가 같은 명제 · 요지 칸 수·근거 문단 `body` 비움(R12g) |
|
|
654
|
+
| 같은 건 묶음이 요청 없이 두 PART 로 갈림 · 앞 PART 가 뒤 PART 물음에 먼저 답함 · 두 절 `marg.key` 가 같은 명제 · 요지 칸 수·근거 문단 `body` 비움(R12g) | 사람의 눈(`references/process.md` 7단계 「PART 간지」 행) — **기계 없음** | 발행 전 |
|
|
635
655
|
| 스킬 문서의 줄 번호 인용(`파일.py` 뒤 쌍점과 줄 번호) · 정의가 없는 심볼 닻(`파일 이름()`) — 스킬을 고칠 때 | `tools/contract-drift.py --skill` — 기준선보다 늘면 실패, 닻은 저장소에서 정의를 찾음. 배포 관문은 아직 `--skill` 없이 돈다 | 스킬 수정 뒤 |
|
|
636
656
|
|
|
637
657
|
다만 **조사·체언 종결 조각문** 규칙은 보고서 문맥에서 완화한다. 목차 항목과 건 제목은
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
3
|
"group": "evidence",
|
|
4
|
-
"title": "
|
|
4
|
+
"title": "3개 도안은 앱에 이미 있는 모양을 따르는가",
|
|
5
5
|
"grade": "코드·화면 확인",
|
|
6
|
-
"symptom": "
|
|
7
|
-
"cause": "앱의 색·글자 규격 목록과 기존 화면
|
|
8
|
-
"fix": "
|
|
6
|
+
"symptom": "3개 도안의 창·카드·띠가 이 앱에 이미 있는 모양과 같은 규격인가?",
|
|
7
|
+
"cause": "앱의 색·글자 규격 목록과 기존 화면 3개를 대조함. 창은 결제 완료 창, 카드는 새 기능 소개 카드, 띠는 점검 안내 띠와 규격이 같음(표 4-1).",
|
|
8
|
+
"fix": "3개 도안 모두 앱의 선례를 따름. 새로 그리는 것은 도안 C 의 밀어서 닫는 동작 1개임.",
|
|
9
9
|
"how_to_check": "대조한 값은 표 4-1 에 있고, 8. 29. 최신 앱 코드의 규격 목록에서 옮겨 적음.",
|
|
10
10
|
"remaining": "선례 화면은 최신 앱에서만 대조함. 이전 앱의 모양은 대조 범위 밖임.",
|
|
11
11
|
"tables": [
|
|
12
|
-
{ "caption": "
|
|
12
|
+
{ "caption": "3개 도안이 따른 앱 선례의 규격",
|
|
13
13
|
"cols": ["도안", "앱의 선례", "글자 크기", "바탕색"],
|
|
14
14
|
"rows": [
|
|
15
15
|
["도안 A 확인 창", "결제 완료 창", "16px", "흰색"],
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"grade": "코드·화면 확인",
|
|
26
26
|
"symptom": "설정을 바꾼 이용자에게 안내가 언제 뜨고, 닫은 뒤 다시 뜨는가?",
|
|
27
27
|
"cause": "앱의 안내 표시 조건을 코드와 시험 계정 화면으로 대조함. 바꾼 뒤 7일 이하에서만 뜨고, 도안 A·B 는 닫으면 다시 안 뜸.",
|
|
28
|
-
"fix": "도안 C 는 띠가 작아
|
|
28
|
+
"fix": "도안 C 는 띠가 작아 1번 더 띄우도록 그림. 나머지 조건은 3개 도안을 1개씩 대조해 같음.",
|
|
29
29
|
"how_to_check": "뜨는 조건은 표 1-2 에 있음. 조건마다 8. 29. 앱 코드와 시험 계정 화면에서 대조함.",
|
|
30
30
|
"remaining": "7일 경계는 기기 시각으로 셈. 시간대가 다른 기기는 대조 범위 밖임."
|
|
31
31
|
},
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"group": "evidence",
|
|
34
34
|
"title": "상단 띠의 작은 글자는 읽히는가",
|
|
35
35
|
"grade": "문헌·타사 사례",
|
|
36
|
-
"symptom": "도안 C 의
|
|
37
|
-
"cause": "공개된 타사 사례
|
|
38
|
-
"fix": "
|
|
39
|
-
"how_to_check": "사례
|
|
36
|
+
"symptom": "도안 C 의 1줄 띠 글자로 안내를 놓치지 않는가?",
|
|
37
|
+
"cause": "공개된 타사 사례 4개를 대조함. 1줄 띠 안내가 창 안내보다 놓쳤다는 문의가 많았다는 사례가 3개.",
|
|
38
|
+
"fix": "3개 도안 가운데 도안 C 가 놓칠 위험이 가장 큼. 이 앱에서 직접 잰 값은 아직 없음.",
|
|
39
|
+
"how_to_check": "사례 4개의 공개 원문은 건 끝의 원본에 있음. 원문 4개는 8. 28. 모두 읽어 대조함.",
|
|
40
40
|
"remaining": "타사 사례라 이 앱 이용자와의 차이는 남음. 근거 등급이 한 단 낮은 이유임.",
|
|
41
41
|
"source_url": "https://example.com/notice-banner-cases",
|
|
42
|
-
"source_text": "타사 사례
|
|
42
|
+
"source_text": "타사 사례 4개의 공개 원문 목록"
|
|
43
43
|
}
|
|
44
44
|
]
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
"title": "방식 A 가 현행보다 찾는 정확도를 올리는가",
|
|
5
5
|
"grade": "직접 실험 확인",
|
|
6
6
|
"symptom": "같은 질문 묶음에서 방식 A 가 현행보다 원하는 자료를 더 자주 찾아 주는가?",
|
|
7
|
-
"cause": "실제 질문 200개를
|
|
7
|
+
"cause": "실제 질문 200개를 2개 방식에 같이 태움. 첫 화면 안에서 답을 찾은 비율이 현행 61%, 방식 A 82%(표 4-1).",
|
|
8
8
|
"fix": "정확도 이득은 실재함. 다만 이득의 대부분은 질문이 길고 구체적일 때 남. 한 낱말 질문에서는 차이가 작음.",
|
|
9
|
-
"how_to_check": "8. 12. 검증 환경에서
|
|
9
|
+
"how_to_check": "8. 12. 검증 환경에서 2개 방식에 같이 태운 결과는 표 4-1, 질문 묶음은 부록 4에 있음.",
|
|
10
10
|
"remaining": "질문 묶음이 최근 석 달치 위주라 계절성 주제는 덜 들어 있음.",
|
|
11
11
|
"tables": [
|
|
12
|
-
{ "caption": "같은 질문 200개를
|
|
12
|
+
{ "caption": "같은 질문 200개를 2개 방식에 태운 결과",
|
|
13
13
|
"cols": ["방식", "첫 화면 안에 찾음", "비율"],
|
|
14
14
|
"rows": [
|
|
15
15
|
["현행", "122개", "61%"],
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"group": "reported",
|
|
4
4
|
"title": "주문서를 저장해도 목록에 반영되지 않던 상황",
|
|
5
5
|
"grade": "운영 환경 확인",
|
|
6
|
-
"symptom": "주문서를 작성하고 저장을 눌러도 목록으로 돌아오면 그 주문이 보이지 않던 상황. 새로고침을
|
|
6
|
+
"symptom": "주문서를 작성하고 저장을 눌러도 목록으로 돌아오면 그 주문이 보이지 않던 상황. 새로고침을 1번 더 하면 나타났음.",
|
|
7
7
|
"cause": "저장이 끝나기 전에 목록을 다시 불러오고 있어, 저장 직전 상태가 화면에 남았음. 순서는 코드로 봄({{그림:save-order}}).",
|
|
8
8
|
"fix": "저장이 끝난 뒤에 목록을 불러오도록 순서를 바꿈. 저장이 일어나는 경로 6곳을 모두 고침.",
|
|
9
9
|
"how_to_check": "주문서를 작성해 저장하면 새로고침 없이 그 주문이 목록 첫 줄에 나타남({{그림:order-saved}}), 8. 23. 운영 관리자 웹에서 봄.",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"title": "주문이 많은 지점에서 목록 첫 화면이 느리던 상황",
|
|
20
20
|
"grade": "실데이터 대조",
|
|
21
21
|
"symptom": "주문이 많은 지점에서 주문 목록 첫 화면을 불러오는 데 10초 넘게 걸리던 상황.",
|
|
22
|
-
"cause": "목록을 그릴 때마다 지점의 주문 전체를 처음부터 훑고 있었음(코드로 봄). 주문이 많은 지점일수록 오래 걸렸음(표
|
|
22
|
+
"cause": "목록을 그릴 때마다 지점의 주문 전체를 처음부터 훑고 있었음(코드로 봄). 주문이 많은 지점일수록 오래 걸렸음(표 4-1).",
|
|
23
23
|
"fix": "자주 쓰는 조회 조건에 조회 색인을 걸어 필요한 만큼만 읽도록 바꿈. 바꾼 뒤 첫 화면 목록 50건을 운영 데이터로 건별 대조해 바꾸기 전과 같은 것을 확인함.",
|
|
24
|
-
"how_to_check": "8. 22. 운영 서버에 지점마다 5번 물어본 결과, 세 지점 모두 첫 화면 목록을 0.3초 안팎에 내줌(표
|
|
24
|
+
"how_to_check": "8. 22. 운영 서버에 지점마다 5번 물어본 결과, 세 지점 모두 첫 화면 목록을 0.3초 안팎에 내줌(표 4-1).",
|
|
25
25
|
"remaining": "주문 목록을 열어 첫 화면이 뜨기까지의 시간은 재지 않았음. 목록 위 총 건수가 예전 데이터 때문에 실제보다 몇 건 많게 나올 수 있는 상황. 기준은 실제 수치와 대조한 결과를 받은 뒤 맞출 예정.",
|
|
26
26
|
"tables": [
|
|
27
27
|
{ "caption": "주문이 가장 많은 세 지점의 첫 화면 목록 시간",
|