
    it                    $   d Z ddlmZ ddlZddlZddlZddlmZmZ ddlm	Z	 ddl
Z
 e	e      j                         j                  d   Zedz  Z ee      ej"                  vr"ej"                  j%                  d ee             ddlZddlZe
j.                  d9d       Ze
j.                  d9d	       Ze
j.                  d
        Z e	e      j6                  j6                  dz  dz  dz  Ze
j:                  j=                  dg d      	 	 	 	 d:d       Zd;dZ e
j:                  j=                  dg d      	 	 	 	 d<d       Z!e
j:                  j=                  dg d      	 	 	 	 	 	 d=d       Z"e
j:                  j=                  dg d      	 	 	 	 	 	 	 	 d>d       Z#e
j:                  j=                  ddddidfd d!d"idfd#ddid$fd%ddid&fd'ddd(dfg      	 	 	 	 	 	 	 	 d?d)       Z$d* Z%d@d+Z&d@d,Z'd- Z(d. Z)d/ Z*d0 Z+d1 Z,d2 Z-d3 Z.d4 Z/d5 Z0d6 Z1d7 Z2d8 Z3y)AuX  
test_lifecycle_penetration.py — task-2469 Phase D Penetration Tests

회장 명시: "기능 추가가 아니라 우회 불가능성 증명. 자동화된 방어 검증 체계를 남겨라."

각 시나리오는:
  - 공격 의도 (docstring)
  - 공격 input 박제 (fixture)
  - Guard 호출
  - assert r.ok is False (또는 high>=1)
  - memory/orchestration-audit/penetration-test-2469.jsonl append

모든 6+ 시나리오 통과 = 우회 시도 0건 성공 = task-2468 Guard 우회 불가능.

Phase 2 (mandatory A-F): 토르 작성 (task-2469)
Phase 3 (optional G-M): 헤임달 작성 (기존)
    )annotationsN)datetimetimezone)Path   scriptsc                0    | dz  }|j                          |S )Neventsmkdirtmp_pathds     Y/home/jay/workspace/.worktrees/task-2514-dev3/tests/taskctl/test_lifecycle_penetration.py
tmp_eventsr   +   s    8AGGIH    c                0    | dz  }|j                          |S )Nevidencer   r   s     r   tmp_evidencer   2   s    :AGGIHr   c              #  L   K   g 	 	 	 	 	 	 	 	 	 	 	 	 d fd}| t         dz  dz  dz  }|j                  j                  dd       |j                  dd	      5 }D ]+  }|j	                  t        j                  |d
      dz          - 	 ddd       y# 1 sw Y   yxY ww)u  audit jsonl emit. 테스트 종료 시 penetration-test-2469.jsonl에 append.

    사용법: audit_emit(scenario, task_id, attack_intent, guard_called, attack_blocked, blocking_reasons)

    attack_blocked: 공격이 차단되었는가? (True = 차단 성공 = 정상)
      - Guard r.ok 기반 호출: `r.ok is False` 전달 (r.ok=False면 차단됨)
      - 직접 boolean: True = 차단됨, False = 우회 성공 (테스트 FAIL 조건)

    production admin-override.jsonl 변조 금지 — 전용 audit 파일에만 append.
    c                    j                  | |||t        |      |rt        |      ng t        j                  t
        j                        j                         j                  j                  d       y )N)scenariotask_idattack_intentguard_calledblockedblocking_reasonsts	test_name)
