① 전체 워크플로우 (PRD §0)
500은 슬랙 직행. 그 외는 서브 에이전트 분석 → 검증 에이전트 적대적 재검증(반려 루프) → task. 막히면 1선에 보충질문, 완료 시 HTML 리포트.
flowchart TD
FA["1선 에이전트 (사람 접수원)
1단계: 테스트계정 · HTTP 상태 코드
2단계(비-500/모름): 오류상황 · 재현단서"]
FA --> Q500{"기재 HTTP 상태 코드
== 500 ?"}
Q500 -->|"Yes · 500"| SLACK["슬랙 → 개발자 직행
ESCALATED_500 (파이프라인 우회)"]
SLACK --> DEV["개발자"]
Q500 -->|"No · 그 외"| QUEUE["작업 큐 (QUEUED)"]
QUEUE --> SUB
subgraph SUB["서브 에이전트 — 분석 (분리 세션)"]
direction TB
A["A. 코드 능동 탐색 (정적 · 병렬)
BE/FE/DB 분류 · suspected_files"]
LOCK{"테넌트 재현 락
회사 단위 · 회사 간 병렬"}
B["B. 능동 재현 (동적 · 직렬)
스테이지 우선 · 콘솔/네트워크/증거 · side_effects"]
C["C. A·B 교차검증 grounding
→ 분석 리포트 저장"]
A --> C
A -.->|"재현 필요 시"| LOCK
LOCK ==>|"점유 → 직렬"| B
B --> C
end
SUB -.->|"정보 부족 · 막힘"| ASK["AWAITING_CLARIFICATION
UI로 1선에 타겟형 보충질문
(대기 중 재현 락 해제)"]
ASK -->|"1선 답변 → 복귀 (재현은 락 재획득 후)"| SUB
C --> VER["검증 에이전트 — 적대적 재검증
분리 세션 · 결론 반박 시도"]
VER --> QV{"분석 타당한가?
(반박 실패 = 통과)"}
QV -->|"반려 · 결함+근거 (최대 3회)"| SUB
QV -->|"통과"| TASK["tasks.json 직렬화 (COMPLETED)
root_cause.layer → primary_category"]
TASK --> LINEAR["Linear export (task-XXX)
→ 자동 개발 파이프라인 진입"]
LINEAR --> DEV
TASK --> RPT["상세 VOC HTML 리포트
고정 템플릿 · voc_evidence 렌더"]
RPT --> READ["1선 / 개발자 열람"]
classDef human fill:#1565c0,stroke:#90caf9,color:#fff
classDef agent fill:#6a1b9a,stroke:#ce93d8,color:#fff
classDef branch fill:#e65100,stroke:#ffb74d,color:#fff
classDef reject fill:#c62828,stroke:#ef9a9a,color:#fff
classDef clar fill:#00838f,stroke:#4dd0e1,color:#fff
classDef out fill:#2e7d32,stroke:#a5d6a7,color:#fff
class FA,DEV,READ human
class SUB,A,B,C,VER,TASK,LINEAR agent
class Q500,QV branch
class LOCK reject
class ASK clar
class RPT out
linkStyle 9,10 stroke:#00838f,stroke-width:2px
linkStyle 13 stroke:#c62828,stroke-width:2px
사람
에이전트
분기/판정
반려 루프·락
1선 보충질문 (§5.12)
HTML 리포트 (§5.13)
신규 ① 1선 보충질문(§5.12). 서브 에이전트가 막히면 UI로 1선에 타겟형 질문 → 대기 중 테넌트 재현 락을 해제해 다른 잡을 막지 않음 → 답변 시 직전 단계로 복귀. (에이전트↔사람 루프 = §5.5 에이전트↔에이전트 적대 루프와 별개)
신규 ② HTML 리포트(§5.13). 검증 통과(COMPLETED) 후
meta.voc_evidence를 고정 템플릿에 렌더 → 1선·개발자가 상세 VOC를 단일 HTML로 열람·공유.
② 잡 상태 머신 (PRD §5.3)
AWAITING_CLARIFICATION은 어느 단계에서든 진입 가능하고 답변 시 직전 단계로 복귀. REJECTED는 ANALYZING으로 회귀.
stateDiagram-v2
[*] --> ESCALATED_500: 에러코드 500 → 슬랙 직행
[*] --> QUEUED: VOC 제출 (비-500)
QUEUED --> ANALYZING: A. 코드 탐색(병렬)
ANALYZING --> AWAITING_REPRODUCTION: 분석완료 · 테넌트 락 대기
AWAITING_REPRODUCTION --> REPRODUCING: 락 획득 (회사 단위 직렬)
REPRODUCING --> VERIFYING: 리포트 저장 → 적대적 재검증
VERIFYING --> COMPLETED: 통과 → tasks.json
VERIFYING --> REJECTED: 반려 (결함 발견)
REJECTED --> ANALYZING: 서브 에이전트 재분석
ANALYZING --> AWAITING_CLARIFICATION: 정보 부족
REPRODUCING --> AWAITING_CLARIFICATION: 정보 부족 (락 해제)
AWAITING_CLARIFICATION --> ANALYZING: 답변(분석발) → 곧바로 복귀
AWAITING_CLARIFICATION --> AWAITING_REPRODUCTION: 답변(재현발) → 락 재획득 경유
COMPLETED --> [*]: HTML 리포트 렌더 (§5.13)
ESCALATED_500 --> [*]
VERIFYING --> BLOCKED: 반려 상한(3회)
AWAITING_CLARIFICATION --> BLOCKED: 응답 타임아웃/상한
REPRODUCING --> FAILED: 재현 오류
BLOCKED --> [*]
FAILED --> [*]
③ 처리 시퀀스 — 락·보충질문·적대 루프·리포트
sequenceDiagram
actor FA as 1선 에이전트
participant FE as 프론트엔드
participant Q as 큐
participant SUB as 서브 에이전트
participant LK as 테넌트 재현 락
participant ST as 스테이지/운영
participant VER as 검증 에이전트
participant LN as Linear
participant RPT as HTML 리포트
actor DEV as 개발자
FA->>FE: 구조화 VOC 제출 (계정+오류+에러코드)
alt 500 에러
FE->>DEV: 슬랙 직행 (ESCALATED_500)
else 그 외
FE->>Q: 큐 적재 (QUEUED)
Q->>SUB: 디스패치 (ANALYZING)
SUB->>SUB: A. 코드 탐색 (BE/FE/DB)
SUB->>LK: 재현 락 요청 (AWAITING_REPRODUCTION)
LK-->>SUB: 락 획득 (REPRODUCING)
SUB->>ST: B. 능동 재현 (스테이지 우선)
ST-->>SUB: 콘솔/네트워크/증거 + side_effects
opt 정보 부족으로 막힘 (§5.12)
SUB->>LK: 재현 락 해제
SUB->>FA: 타겟형 보충질문 (AWAITING_CLARIFICATION)
FA-->>SUB: 답변
SUB->>LK: 재현 재개 시 락 재획득 (AWAITING_REPRODUCTION 경유)
end
SUB->>VER: C. 분석 리포트 제출
loop 적대적 재검증 (최대 3회)
VER->>VER: 결론 반박 시도
VER-->>SUB: 반려 시 → 재분석 (REJECTED→ANALYZING)
end
VER->>LN: 통과 → tasks.json (task-XXX)
LN->>DEV: 자동 개발 파이프라인 진입
VER->>RPT: COMPLETED → 리포트 렌더 (§5.13)
RPT-->>FA: 1선 열람
RPT-->>DEV: 개발자 열람
end
④ 산출 계약 — meta.voc_evidence (PRD §7)
검증 통과분만 직렬화. 1선 입력은 reported만 채우고 나머지는 파이프라인이 채운다.
flowchart LR
ROOT["tasks.json
(task-XXX)"]
ROOT --> STD["표준 필드
primary_category · priority · acceptance_criteria"]
ROOT --> EV["meta.voc_evidence"]
EV --> R1["reported
(1선 입력)
raw_voc · request_url · reported_steps · expected_behavior"]
EV --> CLR["clarifications ⭐신규
1선 Q&A 로그 (§5.12)"]
EV --> R2["reproduced
steps · console · network · side_effects"]
EV --> D["divergence
matches|broader|narrower|different|unreproducible"]
EV --> S["scope_assessment
simple|cascading|needs_decomposition"]
EV --> RC["root_cause
layer(BE/FE/DB) · suspected_files · confidence"]
EV --> VF["verification
적대적 라운드 이력"]
EV --> RM["remediation
side_effects 복구 상태"]
classDef key fill:#00424a,stroke:#4dd0e1,color:#fff
classDef inp fill:#3d2c00,stroke:#ffb74d,color:#fff
class CLR key
class R1 inp
신규 필드
clarifications[]. 서브 에이전트↔1선 보충질문/답변을 라운드별로 영속 기록 → 재현 뷰(§5.11)와 HTML 리포트(§5.13)에 노출. internal_job.clarification_rounds로 왕복 수 카운트.
⑤ 설계 메모
- 두 개의 독립 루프: ①보충질문(에이전트↔사람·§5.12) 과 ②적대적 재검증(에이전트↔에이전트·§5.5). 각각 상한(기본 3회)을 별도로 갖는다.
- 락 양보: 보충질문 대기 중 테넌트 재현 락을 해제 — 사람 응답을 기다리며 같은 회사 다른 잡을 막지 않는다(§4.4·§5.12).
- 500은 산출물이 없다: 슬랙 직행으로 종료되어 tasks.json·리포트를 만들지 않는다.
- 리포트는 결정적: HTML 리포트는 LLM 자유 서술이 아니라
voc_evidence를 고정 템플릿 슬롯에 렌더(§5.13). 색·아이콘은 본 다이어그램 시각 언어를 따른다. - 입력 ≠ 출력: 1선 양식은
reported트리거일 뿐, 재현·코드·적대 검증을 통과해야root_cause가 채워진다.