- name
- subtract
- description
- 뺄셈 — 안 풀릴 때 벤더 패치·PR·새 레이어를 제안하기 전에 다시 묻는 절차. carrier 질문을 뒤집고, 프로세스가 이미 내보내는 표면을 전부 적고, 스레드 안의 측정된 사실을 상자마다 다시 넣어 본다. '안 된다'는 결론은 두 방향·전체 표면·기각 영수증 셋이 갖춰질 때만 쓴다. 트리거: '안 풀려', '막혔어', '없다', '벤더에 없어', 'PR 넣자', '패치해야', '확장 포인트', 'upstream', 'unstuck', 'subtract', '뺄셈', '다시 생각해'.
- user_invocable
- true
# subtract — 개발은 뺄셈이다
GLG의 말: 뺄셈은 코드 양이 아니라 **해결하는 방식**을 말한다. 벤더에게 실어 달라고 부탁하기 전에, 벤더가 이미 그려 주는 것을 읽는다. 이 스킬은 "안 된다"가 나올 때 그 결론을 통과시키기 전에 반드시 거치는 다섯 질문이다.
## 언제 켜나
- "벤더 소스에 그 값이 없다"라고 쓰려는 순간
- 업스트림 이슈·PR·패치·확장 포인트 요청이 다음 수로 떠오른 순간
- 새 레이어(어댑터·supervisor·프록시·매핑 테이블)를 만들어야 풀린다고 느끼는 순간
- 같은 문제를 두 세션 이상 붙들고 있는 순간
PR은 가장 쉬운 답이라서 가장 늦게 내는 답이다. GLG의 규칙은 **2주 숙고 뒤**다.
## 짝 — `evidence-closure`
뺄셈은 문제를 **여는** 쪽이고, 닫는 쪽은 `evidence-closure`다(GLG 2026-09-23). 결함 신고에서 출발했다면 여기서 나온 뺄셈 목록과 기각 영수증이 그 폐루프 3단계(해결안·기각 근거)의 options가 되고, 고른 해법은 red → fix → green → 원 신고 조건 재검증으로 닫는다.
## 선례 — 이 스킬이 태어난 사건
entwurf #95: "Codex threadId → 그 thread를 띄운 TUI의 pane" 매핑. 두 감사가 `rust-v0.153.4`의 프로토콜 타입 표면 여섯 항목(ConnectionId, clientInfo, turn metadata, UDS acceptor, fanout, dynamic MCP)을 읽고 "벤더 소유 carrier 없음"으로 접었고, 업스트림 이슈 openai/codex#44774를 열었다.
정답은 **설정 한 줄 + 읽는 쪽 한 군데**였다. Codex TUI에는 `tui.terminal_title` 리스트가 있고 `thread-id` 항목이 이미 있다(`tui/src/bottom_pane/title_setup.rs:80-81`). TUI가 OSC 0 제목에 자기 threadId를 그리고(`tui/src/terminal_title.rs:90`), tmux는 그것을 `#{pane_title}`로, herdr는 `terminal_title_stripped`로 돌려준다. 벤더 패치 0.
설정만으로 끝나지는 않는다 — 설정은 제목에 id를 *그리게* 할 뿐이고, 매핑은 읽는 레일이 그 제목을 caller anchor로 쓸 때 선다. 뺄셈의 성과는 (a)에서 멈추는 것이 아니라 **(a)가 (b)를 한 군데로 줄이는 것**이다.
놓친 이유 넷:
1. **질문이 한 방향이었다.** "TUI → 요청"으로 값을 실어 나를 carrier만 찾았다.
"요청이 이미 아는 값(threadId)이 TUI 자리에서 관측되는가"는 묻지 않았다.
2. **사실이 다른 상자에 있었다.** 같은 스레드가 "thread title이 유일한 쓰기 가능
carrier"라고 측정해 두었지만 identity 상자에만 넣고 placement 상자에는 안 넣었다.
3. **우리 installer의 범위로 벤더 능력을 가정했다.** entwurf가 `status_line`만
소유하니 `terminal_title`이 별개라는 것도 확인하지 않았다.
4. **거절의 권위를 빌렸다.** 업스트림의 "presentation은 client-side에"라는 답은
이 해법을 가리키고 있었는데, 우리는 그것을 두 번째 요청으로 번역했다.
## 다섯 질문 — 순서대로, 전부 적는다
### 1. carrier를 뒤집어라
"A에서 B로 값을 실어 나를 길이 있나"가 막히면, 같은 깊이로 묻는다: **"B가 이미 아는 값을 A 쪽에서 관측할 길이 있나."** 두 방향을 다 적기 전에는 "없다"를 쓸 수 없다.
```text
막힌 질문: TUI seat ──carrier──▶ request _meta (없음)
뒤집은 질문: request _meta(threadId) ◀──관측── TUI가 그리는 제목 (있음)
```
### 2. 표면 목록을 먼저 다 쓴다
프로세스 하나가 세상에 내보내는 것 전부를 적고, 어느 것을 읽었는지 체크한다.
| 표면 | 예 | 읽었나 | 우리가 이미 쓰나 |
|--------------------|-----------------------------------------|--------|------------------|
| 프로토콜 필드 | request/response/notification 타입 | | |
| 프로세스 env | 자신·자식·hook·MCP child 각각 | | |
| argv / cmdline | `/proc/<pid>/cmdline` | | |
| 파일 | rollout·state db·lock·socket 경로 | | |
| **화면 밖 escape** | OSC 0/2 제목, OSC 52, OSC 9 알림 | | |
| 화면 안 | status line, footer (스크래핑은 마지막) | | |
| 로그 / analytics | tracing, event stream | | |
| 설정 표면 | config 키 전체 — 우리가 안 쓰는 키 포함 | | |
**오른쪽 열이 왼쪽만큼 중요하다.** #95에서 결정적이었던 것은 벤더가 그 표면을 제공한다는
사실이 아니라, 우리가 **이미 그 옆칸에 쓰고 있었다**는 사실이다(`status_line`의 `thread-title`을
소유하면서 `terminal_title`은 확인하지 않았다). 우리가 쓰는 칸의 **이웃**을 전부 적어라.
감사가 한 표면만 훑었다면 결론은 **"그 표면에는 없음"** 으로만 쓴다.
### 3. 스레드 안의 사실을 상자마다 다시 넣는다
측정된 사실 하나를 identity · placement · delivery · liveness 상자에 **각각** 대입해 본다. 사실이 한 상자에만 산다는 가정이 가장 흔한 누락이다. 이슈 스레드를 다시 읽을 때는 "무엇을 측정했나"만 뽑아 표로 만들고, 각 행에 네 상자를 붙인다.
### 4. 벤더 능력은 벤더 소스에서만 확정한다
"우리가 X만 쓴다"와 "벤더에 X만 있다"는 다른 문장이다. 벤더 능력 주장은 `file:line @ tag`가 붙어야 하고, 우리 installer·doctor·문서는 그 증거가 아니다. grep은 literal이 constant로 삽입되면 못 찾는다 — 방출 지점(escape 바이트, 상수 정의)에서 거꾸로 올라가라.
### 5. 뺄셈 목록의 끝에 PR을 둔다
벤더 변경을 제안하기 전에 아래 순서로 적고 **각각 기각 영수증**을 붙인다.
```text
(0) 이미 하고 있지 않은가 — 우리가 쓰는 키의 옆 항목, 우리 선언 옆의 이웃 선언
(a) 설정만으로 되는가 — config 키, 환경변수, CLI flag
(b) 우리 코드만으로 되는가 — 읽는 쪽 추가, 기존 레일에 소비자 하나
(c) 기존 관측면 조합으로 되는가 — 표면 표의 두 칸을 잇기
(d) 벤더 확장 포인트가 이미 있는가 — plugin, hook, dynamic tool
(e) 벤더 변경 요청 — 여기 도달했으면 2주 뒤에 다시 본다
```
(0)이나 (a)에서 성립하면 거기서 멈춘다. (0)~(d)에 영수증이 없는 (e)는 제출하지 않는다. (0)이 맨 앞인 이유는 이 리포에서 두 번 연속 그 모양이었기 때문이다 — #95는 소유한 키의 옆 키였고, #117은 소유한 선언의 옆 선언이었다.
## 결과물 양식
메시지 또는 이슈 댓글 한 장. 파일은 만들지 않는다.
```text
## 뒤집은 질문
원래: … / 뒤집음: …
## 표면 표 (읽음/안 읽음 · 우리가 이미 쓰나)
## 스레드 사실 × 상자 표
## 뺄셈 목록 (0)~(e) + 기각 영수증
## 결론: 성립 / 불성립(어디까지 뒤졌는지)
```
"못 찾았다"는 정직한 답이다. 단 **어디까지 뒤졌는지**가 같이 있어야 한다.
## 하지 않는 것
- 표면 표를 채우기 전에 업스트림 이슈를 열지 않는다.
- 화면 본문 스크래핑을 주소·delivery 증거로 승격하지 않는다(관측 입력까지만).
- 이전 감사자를 탓하지 않는다. 기록은 "무엇을 측정했고 무엇이 그것을 물렸는가"다.
Voir sur GitHub