appendboollistr   nowr   utc	isoformatnodename)r   r   r   r   attack_blockedr   entriesrequests         r   _emitzaudit_emit.<locals>._emitG   s^     	$"!. ,/>ND)9$:TVll8<<0::<$\\..		
r   memoryzorchestration-auditzpenetration-test-2469.jsonlT)parentsexist_okautf-8encodingF)ensure_ascii
N)r   strr   r5   r   r5   r   r5   r(   r!   returnNone)
_REPO_ROOTparentr   openwritejsondumps)r*   r+   
audit_pathfentryr)   s   `    @r   
audit_emitrA   9   s      G


 
 	

 
 

* K h&)>>A^^JD48	w	/ B1 	BEGGDJJu59D@A	BB B Bs   AB$1B	B$B!B$fixtures	task-2469gemini_reviewsmarker_name)zg3-failz	g3-failedg3_fail	g3_failedc                   d| }| | d| z  j                  t        j                  |dgd      d       t        j                  ||       }|j
                  du sJ d	| d
|j                                 t        |j                        dkD  sJ d|j                                  |d| |d| dd|j
                  du |j                         y)u6  공격 의도: G3 verifier가 fail marker를 박제했음에도 .done을 강제 발행하려 시도.
    공격 방법: marker 이름을 4가지 변형으로 위장 (g3-fail / g3-failed / g3_fail / g3_failed).
    기대 차단: lifecycle_guards.check_g3_fail_blocks_done — 4가지 변형 모두 인식.
    ztask-pentest-A-.pentest_attackr   fail_reasonsr0   r1   
events_dirFu   공격 우회 성공! marker=u4    — Guard가 fail marker를 인식하지 못함. r=r   u!   blocking 리스트 비어있음: zA-u&   g3-fail marker 위장 시도 (variant=)check_g3_fail_blocks_doneN)	
write_textr<   r=   lgrP   okas_dictlenblocking)r   rE   rA   r   rs        r   6test_A_done_gfail_concurrent_block_all_marker_variantsrX   p   s      }-GWIQ{m,,88

w9I8JKL 9  	$$WDA445= 
'} 5YY[M	= qzz?QQ"CAIIK= QQ
[M
0Q?#		

r   c                   d}| | dz  j                  t        j                  |dd      d       | | dz  j                  t        j                  |dgd	      d       t        j                  || 
      }|j
                  du sJ d|j                                 d|j                  j                         v s"d|j                  v sJ d|j                           |d|dd|j
                  du |j                         y)u   공격 의도: .done 파일을 직접 작성한 뒤 .g3-fail이 동시 존재.
    공격 방법: 두 파일을 동시에 배치하여 conflict 상태 강제.
    기대 차단: check_done_fail_conflict — done+fail 동시 = CONFLICT → ok=False.
    ztask-pentest-A2z.donez
2026-05-06)r   r   r0   r1   z.g3-failforced_by_attackerrK   rM   FuO   공격 우회 성공! .done + .g3-fail 동시 존재가 차단되지 않음. r=conflictu   동시u,   reason에 conflict/동시 키워드 없음: A2u5   .done 직접 쓰기 + .g3-fail 동시 존재 conflictcheck_done_fail_conflictN)
rQ   r<   r=   rR   r]   rS   rT   reasonlowerrV   )r   rA   r   rW   s       r   #test_A2_done_force_write_with_gfailr`      s   
  GWIU##//

wl;<w 0  WIX&&22

w9M8NOP 3  	##G
CA445= 
YZ[ZcZcZeYfg= ))X-A 
6qxxjAA ?"		

r   zfixture_name,min_high))zhigh_heading_variants.md   )zhigh_inline_labels.md   )zhigh_emoji_variants.mdra   )zhigh_severity_priority.mdrb   )zhigh_keywords.mdra   c                6   t         | z  }|j                         s
J d|        |j                  d      }t        j                  |      }|d   |k\  s&J d|  d|d    d| d|j                  d	g                |d
| d|  d|d   |k\  d|d    d| g       y)uY  공격 의도: Gemini High/Critical severity를 5가지 패턴 계열로 위장.
    공격 방법: heading 변형 / inline label / emoji / severity-priority / keyword.
    기대 차단: count_severities — 모든 변형에서 high>=min_high 검출.
    각 fixture file에 해당 패턴이 충분히(min_high 이상) 포함되어야 함.
    u   Fixture 파일 없음: r0   r1   highu   공격 우회 성공! u
    → high=z < u1    (Guard가 패턴을 인식하지 못함). hits: 	high_hitsBz5pattern group high hiding: count_severitieshigh=zmin_required=N)_FIXTURES_DIRexists	read_textgsprg   get)fixture_namemin_highrA   fixture_pathbodysvs         r   )test_B_gemini_high_hidden_5pattern_groupsrs      s    $ !</L J$;L>"JJ !!7!3D			d	#Bf:! 
 jFCz R;;=66+r;R:S	U! 
