
    8Cj/                       d Z ddlmZ ddlZddlZddlZddlmZ  ee      j                         j                  d   Z ee      ej                  vr"ej                  j                  d ee             ddlmZmZmZ dZdZd	Zd
ZddZddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddZddZdddZedk(  r ej:                   e              yy)u  scripts/stop_hook_terminal_enforcer.py — Stop Hook Terminal Enforcer (task-2779_b) dry-run.

Stop hook 시점에 terminal artifact 존재 여부를 확인하고 결과를 manifest로 기록하는 dry-run 전용 enforcer.

역할:
  - terminal artifact(report/.done/envelope) 부재 시 manifest를 STOP_HOOK_ENFORCED_TERMINAL_RESULT로
    승격하여 기록(격리 canonical root에만 surface)한다.
  - dry-run 전용: 어떤 경우에도 종료를 차단하지 않는다. 모든 경로에서 exit_code=0.
  - 기존 build_manifest/surface_manifest를 재사용한다.

★ 절대 금지 사항:
  - 실제 Stop hook 설치 0.
  - 실제 종료 차단 0.
  - strict/blocking mode 0.
  - callback fire/delivery 0.
  - subprocess import 0.
  - os.system 0.
  - network 호출 0.
  - cron/systemd 조작 0.
  - raw key/secret/ANU key literal 하드코딩 절대 0.
  - 운영 canonical root에 marker/manifest 생성 0 (코드로 차단).
    )annotationsN)Path   )build_manifestsurface_manifest STATUS_TERMINAL_CALLBACK_MISSING"STOP_HOOK_ENFORCED_TERMINAL_RESULT!ENFORCER_INTERNAL_ERROR_FAIL_OPENz/home/jay/workspace#DRYRUN_PRODUCTION_CANONICAL_REFUSEDc                    	 t        |       j                  d      }t        t              j                  d      }||k(  xs ||j                  v S # t        t
        t        f$ r Y yw xY w)u  canonical_root가 운영 root(_PRODUCTION_CANONICAL_ROOT)로 resolve되는지 검사.

    Path(...).resolve(strict=False) 비교로 symlink/상대경로 우회를 방지한다.
    resolve 실패 시 보수적으로 True(운영으로 간주하여 거부)를 반환한다.
    F)strictT)r   resolve_PRODUCTION_CANONICAL_ROOTparentsOSError
ValueErrorRuntimeError)canonical_rootgivenprods      :/home/jay/workspace/scripts/stop_hook_terminal_enforcer.py_is_production_canonicalr   4   si    ^$,,E,:./77u7E}5 55Z. s   AA A('A(dryrun)branchhead
report_reldone_relenvelope_relmodec               p   	 t        |      }	t        | |||||||      }
|
j                  t        k(  }|rmt        |
_        t        |
j
                  vr|
j
                  j                  t               t        |
j
                  vr|
j
                  j                  t               |	r6d}t        |
j
                  vr|
j
                  j                  t               d}nt        |
|      }d}| ||
j                  t        |
j
                        |dd||dd
S # t        $ r | |t        t        gddddddd
cY S w xY w)u  Stop hook terminal enforcer 실행 (dry-run 전용).

    dry-run 전용: 어떤 경우에도 종료를 차단하지 않는다. 모든 경로에서 exit_code=0.

    동작:
      1. _is_production_canonical로 canonical_root가 운영 root인지 검사.
      2. build_manifest로 artifact 존재 여부 확인.
      3. artifact 부재(STATUS_TERMINAL_CALLBACK_MISSING) 시 manifest를
         STATUS_STOP_HOOK_ENFORCED_TERMINAL_RESULT로 승격.
      4. 운영 canonical이면 surface하지 않고 refused_production=True.
         격리 canonical이면 surface_manifest로 격리 root에만 기록.
      5. 어떤 예외도 밖으로 던지지 않는다(fail-open).

    반환 dict 키:
      task_id, mode, status, statuses, terminal_missing, blocked(항상 False),
      exit_code(항상 0), surfaced_index_path, refused_production, failed_open.

    Parameters
    ----------
    task_id:
        대상 task ID.
    canonical_root:
        격리/테스트용 canonical root 경로 (운영 root 거부).
    worktree_root:
        worktree root 경로.
    branch:
        git branch 이름 (선택).
    head:
        git HEAD SHA (선택).
    report_rel:
        report 파일 상대경로 (선택, None이면 기본값 사용).
    done_rel:
        .done 파일 상대경로 (선택, None이면 기본값 사용).
    envelope_rel:
        callback envelope 상대경로 (선택, None이면 기본값 사용).
    mode:
        enforcer 모드. dry-run 고정 (blocking 미구현).
    )r   worktree_rootr   r   r   r   r    T)r   Fr   )
