# Altium Schematic Review

> Altium 회로도 검토

- Skill: `scottjeong/altium-schematic-review` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add scottjeong/altium-schematic-review`
- Raw SKILL.md: https://api.skillmd.com/api/skills/scottjeong/altium-schematic-review/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ScottJeong (https://skillmd.com/u/scottjeong)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/scottjeong/altium-schematic-review

---


# Altium 회로도 검토

검토의 실패는 "못 찾는 것" 보다 **"틀린 걸 찾았다고 말하는 것"** 이 크다.
후보를 뱉는 건 도구가 하고, **판정은 데이터시트가 한다.**

## 하나만 지킨다면 이것

> **미결선·플로팅 핀을 찾으면, 그 핀의 데이터시트 Type 과 내부 풀(PU/PD) 유무를
> 읽기 전에는 결함이라고 부르지 마라.**

오판은 세 갈래로 난다. 전부 이 규칙 하나로 걸린다.

| 오판 유형 | 실제로 확인해야 할 것 |
|---|---|
| 플로팅 입력을 결함이라고 부름 | 데이터시트 Type 열의 내부 풀 표기, 플로팅을 명시 허용하는 문장 |
| 미사용 단자를 고정해야 한다고 함 | 그 핀이 **로직 입력인지** — 아날로그·패스-FET 단자면 관통전류 논리가 적용 안 된다 |
| 이미 된 것을 "미구현" 이라고 함 | 파일이 최신인지, 도구 출력을 **끝까지** 읽었는지 |

세 번째가 특히 중요하다 — **도구를 돌려놓고 출력을 끝까지 안 읽으면 도구가 없는 것과 같다.**

## 0. 전제 확인 — 여기서 헛수고가 갈린다

```
python scripts/check_context.py <프로젝트폴더 또는 .SchDoc>
```

확인하는 것:

- **디스크 파일 시각 vs Altium 실행 여부.** Altium 이 떠 있으면 **메모리가 최신이고
  디스크가 구판일 수 있다.** 저장 안 한 상태에서 파일만 읽으면 "전원부가 없다",
  "애너테이션이 안 됐다" 같은 헛다리를 짚는다. **Altium 이 떠 있으면 저장했는지 먼저 묻는다**
- 애너테이션 상태 (지정자에 `?` 가 남았는지)
- 로컬 데이터시트 목록 — §3 판정에 쓸 재료가 있는지 미리 안다

## 1. 헤드리스 1차 — altium_monkey

Altium 없이 돈다. 항상 실행한다.

```
python scripts/audit_footprints.py <SchDoc> --libs <라이브러리폴더> [...]
python scripts/net_erc.py <SchDoc>
```

| 검사 | 뜻 |
|---|---|
| 풋프린트 링크 없음 / 실물 못 찾음 | PCB 로 못 넘어간다 |
| **단일핀 넷** | 결선 미완 후보. **후보일 뿐이다** → §3 |
| **출력 충돌** | 한 넷에 `Output`/`Power` 가 2개 이상 |
| **구동원 없는 넷** | `Input` 만 있는 넷 |
| 무명 넷 | 대개 정상(지역 배선). 개수만 본다 |

파이썬은 **`altium_monkey` 가 설치된 3.12 venv 인터프리터**를 쓴다
(이 패키지가 Python `<3.13` 을 요구한다). 아래에서는 그걸 `python` 이라고 쓴다.

### 단락처럼 보이면 회로보다 도구를 먼저 의심한다

**전원 단락은 도구 버그의 전형적인 증상이다.** 실제로 한 평가 보드에서
전원 레일끼리·리셋과 GND 가 한꺼번에 단락으로 나왔는데 전부 가짜였다.

원인: `net_erc.py` 가 **멀티파트 심볼의 파트 필터를 안 했다.** 멀티파트는 파트
레코드마다 전체 핀을 들고 있고 `get_pin_hotspot` 은 designator 로만 찾으므로
`A1`/`B1`/`C1` 이 같은 좌표로 나와 서로 다른 넷이 합쳐진다.
(2026-08-13 에 `part_of` / `pin_in_part` 로 고쳤다. 핀의 `owner_part_id` 는 정상이니 그걸 쓴다.)

그러니 결과가 "보드가 죽는다" 수준이면 보고하기 전에:

1. 해당 부품이 멀티파트인가 — `c.part_count`(실제 파트 수 = 이 값 − 1), `c.current_part_id`
2. 문제 핀들의 **좌표를 직접 찍어본다.** 심볼이 정말 겹쳐 놓여 있는지 아닌지 바로 갈린다
3. 커넥터라면 **상대 보드 회로도와 핀맵을 대조한다.** 이게 §2 컴파일 대조보다 강한 근거다

**후보 목록(단일핀·출력충돌·구동원없음)은 자르지 않고 전부 출력하게 되어 있다.**
`--limit` 는 무명넷에만 걸린다. 목록을 잘라 보면 도구를 안 돌린 것과 같다.

## 2. 권위 대조 — altium-mcp `run_altium_script`

**Altium 자체 컴파일러를 부른다. 이게 정답지다.**

```
DM_Compile → DM_DocumentFlattened → DM_NetCount
```

스니펫은 `references/altium-script-snippets.md` 에 검증된 것이 있다.

**넷 개수가 §1 과 다르면 내 도구가 틀린 것이다.** 실제로 105 vs 182 로 77개가 어긋났고,
원인은 기하 넷 구성이 핀-핀 직결·전원포트 직결·hidden 핀을 빼먹은 것이었다
(`references/net-build-notes.md`). 고친 뒤 182 로 일치했다.

**⚠ 잘못 쓰면 Altium 연동 전체가 멈춘다.** 런타임 에러가 나면 스크립트가 디버거에
멈추고, **Altium 의 스크립팅 슬롯은 전역으로 하나뿐**이라 그때부터
`get_footprint_primitives`·`get_screenshot` 같은 **다른 altium-mcp 도구까지 전부** 막힌다
(`Another script executing now.` 다이얼로그).

**사람이 `Ctrl+F3` 를 눌러야만 풀린다. 에이전트는 복구할 수 없다.**
그러므로 이 도구는 **꼭 필요할 때만 최소한으로** 쓴다 — 넷 개수 대조 정도.
핀 상세가 필요하면 `net_erc.py` 로 대체한다.
반드시 `references/altium-script-traps.md` 를 먼저 읽는다.

Altium 이 없거나 막혔으면 이 단계를 건너뛰되, **건너뛴 사실을 보고에 쓴다.**

## 3. 후보별 판정 — 이 단계가 검토의 본체

§1·§2 가 뱉은 후보를 **한 건씩** 판정한다. 묶어서 처리하지 않는다.

판정 순서:

1. **핀 방향을 먼저 본다.** 출력이면 대개 무해, 입력이면 확인 필요
2. **데이터시트에서 그 핀 항목을 찾는다** — Type 열, 내부 PU/PD 표기, 비고
3. 근거를 못 찾으면 **`미확인`** 으로 두고 확인 방법을 적는다. 결함이라고 쓰지 않는다

| 근거원 | 도구 |
|---|---|
| 로컬 PDF | `pymupdf` 로 핀 이름 검색 후 앞뒤 문맥 출력 |
| 웹 | `WebSearch` → `WebFetch`. **PDF 는 본문 추출이 안 되므로** 받아서 로컬에서 `pymupdf` 로 판다 |
| 부품 사양·재고 | `pcbparts` `jlc_get_part` / `jlc_search` |
| 일반 설계 규칙 | `pcbparts` `get_design_rules` (`ldo` `usb` `esd` `power` 등) |

오탐 필터는 `references/pin-verdict.md`. 그것만 봐도 후보 대부분이 걸러진다.

### 회로도 PDF 에서 핀맵을 뜰 때

**전원포트(GND/5V/3.3V 심볼)의 넷 이름은 `get_text('words')` 에 안 잡힌다.** 세로 레일
끝에 붙어 있어 핀 좌표와 이어붙이기도 어렵다. 회전 텍스트가 통째로 빠지는 것도 같은 계열이다.

- **벡터 세그먼트로 자동 트레이스하지 마라.** 심볼 박스 외곽선·핀이름 밑줄까지 세그먼트로
  들어와 한 파트의 핀이 전부 한 넷으로 뭉친다
- **고배율로 렌더해서 정션 도트를 눈으로 읽는 게 가장 빠르고 정확하다.**
  `pg.get_pixmap(clip=fitz.Rect(...), matrix=fitz.Matrix(20, 20))` 정도면 도트가 보인다
- 교차(점 없음) = 미연결, 도트 = 연결. 이 구분이 핀맵 판정의 전부다

## 4. 육안

좌표로 안 잡히는 것 — 심볼 오배치, 글자 겹침, 엉뚱한 곳에 붙은 라벨.

- `altium-mcp` `get_screenshot(view_type='sch')`
- 실패하면 `AltiumSchDoc.to_svg()` → pymupdf 로 PNG

`get_screenshot` 은 **`view_type` 을 무시하고 PCB 문서를 찾는 버그**가 있다.
프로젝트에 PcbDoc 이 없으면 모달이 뜨고 브릿지가 막힌다 (altium-library 스킬의
`references/tool-traps.md` 참조).

## 5. 보고 — 3분류를 강제한다

```
## 조치 필요      근거와 함께. 부품 지정자·핀번호까지
## 무해           왜 무해한지 근거(데이터시트 인용)
## 미확인         확인 못 한 이유 + 확인 방법
```

**"결함 N건" 만 던지지 않는다.** 실제로 후보 18건 중 조치 대상은 1건이었고,
나머지 17건은 근거를 대서 무해로 분류해야 사용자가 쓸 수 있는 보고가 된다.

숫자를 쓸 때 그 숫자가 무엇인지 명시한다. 예를 들어 "배선에 안 닿는 핀 222개" 는
**결함 수가 아니다** — 전원포트 직결·핀끼리 직결·hidden 핀이 다 들어간 숫자다.
이런 중간값을 결함처럼 보고하면 사용자가 헛고생한다.

## 프로젝트 고유 요구사항을 먼저 읽는다

회로도에는 그 프로젝트에서만 참인 제약이 있다. 일반 규칙으로 판정하면 틀린다.

- 프로젝트의 지시 파일(`CLAUDE.md`/`AGENTS.md`), 할 일 목록, 설계 노트 폴더
- 팀 위키·설계 문서에 이미 검증된 표가 있으면 그것과 대조한다

실제 예 — 어떤 칩은 아날로그 GND 중 **일부만** 메인 GND 와 분리하고 나머지는 직결이다.
어떤 전원 핀은 내부 링 탭이라 **핀별 독립 네트**여야 한다(묶으면 링을 우회해 측정이 깨진다).
둘 다 데이터시트가 아니라 **그 프로젝트 문서에만** 있는 제약이고, 일반 규칙으로 판정하면 틀린다.

> **프로젝트 고유 제약을 스킬에 적지 마라.** 여기는 범용 절차만 둔다.
> 칩·보드 이름과 그 설계값은 프로젝트 문서에 남긴다.

## 참고 파일

| 파일 | 언제 |
|---|---|
| `references/pin-verdict.md` | 후보를 판정할 때. 오탐 필터 |
| `references/altium-script-traps.md` | `run_altium_script` 쓰기 **전에** |
| `references/altium-script-snippets.md` | 검증된 DelphiScript |
| `references/net-build-notes.md` | 기하 넷 구성이 Altium 과 안 맞을 때 |

| 스크립트 | 용도 |
|---|---|
| `scripts/check_context.py` | §0 전제 (파일 최신성·애너테이션·데이터시트) |
| `scripts/audit_footprints.py` | §1 풋프린트 |
| `scripts/net_erc.py` | §1 넷 구성 + ERC 유사 검사 |

관련: 라이브러리 제작·검증은 **`altium-library`** 스킬.

