본문으로 건너뛰기

Agent Teams 하네스 비판적 감사 보고서

Context

The Hon: Joseon 프로젝트의 6-에이전트 팀(Leader/Planner/Coder/DevOps/Artist/Composer)이 Claude Code의 실험적 Agent Teams 기능으로 운영 중이다. 실제 이벤트 로그(1,086줄)와 설정 파일 전수 검토를 통해 거버넌스 아키텍처가 근본적으로 무력화된 상태임을 확인했다. 프롬프트 기반 제약은 문서상으로만 존재하며, 기계적 강제 장치가 전무하거나 작동하지 않고 있다.


검증된 핵심 수치

지표의미
총 이벤트1,086줄
이벤트 유형tool(1,030), stop(5), start(8) idle/task_done/task_created/notify = 0건
Leader Write+Edit98회 (Edit 75 + Write 23)"절대 금지" 규칙 완전 무시
Leader 전체 도구623/1,086 (57%)Leader가 실무자 역할 수행
Artist/Composer 이벤트0건팀에서 사실상 부재
.active-sessions미존재Notification 세션 매핑 불능
TASK-026backlog에 없음, MS-002에 참조됨마일스톤 진행률 오류

A. 강제 장치 부재 (Enforcement Gaps)

A-1. 파일 도메인 강제 없음 [P0-Critical]

  • 문제: Coder→game/src/, Artist→game/res/sprites/ 등 도메인 분리가 프롬프트에만 존재. PreToolUse 훅이 단 하나도 없음.
  • 증거: Leader가 dashboard.tsx(10회), backlog.json(6회), wol-wake.sh(3회), .mcp.json(2회), settings.json(2회) 등 DevOps/Coder 도메인 파일을 직접 수정
  • 영향: 어떤 에이전트든 아무 파일이나 수정 가능. 팀 분리 아키텍처 자체가 무의미
  • 수정: PreToolUse 훅 신설 → scripts/agent/enforce-domain.sh — 에이전트별 허용 경로 JSON 맵 + Write/Edit/Bash(리다이렉션) 차단

