
    i]V                    h   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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dZd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ddZddZy)u  tests/regression/test_taskctl_reconcile.py — task-2472+1 회귀 테스트 (T1~T8).

헤임달 (개발2팀 테스트 엔지니어) 작성.
reconcile_orphaned_merge 공개 API를 격리된 환경에서 검증한다.

주의:
- 외부 gh/git 호출 금지. fake_gh 또는 monkeypatch로 격리.
- state_dir_override, events_dir_override, audit_path_override로 tmp_path 격리.
- forbidden_paths(memory/events/task-2472.* 등) 절대 변경 금지.
    )annotationsN)Path   )RECONCILE_AUDIT_FIELDScompute_done_sha256reconcile_orphaned_mergec                    | dz  }|j                  d       |dz  }|j                  dt        j                  |       d       |j	                  d       t        |      gS )uJ   tmp_path에 fake gh shell script 생성. payload를 JSON으로 echo한다.fake_gh_binT)exist_okghz#!/usr/bin/env bash
echo 'z'
i  )mkdir
write_textjsondumpschmodstr)tmp_pathpayloadgh_dirscripts       Z/home/jay/workspace/.worktrees/task-2472+1-dev2/tests/regression/test_taskctl_reconcile.pymake_fake_ghr   $   sa    %F
LL$Ld]F

&tzz'':&;4@ LLK=    c                n    | | dz  }||dd}|j                  t        j                  |      d       |S )u&   task-timer 포맷 .done 파일 생성..donez2026-05-07T00:00:00Z)task_id	qc_resultcompleted_atutf-8encoding)r   r   r   )
events_dirr   r   	done_pathr   s        r   make_done_filer$   0   sG    y..I.G
 G,w?r   c                   | j                   j                  dd       |ddddddd	| d
|dddddd}t        t        |       dd      5 }|j	                  t        j                  |      dz          ddd       y# 1 sw Y   yxY w)uG   audit jsonl에 done_sha256 포함 최소 라인 작성 (사전 시드).T)parentsr   z2026-05-01T00:00:00Z state_orphaned_after_valid_merge(   abc1234abc1234 PASSzmemory/events/r   
no_g3_failzhuman <human@test>z/memory/orchestration-audit/state-recovery.jsonlpre_seed)r   tsclassificationprmerge_commitorigin_main_headancestryr#   done_sha256g3_fail_classificationactorevidence_pathapproved_by_chairmandecisionar   r    
N)parentr   openr   writer   r   )
audit_pathr   r4   recordfs        r   write_audit_linerB   <   s    D48$<(%gYe4"".%J $F  
c*osW	5 +	

6"T)*+ + +s   
(A;;Bc                   | dz  dz  dz  }|j                         s
J d|        |j                  d      j                         j                         }d}t	        |      D ]W  }|j                         }|st        j                  |      }|j                  d      |k(  s@|j                  d	      d
k(  sU|} n |J d| d       t        D cg c]	  }||vs| }}|r
J d|        t        D ]  }	||	   	J d|	d        |S c c}w )u.  workspace/memory/orchestration-audit/state-recovery.jsonl에서
    task_id 매칭 reconcile_state_created 레코드 파싱 + 14필드 검증.

    append_reconcile_audit는 workspace 기반으로 고정 경로에 기록하므로
    audit_path_override가 아닌 workspace 경로를 사용한다.
    memoryzorchestration-auditstate-recovery.jsonlu   audit jsonl 없음: r   r    Nr   r9   reconcile_state_createdu   audit에서 task_id=u&    reconcile_state_created 라인 없음u   audit 14필드 누락: u   audit 필드     값이 None)	exists	read_textstrip