&|n5
6
hF	xj9:r   zfake_approver,expected_block))z
random-botT)attackerT)ztaskctl-gate-fakeT)zanu-verifier-2T)JonghyukJeonTc                D   |}	 | dz  }|j                  t        j                  ddddddgdgd      d	       t        j                  ||
      }|j
                  du sJ d|d|j                                  |ddd| d|j
                  du |j                         y )Nzallowed_approvers.jsontaskctl-gatesystem)logintypezanu-verifierru   	approversmanual_loginsr0   r1   allowlist_pathFuE   공격 우회 성공! approver spoofing 차단 실패: fake_approver=. r=Czapprover-testzapprover spoofing: check_approver_identity)rQ   r<   r=   rR   r   rS   rT   rV   )r   fake_approverexpected_blockrA   _cfgrW   s          r   test_C_approver_spoofingr      s     	A
 -
-CNN

 -h?,h? #1!1	
    	""=EA445= 
OP]O` aYY[M	= 
m_-!		

r   z9scenario,fake_sha,fake_base,origin_returns,expected_block))	empty_sha mainabc123T)null_shaNr   r   T)sha_mismatchr   r   DIFFERENT_SHAT)non_main_base_mismatchr   develop	WRONG_SHATc                h   |}fd}fd}	| j                  t        d|       | j                  t        d|	       t        j                  dd      }
|
j                  du s!J d	| d
dd|
j	                                  |d|d| dddd|
j                  du |
j
                         y)uR  공격 의도: 실제 머지된 commit과 다른 SHA로 done 발행하여 SHA 검증 우회.
    공격 방법: empty SHA / null SHA / mismatch SHA / non-main base mismatch.
    기대 차단: check_merge_commit_sha — 4가지 케이스 모두 ok=False.
    monkeypatch로 외부 API 호출 mock — production gh api 호출 금지.
    c                     di dS )NT)merge_commit_shabase_refrS   raw )_args_kwargs	fake_basefake_shas     r   _mock_fetch_prz8test_D_merge_sha_mismatch_attack.<locals>._mock_fetch_pr"  s     (!	
 	
r   c                    | k(  rS dS )NBAD_SHAr   )baser   r   origin_returnss     r   _mock_fetch_originz<test_D_merge_sha_mismatch_attack.<locals>._mock_fetch_origin*  s    !%!2~A	Ar   fetch_pr_merge_shafetch_origin_head_sha!   z
dummy/repo)repoFu9   공격 우회 성공! SHA 공격 차단 실패: scenario=z. fake_sha=z	, origin=r   Dzmerge SHA attack: z (sha=rO   check_merge_commit_shaN)setattrrR   r   rS   rT   rV   )monkeypatchr   r   r   r   r   rA   r   r   r   rW   s     ```      r    test_D_merge_sha_mismatch_attackr   
  s    . 	A
B 0.A35GH
!!"<8A445= 
CH: N<y(:$qyy{m	M= 
XJfXL	.ASSTU 		

r   zscenario,env,audit_setupbypass_no_auditTASKCTL_BYPASS1emptyoverride_no_auditTASKCTL_PR_AUTHOR_OVERRIDEzfake-botbypass_audit_missing_task
other_taskbypass_audit_deleteddeleteproduction_bypass)r   
PRODUCTIONc           
        | dz  }|dk(  r|j                          n:|dk(  r/|j                  t        j                  ddddd      d	z   d
       n|dk(  r	 d| }|j	                  d      dk(  }t        j                  ||||      }|j                  du s!J d| d|d|d|j                                  |d|d| d|j                  du |j                         y)u_  공격 의도: TASKCTL_BYPASS=1 또는 TASKCTL_PR_AUTHOR_OVERRIDE를 사용하면서 audit 누락.
    공격 방법: audit 빈 파일 / 다른 task entry / 파일 자체 삭제 / production 환경.
    기대 차단: check_bypass_audit — 5가지 케이스 모두 ok=False.
    production admin-override.jsonl 변조 금지 — tmp_path 사용.
    admin-override.jsonlr   r   ztask-other-unrelatedz legitimate bypass for other taskz2026-05-01T00:00:00+00:00admin)r   r^   r   actorr4   r0   r1   r   ztask-pentest-E-r   r   )envr>   
