
    i'                       d Z ddlmZ ddlZddlZddlZddlZddlZddl	Zddl
mZ ddlmZ ddlmZmZmZ ddlmZ dd	lmZmZ  ej.                  d
      Z ej2                  ej4                  d        ee      ZddZd dZd!dZd"dZ d#dZ!d$dZ"d%dZ#d%dZ$d%dZ%ejM                  ddg      d        Z'ejM                  ddg      d        Z(d&dZ)edk(  r e)        yy)'uM   anu-confirm-bot — Telegram inline button webhook for Tier 2 1-tap approval.    )annotationsN)Path)Any)Flaskjsonifyrequest   )config)sign_callbackverify_callbackanu_confirm_botz1%(asctime)s [%(levelname)s] %(name)s: %(message)s)levelformatc                0   t         j                  st        j                  d       dd| |dS dt         j                   d|  }t        j
                  j                  |      j                  d      }	 t        j                  j                  ||d	      5 }t        j                  |j                         j                  d            cd
d
d
       S # 1 sw Y   y
xY w# t        $ r0}t        j                  d|        dt!        |      dcY d
}~S d
}~ww xY w)u2   Telegram Bot API 호출 (urllib, 외부 의존 0).u$   BOT_TOKEN 미설정 — dry-run modeFT)okdry_runmethodpayloadzhttps://api.telegram.org/bot/utf-8
   )datatimeoutNu   Telegram API 호출 실패: r   error)r
   	BOT_TOKENloggerwarningurllibparse	urlencodeencoder   urlopenjsonloadsreaddecode	Exceptionr   str)r   r   urlr   respexcs         M/home/jay/workspace/.worktrees/task-2460-dev6/scripts/anu_confirm_bot/main.py_telegram_apir.      s    =>7SS()9)9(:!F8
DC<<!!'*11':D0^^##CdB#? 	;4::diik009:	; 	; 	; 03C59:c#h//0s<   2"C 2C	C CC C 	D%%D
DDc                   | j                  d      rt        | j                  dd            n
t        |       }t        t        j                               t        j
                  z   }t        d|||t        j                        }t        d|||t        j                        }t        d|||t        j                        }d| d|j                  dd	       d
|j                  dd	       d|j                  dd	       d| d|j                  dd	       d}dd|dd|dd|dggi}	t        j                  |t        j                  |	d      d}
t        d|
      S )u   Tier 2 머지 후보 PR에 대해 inline button 카드 발송.

    summary: {"files": int, "additions": int, "deletions": int, "level": int, ...}
    task- ardu	   ★ task-u'    Tier 2 머지 승인 필요
- 변경: files?u
    파일, +	additionsz / -	deletionsz
- PR #u    · Lv.r   u2    · scope_guard PASS · qc PASS
- 만료: 5분 후inline_keyboardu   ✅ Approve)textcallback_datau
   ❌ Rejectu	   👁 DiffFensure_ascii)chat_idr:   reply_markupsendMessage)
startswithintreplacetimer
   TTL_SECONDSr   