splitlinesreversedr   loadsgetr   )
	workspacer   r?   linesr@   lineobjrA   missingfields
             r   assert_all_audit_fieldsrU   S   sE    X%(==@VVJC"6zl CC  ' 288:EEGEF zz|jj779(SWWZ-@D]-]F e!5gY>dee0DQAVOqDGD;1';;;' Pe}(OM%,*OO(PM	 Es   	D	D	c                2   d}d}d}ddd|id}t        | |      }| dz  }|j                          t        ||      }t        |      }	| d	z  d
z  }
t	        |
||	       | dz  }|j                  dt        t        j                               ddl	m
} |j                  |dd!d       t        |||t        |
      d| d||||
      }|d   du sJ d|d           || dz  }|j                         sJ d       t        j                  |j!                               }|d   dk(  sJ |j#                  d      }t        j$                  |ddd      }t'        j(                  |j+                  d            j-                         }||k(  sJ d        t/        | |       y)"uF   T1: state file missing + PR merged + valid .done → reconcile 성공.ztask-t1-reconciled   *abc1234abc1234abc1234abc1234abc1234abc1234MERGEDz2026-05-01T12:00:00ZoidstatemergedAtmergeCommiteventsauditrE   r\   zutils.state_repair.sys.modulesr   Ncheck_origin_main_ancestryc                    dd| dddS )NTzancestry PASS (monkeypatched)origin_head_fakemerge_commit_sha
origin_shaokreasondetail shacwds     r   <lambda>z+test_t1_reconcile_success.<locals>.<lambda>   s    5+.>PQ
 r   	test/repoTr   	pr_numberre   r7   reporO   r8   gh_cmdstate_dir_overrideevents_dir_overrideaudit_path_overriderh      reconcile 실패: ri   .jsonu   state 파일 미생성current_stateDONE	_checksumF,:ensure_ascii	sort_keys
separatorsr   u   state checksum 불일치N)r   r   r$   r   rB   setattrdictsysmodulesutils.silent_corruption_guardsilent_corruption_guardr   r   rH   r   rM   rI   popr   hashlibsha256encode	hexdigestrU   )r   monkeypatchr   rr   re   
gh_payloadfake_ghr"   r#   done_shar?   	state_dirscg_modresult
state_file
state_datastored_checksumcanonexpected_checksums                      r   test_t1_reconcile_successr   s   s   !GIC */0J
 8Z0G H$Jz73I"9-H G#&<<JZ(3 7"I (S[[ 4$	
 &)*o!$&&F $<4H#5fX6F5G!HH y..J8 88J0023Jo&&000 !nn[1OJJzR\]Eu||G'<=GGI//K1KK/ Hg.r   c                    d}d}dddd}t        | |      }| dz  }|j                          | dz  }| dz  d	z  }t        ||d
t        |      d| d||||      }	|	d   du sJ |	d   dk(  sJ d|	d    d       y)u$   T2: PR not merged → step 1 실패.ztask-t2-open-pr   OPENNr[   r_   r\   r`   rE   (deadbeefdeadbeefdeadbeefdeadbeefdeadbeefrp   Trq   rh   Fstep_failed   step_failed=u    (1 예상))r   r   r   r   )
r   r   r   rr   r   r   r"   r   r?   r   s
             r   test_t2_pr_not_mergedr      s    GI J
 8Z0GH$J7"IG#&<<J%'*o!$&&F $<5   - A%Xf]6K5LK'XX%r   c                   d}d}d}ddd|id}t        | |      }| dz  }|j                          || d	z  }|j                  t        j                  d
di      d       t        |      }	| dz  dz  }
t        |
||	       | dz  }ddlm} |j                  |dd d       t        |||t        |
      d| d||||
      }|d   du sJ |d   dk(  s1d|d   j                         v sd	|d   v sJ d|d    d|d           yyy)!uD   T3: invalid .done (스키마 미준수) → schema 오류로 reject.ztask-t3-bad-donei,  (ccccddddeeeeffffccccddddeeeeffffccccddddrY   z2026-05-02T10:00:00ZrZ   r[   r_   r   foobarr   r    r`   rE   r\   r   Nra   c                    dd| dddS NTancestry PASSfake_originrd   rg   rk   rl   s     r   ro   z-test_t3_invalid_done_schema.<locals>.<lambda>	      %+.mL
 r   rp   Trq   rh   Fr      schemari   u   예상과 다른 실패: step=z	, reason=r   )r   r   r   r   r   r   rB   r   r   r   r   r   lower)r   r   r   rr   re   r   r   r"   r#   r   r?   r   r   r   s                 r   test_t3_invalid_done_schemar      sv    GIA */0J
 8Z0GH$J y..IUEN3gF"9-HG#&<<JZ(37"I3$	
 &)*o!$&&F $<5   - A%VH5E5K5K5M)MQX\bck\lQl 
