patent-block-diagram · git:20261104.5dfc34d · 2026-11-04 · sha256 3163ccf4e1c6bb4d
patent-block-diagram git:20261104.5dfc34dA
Immutable. This exact content never changes and is served at /api/v1/blob/3163ccf4e1c6bb4d.
---
name: patent-block-diagram
description: 자연어·발명자료로 특허 블록도와 흐름도의 PBD 원본을 작성하고 동봉 에디터로 PNG를 렌더한다. 기존 도면 세트 수정은 refine 스킬을 사용한다.
---
# 특허 블록도 자동 작도 (.pbd 생성)
## 무엇을 하는가
자연어 도면 설명 → `.pbd`(에디터 네이티브 JSON) 작성 → 앱에 주입해 렌더 → 이미지 육안 검증 →
좌표 보정 → 출원용 3배 PNG 내보내기. 산출된 `.pbd`는 더블클릭하면 그 도면이 열린 상태로
에디터가 뜨므로, 이후 수정은 사람이 GUI에서 이어서 한다.
**핵심 원칙: 반드시 렌더해서 눈으로 본다.** 좌표만 보고 "됐겠지" 하면 반드시 겹친다.
최소 1회 렌더 → Read로 이미지 확인 → 보정 → 재렌더 루프를 돈다 (실전에서 3회전 걸렸다).
## 앱 위치와 실행
- 앱: `$APP_DIR` (Electron). 이 레포에 동봉된 에디터 소스는 `patent-block-diagram-app/`
이며, 로컬 설치 위치를 `$APP_DIR` 로 잡는다 (예: `~/Desktop/patent-block-diagram`).
최초 1회 `cd "$APP_DIR" && npm install` 로 Electron 의존성을 받는다.
- 평소 실행: 바탕화면 `특허 블록도 에디터.vbs`, 또는 `.pbd` 파일 더블클릭
- **작업용 실행(CDP 필요)** — 반드시 `--user-data-dir`로 사용자 창과 분리한다:
```bash
cd "$APP_DIR" && \
./node_modules/.bin/electron.cmd . --remote-debugging-port=9222 \
--user-data-dir="$TMP/pbd-agent" > /dev/null 2>&1 &
# CDP가 뜰 때까지 기다린 뒤 렌더
node "~/.claude/skills/patent-block-diagram/scripts/render_pbd.mjs" <입력.pbd> <출력.png> [scale]
```
> ⚠️ **`--user-data-dir` 를 빼면 사용자 창을 빼앗는다.** `main.js` 가 `requestSingleInstanceLock()`
> 을 쓰고 그 락은 userData 폴더 단위다. 같은 폴더로 띄우면 두 번째 프로세스는 즉시 종료되고
> **먼저 떠 있던 창**(= 사용자가 쓰던 창, 또는 구버전 코드가 로드된 창)이 대신 잡힌다. 결과로
> ① 내 테스트 도면이 사용자 화면에 나타나 사용자가 앱 버그로 오인하고,
> ② 방금 고친 코드가 아니라 옛 코드를 테스트하게 된다. 실측으로 둘 다 겪었다 (2026-08-04).
> 같은 이유로 `taskkill //F //IM electron.exe` 로 싹 죽이지 않는다 — 사용자가 편집 중인 창까지 날아간다.
`render_pbd.mjs`는 `.pbd`를 앱의 `window._app.state`에 주입하고 앱 자체 내보내기 함수로 PNG를 만든다.
scale 2 = 검토용, 3 = 출원 제출용. 작업이 끝나면 `_app.reset()`으로 도면과 **실행 취소 기록까지**
비운다(`state`만 비우면 Ctrl+Z 한 번에 테스트 데이터가 되살아난다).
- 창이 좁게 열리면 CDP 클릭 좌표가 창 밖으로 나가 아무것도 맞지 않는다.
조작 테스트 전에 `Emulation.setDeviceMetricsOverride`로 1700×1000쯤 잡고, 끝나면
`Emulation.clearDeviceMetricsOverride`로 되돌린다.
## .pbd 스키마 (= 앱의 저장 포맷, 그대로 JSON)
```jsonc
{
"boxes": [
{ "id": 1, "x": 100, "y": 110, "w": 220, "h": 80,
"text": "사용자 인터페이스부", // \n 으로 줄바꿈 (2줄 권장, 3줄 이상은 h 키울 것)
"shape": "rect", // rect | round | diamond | cylinder | cloud | person
"fs": 15, // (옵션) 글자 크기. 없으면 기본 15, 줄 간격은 비례해서 따라간다
"dash": true, // (옵션) 점선 테두리 — 폐쇄망·시스템 경계용
"noFrame": true, // (옵션) 테두리·음영·채움 없이 글자만 — 주석·라벨용 (dash와 배타)
"noShadow": true, // (옵션) 음영만 뺀다 — 컨테이너 안의 패널처럼 겹칠 때
"textTop": true, // (옵션) 글자를 가운데가 아니라 위쪽에 — 컨테이너용
"hatch": true, // (옵션) 채움. true = 45° 빗금, "dot" = 점무늬(더 연해 글자가 잘 읽힌다).
// 회색 음영 대신 쓰는 구분 표시. 툴바 `채움바꾸기` = 흰칠→빗금→점무늬 순환.
// hatch 를 주면 dash·noFrame 은 지워진다(겸용 불가)
"lw": 5, // (옵션) 테두리 두께(기본 2) — 표의 강조 행 등
"math": true, // (옵션) text 를 LaTeX 수식으로 조판 (아래 "수식" 절)
"z": 10 }, // 작을수록 아래. 컨테이너는 반드시 가장 작게
{ "id": 9, "x": 900, "y": 100, "w": 400, "h": 260, // 이미지 상자
"text": "", "shape": "image",
"imgId": "i7", // _images 의 키. 테두리·음영·글자 없이 그림만 그린다
"origImgId": "i7", // 투명 처리 전 원본 (앱의 `이미지 원본` 버튼이 쓴다)
"z": 20 }
],
"arrows": [
{ "id": 30, "from": 2, "to": 4, "style": "ortho", "z": 2, // ortho(직각) | straight(직선)
"dash": true, // (옵션) 점선 화살표 — 산출·참조·포함 관계
"via": [{ "x": 340, "y": 1440 }], // (옵션) 경유점(절대좌표). 지정하면 자동 라우팅·꺾임을 무시하고
// 이 점들을 그대로 지난다. 여백으로 돌아가는 회귀선용
"fromOff": { "dx": 240, "dy": 40 }, // (옵션) 시작점을 손으로 지정 — from 박스 좌상단 기준 상대좌표
"toOff": { "dx": 0, "dy": 30 }, // (옵션) 끝점을 손으로 지정 — to 박스 좌상단 기준 상대좌표
"bend": { "axis": "x", "t": 0.25 } } // (옵션) 중간 꺾임 위치 — 양 끝점 사이 비율 0~1 (기본 0.5)
],
"tags": [
{ "id": 50, "boxId": 1, "label": "100", "dx": 82, "dy": -45, "z": 60 }
],
"nextId": 70, // 쓴 id의 최대값보다 크게
"_images": { // (이미지를 쓸 때만) imgId → data URL. 도면 파일 하나로 이식된다
"i7": "data:image/png;base64,iVBORw0KGgo..."
}
}
```
- `dx`,`dy`는 **박스 좌상단 기준 상대좌표**이며 부호 숫자가 놓일 위치다. 지시선(물결)은
박스 테두리에서 그 숫자까지 자동으로 그려진다.
- id는 boxes/arrows/tags 통틀어 유일해야 한다 (렌더러가 z로 통합 정렬).
- 좌표 단위는 px, 캔버스는 기본 2400×1600이며 도면이 그보다 크면 자동으로 늘어난다. 격자 스냅 5.
- 앱에서 사람이 도형을 끌 때는 **스마트 가이드**(가장자리·중심 정렬, 등간격)가 6px 안에서 자석처럼
붙는다. `.pbd`를 직접 쓸 때는 해당 없다 — 좌표를 처음부터 정렬·등간격으로 계산해 두면 된다.
- 태그도 `fs`로 부호 숫자 크기를 따로 줄 수 있다.
- 이미지 본문은 `_images`에만 있고 `state` 안에는 id만 남는다(실행 취소 스냅샷이 무거워지지 않게).
주입할 때도 `_images`를 함께 넣으면 앱이 알아서 저장소로 옮긴다. 스크립트에서 이미지를 넣을 때는
`_app.insertImage(dataURL, {x, y})`가 원본 픽셀 크기에 맞춰 상자를 만들어 준다.
- **이미지 상자는 사람이 앱에서 넣는 게 정상 경로다.** 자연어 프롬프트만으로 도면을 만들 때는
도형으로 그리고, 이미지는 사용자가 캡처·사진을 직접 끌어다 놓는 용도로 남겨 둔다.
## 도형·화살표로 표현 가능한 것 / 불가능한 것
| 원하는 것 | 방법 |
|---|---|
| 시스템 경계(폐쇄망 등) | `dash: true` 컨테이너 rect, `z`를 최소로. 채움이 없어 내부 클릭이 통과한다 |
| 컨테이너 안에 하위 블록 | 컨테이너 `textTop: true` + 하위 박스 z를 더 크게 |
| DB·저장소 | `shape: "cylinder"` |
| 판단·분기 | `shape: "diamond"` |
| 네트워크(망) | `shape: "cloud"` (음영 없음. 글자는 구름 몸통에 맞춰 조금 아래에 놓인다). **cloud는 "망"을 뜻하므로 외부 시스템에 함부로 쓰지 않는다.** 언어 모델처럼 시스템의 통신 상대인 별개 객체는 `rect`가 맞다 |
| 이용자·사람 | `shape: "person"` (머리+상반신 아이콘, 음영 없음. `text`가 있으면 아이콘 **아래**에 적힌다. 보통은 `text: ""` 로 두고 부호 태그 `U`를 단다) |
| 양방향 화살표 | **화살표 2개**(A→B, B→A)를 같은 스타일로. 두 박스의 중심 좌표축을 정확히 맞추면 겹쳐서 양쪽 화살촉으로 보인다 |
| 1:N 분기(팬아웃) | 소스 1개에서 타깃 N개로 ortho 화살표 N개. 중간 꺾임 x가 모두 같아 세로 스파인처럼 모인다 |
| 수식 | `math: true` 박스. `text` 가 LaTeX 원문이 된다 (아래 "수식" 절) |
| 아이소메트릭·자유곡선 | **불가**. 위 6개 도형뿐 |
| 화살표에 라벨 | `noFrame: true` 글자 상자를 선 옆에 놓는다 (테두리·음영이 없어 선을 가리지 않는다) |
| 도면 주석·범례·제목 | 같은 `noFrame` 글자 상자. 앱 툴바의 `텍스트` 버튼 또는 `테두리 ⇄ 없음` 토글 |
## 수식 (LaTeX)
박스에 `"math": true` 를 주면 `text` 가 LaTeX 원문으로 해석되어 MathJax 로 조판된다.
앱 툴바의 `수식 ⇄ 글자` 버튼으로도 켜고 끌 수 있으며, 텍스트 편집창이 그대로 TeX 입력창이 된다.
```jsonc
{ "id": 12, "x": 500, "y": 310, "w": 1900, "h": 120, "fs": 46,
"math": true, "noFrame": true, "z": 30,
"text": "r_1[\\ell]\\;=\\;-\\frac{1}{|W'|}\\sum_{d\\in W'}\\sigma\\big(\\mathrm{sim}(e(t_\\ell),e(d))\\big)" }
```
- **크기는 `fs` 가 정한다.** 조판 좌표는 1em = 1000 단위이고 `fs/1000` 로 축소되므로,
`fs: 46` 이면 수식의 기준 글자 크기가 46px 이 된다. 박스의 `w`/`h` 는 **가운데 맞춤에만**
쓰이고 수식 크기에 영향을 주지 않는다. 박스보다 넓은 수식은 밖으로 삐져나가고
`fitCanvas` 가 그만큼 캔버스를 늘려주지 않으므로, 박스를 넉넉히 잡는다.
- 출력은 **SVG 경로**다. HTML(CHTML)·MathML 출력은 쓰지 않는다 — PNG 내보내기가
SVG 를 data URL 로 만들어 `<img>` 로 그리는데, 그 문맥에서는 HTML 이 렌더되지 않아
수식이 통째로 사라진다. `index.html` 의 `svg: { fontCache: 'none' }` 설정도 필수다
(`<use>` 참조 대신 글리프를 `<path>` 로 직접 박아 id 충돌을 막는다).
- **한글은 수식 박스에 못 넣는다.** MathJax 수학 폰트에 한글 글리프가 없어
`\text{정렬 결과}` 는 빈칸으로 나온다. 한글이 섞이는 각주·설명은 보통 글자 박스로 따로 둔다.
- TeX 에 오류가 있거나 조판기가 아직 안 떴으면 조용히 보통 글자 렌더로 되돌아간다.
파일이 깨지지는 않으므로, 렌더 결과를 눈으로 보고 수식이 평문으로 나왔는지 확인한다.
- 조판 결과는 TeX 원문을 키로 캐시된다. 앱 코드를 고쳐 다시 띄우면 캐시도 비워진다.
## 화살표 라우팅 규칙 (좌표 설계의 핵심)
`ortho`는 두 박스 **중심**의 dx/dy를 비교해 자동 결정된다.
- `|Δx| ≥ |Δy|` → 수평 우선: 소스 좌/우변에서 나가 중간 x에서 꺾여 타깃 좌/우변으로.
- 그 외 → 수직 우선: 소스 상/하변에서 나가 중간 y에서 꺾인다.
- **두 중심의 x(또는 y)가 정확히 같으면 꺾임 없는 일직선**이 된다.
### 중간 꺾임 위치 조정 (`bend`)
꺾임은 기본적으로 두 끝점의 한가운데에 선다. `bend`로 그 위치를 옮긴다.
```json
{ "axis": "x", "t": 0.25 }
```
- `axis` — 수평 우선 라우팅이면 `"x"`(가운데 세로 구간이 좌우로 움직인다), 수직 우선이면 `"y"`.
현재 라우팅 방향과 `axis`가 다르면 무시된다.
- `t` — 출발 끝점(0)에서 도착 끝점(1) 사이의 **비율**. 절대좌표가 아니라 비율이므로 박스를
옮기거나 크기를 바꿔도 꺾임이 비례해 따라온다. 0~1 밖의 값도 되며, 그때는 선이 되돌아 나간다.
- 쓸 자리: 중간 블록·컨테이너를 피해 선을 돌릴 때, 여러 화살표의 세로 스파인을 서로 다른 x에
떨어뜨려 겹침을 없앨 때.
- **진입면 자동 재선택** — 꺾임 좌표가 박스의 가로(또는 세로) 범위 안까지 들어오면 그 박스는
좌·우변이 아니라 위·아래변으로 붙는다. 즉 `t`를 1 이상으로 주면 타깃 **위에서 아래로 꽂히는
ㄱ자**가 되고(화살촉이 아래를 향한다), 0 이하로 주면 소스 아래변에서 나간다. 꺾임점이 하나
줄어 경로가 3점(양쪽 다 들어오면 2점)이 되며, 손잡이는 그대로 남아 되돌릴 수 있다.
이 규칙이 없으면 마지막 구간이 화살촉(12px)보다 짧아져 화살촉이 옆을 향하는 그림이 나온다.
- 앱에서는 직각 화살표를 선택하면 가운데 구간에 **주황 손잡이**가 떠서 그 구간을 통째로 끌 수 있다
(PowerPoint의 꺾인 연결선 조절점과 같다). 선 위 아무 데나 잡아도 된다. 툴바 `경로 자동`으로 되돌린다.
- 끝점이 두 개뿐인 일직선 직각 화살표에는 조정할 꺾임이 없어 손잡이가 나오지 않는다.
`fromOff`/`toOff`가 있으면 그 점이 끝점으로 **고정**되고(박스 좌상단 기준 상대좌표라 박스를
옮겨도 따라온다), 두 점 사이를 style에 따라 직선 또는 직각으로 잇는다. 한쪽만 지정하면 반대쪽은
그 점을 향하는 테두리점으로 자동 계산된다. 자동 라우팅이 어색한 곳(예: 같은 변에 화살표가 몰릴 때)만
쓰고, 기본은 중심축 정렬로 푸는 게 낫다. 앱에서는 화살표를 선택하면 양 끝에 파란 핸들이 떠서
마우스로 끌 수 있고, 툴바 `경로 자동`으로 끝점과 꺾임을 함께 되돌린다.
따라서:
1. **상하로 잇는 박스는 중심 x를 같게** 맞춘다 → 깔끔한 세로 직선.
2. **좌우로 잇는 박스는 중심 y를 같게** 맞춘다 → 깔끔한 가로 직선. 양방향 화살표는
중심 y가 어긋나면 계단처럼 꺾여 흉해진다 (실전 실패 사례).
3. 팬아웃 스파인이 다른 박스를 관통하지 않는지 확인한다. 스파인 x =
`(소스 우변 + 타깃 좌변) / 2`. 그 x·y 범위에 다른 박스가 있으면 타깃 묶음을 위/아래로 옮긴다.
## 도면부호 태그 배치 규칙
**`dx`, `dy`는 숫자의 왼쪽 끝이 아니라 가운데가 놓이는 좌표다.** 이것을 모르면 `dx = w + 40`에서
숫자의 왼쪽 절반이 박스 안으로 파고든다(fs 56에서 세 자리 숫자 반폭 약 85px).
- **기본은 박스 위쪽** `dx = w/2` 또는 `40`, `dy = -70 ~ -75`. 화살표는 박스 중심 높이로 들어오고
팬인·팬아웃 스파인은 좌우 바깥을 지나므로 위쪽 좌측 모서리는 거의 항상 비어 있다.
- **오른쪽 바깥은 `dx = w + 140`**, 그리고 **그 행에서 가장 오른쪽 박스에만** 쓴다. 체인 중간
박스에 달면 숫자가 다음 박스 좌상단에 올라앉는다(박스 간격이 보통 120~160px).
- 캔버스 우측 끝 박스는 왼쪽(`dx = -125`) 또는 위(`dy = -50`)로 보낸다. 좌측 끝 박스에 음수
`dx`를 쓰면 좌표가 음수가 되므로 저장 시 우측 시프트 가드를 둔다.
- 흐름도 단계부호(S계열)는 박스 **왼쪽** `dx ≈ -62`. 컨테이너 부호는 위쪽 바깥 `dx = 60, dy = -45`.
- 세로로 쌓은 박스에 위쪽 태그를 쓰면 박스 간 세로 간격을 `h + 100` 이상 잡는다(80에서 물린다).
점선 컨테이너는 내부 박스 묶음보다 위아래 각 120px 이상 크게 잡는다.
- **화살표가 드나드는 변에는 태그를 두지 않는다.** 태그 자동 배치는 박스 충돌만 보고 화살표
경로는 보지 않으므로, 렌더 후 "숫자가 선 위에 앉았는가"를 육안으로 따로 본다.
- 부호 체계는 기존 관행대로: 시스템 100 → 하위 110, 120 / 계층은 300 → 310, 320.
전체 규약(인쇄 검산식, z 규약, 절대 금지 4항, 채움 의미 코드, 레이아웃 함정)은
`references/도면_스타일가이드_템플릿.md` §1.
## 작업 순서
1. **프롬프트 해석** — 블록 목록, 계층(무엇이 무엇을 품는지), 연결(방향·양방향), 부호를 표로 정리.
불가능한 요소(사람 아이콘 등)를 먼저 식별해 대체안을 정하고 나중에 사용자에게 보고한다.
2. **좌표 설계** — 열(column) 단위로 x를 잡고, 위 라우팅 규칙대로 중심축을 맞춘다.
컨테이너는 내부 박스를 모두 감싸도록 x/y/w/h를 계산 (여백 40px 이상).
3. **.pbd 작성**: 사건 폴더에 `도면N_이름.pbd`로 저장. z는 **컨테이너=1~8, 화살표=15, 박스=20,
태그=60**. 컨테이너 rect는 흰색 채움이 있어 z가 더 작은 화살표를 완전히 가리므로, 화살표가
컨테이너보다 위이고 박스보다 아래여야 한다.
4. **렌더 & 육안 검증** — 앱을 CDP 포트로 띄우고 `render_pbd.mjs`로 scale 2 PNG → **Read로 이미지 확인**.
점검: 글자 잘림, 태그가 선에 물림, 화살표 계단 꺾임, 스파인이 박스 관통, 컨테이너 밖으로 삐져나옴.
5. **보정 → 재렌더** — 문제가 없을 때까지 반복.
6. **출원용 내보내기** — scale 3으로 사건 폴더에 PNG 저장. 필요하면 `topatent`로 TIFF 변환
(kr-patent 도면 도구체인 참조).
7. **앱 열어두기** — `.pbd`를 `Start-Process`로 열어 사용자가 바로 이어서 편집하게 한다.
## 예시
- `examples/simple_blockdiagram.pbd` — 실선 컨테이너 + 원기둥 저장부 + 4블록 파이프라인 (기본형)
- `examples/system_architecture.pbd` — 점선 폐쇄망 경계, 중첩 컨테이너(저장부 안에 2블록),
양방향 화살표 2쌍, 5분기 팬아웃 (복합형). 위 규칙이 모두 들어 있으니 새 도면은 이걸 베끼는 게 빠르다.
## 도면 세트 수정 가이드 (범용 템플릿)
기존 명세서 도면 세트를 **수정**할 때는 `references/도면_스타일가이드_템플릿.md`를 사건 폴더로
복사해 `도면_스타일가이드.md`로 채워 쓴다. 하우스 스타일(도형 용법·fs 규약·레이아웃 아키타입·
z-순서·부호 태그 배치)을 고정하고, 부호 체계 SINGLE SOURCE 표·도면 대장·유형별 수정 프롬프트
템플릿을 제공한다. `§1/§4/§5/§6`은 공통이라 그대로 두고 `§0` 경로·`§2` 부호·`§3` 도면 대장만
사건값으로 채운다. 부호를 바꾸면 명세서 본문·【부호의 설명】도 같은 세션에서 수정 대상.
## 누적 학습 항목
- (2026-09-16 정리, 도면 13장 세트 실측) **★ 스타일가이드 템플릿 §1 전면 갱신.** 구버전 fs
16~24는 인쇄 0.8~1.2mm로 규정 위반이라 폐기하고, `fs >= 0.0188 x W`(폭) 또는 `0.01255 x H`(높이)
중 큰 값, 실무 확정값 **fs 44 / 캔버스 폭 2300 / 높이 3400**으로 교체했다. 사무소 기출원 실측
목표는 `fs / W ≈ 0.03`. fs 44에서 폭 2300px에 들어가는 열은 **최대 3열**이므로 이 제약이
레이아웃을 규정한다.
- (2026-09-16) **컨테이너가 화살표를 삼킨다.** 컨테이너 z=1~8, **화살표 z=15**, 박스 20, 태그 60.
컨테이너 안 블록들을 잇는 화살표가 통째로 사라진 렌더가 실제로 나왔다.
- (2026-09-16) **세로 팬인은 반드시 관통한다.** 같은 x 열에 쌓은 N개 박스를 아래 한 박스로
모으면 첫 박스에서 나온 선이 중간 박스들을 뚫는다. `bend` 우회로 해결되지 않고 **가로 3열
재배치**가 유일한 해법이다. 팬아웃(1 -> N)은 세로 배치가 정상이다.
- (2026-09-16) **태그 dx, dy는 중앙 정렬 좌표다.** 우측 배치는 `w + 140`, 그것도 그 행의 맨
오른쪽 박스에만. 체인 중간 박스의 우측 태그는 다음 박스 좌상단에 올라앉는다. **기본값을
위쪽 배치(`dx = w/2, dy = -70`)로 바꾸면 스파인 충돌이 한 번에 사라진다.**
- (2026-09-16) **★ 흐름도에는 단계 박스 옆에 산출물 객체 박스를 세운다.** 절대 금지 2항 때문에
흐름도만 그리면 그 단계의 산출물 부호가 도면에 못 올라가고, 본문은 그 부호를 서술하므로
정합성 점검에서 「본문에만 있는 부호」로 걸린다. 세로 스파인에 단계 박스를 쌓고 각 단계
오른쪽에 산출물 객체 박스를 중심 y 맞춰 세운다(단계 박스는 S부호만, 객체 박스는 객체 부호만).
가로로 넓어지므로 인쇄 검산을 다시 돌린다. **행위 주체(프로세서, 시스템)는 예외**로 흐름도에
그리지 않으며 정합성 점검에서 화이트리스트로 뺀다.
- (2026-09-16) **검증은 OCR보다 `.pbd` 직접 대조가 정확하다.** `boxes[].text`와 `tags[].label`을
읽어 본문과 대조하면 100% 정확하다. 이 방법으로 "도면에 있으나 본문에 한 번도 서술되지 않은
라벨" 10건을 찾았다. 반대 방향(본문 부호 - 도면 태그 차집합)이 더 위험하며, 청구항 구성요소가
미도시면 지원요건 시비가 붙는다.
- (2026-09-16) **자동 검산에서 빈 컨테이너의 fs를 잡지 마라.** `text: ""` 컨테이너는 fs 기본값이
15라 「모든 박스 fs >= 52」 규칙에 전부 FAIL로 잡힌다. fs 검사와 `minfs` 계산 모두
`text.strip()`이 있는 박스만 대상으로 하고 `shape == "image"`도 제외한다.
- (2026-09-16) **도면 라벨 문구는 본문 표기에 맞춘다.** 도면은 명사형("의미적 대응 판단"),
본문은 동사형("의미적 대응을 판단하는 단계")으로 갈리는데, 심사관과 번역자가 둘을 대조하므로
도면 쪽을 고치는 것이 옳다. 조사 하나 차이도 맞춘다.
- (2026-09-16) **육안 검증은 3회로 안 끝난다.** 13장 세트에서 7회전이 걸렸고 회전마다 결함
유형이 달랐다(z 은닉 -> 부호 잘림 -> 경로 관통 -> 폰트 규격 -> 재배치 후 신규 관통 -> 태그
여유 -> 최종 미세). 중간 회전은 scale 0.7~1.2로 돌려도 결함이 보인다. 최종만 scale 3.
- (2026-08-20, 규제 준수 보고서 건) **★ 사용자 확정 절대 금지 4항.** ① 한 박스에 여러 요소를
줄바꿈으로 나열 금지(항목 수만큼 박스 분할, 2열 격자로 높이 억제). «객체명+값» 2줄만 허용.
② 한 박스에 태그 2개 이상 금지 — **흐름도 단계 박스는 S부호만** 달고 요소 부호는 옆에 실제
객체 박스를 세워 거기 붙인다. 같은 종류 복수면 각 박스에 같은 부호 반복(상태값 5개 전부 361).
③ **자식 박스를 품은 컨테이너에는 글자를 넣지 않는다**(`text: ""`, textTop 제거). 정체는 부호
태그로만. ④ **점선 화살표 전면 금지** — 분기는 다이아몬드 옆 `noFrame`, `fs 56` 라벨
(충족/미충족, 예/아니오)로 표시하고 태그는 안 붙인다. 컨테이너의 `dash`는 계속 허용.
전수 검산 코드는 [[feedback_patent_drawing_box_tag_rules]] 참조.
- (2026-08-20) **인쇄 문자 크기 검산식.** 도면은 A4 도면란(약 170x255mm)에 종횡비 유지로
축소되므로 `s = min(170/maxX, 255/maxY)` mm/px, `fs x s >= 3.2mm`(시행규칙 0.32cm)여야 한다.
**세로로 긴 도면은 높이가 구속조건**이라 fs 48이 탈락한다(maxY 4010에서 fs 48 = 3.05mm 위반,
fs 64 = 4.07mm 적합). maxY >= 3600이면 부속 항목도 48을 쓰지 않는다.
- (2026-08-20, 규제 준수 보고서 건) **채움은 두 종류이고, 세트 전체에 의미 코드를 고정한다.**
`hatch: true`(빗금)와 `hatch: "dot"`(점무늬)를 아무 데나 쓰면 심사관이 강조로 읽는다.
도면 세트 스타일가이드에 예컨대 「빗금 = 확정·충족 계열, 점무늬 = 후보·보류·미충족 계열」로
못 박고 그대로만 쓴다. 한 도면에 합쳐 3~4개까지. 전체 조망 도면(시스템 블록도, 전체 흐름도)은
채움 없이 둔다. 글자가 긴 박스에는 dot(더 연하다).
- (2026-08-20) **도면 세트는 포트를 나눠 병렬로 작도한다.** `render_pbd.mjs`가 `PBD_PORT`를 읽으므로
`--remote-debugging-port=9333/9334/9335` + 각기 다른 `--user-data-dir`로 인스턴스를 띄우면
에이전트 3개가 동시에 렌더한다(9장을 3×3으로 나눠 세 배 빨랐다).
**단, 병렬 착수 전에 스타일가이드 1장**(fs·z 규약, 부호 SINGLE SOURCE 표, 도면별 부호 배정표,
채움 의미코드)을 먼저 써서 전원에게 물려야 한다. 없으면 세 가지 양식이 나온다.
정리는 CommandLine에 `pbd-agent`가 든 PID만 골라 종료한다.
- (2026-08-06, P26070103KR-a) **★ 시스템 블록도에 `~부`를 남발하지 말 것.**
마스터 프롬프트 A-5: 입력계·저장계·출력계처럼 **물리적 실체가 있는 블록만** `~부`로 분리하고,
변환·판정·산출 등 **내부 처리 로직은 전부 단일 `제어부`(또는 `프로세서`) 동작으로 통합**한다.
이 건에서 프로세서 밑에 `인용 정보 획득부`, `직접 지지 판단부`, `참조 경로 탐색부` 등 7개를 만들었다가
전부 지우고 프로세서 1개로 합쳤다. 도면만이 아니라 **본문 58곳**을 되돌려야 했다.
판별법: 그 `~부`를 떼어 별도 부품으로 살 수 있는가. 없으면 제어부 안이다.
작도 전에 **청구항 시스템 독립항이 부르는 이름**을 그대로 블록명으로 쓴다.
- (2026-08-06) **투명 박스(noFrame) 텍스트 금지.** 결과 서술("~에서 제외"), 패널 제목("[…의 경우]"),
분기 라벨("예"/"아니오")을 테두리 없는 글자로 띄우면 안 된다. 부호를 붙일 수도 없다.
필요한 정보는 (i) 점선/실선 스타일 대비, (ii) 부호가 붙은 실제 박스, (iii) 본문 서술로 옮긴다.
같은 이유로 **연결선(화살표) 자체에 부호를 할당하지 않는다.**
- (2026-08-06) **부호 태그가 화살표 위에 얹히는 사고**가 반복된다. 태그 자동 배치 검사는 박스 충돌만 보고
화살표 경로는 보지 않으므로, 렌더 후 육안으로 "숫자가 선 위에 앉았는가"를 따로 본다.
얹혔으면 박스의 반대편(위/아래/좌)으로 옮기고, 자리가 없으면 컨테이너 폭을 늘려 바깥에 자리를 만든다.
- (2026-07-20, PK26239KR) 지시선이 부호 글자 직전에서 멈추는 거리가 14px 고정이라 `S150`,
`S1200-1` 처럼 넓은 부호에서 선이 글자를 파고들었다. `measureText`로 실제 글자 폭을 재어
글자 상자 경계까지 물러나도록 고쳤다. 폰트 크기를 키운 태그(`fs`)도 자동으로 따라간다.
- (2026-07-20) `noFrame` 글자 상자는 그려지는 게 글자뿐이라 마우스로 잡을 곳이 없다.
투명 사각형(`fill="transparent"`)을 깔아 클릭 영역을 만들고, 파선 안내틀은 선택 중일 때만
덧그린다. 내보내기 직전에 선택이 해제되므로 안내틀은 PNG에 나오지 않는다.
- (2026-07-20, PK26239KR) SVG `width`/`height`와 `#wrap`의 CSS 크기가 2400×1600으로 고정이라
그보다 큰 도면은 오른쪽·아래쪽이 화면에서 잘려 클릭조차 안 됐다(PNG 내보내기는 `getBBox`
기준이라 멀쩡했다). `render()` 끝의 `fitCanvas()`가 내용에 맞춰 둘 다 늘리도록 고쳤다.
- (2026-07-20) 다중 선택 추가: `selection`(주 선택, 툴바·텍스트창 대상) + `multi`(선택 전체).
Ctrl+A 전체 선택, Shift+클릭 추가/해제, 묶음 드래그·삭제·앞뒤 이동. 여러 개 선택 중엔
텍스트 편집창을 비활성화한다(주 선택 하나만 바뀌어 혼란스럽다).
- (2026-07-20) 묶음 드래그 시 태그의 `dx`/`dy`는 박스 상대좌표라, 박스와 태그를 같이 옮기면
이중으로 이동한다. 함께 움직이는 박스에 딸린 태그는 드래그 대상에서 빼야 한다.
- (2026-07-14, PK26231KR) `did-finish-load` 시점에도 `webContents.isLoading()`이 true라
파일 자동 로드가 조용히 실패했다. 앱의 파일 연결·자동 로드는 `ready` 플래그 방식으로 고쳐져 있다.
- (2026-07-14) 컨테이너 박스에 `text`를 넣으면 세로 중앙에 찍혀 내부 블록과 겹친다 → `textTop` 추가.
- (2026-07-14) 양방향 화살표는 두 박스의 중심 y를 1px이라도 어긋나게 두면 계단 꺾임이 생긴다.
중심축 정렬이 곧 도면 품질이다.
- (2026-07-14) 태그 dx를 컨테이너 폭에 딱 맞추면 숫자가 테두리·음영에 물린다. 컨테이너를
30px 넓혀 안쪽에 태그 자리를 확보하는 편이 낫다.
- (2026-07-14) 조작 핸들(화살표 끝점 등)은 z-순서상 박스보다 아래에 그리면 박스에 덮여 클릭이
먹지 않는다. 핸들은 z와 무관하게 항상 마지막에(최상단) 그린다.
- (2026-07-14) 앱 창이 좁게(innerWidth ~611px) 열려 있으면 CDP로 보낸 클릭 좌표가 창 밖으로
나가 아무 것도 선택되지 않는다. 마우스 시뮬레이션 검증 전에
`Emulation.setDeviceMetricsOverride`로 뷰포트를 넉넉히 잡을 것.
- (2026-08-06, P26070102KR-a) 장치 블록도(도 1)에 **청구항에 없는 기능 블록을 그리지 말 것**. 제어부 컨테이너 안에 `문서 구조화부`, `트리플 추출부` 같은 하위 블록 6개를 그렸다가 전량 삭제하고 제어부 단일 박스로 되돌렸다. 블록도는 청구항 장치항의 구성요소(메모리, 제어부, 실체 있는 입출력 수단)와 메모리가 보유하는 데이터 객체만 담는다. 내부 처리 로직은 도 2 이하의 흐름도·개념도에서 단계 부호로 표현한다.
- (2026-08-06) 컨테이너 안에 세로로 쌓은 박스들의 부호 태그는 `dx`를 박스 폭보다 **60px 이상 크게**(예 w=540 → dx=600) 주고 `dy`는 박스 중앙(+45 등)으로 둘 것. `dy=-50`(박스 위)으로 두면 위 박스의 아래 테두리에 숫자가 물리고, `dx`가 박스 폭에 가까우면 지시선이 테두리를 파고든다. 컨테이너 폭은 태그 자리만큼 미리 넓혀 둔다.