A-2. Leader 쓰기 제한 미강제 [P0-Critical]

  • 문제: Leader 프롬프트에 "Write/Edit는 오직 .claude/agent-memory/leader/만" 명시. 실제로는 98회 외부 파일 수정
  • 증거: restart-server.sh(6회), leader.md(3회), planner.md(3회), .env.example(3회), settings.local.json(1회) 등
  • 영향: Leader가 매니저가 아닌 만능 실무자로 작동 → 팀 위임 구조 와해
  • 수정: (1) Leader frontmatter에서 disallowedTools: Write, Edit 추가, 또는 (2) PreToolUse 훅에서 Leader의 Write/Edit를 .claude/agent-memory/leader/**만 허용

A-3. Coder 린트 우회 가능 [P1-High]

  • 문제: gdscript-lint.shWrite|Edit matcher에만 걸림. Bash로 .gd 파일 생성 시 린트 우회
  • 수정: Bash matcher 추가 또는 PostToolUse Bash 훅에서 git diff --name-only *.gd 체크

A-4. Planner-First 파이프라인 미강제 [P1-High]

  • 문제: "새 시스템은 Planner 설계 → Coder 구현 순서" 규칙이 프롬프트에만 존재
  • 증거: TASK-033(캐릭터3종)이 blocked_by: null로 진행 중, TASK-020(Phase2설계)은 아직 In Progress
  • 수정: TaskCreated 훅에서 Feature+Coder 조합이면 blocked_by에 Design 작업 필수 검증

B. 훅 결함 (Hook Deficiencies)

B-1. TeammateIdle/TaskCompleted/TaskCreated/Notification 훅 미작동 [P0-Critical]

  • 문제: 1,086줄 이벤트 로그에 idle, task_done, task_created, notify 이벤트가 단 한 건도 없음
  • 의미: 품질 게이트(커밋 전 완료 차단), 유휴 킥, 작업 생성 로깅이 한 번도 작동한 적 없음
  • 원인 가설: (1) in-process 모드에서 이 훅 이벤트가 아직 미구현, (2) settings.json 위치/형식 문제, (3) 스크립트 실행 권한 문제
  • 수정: (1) 각 훅에 touch /tmp/hook-fired-{event}-$(date +%s) 추가하여 발화 여부 확인, (2) 미발화 시 PostToolUse의 TaskUpdate 감지를 대안으로 활용 (log-tool-use.sh 66-72줄이 이미 일부 구현)

B-2. TeammateIdle 훅 blocked_by 미검사 [P1-High]

  • 문제: log-agent-idle.sh 30-32줄에서 assignee+status만 체크. blocked_by가 있는 To Do 작업도 "할 일 있음"으로 판단
  • 영향: 차단된 작업만 있는 에이전트가 무한 킥 루프에 빠짐 (토큰 낭비)
  • 수정: Python 블록에 blocked_by 필드 체크 추가 — 블로킹 작업이 Done이 아니면 pending에서 제외

B-3. SubagentStart/SubagentStop 훅 미등록 [P2-Medium]

  • 문제: log-agent-start.sh, log-agent-stop.sh 스크립트 존재하나 settings.json에 미등록
  • 증거: Explore(84건), Plan(66건) 서브에이전트가 로그에 보이지만 라이프사이클 추적 불가
  • 수정: settings.json에 SubagentStart/SubagentStop 항목 추가

B-4. log-stop.sh 비동기 로그 의존 (경합 조건) [P1-High]

  • 문제: Stop 훅(동기)이 agent-events.jsonl을 읽는데, 이 파일은 log-tool-use.sh(비동기)가 씀
  • 영향: 팀원 최신 활동이 아직 안 쓰여서 Leader가 조기 종료할 수 있음
  • 수정: 에이전트별 하트비트 파일(/tmp/.agent-heartbeat-{name}) touch 방식으로 전환

B-5. TaskCompleted 훅 — 테스트 통과/도메인/담당자 미검증 [P1-High]

  • 문제: git diff만 체크. 테스트 통과 여부, 파일 도메인 준수, 작업 담당자 일치 미확인
  • 수정: (1) Coder 작업 시 run-tests.sh 실행, (2) 변경 파일이 에이전트 도메인 내인지 확인, (3) $AGENT와 backlog 담당자 대조

B-6. Artist/Composer TaskCompleted git 체크 제외 [P2-Medium]

  • 문제: case문에 coder|devops|planner만 있음. Artist/Composer는 커밋 없이 완료 가능
  • 수정: Artist/Composer도 git diff 체크 추가, 또는 validate-asset.sh 호출

B-7. 인라인 git push 감지 (유지보수 불가) [P3-Low]

  • 문제: settings.json 19-27줄에 200자 인라인 셸 명령
  • 수정: scripts/agent/detect-git-push.sh로 추출

C. 태스크보드 무결성 (Task Board Integrity)

C-1. TASK-026 유령 참조 [P1-High]

  • 문제: backlog.json에 TASK-026 없음. milestones.json MS-002가 TASK-026 참조
  • 영향: Phase 2 진행률 계산 오류
  • 수정: TASK-026을 backlog에 추가하거나, milestones.json에서 제거. 교차 검증 스크립트 추가

C-2. TASK-033 종속성 불일치 [P1-High]

  • 문제: TASK-033 In Progress + blocked_by: null, 하지만 TASK-020(Phase2설계) 아직 미완료
  • 수정: TASK-033에 blocked_by: "TASK-020" 설정. update-task.sh에 In Progress 전환 시 blocked_by 검증 추가

C-3. 순환 종속성 미탐지 [P2-Medium]

  • 수정: update-task.sh에 blocked_by 체인 워킹 → 순환 발견 시 거부

C-4. 작업 담당자 검증 없음 [P2-Medium]

  • 수정: update-task.sh에 에이전트명 파라미터 추가, assignee 대조

C-5. MS-002 태스크 목록 불완전 [P2-Medium]

  • 문제: MS-002에 TASK-020, 025, 026만. 실제 Phase 2는 TASK-033~039 포함
  • 수정: Phase 2 모든 작업 추가. 또는 phase 필드 기반 자동 집계로 전환

D. 에이전트 정의 결함 (Agent Definition Flaws)

D-1. 전 에이전트 bypassPermissions [P0-Critical]

  • 문제: 6개 에이전트 전부 permissionMode: bypassPermissions. 모든 안전 장치 비활성
  • 영향: 환각에 의한 파괴적 명령(rm -rf, git push --force) 무방비 실행
  • 수정: Leader/Artist/Composer는 bypassPermissions 제거. Coder/DevOps/Planner는 PreToolUse 보상 컨트롤로 유지 검토

D-2. 훅에서 에이전트 식별 불안정 [P1-High]

  • 문제: teammate_name이 null인 경우 다수. 서브에이전트는 "Explore", "Plan", "main"으로 기록
  • 증거: debug-tool-hook.json에 teammate_name: null
  • 수정: SessionStart 훅으로 session_id→agent_name 매핑 구축

D-3. agents.md 참조 파일 미존재 [P2-Medium]

  • 문제: CLAUDE.md에서 .claude/reference/agents.md 참조하나 파일 없음
  • 수정: 파일 생성 또는 CLAUDE.md에서 참조 제거

D-4. disallowedTools 비일관 [P2-Medium]

  • 문제: Coder/DevOps만 NotebookEdit 차단. Leader/Planner/Artist/Composer는 disallowedTools 없음
  • 수정: 에이전트별 불필요 도구 체계적 차단 (특히 Leader에 Write/Edit)

E. 운영 안정성 (Operational Reliability)

E-1. .active-sessions 파일 미생성 [P1-High]

  • 문제: log-notification.sh가 의존하는 파일이 존재하지 않음
  • 영향: 모든 Notification이 "system"으로 귀속
  • 수정: SessionStart/SubagentStart 훅에서 세션 매핑 파일 생성

E-2. 로그 로테이션 없음 [P2-Medium]

  • 수정: log-tool-use.sh에 크기 체크 추가 (10MB 초과 시 아카이브)

E-3. stop-agents.sh 이름 혼동 [P3-Low]

  • 수정: stop-dashboard.sh로 통합/리네임

E-4. check-pending-commands.sh 폐기 코드 잔존 [P3-Low]

  • 수정: 스크립트 + pending-commands.jsonl 삭제

E-5. 대시보드 PID 경합 [P3-Low]

  • 수정: flock 기반 원자적 시작

F. 보안 및 격리 (Security & Isolation)

F-1. 평문 자격증명 전 에이전트 접근 가능 [P0-Critical]

  • 문제: settings.local.json에 Slack/GitHub/Notion/HF/Stitch 토큰 평문. Read 권한이 //Users/jihunbang/** 전체 허용
  • 영향: 프롬프트 인젝션이나 환각으로 토큰 유출 가능
  • 수정: (1) Read 권한 범위를 프로젝트 디렉토리로 축소, (2) PreToolUse에서 settings.local.json Read 차단, (3) macOS Keychain 활용 검토

F-2. Slack 채널 ID 하드코딩 [P2-Medium]

  • 수정: conversations.list 캐시 또는 채널명 기반 API 호출

F-3. 에이전트 간 메모리 읽기 가능 [P2-Medium]

  • 수정: PreToolUse에서 타 에이전트 메모리 디렉토리 Read 차단

G. 아키텍처 이슈 (Architecture Issues)

G-1. "LLM을 믿어라" 아키텍처의 근본 한계 [P0-Critical]

  • 문제: 파일 도메인, Leader 제한, Planner-First, Slack 보고, 태스크보드 업데이트, 브랜치 전략 — 전부 프롬프트 지시에만 의존
  • 증거: Leader 98회 쓰기 위반, 4개 훅 미작동, TASK-033 종속성 무시
  • 수정: Defense-in-depth — PreToolUse 강제, TaskCompleted 품질 게이트, per-agent 도구 제한, bypassPermissions 선별 제거

G-2. Git 커밋 에이전트 식별 불가 [P1-High]

  • 문제: 모든 에이전트가 동일 Git identity 사용
  • 수정: 에이전트별 GIT_AUTHOR_NAME 설정 (예: "Coder (AI Agent)")

G-3. 단일 브랜치 동시 Push 충돌 [P1-High]

  • 문제: dev 브랜치 직접 작업, feature 브랜치 금지 → 동시 push 시 충돌
  • 수정: git push 전 자동 git pull --rebase 강제 (PreToolUse 또는 래퍼 스크립트)

G-4. 작업↔커밋 추적 불가 [P2-Medium]

  • 수정: TaskCompleted에서 git log --oneline -5 기록, 커밋 메시지에 TASK-ID 포함 규칙

심각도 요약

등급건수항목
P0-Critical6A-1, A-2, B-1, D-1, F-1, G-1
P1-High10A-3, A-4, B-2, B-4, B-5, C-1, C-2, D-2, E-1, G-2, G-3
P2-Medium11B-3, B-6, C-3, C-4, C-5, D-3, D-4, E-2, F-2, F-3, G-4
P3-Low4B-7, E-3, E-4, E-5

구현 계획

지금 (에이전트 실행 중 — 안전한 것만)

실행 중인 에이전트에 영향 없는 데이터 정합성 수정만 수행:

  1. C-1: ops/milestones.json — TASK-026 유령 참조 제거 + Phase 2 태스크 목록 갱신 (C-5 통합)
  2. C-2: ops/tasks/backlog.json — TASK-033 blocked_by 필드 추가 (현재 idle 훅이 blocked_by를 안 읽으므로 안전)
  3. D-3: CLAUDE.md에서 .claude/reference/agents.md 참조 제거 (파일 미존재)

다음 세션 (에이전트 중지 후) — P0 수정

  1. B-1 조사: 4개 훅 미작동 원인 파악 (touch 테스트)
  2. A-1+A-2: PreToolUse enforce-domain.sh 훅 신설
  3. D-1: Leader에 disallowedTools: Write, Edit 추가
  4. F-1: Read 권한 범위 축소 + settings.local.json 접근 차단

이후 세션 — P1/P2 수정

  1. B-2, B-4, B-5, G-2, G-3 (거버넌스 복원)
  2. B-3, B-6, C-3, C-4, D-4, E-1 (보완)
  3. E-2~E-5, B-7, F-2, F-3, G-4, A-3, A-4 (견고화)

지금 수정할 파일 (안전)

파일수정 내용
ops/milestones.jsonTASK-026 제거, Phase 2 태스크 목록 갱신
ops/tasks/backlog.jsonTASK-033 blocked_by 추가
.claude/CLAUDE.mdagents.md 미존재 참조 제거

검증 방법

  1. 훅 발화 테스트: 각 훅에 /tmp/hook-fired-{event} touch 추가 → 에이전트 팀 실행 → 파일 생성 확인
  2. 도메인 강제 테스트: Leader로 game/src/test.gd Write 시도 → deny 확인
  3. TaskCompleted 테스트: Coder가 커밋 없이 완료 시도 → exit 2 확인
  4. idle 킥 테스트: blocked 작업만 있는 에이전트 idle → exit 0 (킥 안 함) 확인
  5. TASK/마일스톤 정합성: jq 교차 검증 스크립트 실행