Post

바로 자동화 - Phase 2 구현하기

바로 자동화 - Phase 2 구현하기

0. 들어가며

지난 글에서 자동화 시스템의 설계 방향과 Phase별 로드맵을 정리했다. 요약하자면 자연어를 직접 코드 생성에 쓰는 것은 위험하며, 자연어 → 명세 → 코드라는 이단 구조가 핵심이었다.

이번 글에서는 그 계획을 실제로 어떻게 구현했는지를 다룬다. Phase 1에서 Phase 2로 전환하는 오케스트레이터, BE-claude-dev-worker를 설계하고 만들면서 겪은 것들이다.


1. 현재 위치: Phase 1 → Phase 2

기존 로컬 워크플로우는 다음과 같았다.

1
2
개발자가 터미널에서 직접 claude --print '/dev:start-task 123' 실행
     → plan.md 생성 → 눈으로 확인 → claude --print '/dev:continue-task 123' 실행

이것이 Phase 1이다. 명세 기반 코드 자동화는 동작하지만, 개발자가 로컬에 붙어 있어야 하고 한 번에 하나의 이슈만 처리할 수 있다.

Phase 2의 목표는 이 과정을 클라우드 워커로 옮기고, 인간의 개입 지점을 계획(plan.md) 승인 하나로 줄이는 것이다.

flowchart LR
    A[외부 시스템] -->|LPUSH| B[Redis Queue]
    B -->|BRPOP| C[BE-claude-dev-worker]
    C -->|spawn Claude CLI| D[barlow 디렉토리]
    D -->|plan.md 생성| C
    C -->|plan 게시 + 버튼| E[Slack]
    E -->|승인 / 피드백| C
    C -->|PR 생성 완료| E

2. 핵심 설계: 신호 계약

Worker가 Claude를 블랙박스 서브프로세스로 실행하고, stdout에서 특정 패턴만 파싱하는 방식을 선택했다.

Claude 명령이 stdout으로 아래 신호를 출력하면 Worker가 다음 단계로 진행한다.

1
2
3
4
5
6
PLAN_READY:{branch}      → 계획 생성 완료, Slack에 plan.md 게시
PLAN_UPDATED             → 피드백 반영 완료, 수정된 plan 재게시
PLAN_UNCHANGED           → 질문에 대한 답변만 (계획 변경 없음)
PLAN_CONFIRMED:{branch}  → 수정 + 즉시 확정, 구현 단계로 진행
ANSWER:{text}            → Claude 답변 내용
PR_CREATED:{url}         → PR 생성 완료

이 계약이 두 프로젝트의 통합 인터페이스다. Barlow의 Claude 명령들이 이 신호를 출력하지 않으면 Worker는 멈춘다.


3. 전체 워크플로우

3.1 태스크 수신부터 계획 승인까지

sequenceDiagram
    participant R as Redis
    participant W as Worker
    participant C as Claude CLI
    participant S as Slack

    R->>W: BRPOP (태스크 수신)
    W->>W: git stash (이전 uncommitted 정리)
    W->>S: 🚀 작업 시작 알림 (스레드 앵커)
    W->>C: spawn /dev:start-task 123 (15분)
    C-->>W: stdout: PLAN_READY:feature/issue/123
    W->>W: plan.md 읽기
    W->>S: plan 게시 + [승인] [피드백] 버튼

3.2 승인 루프

피드백이 들어오면 Claude를 다시 실행해 plan.md를 수정한다. 승인이 날 때까지 반복된다.

flowchart TD
    A[Slack 버튼 대기] --> B{승인 / 피드백?}
    B -->|승인| C[구현 단계 진행]
    B -->|피드백| D[/dev:revise-plan 실행, 20분/]
    D --> E{신호 파싱}
    E -->|PLAN_UNCHANGED| F[ANSWER 내용 Slack 포스팅]
    E -->|PLAN_UPDATED| G[수정된 plan 재게시 + 버튼]
    E -->|PLAN_CONFIRMED| C
    F --> A
    G --> A

3.3 구현 및 PR 생성

sequenceDiagram
    participant W as Worker
    participant C as Claude CLI
    participant S as Slack

    W->>S: ✅ 구현 시작합니다...
    W->>C: spawn /dev:continue-task 123 (60분)
    Note over C: plan.md 기반 코드 작성<br/>테스트 실행<br/>git commit → gh pr create
    C-->>W: stdout: PR_CREATED:https://github.com/...
    W->>S: 🎉 PR 생성 완료! {url}
    W->>W: Redis 현재 태스크 삭제

4. .workspace 디렉토리의 역할

Worker와 Claude 사이의 공유 상태는 파일로 관리된다.

1
2
3
4
5
barlow/.workspace/
├── routing.md       # BC 결정, 브랜치 타입, 이슈 요약
├── scope.md         # 영향 파일, 함수명, 코드 분석 결과
├── rules-applied.md # 아키텍처 규칙 적용 결과
└── plan.md          # 최종 구현 계획 (Worker ↔ Claude 공유)

plan.md가 핵심이다. Worker는 이 파일을 읽어 Slack에 게시하고, Claude는 이 파일을 수정하며 계획을 발전시킨다. 인간도 Slack을 통해 이 파일의 내용을 보고 승인 여부를 결정한다.


5. 안정성 설계

자동화 시스템에서 크래시는 피할 수 없다. 다음과 같이 대응한다.

상황처리 방식
Uncommitted changes 존재git stash로 정리 후 진행
PLAN_READY 신호 미수신Slack 알림 후 태스크 종료
plan.md 10초 내 미생성예외 발생 → 태스크 정리
Claude 프로세스 타임아웃SIGTERM으로 서브프로세스 종료
Worker 프로세스 크래시PM2 자동 재시작 + 시작 시 abandoned task 알림

Redis에 현재 태스크를 TTL 48h로 저장해두기 때문에 Worker가 재시작되더라도 중단된 작업을 추적할 수 있다.


6. 현재 위치와 다음 과제

현재 시스템은 Phase 2까지 완성된 상태다.

Phase상태설명
Phase 1✅ 완료로컬 CLI 기반 명세 → 코드 자동화
Phase 2✅ 완료Redis 큐 + Slack Human-in-the-Loop + PM2 상시 대기
Phase 3미구현테스트 에이전트 통합 + 실패 시 피드백 루프

Phase 3으로 가기 위해서는 구현 단계에도 피드백 루프가 필요하다. 현재는 승인 루프가 계획 단계에만 존재한다. 구현 중 테스트가 실패했을 때 이를 Worker가 감지하고 Claude에게 재시도를 지시하는 구조가 추가되어야 한다.

구체적으로는 TEST_FAILED:{reason} 같은 신호를 /dev:continue-task 명령에서 출력하도록 확장하고, Worker의 오케스트레이션 로직에 구현 단계 재시도 루프를 추가하는 작업이다.

완전 자동화는 아직 위험하다. Phase 3까지 운영해보며 인간이 어느 지점에서 개입해야 하는지 데이터를 쌓아가는 것이 지금 단계에서 할 수 있는 가장 현실적인 접근이다.

This post is licensed under CC BY 4.0 by the author.