productionFuB   공격 우회 성공! audit 누락 bypass 차단 실패: scenario=z. env=z, audit_setup=r   Ezadmin override no audit: check_bypass_auditN)
touchrQ   r<   r=   rm   rR   r   rS   rT   rV   )	r   r   r   audit_setuprA   r>   r   r   rW   s	            r   test_E_admin_override_no_auditr   A  s$   $ 22Jg		$JJ5@5$	   	 	
 
	 z*G&#-J
		A 445= 
LXJ Wg^K?$qyy{m	E= 
#H:.		

r   c           
     >   t        t              j                  j                  dz  dz  dz  dz  }|j                         s
J d|        |j	                  d      }t        j                  |      }|d   d	k\  s
J d
|         | dddd|d   d	k\  d|d    dg       y)ux  공격 의도: 보고서 메타/summary에 'PASS'/'high=0'이라 적었지만 본문에 High 키워드 산재.
    공격 방법: tampered_report_pass_with_high.md — 메타는 PASS이나 본문에 High 패턴 다수.
    기대 차단: count_severities 본문 재검증 → high>=1 검출.
    이것이 task-2467+3 'silent corruption' 사고의 정확한 재현이다.
    rB   rC   rD   z!tampered_report_pass_with_high.mdu   F1 fixture 없음: r0   r1   rd      uX   공격 우회 성공! 본문 high 키워드 위장이 count_severities를 통과함. sv=F1zreport-body-tamperz@report metadata says PASS/high=0 but body contains High keywordsrg   rh   body_high_detectedN)r   __file__r9   rj   rk   rl   rg   )rA   fixturerq   rr   s       r   )test_F1_report_body_pass_but_high_in_bodyr     s     	X$$
	
	 	 .		.  >><27)<<g.D			d	#Bf:? 
bcebfg? J
6
aF	34r   c           	     |   | dz  }|j                          d}||z  }|j                          |dz  j                  t        j                  ddddd      d	
       t	        j
                  |dd|      }|j                  du sJ d|j                                  |d|dd|j                  du |j                         y)u  공격 의도: 다른 task의 g3-pass.json을 현재 task에 재사용 (stale task_id).
    공격 방법: evidence에 task_id="task-2467+3" (다른 task)를 심어 PASS 위장.
    기대 차단: check_done_g3_pass_evidence — task_id 불일치 검출 → ok=False.
    r   ztask-pentest-F2g3-pass.jsonztask-2467+3PASSr   (abc123def456abc123def456abc123def456abc1r   result	pr_numbershar0   r1   c   r   head_shaevidence_dirFuQ   공격 우회 성공! stale task_id evidence 재사용이 차단되지 않음. r=F2u>   stale task_id evidence reuse (task-2467+3 → task-pentest-F2)check_done_g3_pass_evidenceN	r   rQ   r<   r=   rR   r   rS   rT   rV   r   rA   ev_dirr   task_dirrW   s         r   test_F2_stale_task_id_evidencer     s    
 
"F
LLNGHNN**

( A		
  + 
 	&&;		A 445= 
[\]\e\e\g[hi= H%		

r   c           	     |   | dz  }|j                          d}||z  }|j                          |dz  j                  t        j                  |dddd      d	       t	        j
                  |dd
|      }|j                  du sJ d|j                                  |d|dd|j                  du |j                         y)u
  공격 의도: force-push 이후 이전 SHA의 PASS evidence를 재사용 (stale SHA).
    공격 방법: evidence의 sha="DEADBEEF..." (old SHA)이나 실제 HEAD는 NEW_SHA.
    기대 차단: check_done_g3_pass_evidence — sha 불일치 검출 → ok=False.
    r   ztask-pentest-F3r   r   r   (DEADBEEF00000000000000000000000000000000r   r0   r1   )NEW_SHA_AFTER_FORCE_PUSH_0000000000000000r   FuM   공격 우회 성공! stale SHA evidence 재사용이 차단되지 않음. r=F3uD   stale SHA evidence reuse (force-push scenario: DEADBEEF → NEW_SHA)r   Nr   r   s         r   test_F3_stale_sha_evidencer     s    
 
