gptbutler — ChatGPT 앱 비서 (handoff)
ChatGPT 공식 앱을 창구로 삼아, 내 자산(PFS·user_brief·GitHub·
C:\dev)을 MCP 서버 1개로 노출한다. PC = 데스크톱 앱(Codex 모드) 로컬 stdio(터널·인증 불필요) / 모바일 = 원격 HTTPS 커넥터. 역할 = 조회 · 브리핑 · devplan 매니저(현업↔AI개발 균형 조절). 서버는 신규가 아니라C:\dev\tools\cody-mcp-gateway확장.
🔶 루트 NOW 이관 — 진행·미결 (2026-08-19 대청소, 페페 지시)
루트
HANDOFF.md를 pncad 만 남기고 비웠다. 아래는 그때 옮겨온 원문(문구 무변경).
- 🆕gptbutler P0/P1 [코디] 26.8.4 ✅P0 전량 + P1 일부 완료 — 매니저가 한 바퀴 돈다. 확인 창구 = devplan
ai-stack-map.html최상단 진행상태(정적 JSON+10초 폴링, 8799 재시작 불필요) — 18항목 중 완료 7·페페차례 3·보류 1·대기 7. ①P0-1 가드레일 =runner.py스폰 시--disallowedTools18개(broker 독립) — 🔑claude -p6회 실측으로 문법 확정(경로는Edit(path)만 먹고Write(path)는 무시·도구명만 막으면 Bash로 우회·MultiEdit은 없는 도구), 🔴남은 구멍 =python -c우회는 통과(차단목록은 증명이 아니다). ②P0-2 배선 =run_claude_code_task(card=…)로 카드→승인→실행→상태갱신 폐루프(새 툴 0·9개 상한, 상태는 CLI 경유,next_owner=페페카드 실행 거부). ③P1-1mem_find주입·P1-3 사후계측·P2-2 호출부 대조표·현업 P0-1 회귀테스트 선행 규칙화. 🔴P2-2에서 발견 = poin-agent watcher만 도구 제한 0(셋 중 모델이 파일을 쓸 수 있는 유일한 호출부 — "도구 0"은 MCP 이야기였고 내장 도구는 열려 있다) → 현업 P0-4 신규·페페 승인 후(상시 데몬). ⏸판정 가중치는 페페 보류(priority_rules.md). handoff 정리 = 31.9KB→8.9KB(완료 서사 10절 →archive.md). ⏳페페 = ①P0-1 구멍 택1 ②P0-4 승인 ③보류 결정 3건. ⏳다음 = 현업 P0-2 관측 → P0-3 임계치 → 개발 P1-4. →projects/gptbutler/session-2026-08-04-p0-1-spawn-guardrail.md - 🆕gptbutler 26.8.2 신규 — ChatGPT 앱 비서(MCP) + devplan 매니저. PC=Codex 로컬 stdio / 모바일=커넥터(P2). 매니저=페페의 아바타(승인은 사람 몫), 완료 목표=완성도 모델(범위×차수·단계×회차·퍼센트 금지), 목업 v4=단계 게이지+회차 배지 채택→진행판 가동. ✅26.8.3 P0 코디 몫 완료 — 가드 구멍 2건 봉합(
gpt_tools.py+ 회귀 GUARD OK, 실파일 종단 확인) · gateway venv 재생성(py3.14 preview 삭제로 죽어 있었음,mcp<2핀 — 2.0.0이 fastmcp 1.x API 제거) ·~/.codex/config.toml직접 편집으로 STDIO 등록 →codex exec가 gateway_doctor 실호출 성공. 🔑헤드리스 제약 실측 = codex exec의 MCP 툴은 자체 승인에 걸려 즉시취소,--dangerously-bypass-approvals-and-sandbox에서만 실행(relay codex 백엔드도 동일 — broker 게이트는 gateway 안에서 유지). ✅P1 조회툴 2종(brief_today·portfolio_review) 탑재 — codex 종단 실브리핑 수신(gateway 8b1d2ed). ✅26.8.3 P0 완전 통과(페페 실측) — 텍스트+음성 모두 비서 작동, 음성→MCP 도달 확정. ⏳다음 = P1 잔여(판정층, 코디). →projects/gptbutler/handoff.md
🆕 NOW (2026-08-04) — P0 전량 + P1 일부 완료 (진행상태는 페이지 최상단에서 본다)
단일 확인 창구 = devplan ai-stack-map.html 최상단 진행상태 블록(ai-stack-map-progress.json + 10초 폴링, 8799 재시작 불필요). 현재 18항목 = 완료 7 · 페페 차례 3 · 보류 1 · 대기 7(개발 6/9 · 현업 1/9).
- ✅개발 P0-1 가드레일 —
runner.py가 스폰 시--disallowedTools18개(broker 독립). 🔑경로 규칙은Edit(path)만 먹는다(Write(path)는 무시·CLI 경고), 도구명만 막으면 Bash로 우회됨,MultiEdit은 없는 도구 — 전부claude -p6회 실측. 🔴남은 구멍 =python -c인터프리터 우회는 통과(차단목록은 증명이 아니다). - ✅개발 P0-2 배선 —
run_claude_code_task(card=…)카드 모드로 카드 → 승인 → 실행 → 상태갱신이 한 바퀴 돈다. 새 툴 0(9개 상한), 상태는project_state.pyCLI 경유(운영규칙이 코드로 강제), stage 무변경,next_owner=페페카드는 실행 거부. - ✅개발 P1-1 창고 검색 — 카드 지시문에
mem_find(FTS5) 결과 주입. ⚠색인 5분 주기라 브리핑 통짜읽기는 병존. - ✅개발 P1-2 상태 자동화(P0-2에 포함) · ✅P1-3 사후 계측(
_spawn_metrics.jsonl) · ✅P2-2 호출부 3곳 대조표(docs/headless-call-sites.md). - ✅현업 P0-1 — PROMPT 수정 시 회귀테스트 선행을
rules.md+watcher.py주석에 못박음(코드 로직 0). - ⏸개발 P0-3 판정층 = 페페 보류(가중치는 페페 의견+매니저 문맥 판단) →
devplan/priority_rules.md"⏸ 보류 중인 규칙 결정"에 사유·재개조건·실측 근거. - 🔴P2-2에서 발견 = 안전은 "도구 × 훅" 두 축인데 poin-agent watcher만 도구 제한 0 — 셋 중 모델이 파일을 쓸 수 있는 유일한 호출부다. "도구 0"은 MCP 도구 이야기였고 내장 도구는 열려 있다(매트릭스 8층 근거가 절반만 맞았다) → 현업 P0-4 신규, 상시 데몬이라 페페 승인+드라이런 후 착수.
- ⏳페페 = ①P0-1 남은 구멍 택1(그대로/허용목록/broker 규칙) ②P0-4 승인 ③보류 결정 3건(가구지식 태그 기준·KB 인계 범위·대화 채널 순서).
- ⏳다음 순번 = ①현업 P0-2 관측 ②현업 P0-3 임계치 ③개발 P1-4 되먹임 ④현업 P1-2 비전 ⑤현업 P1-3 학습 ⑥개발 P2-1 ⑦현업 P2-1. 병행 = 개발↔현업(리포가 달라 안 막힘), 순차 = 축 내부.
- →
session-2026-08-04-p0-1-spawn-guardrail.md·archive.md(완료 서사 원문)
확정 (그릴링 8건, 2026-08-02 — 재논의 금지)
| 항목 | 확정 |
|---|---|
| 보이스 경로 | 하이브리드 — 텍스트=커넥터, 보이스=사전 브리핑 주입(추가 과금 0) |
| 노출 | Cloudflare Tunnel (고정 도메인·자동 TLS). PC 상주 전제 |
| 인증 | 비공개 URL(경로 토큰) + 서버측 검증, 커넥터는 "무인증" 등록 |
| 쓰기 | 기존 cody-permission-broker(위험도 분류 + Telegram 승인) 재사용 |
| 1차 범위 | PFS 업무조회 / user_brief·devplan 문서·결정 검색 / 작업·아이디어 등록(쓰기) / 코드·리포·로그 조회 |
| PFS 경로 | PFS REST API 재사용 (POST /api/auth/login → 세션 → API) |
| 코드 위치 | cody-mcp-gateway 확장 (원격 HTTPS 트랜스포트 + 조회 툴) |
| 브리핑 시작 | 같은 대화에서 텍스트 호출 → 음성 버튼 전환 |
확정 2차 — devplan 매니저 (같은 날 추가 지시, 4건)
| 항목 | 확정 |
|---|---|
| 분류 | 기존 5카테고리 유지 + 카드에 biz(direct/indirect/experiment) 1줄 추가. 카테고리는 신규 프로젝트에 맞춰 수정 가능 |
| 순위 원리 | 2트랙 균형 모델 — 단일 순위표 금지. 현업/개발을 따로 뽑고 배분 자체를 감시 |
| 리듬 | 요청 시 1콜 + 주 1회 주간리뷰 자동 생성(weekly-review.html append) |
| 쓰기 | 파일 직접 수정 금지. 추천 + 코디 지시문까지 생성, 승인 시 task_run으로 전달 |
- 페페 진단 = "나는 사람이고 현업과 AI개발을 병행해야 한다. 두 길 위에서 균형을 조절해줄 비서가 필요하다." → 순위 문제를 배분 문제로 바꿔 푼다.
[페페] 현업·개발 정의 확정 (2026-08-02) — devplan은 개발 보드다
| 구분 | 정의 | 어디서 |
|---|---|---|
| 현업 | PFS·poin-agent·furniture-expert 등 실 업무 자동화를 실제로 활용하는 일(만드는 게 아니라 쓰는 것) | devplan에서 다루지 않는다. 현재 창구=PFS, 별도 현업 대시보드는 추후 신설 후보. 매니저는 PFS API로 신호만 읽음 |
| 개발 | 가구·자동화·AI에 두루 걸친 만드는 일 | devplan 카드 34개 전부 |
- 현업/개발은 카드 필드가 아니라 원천이 나눈다 → 초안의
biz(direct/indirect/experiment) 폐기. - 개발 1차 분류 =
dev_track2값:pfs-furniture(가구·PFS 직결) /tool(그 외 도구·프로젝트). 카테고리는 하위 표시축으로 유지(추가·개명 자유).
[코디] 균형 목표 재수립 — 시간 비율을 버리고 순환을 본다
"현업 60:개발 40"은 현업 실행 시간을 devplan이 볼 수 없어 근거가 없었다. 새 정의에서 현업과 개발은 경쟁이 아니라 공급-수요 관계(현업의 병목 → 개발 백로그 → 결과물이 다시 현업에서 활용)다. → 감시 대상을 "시간을 어떻게 쪼갰나"에서 "순환이 도는가"로 바꾸고, 목표는 측정 가능한 것에만 건다.
| # | 목표 | 측정 | 경보 |
|---|---|---|---|
| A(핵심) | 환류 — 만든 것이 실제로 쓰이는가 | live 카드별 최근 30일 사용 흔적(스케줄러 실행 기록·로그 mtime·산출물 갱신일). 전량 자동은 불가 → 나머지는 "확인 필요" 표기 | live인데 30일 흔적 0 = 헛돈 개발 후보 |
| B | 개발 갈래 배분(가구·PFS : 도구) | 최근 2주 세션문서 수 × dev_track — devplan 안에서 정확히 측정 |
기본값(가정) 60:40, ±15%p |
| C | 유입 — 현업의 고통이 개발로 올라오는가 | PFS·poin-agent 판정 항목 중 백로그 미이관분의 체류일수 | 판정만 되고 7일째 착수 0 |
현업 실행량에는 목표를 걸지 않는다(측정 근거가 근사뿐 → 거짓 경보). A·C가 현업을 대리한다. 현업 대시보드가 생기면 A·C를 실측으로 대체.
[페페] 초안 수정 (2026-08-02) — 수치형 순위의 cold start
초안은 순위를 이력 수치(정체일수·마감 D-N·세션 수)로 만들었다. 그러면 신규 작업이 구조적으로 하위에 깔린다 — 방금 생긴 일은 이력이 0이라 어느 규칙에도 안 걸리는데, 현장에서 방금 터진 문제나 통화로 막 확정된 납기가 대개 제일 급하다. → 2층 분리로 수정.
| 층 | 하는 일 | 근거 |
|---|---|---|
| 판정층(순위 생성) | "이게 지금 얼마나 중요한가" | 문맥 판정 — poin-agent(현장 급박도: 통화·카톡·PFS 실황) / furniture-expert(도메인 영향: 제조·납기) / 코디(기술 병목·비용: 코드·의존). 3축 라벨 + 근거 1줄. 이력이 없어도 판정된다 |
| 배분층(가드레일) | "어느 트랙에 시간을 쓰고 있나" | 수치 — 편향 경보·방치 감지·예산 잔량. 순위를 만들지 않고 감시만 |
- 판정 트리거 = 등록 즉시 자동(페페 확정).
note_add·신규 카드·PFS 이벤트로 항목이 생기면 바로 돈다. 비용 가드 = 라우터가 판정자를 골라 보통 1~2콜(최대 3), 잡담·중복은trivial로 끊음. 실패는 재시도하지 않고 "미판정"으로 상단 노출. - 저장 =
devplan/priority_state.json(항목별 중요도·3축 라벨·근거·판정자·판정일). 코디가 쓰고 매니저는 읽는다 —projects.json은 건드리지 않는다. - 재판정 = 7일 경과 · 상태 변경 · 현장 이벤트 중 하나. 리뷰에는 판정일 병기.
- 순위 규칙(
priority_rules.md, 사람이 편집) = ①판정 '현장 급박도 높음'(신규 포함, 이력 무관 — cold start를 막는 자리) ②현업 마감 임박 ③병목 ④90% 마무리 ⑤60일 방치 정리 / 트랙 예산 초과분은 다음 슬롯, 단 ①②는 예산 무시. - 갈래 목표 기본값(가정) = 가구·PFS 직결 60 : 도구·기타 40, ±15%p면 경보. 미확정 제안값 — P1 착수 전 확인 필요.
[페페] 기록 주체 표기 (2026-08-02) — 비서를 열기 전 선행
코디·GPT 병행으로 파일 기록에서 누가 쓴 것인지 혼선이 생긴다 → 모든 기록 문서에 작성자 태그. 표기 = [코디]/[GPT]/[페페](SARA 노션 컨벤션 승계), 위치 = 항목 단위 접두(sessions.md 각 줄·handoff NOW 항목·ideas.md append·archive 이관 항목), 세션문서는 제목 줄에 — 기록: [코디] 1회. frontmatter 금지(No frontmatter 유지). 발화 주체 우선(페페 지시를 코디가 옮겼으면 [페페]). 자동화 기록은 도구명([relay]).
전역 규칙 원본 = user_brief/rules/workflow.md "작업 원칙"에 기록 완료. 이 프로젝트 적용 = note_add가 남기는 줄은 자동 [GPT], task_run이 코디를 돌려 만든 기록은 [코디], 판정 judged_by도 같은 어휘.
🔑 플랫폼 제약 (재조사 금지 — 결론만. 2026-08-02 확인)
⚠ 초안 정정 — "음성모드엔 커넥터가 없다"는 웹·모바일 커스텀 커넥터에만 해당했다. 데스크톱 앱은 다르다. 페페 지시로 Codex 경로를 확인해 계획을 2트랙으로 재편했다.
- 데스크톱 앱(Codex)은 로컬 stdio MCP를 직접 등록한다 — 설정 → MCP servers → STDIO/Streamable HTTP,
~/.codex/config.toml에 저장되고 데스크톱 앱·Codex CLI·IDE 확장이 설정 공유. → PC 경로는 터널·인증·경로토큰이 전부 불필요. - 데스크톱 음성이 Codex를 지휘한다(2026-07-23~, Win/macOS, Plus 포함). ✅[페페 실측 26.8.3] 음성 대화가 MCP 툴까지 도달한다 — Codex 모드 음성으로 비서 툴(brief_today 등) 작동 확인. P0 실측 항목 해소.
- 웹·모바일 커스텀 커넥터는 음성 모드에서 동작하지 않는다 → 모바일 음성에는 브리핑 주입 유지.
- 모바일에는 로컬 stdio가 없다 — 원격 HTTPS 커넥터만. 모바일을 포기하지 않는 한 터널+HTTP 트랜스포트는 필요하나 P2로 후순위.
- 모바일 앱은 쓰기 액션 비활성 — 이동 중에는 읽기·브리핑만 된다고 전제.
- GPT-Live 음성은 30~40분에 컨텍스트 한계로 끊긴다(session-relay 조사, OpenAI 헬프센터 명시·수치 비공개) + 음성 세션 딥링크가 없어 자동 인계 불가 → 브리핑은 언제든 1콜로 재생성 가능해야 한다.
🔁 session-relay 통합 (2026-08-02 — 그쪽 Codex v1 설계 확정분과 결합)
두 프로젝트는 역할이 다르고 Codex 표면이 같다. session-relay = Codex 세션 자동 인계(codex exec 체인), gptbutler = 사람이 Codex와 대화(MCP 툴). 공유하는 것은 셋뿐이고 코드는 각자 리포에 남는다.
- MCP 설정 공유(공짜 통합) —
~/.codex/config.toml의 MCP 서버는 데스크톱 앱·CLI·IDE 공통 → gateway를 한 번 등록하면codex exec체인이 돌린 무인 세션도 같은 툴(PFS·문서·코드 조회)을 그대로 쓴다. task_run백엔드 2개 — 대화형=claude -p, 무인 장시간=relay.py --target codex. 체인상한(12h/5회)·텔레그램 승인·"중단" 지시는guard.py무수정 공유. codex 백엔드 연결은 session-relay v1 완성 후(선행 의존).- 사용량 지표 — codex는
rate_limits.primary.used_percent자체 보고, Claude는/usage역산 → 매니저 주간리뷰에 "개발 예산 잔량"으로 함께 싣는다. ⚠usage는 비용 지표지 컨텍스트 잔량이 아니다(GPT 상의 결론) — 두 숫자를 섞지 않는다. - 고정 vs 동적 분리 — AGENTS.md=고정 컨벤션 / 인계문·툴 반환값=동적.
priority_rules.md도 고정 쪽. ⚠.chatgpt-projects/g-p-*/AGENTS.md는 앱이 덮어쓰는 읽기전용 미러라 주입 채널로 쓰지 않는다. - 음성 30분 벽 — session-relay의 발단이 GPT-Live 30~40분 컨텍스트 한계였고, 음성 세션 자동 인계는 비범위로 확정(시작·재개 딥링크 없음) → gptbutler는 "끊기면
brief_today1콜로 재시작"으로 우회.
재조사 금지(session-relay 실측 완료): 딥링크 codex://new?prompt= 프리필 성공 · codex exec --json 이벤트 스트림과 -o 파일 · rollout jsonl 경로 · app-server daemon Windows 전면 불가 · state_5.sqlite threads 지연 삽입(검증 소스 부적합) · 앱 번들 alpha exe 대신 standalone codex + 버전 핀.
불변 핵심
- 브리핑과 매니저가 킬러툴이다 — 나머지 툴이 늦어도 이 둘이면 비서가 성립한다.
- 매니저는 아바타다 — 순위만 알려주고 끝나지 않는다. 계획→승인→완료 목표→추진→갱신→보고를 완료까지 끌고 간다. 단 승인은 사람 몫.
- 매니저는 단일 순위표를 만들지 않는다 — 34개를 한 줄로 세우면 현업이 다 먹거나 개발이 다 먹는다. 트랙별로 뽑고 배분을 감시.
- 수치로 순위를 만들지 않는다 — 이력 수치는 신규 항목을 구조적으로 묻는다. 순위는 문맥 판정(poin-agent·furniture-expert·코디), 수치는 가드레일.
- 매니저는 파일을 고치지 않는다 —
projects.json은 허브 전체의 단일 원천. 판단은 GPT, 손은 코디. - 툴 9개 상한 — 툴이 늘면 오선택·프롬프트 비용이 늘어난다. "조회 축 하나 = 툴 하나".
- 읽기 툴의 가드(허용 루트·비밀파일 차단·마스킹)는
agent-dialogue-hub/hub/adapters/gpt_tools.py가 원본 → 복제 금지, import 재사용. - session-relay와 합치지 않는다 — 공유는 MCP설정·guard·사용량 지표 셋뿐. 세션 수명 관리는 그쪽, 비서 인터페이스는 이쪽.
- 관련: session-relay(Codex 세션 인계·
codex execv1) · callbot(브리핑 주입 원칙 원본·GPT Live) · voicecody(로컬 음성) · cody-mcp-gateway(서버 골격) · cody-permission-broker(승인 게이트).
아카이브 (완료된 작업 서사 — 원문은 archive.md)
- (2026-08-04) — ✅P0-1 완료: 스폰 세션 파일쓰기 가드레일
- (2026-08-04) — 3차 정리: 기반↔제품 분리 + 라이브 대화 접점 + 그림 3장
- (2026-08-04) — GPT 비서 1주기 완주: 상의 → 인계 → 본문 반영 (2차 정리)
- 🆕 (2026-08-04) — GPT 비서 배관 구축: 기획서 읽기 + 구역별 말풍선 실시간 반영 (임시작업)
- 🆕 NOW (2026-08-04) — AI 12층 지도로 자산 실사 → 개발축 개선안 8항목 (기획서)
- 🆕 NOW (2026-08-03) — 🟢 P0 완전 통과, 비서 가동 개시
- [페페] devplan 허브 개선 목업 + 심사 대시보드 폐기 (2026-08-02)
- ✅ P0 코디 몫 완료 (2026-08-03) — 가드 봉합 + Codex STDIO 등록·실호출 성공
- ✅ P1 조회 툴 2종 탑재 (2026-08-03) — 비서 첫 실동작
- 다음 = P0 페페 몫 → P1 잔여
→ 원문 = projects/gptbutler/archive.md · 세션 색인 = sessions.md