2026-06-06 (토) 개발일지
오늘의 트러블슈팅: 세 가지 프로젝트에서 맞닥뜨린 예상 밖의 발견들
오늘은 세 프로젝트에서 각기 다른 성격의 이슈를 잡았다. 게임 쪽은 컴파일 에러 해석 오해, bit-scalp는 MCP 프로세스 폭증과 트레이딩 조건 변경, demo_apps는 load-gen 정리 중 엉뚱한 볼륨을 발견한 건데 — 공통점은 처음 본 증상을 전혀 다른 방향으로 의심했다가, 실제 원인을 추적하면서 가설이 전부 갈아엎어졌다는 점이다.
게임 — quiz.gd 컴파일 에러라 생각했지만, 사실은 autoload 잡음이었다
증상 — 검증 과정에서 Identifier not found 폭탄
JLPT N2 독해 퀴즈 생성 후 quiz.gd를 --script 모드로 검증하던 중, 콘솔에 이런 에러가 수십 줄 찍혔다:
Identifier not found: PackStore
Identifier not found: ProgressStore
처음엔 새로 만든 quiz.gd가 pack_store.gd나 ProgressStore를 제대로 참조하지 못하고 있다고 생각했다. “분명 autoload에 등록했는데 왜 안 찾지?” — 이 가설 아래 _tmp_quiz_scene_check.gd와 _tmp_reading_check.gd를 추가로 만들어 참조 경로를 다시 확인했다.
단서 수집 — 기존 코드도 똑같이 뱉고 있었다
뭔가 이상했다. quiz.gd만 문제라면 기존 정상 동작하던 sword_display.gd는 멀쩡해야 하는데, 검증해보니 똑같은 에러를 뱉고 있었다. 즉, 이 에러는 --script 모드의 autoload 미탑재로 인한 공통적인 예상 잡음일 가능성이 높았다.
전환점:
sword_display.gd도 동일한Identifier not found를 내면서도 런타임에서는 정상 작동 중이었다.
원인 추적 — OK compile이 핵심이었다
로그를 다시 들여다봤다. 에러 메시지보다 중요한 한 줄이 있었다:
OK compile: quiz.gd
Godot 4의 --script 모드는 autoload 없이 단일 스크립트만 로드하므로, PackStore 같은 전역 변수를 찾을 수 없는 건 정상 동작이다. 구문 오류가 없고 컴파일만 성공하면 검증 목적은 달성된다. Identifier not found는 에러가 아니라 경고(잡음)에 가까웠다.
해결 — 검증 기준을 바꿨다
수정한 코드는 없었다. 대신 검증 방식을 바꿨다:
- before:
Identifier not found가 뜨는 걸 보고 “스크립트 깨짐”으로 판단 → 불필요한 디버깅 스크립트 생성 - after:
OK compile만 확인하고,Identifier not found는 무시 (단, 실제 게임 실행으로 최종 검증)
게임을 직접 부팅(bn14blpb2)해 autoload가 실제로 동작하는 환경에서 확인했고, 지문 패널 + 정답 피드백(+3 강화권)이 정상 동작했다.
검증 + 남은 과제
workbook의 정답 유일성 방지 로직도 추가로 완료했다. avoid 리스트를 통해 기존 3327개 문제와 비중복되는 주제 클러스터(환경/재택근무/전통공예)로 지문을 작성해 겹침을 최소화했다. 남은 건 실사용 피드백 — 극단적으로 적은 어휘 풀에서의 중복률을 모니터링할 필요가 있다.
bit-scalp — MCP 프로세스 67개에서 20개로: 진짜 보존할 대상을 가려내는 데 시간이 더 걸렸다
증상 — npm exec mcp 관련 프로세스가 수십 개 떠 있음
ps aux | grep mcp를 쳤더니 프로세스가 67개나 나왔다. 대부분 npm exec @anthropic-ai/claude-code-mcp 같은 형태였다. 처음엔 단순히 죽이면 되는 줄 알았다. 하지만 지난 세션에서 MCP를 사용 중인 Claude Code 세션이 그중에 껴 있었고, 잘못 죽이면 현재 작업 중인 세션의 텔레그램 reply / context 기능이 깨질 위험이 있었다.
단서 수집 — PPID 2951이 키였다
먼저 현재 Claude Code 세션의 PID를 추적했다. ps --ppid $$로 직접 자식 프로세스를 확인하고, pstree로 전체 계층을 그려봤다.
보존 필수 목록:
- PPID 2951 = 현재 bit-scalp Cursor 워크스페이스
- 6796 (playwright) / 14302 (context7) / 6806 (oh-my-claudecode bridge) / 6802 (telegram) + 자식들
- 이걸 죽이면 안 된다
첫 번째 시도: 단순히 pkill -f mcp를 쓰면 현재 세션도 같이 죽는다. 그래서 PPID 기반으로 분류하는 스크립트를 만들었다.
원인 추적 — 실제 분류 결과가 예상과 달랐다
분류해보니 67개 중 진짜 idle한 Claude CLI 세션이 12~4일 묵은 게 9개, Cursor 워크스페이스 잔여 프로세스가 2개, 나머지는 보존 대상이었다. 즉, 문제는 “MCP 프로세스가 많다”가 아니라 버려진 Claude CLI 세션이 수일간 쌓인 것이었다.
처음 가설(“단순 MCP 프로세스 폭증”) → 실제 원인(“오래된 Claude CLI 세션 누적”). 이 전환점에서 grep 필터를 바꿨다. npm exec만 죽이지 말고, 실행 시간이 2시간 이상인 CLI 세션만 골라 죽이는 식으로.
해결 — 2단계 정리
1차: 현재 활성 세션(37분/2.5h)만 빼고 나머지 MCP 프로세스 34개 제거 (Cursor 워크스페이스 6개 포함) 2차: 추가로 발견된 idle Claude CLI 9개 + 잔여 Cursor 2개 = 47개 추가 제거
| 항목 | 숫자 |
|---|---|
| 처음 프로세스 | 67개 |
| 죽인 PID (1차) | 34개 |
| 죽인 PID (2차) | 47개 |
| 정리 후 | 20개 (모두 보존 대상) |
변화 — allow_short에 TRENDING_DOWN 추가 + vol_mult cap
같은 맥락에서 트레이딩 조건도 변경했다. 기존에는 TRENDING_DOWN이 SHORT 진입을 허용하지 않았는데, 추가하면서 동시에 vol_mult를 0.5로 cap — 전체 잔액의 절반만 진입하도록 제한했다.
검증 + 남은 과제
봇 재시작 (PID 38983), 다음 스캔 KST 17:15. vol_mult cap이 실제로 의도한 포지션 사이즈를 만드는지는 3일 후 PDF 리포트에서 확인 예정.
demo_apps — load-gen 로컬 데이터가 69MB라고? 알고 보니 다른 프로젝트 postgres였다
증상 — load-gen의 로컬 영향력을 파악하라는 요청
load-gen 제너레이터를 정지한 뒤 “맥북 로컬에 쌓인 데이터 크기가 얼마인지”를 알아야 했다. 제너레이터는 OTLP를 원격 10서버(http://<INTERNAL_IP>:14318)로 보내고 있었기 때문에, 로컬에는 로그 정도만 남을 거라 예상했다. 하지만 docker volume ls에서 docker_pgdata가 69MB로 보였다.
단서 수집 — postgres가 의심스러웠다
처음 가설: “load-gen이 로컬 backend(127.0.0.1:8080)를 거쳐 postgres에 INSERT한 데이터가 쌓인 것이다.” 하지만 실제로 backend가 켜져 있는지, postgres 안에 어떤 테이블이 있는지 확인해야 했다.
원인 추적 — postgres를 열어보니 bitscalp였다
docker exec -it <postgres_container> psql -U postgres -c "\l"
결과: DB 이름이 bitscalp였다. 트레이딩 봇의 virtual_entries(11,909행), trades(138행), signal_features, daily_pnl 등 완전히 다른 프로젝트의 데이터베이스였다. load-gen은 backend에조차 접근하지 않고 있었다 (backend가 꺼져 있으면 load-gen 호출 자체가 실패함).
전환점: postgres 69MB가 load-gen 때문이라는 가설은 완전히 틀렸다.
해결 — load-gen 관련 로컬 데이터는 거의 없었다
실제 load-gen으로 인해 로컬에 남은 건:
- stdout 로그 (~25KB)
- 코드 디렉토리 (~68KB)
postgres는 그대로 두었다 (bitscalp 운영에 필요). load-gen 관련 볼륨은 없었다.
검증 + 남은 과제
제너레이터 정지 완료. 추후 같은 프로젝트에서 load-gen을 다시 가동할 때 이번 발견을 참고해, postgres 볼륨이 다른 프로젝트와 섞이지 않도록 네트워크 격리를 확실히 해둘 필요가 있다.
오늘의 한줄
“컴파일 에러인 줄 알았는데 autoload 잡음이었고, MCP 폭증인 줄 알았는데 Claude CLI 누적이었고, postgres 볼륨이 load-gen 거인 줄 알았는데 트레이딩 봇이었다 — 첫인상이 답이 되는 경우는 거의 없다.”