"F
LLNGHNN**

" A		
  + 
 	&&<		A 445= 
WXYXaXaXcWde= N%		

r   c                    | dz  }|j                  t        j                  dgdgd      d       t        j                  d|      }|j
                  d	u sJ  |d
ddd|j
                  d	u |j                         y)uZ  공격 의도: allowed_bot_accounts.json에 비허용 attacker-bot 추가.
    공격 방법: fixture 임시 변조본을 만들어 allowlist_path로 주입.
    기대 차단: check_bot_author_allowlist — production allowlist만 신뢰. 변조본도 attacker-bot이 추가되었지만, _match_bot_author 함수는 패턴 정확히 매칭.
    zallowed_bot_accounts.jsonzjeon-jonghyuk-taskctl-bot[bot]z[bot]exactwildcard_suffixr0   r1   zattacker-humanr~   FGzbot-allowlist-testu   비허용 author 차단 검증check_bot_author_allowlistNrQ   r<   r=   rR   r   rS   rV   r   rA   r   rW   s       r   "test_G_allowed_bot_accounts_tamperr     s     0
0CNN4::23#9    
 	%%&6sKA445==s(*J+QTTU]AJJHr   c                    | dz  }|j                  t        j                  g g d      d       t        j                  d|      }|j
                  du sJ d        |d	d
dd|j
                  du |j                         y)u   공격 의도: allowlist 파일을 빈 list로 변조하여 fail-open 유발 시도.
    기대 차단: 빈 allowlist → fail-closed (모든 author 차단).
    zempty_allowlist.jsonr   r0   r1   zany-bot[bot]r~   Fu7   빈 allowlist 시 fail-closed 안 됨 → 우회 성공G2zempty-allowlistu    빈 allowlist fail-closed 검증r   Nr   r   s       r   'test_G2_bot_allowlist_empty_fail_closedr     sy     +
+CNN4::rBCgNV
%%nSIA445=SSS=t&(J+QTTU]AJJHr   c                    | dz  }|j                  t        j                  g g d      d       t        j                  d|      }|j
                  du sJ  |dd	d
d|j
                  du |j                         y)u   공격 의도: allowed_approvers.json을 빈 list로 변조.
    기대 차단: 빈 list → fail-closed (모든 approver 차단).
    zempty_approvers.jsonr{   r0   r1   zany-botr~   FHzempty-approversu    빈 approvers fail-closed 검증r   N)rQ   r<   r=   rR   r   rS   rV   r   s       r   *test_H_allowed_approvers_empty_fail_closedr     st     +
+CNN4::BDEPWNX
""9SAA445==s%'I(!$$%-Er   c                    | dz  }t        j                  d|      }|j                  du sJ  |dddd|j                  du |j                         y	)
ur   공격 의도: allowed_approvers.json 파일 자체 삭제.
    기대 차단: 파일 부재 → fail-closed.
    znonexistent.jsonrw   r~   FH2zmissing-approversu#   approvers 파일 부재 fail-closedr   N)rR   r   rS   rV   r   s       r   &test_H2_allowed_approvers_missing_filer     sU     '
'C
"">#FA445==t(*O(!$$%-Er   c                   | dz  }t        j                  dd|       |j                  dd       t        j                  ddd	i|
      }|j                  du sJ d        |dddd|j                  du |j
                         y)u  공격 의도: admin-override.jsonl을 truncate하여 과거 audit 흔적 제거.
    공격 방법:
      1. 정상 audit 기록
      2. 파일 truncate
      3. 새 audit 기록
      4. check_bypass_audit 호출 → 과거 task_id의 audit이 사라졌는지 검증.
    기대 차단: check_bypass_audit는 현재 task_id 기준으로 검증. truncate 후 task_id entry 부재 → fail.
    r   ztask-pentest-I-historyztest reason)r>   r   r0   r1   r   r   )r   r>   Fu'   truncate 후 audit 검증 우회 성공Iu#   audit truncate (append-only 위반)r   N)rR   append_admin_override_auditrQ   r   rS   rV   )r   rA   r>   rW   s       r   &test_I_admin_override_overwrite_attackr   -  s     22J""#;]Wab"w/