task_idr   statusstatusesterminal_missingblocked	exit_codesurfaced_index_pathrefused_productionfailed_open)r   r   r$   r   )STATUS_STOP_HOOK_ENFORCED_TERMINAL_RESULTr%   append*STATUS_DRYRUN_PRODUCTION_CANONICAL_REFUSEDr   list	Exception_ENFORCER_INTERNAL_ERROR_STATUS)r#   r   r!   r   r   r   r   r   r   is_prodmanifestr&   surfacedr*   s                 r   run_enforcerr5   C   sW   dD
*>:
 ")'!%	
 $??.NNGHO8@Q@QQ!!(()RS/x7H7HH!!(()IJ H9ARARR!!(()ST!% (PH!& ooX../ 0#+"4 
 	
  
 589 %#%"'
 	

s   DD D54D5c                    t        j                  dt         j                        } | j                  ddd       | j                  ddd       | j                  d	dd
       | j                  ddd       | j                  ddd       | j                  dddd       | j                  dddd       | j                  dddd       | j                  dddd       | S ) u   argparse 파서 생성.

    --canonical-root는 required=True (기본값 없음) — 실수로 운영 canonical default 사용 방지.
    uW   Stop Hook Terminal Enforcer CLI (task-2779_b) — dry-run 전용, 종료 차단 없음.)descriptionformatter_classz	--task-idTu"   대상 task ID (예: task-2779_b).)requiredhelpz
--worktreeu+   worktree root 경로 (절대경로 권장).z--canonical-rootu[   격리/테스트 canonical root 경로 필수 — 운영 root 지정 시 surface 거부됨.z--branchNu   git branch 이름 (선택).)defaultr:   z--headu   git HEAD SHA (선택).z--report-relr   u$   report 파일 상대경로 (선택).)r;   destr:   z
--done-relr   u#   .done 파일 상대경로 (선택).z--envelope-relr   u(   callback envelope 상대경로 (선택).z--json
store_trueoutput_jsonu   결과를 JSON으로 출력.)actionr<   r:   )argparseArgumentParserRawDescriptionHelpFormatteradd_argument)ps    r   _build_parserrE      s   
 	e <<		A NN;4XNYNN<$5bNcNNj  
 NN:t2ONPNN8T0HNINN3	   NN2	   NN7	   NN+	   H    c                   d| d    d| d    d| d    d| d   d	| d
    d| d    d| d    d| d    d| d    g	}| d   r|j                  d| d           n|j                  d       dj                  |      S )uD   사람이 읽을 수 있는 enforcer 결과 요약 문자열 반환.z)[stop-hook-enforcer] task_id           : r#   z)[stop-hook-enforcer] mode              : r   z)[stop-hook-enforcer] status            : r$   z)[stop-hook-enforcer] statuses          : r%   z)[stop-hook-enforcer] terminal_missing  : r&   z)[stop-hook-enforcer] blocked           : r'   z)[stop-hook-enforcer] exit_code         : r(   z)[stop-hook-enforcer] refused_production: r*   z)[stop-hook-enforcer] failed_open       : r+   r)   z)[stop-hook-enforcer] surfaced_to       : u^   [stop-hook-enforcer] surfaced_to       : (surface 실패, 운영 거부, 또는 경로 없음)
)r-   join)resultliness     r   _human_summaryrL      s     4F94E3FG
3F6N3CD
3F84D3EF
3F:4F3IJ
3F;M4N3OP
3F94E3FG
3F;4G3HI
3F;O4P3QR
3F=4I3JK
E #$7?T8U7VW	
 	l	
 99UrF   c                "   t               }	 |j                  |       }	 t        |j                  |j                  |j                  |j                  |j                  |j                  |j                  |j                  d	      }|j                  r"t        t!        j"                  |dd             nt        t%        |             |d   S # t        $ r-}|j                  t	        |j                        ndcY d}~S d}~ww xY w# t&        $ r Y y	w xY w)
u   CLI 메인 진입점.

    dry-run 전용: 어떤 경우에도 0 반환 — 종료를 절대 차단하지 않는다.
    argparse SystemExit는 그대로 코드 반환, 그 외에는 모든 경로에서 0 반환.
    Nr   r   )r   r!   r   r   r   r   r   r   F   )ensure_asciiindentr(   r   )rE   
parse_args
SystemExitcodeintr5   r#   r   worktreer   r   r   r   r   r>   printjsondumpsrL   r0   )argvparserargsexcrJ   s        r   mainr]     s     _F<  &
LL..--;;]]**

 $**V%BC.() k""/  < # 4s388}!;<2  s/   C	 B*D 		C?"C:4C?:C?	DD__main__)r   strreturnbool)r#   r_   r   r_   r!   r_   r   
str | Noner   rb   r   rb   r   rb   r   rb   r   r_   r`   dict)r`   zargparse.ArgumentParser)rJ   rc   r`   r_   )N)rY   zlist[str] | Noner`   rT   )__doc__
__future__r   r@   rW   syspathlibr   __file__r   r   
_REPO_ROOTr_   pathinsert dispatch.terminal_artifact_indexr   r   r   r,   r1   r   r.   r   r5   rE   rL   r]   __name__exit rF   r   <module>rp      sC  , #   
  (^##%--a0
z?#(("HHOOAs:'  -Q )"E  3 -R *( !#v
v
 v
 	v

 v
 v
 v
 v
 v
 v
 
v
r,^0$N zCHHTV rF   