SECRET_KEYgetCHAT_IDr$   dumpsr.   )task_idpr_numsummarytask_numexpirycb_acb_rcb_dr:   keyboardr   s              r-   send_approval_cardrS   '   sc   
 5<4F4Fw4Os7??7B/0UXY`UaH 2 22Fh8I8IJDh8I8IJDh8I8IJD H: [[#./ 0KKS)*$w{{;/L.M NGS 9: ;	 	 	"T:!D9 48
 H >>

8%@G
 00    c                L    t        t        j                        d|  d| d| z  S )Nz
processed--)r   r
   PROCESSED_DIRrM   rK   actions      r-   _processed_markerrZ   H   s+    $$%*XJaxq(QQQrT   c                8    t        | ||      j                         S )N)rZ   existsrX   s      r-   _is_processedr]   L   s    Xvv6==??rT   c                    t        | ||      }|j                  j                  dd       |j                  t	        j
                  t        t        j                               |ddd      d       y )	NTparentsexist_ok)	timestampresultF   )r=   indentr   encoding)rZ   parentmkdir
write_textr$   rI   rB   rD   )rM   rK   rY   rc   markers        r-   _mark_processedrl   P   s_    x8F
MMt4


TYY[!1VDSXabc  rT   c                ,   t        t        j                        dz  dz  }|j                  dd       |dz  }d}|j	                         r'	 t        d |j                  dd	
      D              dz   }| j                  dt        j                  dt        j                                      || d<   d| d<   |j                  dd	
      5 }|j                  t        j                  | d      dz          ddd       y# t        $ r d}Y w xY w# 1 sw Y   yxY w)u?   memory/audit/auto-merge.log에 본 webhook 기원 entry 기록.memoryauditTr_   zauto-merge.logr	   c              3      K   | ]  }d   yw)r	   N ).0_s     r-   	<genexpr>z _audit_append.<locals>.<genexpr>a   s     L1Ls   r3   r   rf   rb   z%Y-%m-%dT%H:%M:%S%zsequencer   mergerr2   Fr<   
N)r   r
   WORKSPACE_ROOTri   r\   sumopenOSError
setdefaultrD   strftime	localtimewriter$   rI   )record	audit_dir	audit_logru   fs        r-   _audit_appendr   Y   s   V**+h6@IOOD4O0,,IH	LinnS7n&KLLqPH k4==1FHX#YZ!F:(F8	g	. ?!	

66=>? ?  	H	
? ?s   &C9 *D
9DD
Dc           
        t        t        j                        dz  dz  d|  dz  }|j                         rd| |d|  ddd	S t        t        j                        d
z  dz  }d|  }dD ]b  }t	        j
                  dt        |      ||gddd      }|j                  dk7  s9d| |d| d|j                  dd  |j                  d| dc S  t        t        j                        d
z  dz  }dt        |      d|g}	 t	        j
                  |ddd      }	|	j                  dk(  | ||	j                  dd |	j                  dd |	j                  ddS # t        $ r}
d| |t        |
      ddcY d}
~
S d}
~
ww xY w) u   gh pr merge 호출. GitHub API가 직렬화 보장.

    Lock-in 1 First-line: cancelled 검사 + guard.sh 강제 실행이 함수 첫 statement.
    Lock-in 2 Hard stop: 가드 실패 시 gh pr merge subprocess 진입 0회 보장.
    rn   eventsr0   z
.cancelledFu"   cancelled — merge blocked (task-)z anu_confirm_bot.cancelled_marker)r   rM   rK   stderr
blocked_byscriptszguard.sh)zpre-pushzqc-checkbashT<   capture_outputr:   r   r   z	guard.sh z FAIL: iNz	guard.sh.)r   rM   rK   r   
returncoder   z
taskctl.pypython3mergex   ztaskctl.merge)r   rM   rK   stdoutr   r   
routed_via)r   rM   rK   r   r   )r   r
   rx   r\   
subprocessrunr)   r   r   r   r(   )rM   rK   _cancelled_marker	_guard_sh_task_id_stage_gp_taskctlcmdprocr,   s              r-   _execute_approver   k   s    V223h>IeT\S]]gLhh!VQst|s}}~O  Pr  s  	sV**+i7*DIxj!H* Ennfc)nfhGX\cgqst>>QXU^_e^ffmnqnxnxy}y~n  nA  TB  RU  R`  R`  r{  |B  {C  pD  E  EE F))*Y6EHc(mWh
7Cw~~c$T3O//Q& kk$%(kk$%(//)
 	
  wVcRUhfuvvws   =AE 	E5E0*E50E5c           
     "   dddt        |      dt        j                  dd|  dg}	 t        j                  |ddd	
      }|j
                  dk(  |j                  dd |j                  dd dS # t        $ r}dt        |      dcY d}~S d}~ww xY w)u5   reject: PR에 코멘트 추가하고 escalate 알림.ghprcommentz--repoz--bodyu.   [REJECT] Tier 2 인라인 버튼 거부 (task-u   ). 회장 검토 필요.T   r   r   r   N)r   r   r   Fr   )	r)   r
   GH_REPOr   r   r   r   r   r(   )rM   rK   r   r   r,   s        r-   _execute_rejectr      s    y#f+xEhZOghjC0~~c$T2Noo*dkk$%6HTXT_T_`d`eTfgg 0c#h//0s   AA- -	B6B	B	Bc                <    dt         j                   d| }d| ||dS )u=   diff: PR 페이지 URL 반환 (Telegram에 메시지 발송).zhttps://github.com/z/pull/T)r   rM   rK   diff_url)r
   r   )rM   rK   pr_urls      r-   _execute_diffr      s(    "6>>"2&AFHFSSrT   z/healthzGET)methodsc                 :    t        dt        j                  d      S )Nr   )statustrigger_marker)r   r
   TRIGGER_MARKERrq   rT   r-   healthzr      s    df6K6KLMMrT   z/webhookPOSTc                 r   	 t        j                  d      } | j	                  d      }|st        ddd	      d
fS |j	                  dd      }|j	                  dd      }t        |t        j                        }|d   s_t        j                  d|d    d|        t        d|d|d    dd       t        dddd|d   |dd d       t        d|d   d      dfS |d   }|d   }|d   }t        |||      r t        d|ddd       t        dd d      d!fS |d"k(  r"t        ||      }|j	                  d      rd#nd$}	n/|d%k(  rt        ||      }d&}	n|d'k(  rt        ||      }d(}	ndd)d*}d&}	t!        ||||       t        d+| |d|	||j	                  d      |j	                  d,d      dd
 d-d.       d/d0|j	                  d1d      dd2  d3d4|j	                  d5d       d6j	                  |	d7      }
t        d||
dd       t        d|	|||d8      d
fS # t        $ r t        ddd      dfcY S w xY w)9u'   Telegram inline button callback 수신.T)forceFinvalid_json)r   reasoni  callback_queryno_callback_query)r   ignored   r   r1   idr   u   callback 검증 실패: r   z | data=answerCallbackQueryu   ❌ 검증 실패: )callback_query_idr:   
show_alertunknownNtier2callback_rejected    )rJ   	pr_numbertieroutcomer   callback_data_prefixi  rY   rM   rK   u    이미 처리됨 (replay 차단)already_processedi  r2   mergedmerge_failedr3   rejectedr4   
diff_shownunknown_actionr   r0   r   )r   r   )rJ   r   r   r   rY   callback_resultu   ✅ 머지 완료u   ❌ 머지 실패: r   d   u,   ❌ Reject 처리 — PR에 코멘트 추가z	PR diff: r   )r   r   r   r   u   처리 완료)r   r   rY   rM   rK   )r   get_jsonr(   r   rG   r   r
   rF   r   r   r.   r   r]   r   r   r   rl   )updater   r;   callback_idverifiedrY   rM   rK   rc   r   user_msgs              r-   telegram_webhookr      s   E!!- ZZ 01Nd/BCDcII"&&vr2M $$T2.K}f.?.?@HD>1(82D1EXm_]^+;Zmnvw  oA  nB  YC  SW  .X  	Y *x($1#2$6
 	 ex/ABCSHHhF
#HhFXvv.+;Xz  KO  .P  	Qe/BCDcII}!(F3$jj.(N	3 62	3x0(89Hfff58*%"(**T"2fjjSU>VW[X[>\]  &-fjj9.Mds.S-TUB!&**Z"<!=>	
 
c'?#  '{T\lq)rs$7fRZflmnpsss  Ee~>?DDEs   H H65H6c                     t         j                  dt        j                   dt        j                   dt        j
                          t        j                  t        j                  t        j                  d       y )Nu   anu-confirm-bot 시작: :z
, trigger=F)hostportdebug)r   infor
   LISTEN_HOSTLISTEN_PORTr   appr   rq   rT   r-   mainr      sW    
KK*6+=+=*>a@R@R?SS]^d^s^s]tuvGG##&*<*<EGJrT   __main__)r   r)   r   dict[str, Any]returndict)rJ   r)   rK   rB   rL   r   r   r   )rM   rB   rK   rB   rY   r)   r   r   )rM   rB   rK   rB   rY   r)   r   bool)
rM   rB   rK   rB   rY   r)   rc   r   r   None)r   r   r   r   )rM   rB   rK   rB   r   r   )r   r   )*__doc__
__future__r   r$   loggingr   rD   urllib.parser   urllib.requestpathlibr   typingr   flaskr   r   r   r1   r
   signerr   r   	getLoggerr   basicConfigINFO__name__r   r.   rS   rZ   r]   rl   r   r   r   r   router   r   r   rq   rT   r-   <module>r      s    S "         ) )  2			,	-   ',,/b cHo01BR@?$wD0T :w'N (N :x(Ct )CtLK
 zF rT   