
    o0j                        d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
 dZdZdZd	Ze G d
 d             ZedddZddZed	 	 	 	 	 	 	 	 	 	 	 	 	 ddZdddZedk(  r e e             y)u  scripts.result_only_no_commit_guard — task-2755 Wiring3.

result-only executor task 가 canonical main 에서 commit/push/PR/merge 를 시도하면
차단(hard fail)한다. result.json inbox write(git 아님)는 허용. f7232015 유형
(result-only artifact 의 canonical main commit) 재발을 구조적으로 차단.

side-effect 0: 순수 판정 함수 + CLI. cron/subprocess(git 실행) 0, key/token 0,
owner_proof_pickup_gate 미참조. canonical main 보호 경계만.
    )annotationsN)	dataclass)OptionalSequencez/home/jay/workspace)commitpushmerge)creater	      c                  4    e Zd ZU ded<   dZded<   dZded<   y)GuardDecisionboolallowed strreasonactionN)__name__
__module____qualname____annotations__r   r        :/home/jay/workspace/scripts/result_only_no_commit_guard.pyr   r      s    MFCFCr   r   rootc               .   t        |t              r|j                         dk(  sy	 t        j                  j                  |       }t        j                  j                  |      }t        j                  j                  ||g      |k(  S # t        $ r Y yw xY w)uw  cwd 가 canonical root(또는 그 하위 디렉토리)이고 branch 가 main 이면 True.

    ★ HIGH fix (PR #228 inline): 기존 구현은 ``realpath(cwd) == realpath(root)``
      정확 일치만 검사 → canonical root 하위(``dispatch/``, ``scripts/`` 등)에서
      ``git commit`` / ``gh pr`` 실행 시 우회됨(Wiring3 핵심 결함). symlink 정규화
      후 ``os.path.commonpath`` 로 cwd 가 root 의 하위(또는 동일)인지 판정한다.

    경계 규칙:
      - branch 가 'main' 이 아니면 → False (feature branch/worktree false-positive 방지).
      - cwd == root 또는 cwd 가 root 하위 → True (canonical context, 하위 디렉토리 포함).
      - cwd 가 canonical root '밖' → False (불필요한 차단 방지, false-positive 0;
        ``/home/jay/workspaceX`` 같은 prefix-유사 sibling 은 commonpath 경계로 정확히 배제).
      - 경로 정규화/commonpath 판정 불가(예외) + branch == main → fail-safe 로
        canonical 간주(True, 차단 우선). path traversal/symlink/상대경로 혼동 시에도
        보수적으로 차단(차단 우선 = 안전).
    mainFT)
isinstancer   stripospathrealpath
commonpath	Exception)cwdbranchr   real_cwd	real_roots        r   is_canonical_mainr*      s~    " vs#&(@77##C(GG$$T*	 ww!!8Y"78IEE s   A!B 	BBc                    | D cg c]4  }t        |t              s|j                         s%|j                         6 c}S c c}w )u   argv 토큰 정규화 — str 토큰만 추출 + 앞뒤 공백 제거.
    `" commit "` 처럼 공백 패딩으로 exact-match 우회하는 시도를 차단(fail-safe).)r   r   r    )argsas     r   _norm_tokensr.   <   s/      $H!z!S'9aggiAGGIHHHs   AAAc               0   |st        dd      S t        |||      st        dd      S t        |      }| dk(  r$|D ]  }|t        v st        dd| d	d
      c S  n,| dk(  r'd|v r#|D ]  }|t        v st        dd| d	d
      c S  t        dd      S )um  result-only task 의 canonical main 에서 commit/push/PR/merge 차단 판정.
    result_only=False 또는 canonical main 아님 → 항상 allowed(무간섭).
    git 이 아닌 일반 파일 write(result.json inbox)는 이 함수 대상 아님 → 호출자가 allowed.

    ★ 보안(fail-safe): 글로벌 플래그/값을 통한 우회(`git -c user.name=x commit`,
      `gh --repo o/r pr create`)를 막기 위해 "첫 토큰"만 보지 않고 **전체 argv 토큰을
      exact-match 스캔**한다(_first_subcommand 의 위치 가정 우회 차단). forbidden
      subcommand 가 위치와 무관하게 존재하면 차단. result-only task 는 어차피
      commit/push/merge 호출 0 이 정상이므로 보수적 차단이 안전(false-allow 0).
      공백 패딩(`git " commit "`)·글로벌 옵션 별칭(`--git-dir=`, `-c`, `--repo=`) 우회 모두 차단.Tnot_result_only)r   r   r   not_canonical_maingitFresult_only_git__on_canonical_main	hard_fail)r   r   r   ghprresult_only_gh_pr_r   )r   r*   r.   FORBIDDEN_GIT_SUBCOMMANDSFORBIDDEN_GH_PR_ACTIONS)toolr,   r&   r'   result_onlyr   tokenstoks           r   check_commandr?   B   s    & T2CDDS&t4T2FGG$Fu} 	C//$!-cU2DE& 	 
 6> 11( %!3C58JK*  i88r   c                   t        j                  d      }|j                  dddgd       |j                  dt        j                                |j                  d	d
       |j                  dd       |j                  dt
               |j                  dt         j                  d       |j                  | t        |       nd       }|j                  }|r|d   dk(  r|dd  }t        |j                  ||j                  |j                  |j                  |j                        }|j                   ryt"        j$                  j'                  d|j(                   d|j*                   d       t,        S )Nz/result-only no-commit guard (task-2755 Wiring3))descriptionz--toolr2   r6   )choicesdefaultz--cwd)rC   z--branchr   z--result-only
store_true)r   z--rootcmdu   -- 뒤의 서브커맨드 argv)nargshelpr   z--   )r&   r'   r<   r   z'[result_only_no_commit_guard] BLOCKED: z	 (action=z)
)argparseArgumentParseradd_argumentr!   getcwdCANONICAL_ROOT	REMAINDER
parse_argslistrE   r?   r;   r&   r'   r<   r   r   sysstderrwriter   r   GUARD_BLOCK_EXIT)argvpnsr,   ds        r   r   r   p   s,   ,]^ANN8eT]ENBNN7BIIKN0NN:rN*NN?<N8NN8^N4NN5 2 29YNZ	
D$4d4j$	?B66DQ4ABxbggt		r~~dfdkdklAyyJJ>qxxj	RSRZRZQ[[^_`r   __main__)r&   r   r'   r   r   r   returnr   )r,   Sequence[str]rZ   rP   )r;   r   r,   r[   r&   r   r'   r   r<   r   r   r   rZ   r   )N)rU   zOptional[Sequence[str]]rZ   int)__doc__
__future__r   rI   r!   rQ   dataclassesr   typingr   r   rM   r9   r:   rT   r   r*   r.   r?   r   r   
SystemExitr   r   r   <module>rb      s    #  	 
 ! %&7 -  
  
 =K :I ,9
,9
,9 
	,9
 ,9 ,9 ,9 ,9\$ z
TV
 r   