13.7 KB · 수정 2026-08-04 22:17
목차

2026-08-04 세션 — P0 착수: P0-1 스폰 가드레일 + P0-2 카드↔실행 배선 [코디]

페페 지시 = "판정 가중치는 관리페이지 관리항목으로 넣어놔라. 내 의견과 devplan 매니저의 문맥적 파악으로 결정하겠다. 당장은 규칙 지정 보류다. P0부터 이제 작업 시작해." → 개발 축 P0-1(파일쓰기 가드레일) 착수. 기획서 = devplan ai-stack-map.html 8절.

논의·대안

메운 구멍 — task 단계 승인은 broker(7777)에 연결돼 있는데(runner.py:7,34,47), 실행 중 개별 툴콜은 전역 훅 whitelist.classify()_is_ops_file이 아니면 전부 AUTO_ALLOW라 파일쓰기에 사실상 게이트가 없었다.

결정 — 문법을 추측하지 않고 실측으로 확정했다

claude -p 종단 6회를 돌려 규칙 문법을 확인한 뒤에 코드를 썼다. 추측했으면 조용히 안 걸리는 규칙을 넣을 뻔했다.

실측 결과
--disallowedTools Write 로 파일 생성 요청 🔴막히지 않는다 — 모델이 Bash로 우회해 파일을 만든다
Write + Bash + Edit 동시 차단 ✅ BLOCKED, 파일 없음
Write(ops/**) 경로 규칙 🔴무시된다. CLI가 경고까지 찍는다 — "only Edit(path) rules are ... Edit rules cover all file-editing tools"
Edit(**/ops/**) 경로 규칙 ✅ 차단 경로만 BLOCKED, 다른 경로는 정상 생성
Bash(rm:*) 콜론형 / Bash(rm *) 공백형 ✅ 둘 다 차단. 설정파일 문법과 같은 콜론형으로 통일
MultiEdit 없는 도구다 — CLI가 "matches no known tool" 경고 → 목록에서 뺐다

🔑핵심 함정 = 경로 규칙은 Edit(...)로만 쓴다. 기획서 문구(Edit/Write/MultiEdit)를 그대로 옮겼으면 Write(경로) 규칙이 조용히 무시되고, MultiEdit 경고까지 떴을 것이다.

산출물

검증

다음

⏳ 페페 결정 1건 — 남은 구멍을 닫을까 1. 그대로 둔다(추천) — 스폰 세션은 우리가 낸 지시로만 돌고, task 단계 broker 승인이 앞단에 있다. 구멍은 "실수"가 아니라 "우회 의지"가 있어야 열린다. 2. 허용목록 모드--allowedTools로 도구를 좁힌다. 진짜로 닫히지만 범용 작업 러너가 자주 막힌다(운영 부담). 3. broker에 Bash-ops 규칙 추가 — 명령문에 ops 경로가 보이면 텔레그램 승인. 페페 대화형 세션도 같이 걸린다(그래서 이번엔 안 했다).

코디 잔여 = P0-2(카드↔실행 배선). P0-3(판정층)은 가중치 규칙이 페페 보류라 규칙기반 1차는 세우지 않고 대기.

관계


P0-2 — 카드 ↔ 실행 배선 (같은 세션, 26.8.4) [코디]

페페 지시 = "다음 작업 진행하고 ai stack map 페이지 최상단에 진행상태 표시해. 거기서 진행상태를 확인할게."

메운 구멍 — 실행 통로(run_claude_task)도 상태층(project_state.py)도 둘 다 이미 있었다. 없던 것은 그 사이를 잇는 코드다(카드↔실행 grep 0건). 그래서 매니저가 "이름만 매니저"였다.

설계 결정 3개 1. 🔑새 툴을 만들지 않았다 — 게이트웨이 툴 9개가 상한이다(handoff 규약). run_claude_code_taskcard 인자 하나를 붙여 카드 모드로 돌린다. 툴 수 그대로 9. 2. 상태 갱신은 JSON 직접 쓰기가 아니라 project_state.py CLI 호출 — 운영규칙(보류=사유+재개조건, 회차+1=--why)이 그 CLI에 코드로 강제돼 있다. 우회하면 규칙이 죽는다. 3. 단계(stage)는 안 건드린다 — 단계 전환은 페페 승인 영역. 카드 모드는 진행 보고만 남긴다.

동작card 주면 ①카드의 next_action·이번 회차 기준·설명으로 지시문을 만들고 ②기존 위험분류+broker 승인을 그대로 타고 ③--disallowedTools(P0-1)가 걸린 세션으로 실행한 뒤 ④성공했을 때만 카드에 진행 보고를 되돌려 쓴다.

사람 몫을 대신하지 않는다(방어 3종) - 보류 카드 → 실행 거부(사유·재개조건을 그대로 돌려준다). - next_owner == pepe 카드 → 실행 거부. 페페 결재가 필요한 걸 코디가 대신 눌러버리면 승인 게이트가 무의미해진다. - 없는 카드 → 후보 이름과 함께 거부. - dry run은 상태를 갱신하지 않는다 — 안 돌린 것을 진행으로 적으면 카드가 거짓말을 한다.

🆕 페이지 최상단 진행상태(페페 지시) — ai-stack-map-progress.json + 10초 폴링. 🔑정적 JSON으로 구동한 이유 = devplan 8799는 상승권한이라 코디가 재시작할 수 없다. 라우트를 새로 만들었으면 페페가 재시작할 때까지 죽은 코드였다(design-refs catalog.json·말풍선 notes.json과 같은 선례). 항목을 끝내면 코디는 JSON의 status·note만 고친다. - 17항목 = 개발 9 + 현업 8. 축별 (완료/전체) 헤더 + 상단 요약 칩(완료·페페 차례·보류·대기·전체). - 남이 쓴 텍스트는 textContent로만 넣는다(innerHTML 금지).

검증 - butler_tools._selfcheck_cards() — 없는카드·페페몫·보류 방어 + 지시문 생성(카드 맥락·추가 지시 포함) PASS(기존 selfcheck에 연결). - E2E dry runcard='gptbutler' → 지시문 생성·decision=allow·state_update="상태 갱신 안 함(dry run)" 확인. card='ai-stack-map'(페페 몫) → blocked. 인자 둘 다 없음 → invalid. - 상태 갱신 실경로 확인card_progress('gptbutler', …) 실행 → 카드 report·last_progress 실제 갱신됨(CLI 경유). - 실브라우저 — 진행상태 17행 렌더 · 축 헤더 개발 3/9 현업 0/8 · 요약 칩 · 페이지 가로스크롤 0 · 13px 미만 0 · 최상단 위치(스크롤 0에서 sticky 헤더에 안 가림: hdr 120 < prog 136) · 콘솔 = favicon 404뿐. - 게이트 = check_theme/check_font FAIL 0 · runner/plan_tools selftest PASS · 모듈 임포트 정상.

남긴 것(정직하게) - 🔴대시보드 댓글(app.py QA봇) → 실행 경로는 안 이었다. app.py에 라우트를 넣으면 8799 재시작 전까지 죽은 코드다(코디는 재시작 못 한다). 지금 배선의 입구는 매니저(Codex) 쪽이고, 댓글 입구는 페페가 재시작할 때 붙이는 게 맞다. - 카드 모드는 한 번에 한 카드다. 큐·병렬은 안 만들었다(YAGNI).

다음 = 개발 P1-1(mem_find 연결) 또는 현업 P0-1~3. P0-3은 가중치 보류라 대기.


3차 묶음 — P1-1 · P1-3 · P2-2 · 현업 P0-1 (같은 세션) [코디]

페페 지시 = "projects/gptbutler/handoff.md 정리하고, 나머지 진행가능한 항목들은 병행 및 순차 계획 잡아서 작업 진행해."

handoff 정리handoff.md 31,930 → 8,919 bytes(h2 16 → 7). 완료된 작업 서사 10절을 archive.md로 원문 cut + handoff엔 제목 목록만. archive.md register_doc 등록(229엔트리, 검증 OK). 유실 검사 = 이관 10절 본문 전부 archive에 존재 확인. ⚠남은 8.9KB는 시드 권장(6KB)을 넘지만 전부 "재논의 금지"로 못박은 확정 사항(그릴링 8건·매니저 확정 2차·플랫폼 제약·session-relay 통합·불변 핵심)이라 더 자르지 않았다.

계획 = 병행 2트랙 · 축 내부는 순차 - 병행 가능 = 개발 축(gateway·devplan) ↔ 현업 축(poin-agent) — 리포가 달라 서로 안 막는다. - 순차 제약 = 현업 P0-1(테스트 게이트) → P0-2(관측) → P0-3(통짜주입)(관측이 있어야 P0-3 전후를 숫자로 본다) · 개발 P1-4는 P0-2 뒤. - 이 계획은 ai-stack-map-progress.json_plan 필드에 박아뒀다(다음 세션이 그대로 읽는다).

이번에 끝낸 4건 1. ✅개발 P1-1 — 창고 검색기 연결. search_memory()mem_find.py(FTS5)를 부르고, 카드 모드 지시문에 과거 기록을 주입한다. 실측 809자 회수. ⚠색인 5분 주기라 방금 쓴 건 안 보인다 → 브리핑의 통짜읽기는 그대로 둔다(덤이지 대체가 아니다). 검색 실패는 조용히 무시 — 참고자료 때문에 실행이 막히면 안 된다. 🔑PYTHONUTF8=1을 subprocess env에 넣었다(한글 print cp949 사고 예방). 2. ✅개발 P1-3 — 스폰 세션 사후 계측. _spawn_metrics.jsonl에 소요초·rc·출력크기·timeout·task 앞 80자. 실시간 릴레이는 안 만들었다(헤드리스는 끊을 방법이 없어 과설계). selftest는 임시파일로 형식만 확인해 실제 로그를 더럽히지 않는다. 3. ✅개발 P2-2 — 헤드리스 호출부 3곳 대조표 (docs/headless-call-sites.md). 공용 wrapper는 안 만든다(세 곳의 목적이 다르다), 동기화 체크리스트로 쓴다. 4. ✅현업 P0-1 — 회귀테스트 선행 규칙화. rules.md 1항목 + watcher.py PROMPT 정의부 바로 위 주석 4줄. 코드 로직 변경 0. 테스트(test_watcher_rules.py 8항목) 통과 재확인 + 구문 검사.

🔴 P2-2 표를 만들다 나온 발견 — 안전은 "도구 × 훅" 두 축이다

gateway runner devplan QA봇 poin-agent watcher
도구 제한 차단목록 18 전면 차단(답변 전용) 🔴없음
훅(broker) 살아 있음 꺼짐(--settings '{"hooks":{}}') 살아 있음
판정 이중 일관되게 닫힘 가장 약함

검증 = runner selftest(계측 형식 포함) · _selfcheck_cards() · mem_find 실호출 809자 · 카드 지시문에 과거기록 주입 확인 · test_watcher_rules.py 8항목 PASS · watcher 구문 검사 · 실브라우저 18행(개발 6/9 · 현업 1/9 · 완료 7 · 가로스크롤 0) · 매니페스트 검증 OK.

다음 순번(계획 그대로) = ①현업 P0-2 관측 ②현업 P0-3 임계치 ③개발 P1-4 되먹임 ④현업 P1-2 비전 ⑤현업 P1-3 학습 ⑥개발 P2-1 ⑦현업 P2-1.