6$4c#:*4	6A 445=CCC=s,.S#QTTU]AJJ@r   c                   | dz  }|j                          |dz  }|j                          | dz  dz  }|j                  j                          |j                  t        j                  dddd      d	       	 |d
z  j                  |       d}|rRt        j                  ddd|      }|j                  du sJ d        |dddd|j                  du |j                         yt        j                  d       y# t        $ r d}Y ww xY w)uV  공격 의도: events/ 외부에 evidence를 만들고 symlink로 우회.
    공격 방법: g3-pass.json을 evidence_dir 외부 경로로 symlink → 경로 검증 우회 시도.
    기대 차단: check_done_g3_pass_evidence는 evidence_dir/<task_id>/ 안에서만 lookup. 외부 파일은 무시 → 결국 evidence 없음으로 fail.
    r   ztask-pentest-Joutsidezfake_pass.jsonr   abcr   r   r   r0   r1   r   TFr   r   r   u4   symlink + sha mismatch 차단 못함 = 우회 성공Jz"symlink evidence with sha mismatchr   u   symlink 권한 없음N)r   r9   rQ   r<   r=   
symlink_toOSErrorrR   r   rS   rV   pytestskip)r   rA   r   r   r   
symlink_okrW   s          r   test_J_symlink_evidence_outsider  F  s   
 
