- name
- a-question-back-instead-of-a-choice-means-the-menu-is-wrong
- description
- 선택지를 냈는데 사용자가 고르지 않고 **되물으면**, 그건 혼란이 아니라 **프레이밍이 틀렸다는 증거**다. 되물음은 거의 항상 내가 건너뛴 층을 정확히 가리킨다 — 답을 주고 같은 메뉴를 다시 내지 말고, **그 질문이 드러낸 층을 먼저 측정해서 지도를 그려라.** 메뉴를 두 번 되돌려받으면 결정 자체가 아직 이르다는 뜻이다. 트리거 - AskUserQuestion 응답이 물음표로 끝날 때, "그러면 X 는 어떻게 되는 거야?", "그건 Y 가 안 된다는 거 아냐?", 사용자가 옵션 대신 전제를 건드릴 때.
- version
- 1.0.0
- task_types
- ["planning","communication","investigation"]
- triggers
- [{"pattern":"AskUserQuestion 의 답이 선택지가 아니라 질문으로 돌아왔을 때"},{"pattern":"사용자가 '그러면 …는 어디로 가?' / '…가 안 되고 있단 거 아냐?' 라고 되물을 때"},{"pattern":"같은 주제로 두 번째 메뉴를 내려는 순간"}]
- category
- process
# 고르지 않고 되물으면, 메뉴가 틀린 층에 있다
## Problem
측정을 마치고 정직한 선택지를 냈다고 믿을 때가 있다.
> **seeds/ 배관을 어떻게 할까요?**
> 1. 거짓말·죽은 배관만 삭제 (추천)
> 2. 플러그인 write_seed 까지 삭제
> 3. seeds/ 스위퍼를 배선한다
사용자는 고르지 않았다.
> *"seeds가 없으면 초기 데이터는 어디로 가?"*
답을 주고 **같은 층에서 메뉴를 다시 냈다.** 또 안 골랐다.
> *"근데 그러면 초기 데이터는 저장이 안되고 있단거 아냐?"*
두 번째 되물음에서야 알았다 — 사용자가 알고 싶은 것은 *배관의 처분*이 아니라
**데이터가 저장되기는 하는가**였다. 내 메뉴는 그보다 두 층 위에 떠 있었다.
### 되물음은 혼란이 아니라 좌표다
되물음을 "설명이 부족했다"로 읽으면 **더 긴 설명 + 같은 메뉴**를 내게 된다.
그건 같은 실패를 반복하는 것이다.
되물음은 거의 항상 **내가 측정하지 않고 지나간 층**을 가리킨다. 위 사례에서
그 질문이 드러낸 것:
* 나는 "seeds/ 가 비었다"까지만 쟀고 **"그럼 데이터는 어디로 들어가나"는 안 쟀다**
* 재보니 입구는 둘이었고(bootstrap · settle), 둘 다 메모리 items 를 바로 컴파일했다
* 그리고 진짜 발견 — **원문(raw source)이 vault 에 아예 안 남는다.**
2770 artifacts 가 330 notes 만 남기고 증발했고, `bootstrap_artifacts_count` 는
저장 위치가 아니라 **개수 카운터**였다
애초 메뉴(배관 삭제 vs 배선)에는 이 발견이 들어갈 자리가 없었다. 어느 걸 골랐어도
틀린 답이었을 것이다.
## Solution
### 1. 되물음이 오면 메뉴를 접는다
다시 내지 마라. 그 질문을 **측정 과제로 바꾼다.**
```
"seeds가 없으면 초기 데이터는 어디로 가?"
→ 측정: 프로덕션에서 그 데이터를 만드는 지점을 전부 찾아라
→ 측정: 그 지점들이 무엇을 어디에 쓰는지 실물로 확인해라
→ 산출: 층별 지도 (생산자 → 저장소 → 읽는 표면)
```
### 2. 지도를 먼저 내놓는다 — 선택지는 그다음
지도가 있으면 사용자가 **스스로 다음 질문을 만든다.** 위 사례에서 지도를 내놓자
사용자는 처음으로 방향을 골랐고, 그 방향은 원래 세 선택지에 **없던 것**이었다
(*"실제 사용 과정의 요청·피드백·회고가 원본 그대로 저장되어야 한다"*).
### 3. 두 번 되돌아오면 결정이 아직 이르다
- 1회 되물음 → 내 설명에 구멍
- **2회 되물음 → 결정 자체가 시기상조.** 측정이 덜 됐다는 뜻이다.
이때 할 일은 더 나은 메뉴가 아니라 **더 낮은 층의 측정**이다.
### 4. 지도는 사용자의 언어가 아니라 실물로 그린다
문서·설계 인용 금지. prod 컨테이너의 파일과 DB 행으로.
```bash
# 디렉터리별 실물 개수
docker exec … sh -c "cd $VAULT && for d in */; do echo -n \"\$d \"; find \"\$d\" -name '*.md' | wc -l; done"
# 생성 지점이 몇 개인지 (두 번째 정의가 없는지)
grep -rn --include='*.py' "IngestCompiler(" backend/ | grep -v test
```
## Checklist
AskUserQuestion 의 답이 물음표로 돌아왔을 때:
- [ ] 같은 메뉴를 다시 내려 하고 있지 않은가
- [ ] 그 질문이 가리키는 **층**이 무엇인지 한 문장으로 적었나
- [ ] 그 층을 **실물로** 측정했나 (문서·설계 인용 아님)
- [ ] 측정 결과가 원래 선택지를 무효로 만들지 않았나 — 만들었다면 그렇게 말했나
- [ ] 두 번째 되물음이라면, 메뉴 대신 **지도**를 내놓았나
## Why it matters
선택지는 되돌릴 수 없다 — 사람은 이미 골랐다. 틀린 층의 메뉴는 사용자에게
**틀린 전제 위에서 결정하게** 만든다. 되물음은 그 사고를 막아 주는 신호이고,
그 신호를 "설명 부족"으로 오독하면 신호가 두 번째로 올 때까지 못 알아챈다.
관련: [[confirm-the-premise-before-offering-the-choice]] (선택지를 내기 **전에**
코드로 확인하라 — 이 스킬은 그 **다음** 국면, 이미 낸 뒤 되물음을 받았을 때다) ·
[[build-the-missing-link-not-the-missing-system]] (지도를 그리면 큰 트랙이 배선
하나로 줄어든다) · [[audit-findings-need-remeasurement-before-acting]]
---
## Case: 되물음이 내 **추천안이 결함을 키웠을 것**임을 드러냈다 (BSVibe 2026-09-02)
이 변종이 가장 값비싸다. 메뉴가 단지 층을 잘못 잡은 게 아니라, **추천 옵션을 실행했으면
결함을 더 크게 만들었을** 경우다.
배경: 프레이머가 작업을 어떤 단계로 나눌지 판단할 때 읽는 설명이 라우팅 규칙에서
왔고, prod 에서는 그게 `"설계 단계는 opus로"` 였다. 나는 이렇게 물었다:
> **`source_text` 를 채울까요?** 그러면 프레이머가 모델명 대신 일의 성격을 읽습니다.
사용자는 고르지 않고 되물었다:
> *"stage가 왜 따로 있어? 설계 단계 == opus 는 자연어잖아. 그래서 일부러 정적인
> stage 를 만들지 않고 사용자의 라우팅 규칙을 미리 읽어서 활용하려는 거였는데?"*
그 한 문장이 내 메뉴 전체를 무효화했다. 측정해 보니:
| 내 메뉴의 전제 | 실제 |
|---|---|
| 사용자가 `source_text` 를 **안 채운** 설정 공백 | `compile → apply` 경로에 그 **필드 자체가 없다** — 주 경로가 원문을 버리는 **결함** |
| 채우면 일의 성격을 읽는다 | `source_text` 는 **조건이 컴파일돼 나온 원문**이라 필연적으로 모델을 지목한다 |
⇒ **내 추천안을 실행했으면 모델명이 든 문장을 더 잘 보이게 만들었을 뿐이다.**
올바른 수정은 정반대 방향 — 설명 필드를 **지우는 것**이었다(라벨이 이미 사용자의 말).
그리고 두 번째 되물음(*"근데 그거는 프레이머가 모델도 알고 있단거야?"*)이 결함의
**심각성**까지 드러냈다: 프레이머의 출력 스키마에는 모델 필드가 없으므로, 그 정보로
할 수 있는 유일한 일이 *"어려우니 opus 받게 design 이라 부르자"* — **라벨 선택을 통한
모델 결정**이었다. 코드가 *"두 번째 라우팅 권한은 없다"* 고 못박은 바로 그것. 쓸 수
없으면서 **우회로만 만드는** 정보였다.
### 왜 내가 놓쳤나
측정은 했다 — `source_text` 가 null 인 것도, 설명이 이름으로 폴백하는 것도 확인했다.
그런데 **"왜 null 인가"를 안 물었다.** 값이 없으면 반사적으로 *"사용자가 안 채웠다"*
로 읽었고, 그러면 남는 행동은 "채우기"뿐이다. **부재를 사용자 탓으로 읽는 순간
메뉴는 이미 한쪽으로 기운다.**
### 판별기
```bash
# 설정 값이 비어 있을 때, "안 채웠다"고 결론내기 전에 채우는 경로를 찾아라
grep -rn "source_text" --include="*.py" backend/ | grep -v test
# → 쓰는 곳: 단일 create 만. compile→apply 의 wire 스키마엔 필드가 아예 없다
# → 사용자가 안 채운 게 아니라, 주 경로가 나를 수 없었다
```
**규칙**: 설정 필드가 비어 있으면 **그 필드를 채우는 경로를 전부 열거**하고, 사용자가
실제로 쓰는 경로가 그중에 있는지 확인해라. 없으면 그건 설정 공백이 아니라 결함이고,
"채우세요"는 결함 위에 얹는 우회로다.
### Red flag (addition)
- 사용자에게 *"이 값을 채울까요?"* 를 물으려는 순간. 먼저 **왜 비어 있는지**를 물어라.
- 사용자가 옵션 대신 **설계 의도**를 설명하기 시작할 때 — 그건 내 메뉴가 그 의도와
어긋난다는 뜻이다.
View on GitHub