()>(?yPXIYHZ[lQl)M%r   c                   d}d}d}ddd|id}t        | |      }| dz  }|j                          t        ||      }t        |      }	|| d	z  }
|
j	                  t        j                  d
dgi      d       | dz  dz  }t        |||	       | dz  }ddlm	} |j                  |ddd       t        |||t        |      d| d||||      }|d   du sJ |d   j                         }d|v sd|v sJ d|d           yy)uQ   T4: .g3-fail이 unresolved (fail_reasons에 'test failure') → reconcile 차단.ztask-t4-g3-unresolvedi  (dddd1111dddd2222dddd3333dddd4444dddd5555rY   z2026-05-03T10:00:00ZrZ   r[   r_   .g3-failfail_reasonsz test failure: pytest exit code 1r   r    r`   rE   r\   r   Nra   c                    dd| dddS r   rk   rl   s     r   ro   z,test_t4_g3_fail_unresolved.<locals>.<lambda>N  r   r   rp   Trq   rh   Fri   g3
unresolvedu+   reason에 'g3' 또는 'unresolved' 없음: r   )r   r   r$   r   r   r   r   rB   r   r   r   r   r   r   )r   r   r   rr   re   r   r   r"   r#   r   g3_fail_pathr?   r   r   r   reason_lowers                   r   test_t4_g3_fail_unresolvedr   *  sr   %GIA */0J
 8Z0GH$J z73I"9-H 7)8 44L

N%G$HIJ  
 G#&<<JZ(37"I3$	
 &)*o!$&&F $<5   (#))+L<<<#? 
5fX6F5GH?#?r   c                .   d}d}d}ddd|id}t        | |      }| dz  }|j                          | d	z  }| d
z  dz  }	ddlm}
 |j	                  |
ddd       t        |||t        |	      d| d||||	      }|d   du sJ |d   dk(  sJ d|d    d       y)uA   T5: PR=MERGED 이지만 ancestry 검증 실패 → step 2 실패.ztask-t5-ancestry-faili  (eeee1111eeee2222eeee3333eeee4444eeee5555rY   z2026-05-04T10:00:00ZrZ   r[   r_   r\   r`   rE   r   Nra   c                    dd| dddS )NFz8merge_commit not ancestor of origin/main (monkeypatched)r   rd   rg   rk   rl   s     r   ro   z'test_t5_ancestry_fail.<locals>.<lambda>  s    P+.mL
 r   rp   Trq   rh   Fr   r   r   u    (2 예상)r   )r   r   r   r   r   r   r   )r   r   r   rr   re   r   r   r"   r   r?   r   r   s               r   test_t5_ancestry_failr   o  s    %GIA */0J
 8Z0GH$J7"IG#&<<J 4$	
 &)*o!$&&F $<5   - A%Xf]6K5LK'XX%r   c                   d}d}d}ddd|id}t        | |      }| dz  }|j                          t        ||      }d	}	| d
z  dz  }
t        |
||	       | dz  }ddlm} |j                  |ddd       t        |||t        |
      d| d||||
      }|d   du sJ |d   j                         }d|v sd|v sJ d|d           yy)uE   T6: audit의 done_sha256과 실제 .done sha256 불일치 → reject.ztask-t6-sha256-mismatchiX  (ffff1111ffff2222ffff3333ffff4444ffff5555rY   z2026-05-05T10:00:00ZrZ   r[   r_   @aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar`   rE   r\   r   Nra   c                    dd| dddS r   rk   rl   s     r   ro   z+test_t6_checksum_mismatch.<locals>.<lambda>  r   r   rp   Trq   rh   Fri   r   checksumu-   reason에 'sha256' 또는 'checksum' 없음: r   )
r   r   r$   rB   r   r   r   r   r   r   )r   r   r   rr   re   r   r   r"   r#   	wrong_shar?   r   r   r   r   s                  r   test_t6_checksum_mismatchr     s+   'GIA */0J
 8Z0GH$Jz73IIG#&<<JZ)47"I3$	
 &)*o!$&&F $<5   (#))+L|#z\'A 
7x8H7IJA'A#r   c                   d}d}d}ddd|id}t        | |      }| dz  }|j                          t        ||      }t        |      }	| d	z  d
z  }
t	        |
||	       | dz  }ddlm} |j                  |ddd       t        |||t        |
      d| d||||
      }|d   du sJ d|d           t        | |      }t        D ]!  }||v sJ d|d       ||   J d|d        y)uO   T7: 성공 시나리오에서 audit jsonl 14필드 모두 존재 + None 아님.ztask-t7-audit-fieldsi  (aaaa1111bbbb2222cccc3333dddd4444eeee5555rY   z2026-05-06T10:00:00ZrZ   r[   r_   r`   rE   r\   r   Nra   c                    dd| dddS )NTr   t7_origin_headrd   rg   rk   rl   s     r   ro   z)test_t7_audit_14_fields.<locals>.<lambda>  s    %+.>NO
 r   rp   Trq   rh   rx   ri   u   필드 u    없음rG   r   )r   r   r$   r   rB   r   r   r   r   r   rU   r   )r   r   r   rr   re   r   r   r"   r#   r   r?   r   r   r   r@   rT   s                   r   test_t7_audit_14_fieldsr     sW   $GIA */0J
 8Z0GH$Jz73I"9-HG#&<<JZ(37"I3$	
 &)*o!$&&F $<4H#5fX6F5G!HH %Xw7F ( J:'%' ::e}(IGE9L*II(Jr   c                b   d}d}d}ddd|id}t        | |      }| dz  }|j                          || d	z  }|j                  t        j                  |d
