PetV3 에이전트 공장 3: 터미널 대시보드를 제어면으로 만들기
PetV3 자동화 시스템 시리즈 3/4
앞 글의 Git 작업장은 안전했지만, 사람이 상태를 읽기에는 불편했다. branch, worktree, backlog, ledger, 세션 로그를 각각 열어봐야 했기 때문이다.
그래서 별도 웹 대시보드 대신 터미널 TUI를 만들었다. 이유는 단순했다. 관제 대상이 이미 로컬 Git과 프로세스, 터미널 세션에 있었고, 브라우저 런타임을 하나 더 상주시킬 이유가 없었다.
첫 화면에는 요약만 둔다
초기 작업 그래프는 모든 파일과 충돌을 한 화면에 펼쳤다. 정보는 많았지만 유용하지 않았다. 세로로 끝없이 스크롤됐고, 마우스 클릭 대상도 흔들렸다.
현재 구조는 task → worker → file 관계를 유지하되 단계적으로 연다.
TASK R-3 overlay 틱 순서 고정
└─ WORKER work/r3-tick-order 커밋됨 · 착지 대기
└─ 파일 3 · 충돌 0
첫 화면에는 관계 요약과 근거만 보인다. Enter나 클릭으로 노드 상세에 들어가고, 파일 목록은 접어서 +N more로 제한한다. 렌더링 단계에서는 이미 만든 그래프를 화면 높이만큼만 잘라 그린다.
진행률 대신 진행 근거를 보여준다
에이전트 작업에 “73% 완료” 같은 숫자를 자동으로 붙이면 정밀해 보이지만 대부분 근거가 없다. PetV3는 Git과 ledger에서 관찰 가능한 상태만 사용한다.
- 새 파일 신고만 있음 →
신고됨 - 신고가 branch commit보다 새로움 →
작업중? · 새 신고 - WIP commit →
WIP 커밋 · 작업중? - 일반 branch commit →
커밋됨 · 착지 대기 - 아무 근거 없음 →
진행 근거 없음
mtime은 생존 신호가 아니기 때문에 작업중?의 물음표를 지우지 않는다. 테스트 통과도 임의의 백분율로 바꾸지 않는다.
애니메이션과 상태 수집의 시계를 분리했다
Codex와 Claude 세션이 움직이는 느낌을 주기 위해 provider별 ASCII 애니메이션을 넣었다. 하지만 효과를 위해 Git과 수 GB 세션 로그를 초당 여러 번 다시 읽으면 대시보드가 관제 대상보다 무거워진다.
그래서 두 박자를 분리했다.
- 160ms: 주입된 frame phase로 ASCII만 다시 그림
- 느린 refresh: Git, backlog, ledger, 세션 후보를 다시 읽음
렌더러는 실제 시계를 읽지 않는다. 같은 phase를 넣으면 항상 같은 프레임이 나와 테스트가 결정적이다.
입력 복귀도 상태기계다
다른 task로 이동했다가 돌아오면 마우스 포인터가 I-beam으로 남고 클릭이 어긋나는 문제가 있었다. 터미널 focus gain, resize, editor resume 경로에서 raw mode, mouse protocol, cursor, 전체 repaint를 같은 재진입 함수로 복구했다.
Codex는 흰색, Claude는 CI 계열 주황색으로 표시하고, 접힌 상태에서도 provider와 확인된 concise model을 보여준다. prompt 전문, cwd, resume id처럼 화면에 필요 없는 정보는 노출하지 않는다.
화면도 거짓말할 수 있다
한 번은 새 대시보드 코드가 main에 착지했는데 실행 화면은 계속 옛 UI를 보여줬다. 원인은 launcher가 release 바이너리가 존재한다는 이유만으로 재사용한 것이었다.
이후 launcher는 시작할 때 Rust 소스가 바이너리보다 최신인지 확인한다. 최신이면 왜 다시 빌드하는지 알리고 release 실행 경로로 물러난다. 이 검사는 프레임마다가 아니라 시작할 때 한 번만 수행한다.
실제 규모에서 잰 값
진행 근거 기능을 넣은 release bench는 다음 조건에서 측정했다.
- worktree 16개
- 추적 파일 1,398개
- 세션 후보 1,684개, 약 2.28GB
- 읽기 루프 중앙 5.47ms, 최대 10.38ms
- 렌더 루프 중앙 0.38ms
- 입력→재렌더 중앙 0.45ms
- 유휴 렌더 포크 0
- RSS 12,592KiB
숫자에는 조건을 붙였다. 다른 commit, 다른 저장소 크기, 다른 터미널에서 같은 값이라고 주장하지 않는다.
대시보드는 코드를 고치지 않는다
TUI가 쓰는 것은 비추적 control.ini와 제한된 event cache뿐이다. pause/resume, 강도, 자동 정지, brainstorm 상태, refactor audit 요청을 조절할 수 있지만 코드, backlog, Git ref, 사용자 설정은 직접 수정하지 않는다.
다음 편에서는 이 제어면이 어떻게 모델 사용량을 제한하고, Codex와 Claude 사이의 안전한 중단·재개를 만드는지 설명한다.