"F
LLN((HNN"%55GNNtzz.>&Y^"_` '  )	N	"..w7
  **+;r5D9?A ttu}TTT}3(*N0!$$%-	M 	+,  
s   8C8 8DDc                n   | dz  }|j                          | dz  }|j                          |dz  j                  t        j                  dddd      d	       t	        j
                  dd
d|      }|j                  du sJ d|j                           |dddd|j                  du |j                         y
)u}  공격 의도: task_id에 '../'를 포함시켜 path traversal + sha 위조 시도.
    시나리오: 외부 danger/ 디렉토리에 g3-pass.json을 만들어 evidence_dir/../danger/로 접근.
    task_id를 "../danger"로 설정해 경로 탈출을 시도하더라도, head_sha를 다르게 지정하면 sha mismatch로 차단.
    기대 차단: sha 불일치 → ok=False.
    r   dangerr   z	../dangerr   danger_sha_999r   r0   r1   NEXPECTED_SHAr   FuI   path traversal + sha mismatch 시 차단 실패 — guard returned PASS: J2z%task_id path traversal + sha mismatchr   )	r   rQ   r<   r=   rR   r   rS   r^   rV   )r   rA   r   
danger_dirrW   s        r   test_J2_path_traversal_task_idr  h  s     
"F
LLNH$J. ,,TZZ&9I9 . - 
 	&&{d^5;	=A 445= 	  !z	+= t["IKhttu}ajj*r   c                   | dz  }|j                          | dz  dz  }|j                  d       |dz  j                  dd	       t        j                  d
|      }t	        |      dk(  sJ d        |dd
ddddg       |dz  j                  dd	       t        j
                  d
|      }|j                  du sJ  |dd
dd|j                  du |j                         y)u  공격 의도: .g3-fail 마커를 events/ 외부 (.git/, _temp/, dot-prefix dir)에 숨김.
    기대 차단: find_g3_fail_markers는 events_dir만 스캔. 외부 박제는 무시되지만, 동시에 events_dir에 마커가 있을 때 그 마커를 차단함을 검증.
    r
   z.gitfake_eventsT)r-   ztask-pentest-K.g3-failz{}r0   r1   ztask-pentest-KrM   r   uD   hidden path 마커가 events_dir 검색에 포함됨 = 격리 실패Kzhidden path g3-fail isolationfind_g3_fail_markersisolation_okFK2u   events_dir 정상 마커 차단rP   N)r   rQ   rR   r  rU   rP   rS   rV   )r   rA   real_eventshiddenmarkersrW   s         r   )test_K_hidden_path_g3_fail_outside_eventsr    s     X%K.F
LLL&&224'2J%%&6;OGw<1ddds$&E%tn-=? ++77w7O
$$%5+NA445==t%'H*ADDEM1::Gr   c                    t        t              } | j                  d      }|j                         }|D cg c]'  }|j	                         j                  d      rd|v r|) }}t        |      dk(  s
J d|        yc c}w )uR  메타 테스트: 만약 신규 pentest를 xfail로 마스킹하면 회귀 감지.

    이 테스트는 본인이 PASS 함으로써 xfail 마커가 silent 차단의 우회로 쓰이지 않음을 확인.

    실제 의도: 본 파일 안에 @pytest.mark.xfail 데코레이터가 (주석 외) 사용되지 않았는지 정적 검사.
    r0   r1   @xfailr   u]   test_lifecycle_penetration.py에서 @xfail 데코레이터 발견 — pentest 우회 시도: N)r   r   rk   
splitlinesstrip
startswithrU   )	test_filerq   lineslndecorator_liness        r   !test_L_xfail_abuse_detection_metar    s     XI0DOOE$) Hb((*//4B  HO H1$ 
g
	$Hs   ,A=c                     t        t              } | j                  d      }t        j                  d|t        j
                        }t        |      dk\  sJ dt        |       d       y)u   메타: 본 파일에 정의된 test_ 함수가 13개 이상 (mandatory 6 + optional 7).
    pentest를 누락/삭제하면 회귀 감지.
    r0   r1   z^def (test_\w+)   u   pentest 함수 수 = u    < 13 (시나리오 누락)N)r   r   rk   refindall	MULTILINErU   )r  rq   
test_funcss      r   test_L2_pentest_count_metar$    s^     XI0D.bllCJz?b f$9#j/9JJe"ff r   c                H   | dz  }|j                          |dz  }|j                          |dz  j                  t        j                  ddd      d       t	        j
                  ddd|	      }|j                  d
u sJ  |dddd|j                  d
u |j                         y)u   공격 의도: g3-pass.json 파일은 있지만 result="FAIL".
    기대 차단: check_done_g3_pass_evidence — result≠"PASS" 검출.
    r   ztask-pentest-Mr   FAIL)r   r   r0   r1   Nr   FMzg3-pass.json with result=FAILr   )r   rQ   r<   r=   rR   r   rS   rV   r   rA   r   r   rW   s        r   &test_M_report_pass_but_result_not_passr)    s     
"F
LLN((HNN**4::#v7 , +  	&&'74RV5;	=A445==s$&E,addemQZZIr   c                   | dz  }|j                          |dz  }|j                          |dz  j                  dd       t        j                  ddd|      }|j                  d	u sJ  |d
ddd|j                  d	u |j
                         y)u   공격 의도: g3-pass.json을 잘못된 JSON으로 작성하여 파싱 실패 우회 시도.
    기대 차단: 파싱 실패 → fail-closed.
    r   ztask-pentest-M2r   z{not valid json}r0   r1   Nr   FM2zcorrupt JSON g3-pass.jsonr   )r   rQ   rR   r   rS   rV   r(  s        r    test_M2_report_pass_corrupt_jsonr,    s     
"F
LLN))HNN**+=*P
&&'8DSW5;	=A445==t&(C,addemQZZIr   )r   r   r6   r   )r   r   rE   r5   )r   r   )rn   r5   ro   int)r   r   r   r5   r   r!   )r   r5   r   r5   r   r5   r   r!   )r   r   r   r5   r   dictr   r5   )r   r   )4__doc__
__future__r   r<   r   sysr   r   pathlibr   r   r   resolver-   r8   _SCRIPTS_DIRr5   pathinsertlifecycle_guardsrR   gemini_severity_parserrl   r   r   r   rA   r9   ri   markparametrizerX   r`   rs   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r$  r)  r,  r   r   r   <module>r;     s  " #  	 
 '   (^##%--a0
I%|CHH$HHOOAs<()  $     )B )B` X%%,,z9KGJZZ 4#&	8B 	!$	: "	""#&"8<"	"P ?(( 	(
 ( ((\ 	-s3W=	;ZH'R	$'7&=|L	"2C!8(C	CH'R	..!.(,.;>.	.h:%P%^H$	H	E	E@2-D*:G6(gI$Ir   