d|d      d       t        |      }	|| dz  }
|
j                  t        j                  ddgi      d       | dz  dz  }|j                  d       || dz  }|j                  d| dd       |
j                         j                  }t        j                  t        |      |dz   |dz   f       | dz  dz  }t        |||	       | dz  }ddlm} |j                  |dd.d        t        |||t        |      d!| d||||"      }|d#   du sJ d$|d%           || d&z  }|j!                         sJ t        j"                  |j%                               }|d'   d(k(  sJ |j'                  d)      }t        j                  |d*dd+,      }t)        j*                  |j-                  d            j/                         }||k(  sJ d-       y)/u   T8: task-2472 케이스 격리 재현. 실제 파일 변경 없이 unit test로 검증.

    task_id="task-2472-dogfooding-test" 로 격리.
    ztask-2472-dogfooding-testr(   (6ec4e0d8a4e4d2dd39fbd13eb19a69d4212faebarY   z2026-04-20T08:00:00ZrZ   r[   r_   r   r+   z2026-04-20T07:55:00Z)r   r   r   re   r   r    r   r   zreport not foundrD   reportsT)r&   z.mdz# z report

   r`   rE   r\   r   Nra   c                    dd| dddS )NTzancestry PASS (dogfooding sim)dogfooding_originrd   rg   rk   rl   s     r   ro   z/test_t8_dogfooding_simulation.<locals>.<lambda>\  s    6+.>QR
 r   rp   rq   rh   u#   dogfooding 시뮬레이션 실패: ri   ry   rz   r{   r|   Fr}   r   u#   dogfooding state checksum 불일치r   )r   r   r   r   r   r   statst_mtimeosutimer   rB   r   r   r   r   rH   rM   rI   r   r   r   r   r   )r   r   r   rr   re   r   r   r"   r#   r   r   reports_dirreport_pathg3_mtimer?   r   r   r   r   r   r   r   r   s                          r   test_t8_dogfooding_simulationr   "  s   
 *GIA */0J
 8Z0GH$J y..I

2 0	
 	    #9-H 7)8 44L

N%7$89:   X%	1Kd#7)3/KRy	2WE   "++HHHS2x"}=>G#&<<JZ(37"I3$	
 &)*o!$&&F $<4Y#FvhGWFX!YY y..JJ0023Jo&&000 !nn[1OJJzR\]Eu||G'<=GGI//V1VV/r   )r   r   r   r   returnz	list[str])r+   )r"   r   r   r   r   r   r   r   )r?   r   r   r   r4   r   r   None)rO   r   r   r   r   r   )r   r   ) __doc__
__future__r   r   r   r   r   pathlibr   __file__resolver&   _WT_ROOTr   pathinsertutils.state_repairr   r   r   r   r$   rB   rU   r   r   r   r   r   r   r   r   rk   r   r   <module>r      s   	 #   	 
  >!!#++A.x= HHOOAs8}% 		+.@H/` YP7~=J-Yj6|8J@^Wr   