report HAN-268 asurada final 2026-05-22

[HAN-268] Result — Raphael 발송 Spec Gate auto-approval + 회수 메커니즘

Summary

PR #100 머지 완료 (b84c449, fast-forward). Raphael 페르소나가 발송한 [Spec Gate] 브리핑도 Jarvis 자동 검토→[APPROVED]→라벨/리액션/execution 픽업이 동작하며, 사용자 👎 또는 [CANCEL] 코멘트로 회수 가능한 fail-safe 경로 추가. 13 TC + 전체 122 통과, code review clean pass.

완료된 것

코드 변경

파일 변경 요약
bridge.py subtype 가드 완화(bot_message 허용) · _handle_approval_briefing pending.json hydrate · idempotency 가드 · _handle_cancel_comment 신규 · 단계별 회수 분류 · Jarvis 자동 승인 시 사용자 DM 알림
spec_gate.py handle_reaction thumbsdown 시 approved/implementing 함께 제거 + 단계별 사용자 DM (label_only / processing / done)
tests/test_approval_handler.py 7 신규 TC + autouse _isolate_env fixture (env + store 경로 격리)
.agent/docs/HAN-268.md SDD 스펙 (spec-reviewer 통과)

AC 통과

회수 단계 분류

Stage 조건 회수 동작
label_only execution_store에 처리 흔적 없음 라벨만 제거
processing execution_store에 worktree 생성됐으나 PR 없음 라벨 제거 (워크트리 강제 종료는 별도 이슈)
done execution_store에 pr_url 존재 회수 불가 + 사용자 DM에 명시

배운 것

Plan 단계 — bundle vs split 판단

사용자가 HAN-268·HAN-168 묶음 검토 요청. 표면 가설(“비-멤버 봇 멘션 무효”)이 유사해 보였으나 코드 surface·트리거 메커니즘·실패 본질이 모두 달랐음: - HAN-268은 Jarvis가 이미 채널 멤버 → 핸들러 로직 문제 - HAN-168은 Asurada가 DM 비멤버 → Slack IM 2인 멤버십 구조 문제

premature abstraction 회피: 표면 유사성에 끌려 묶지 말 것. 3번째 유사 케이스 나오면 그때 추상화 검토.

TDD 사이클 + 회귀 baseline 가치

기존 test_approval_handler.py의 6 TC가 회귀 baseline으로 작동. subtype 가드를 not event.get("subtype")에서 subtype in (None, "bot_message")로 변경할 때 안전망 역할. TC8(test_message_changed_subtype_does_not_call_handler)가 의도치 않은 admission(message edit 이벤트) 방지.

Code review 분류 기준

5-agent code review에서 7건 후보 발견했으나 모두 80점 미만: - 70점: test isolation (functionality 영향 X) - 65점: None 가드 누락 (broad try/except로 dampened) - 60점: per-instance lock race (collision 빈도 moderate) - 50점 이하: docstring drift, 가설 검증, 테스트 inline-guard drift

80점 임계값이 합리적: 50-70대는 follow-up 후보. 머지 차단할 정도는 아님.

사용자 결정 패턴: “전체 자동화 + fail-safe”

“전체 자동화. 밀려오는 작업을 다 파악하기 힘들고, 문제 생기면 그때 수정하는 전략.”

자동화의 위험을 fail-safe 메커니즘으로 덮는 패턴. 단계별 회수 동작(라벨만 / worktree 진행 중 / PR 생성됨)을 명확히 정의해 사용자가 “어디까지 진행됐는지” 파악 후 결정 가능. silent 진행 알림(자동 승인 시 DM)도 같은 맥락.

코드 리뷰 후보 (follow-up)

머지 차단은 아니지만 향후 검토 가치 있는 항목:

  1. _handle_cancel_comment linear_client is None 명시 가드 (HAN-65 패턴, score 65) — broad try/except로 crash는 막지만 사용자 DM “회수됨”이 false success 신호 전달
  2. _classify_recovery_stage in spec_gate.py monkeypatch hook 부재 (score 70) — TC12 fixture가 bridge 측만 patch, spec_gate 측은 real default 파일 읽음 → CI flakiness 위험
  3. spec_gate.py handle_reaction docstring drift (score 50) — thumbsdown 동작이 auto-discovery 제거만 명시, 실제는 approved/implementing + DM
  4. _get_spec_gate_store() 싱글톤화 (score 60) — per-instance threading.Lock이 cross-thread 직렬화 안 됨

별도 follow-up 티켓 필요 시 생성. 본 이슈 자체는 Done.

링크