
    gid                    P   d Z ddlmZ ddlZddlmc 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mZ ddlZ ee      j%                         j&                  d   Zedz  dz  Z ej,                         dd       Zdd	d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y)u  tests/regression/test_archive_escalated_audit.py — task-2471+1 자동화 회귀.

회장 명령 (B): ``.done.escalated`` 처리 자동화 검증.
- archive 스크립트/subcommand로 처리 (수동 삭제 금지)
- 원본 path / size / sha256 / reason / archived_path 를 audit jsonl 자동 기록
- archive 후 .done + .done.escalated 충돌 자동 검증
- 빈 marker 차단

``taskctl archive-escalated`` 자동화 경로의 회귀 차단.
    )annotationsN)Path   scriptsz
taskctl.pyc                    | dz  }|j                          |dz  }| dz  dz  }| dz  }|j                          | dz  }|j                          |j                  dt        |              | |||||dS )	u/   격리 환경: 임시 events_dir + audit jsonl.eventsarchivezorchestration-auditzescalated-archive.jsonlstateevidenceWORKSPACE_ROOT)tmp_path
events_dirarchive_dir	audit_log	state_direvidence_dir)mkdirsetenvstr)r   monkeypatchr   r   r   r   r   s          `/home/jay/workspace/.worktrees/task-2471+1-dev2/tests/regression/test_archive_escalated_audit.pyenvr      s     H$Jy(K003LLI7"IOOj(L'X7 "$     F)reasonfail_when_missingcwdc               :   t         j                  t        t              d| dt        |      dg}|r|d|gz  }|r|j	                  d       t        j                  |dddt        |xs t              i t        j                  dt        |j                        i	      S )
Nzarchive-escalatedz--events-dirz	--machinez--reasonz--fail-when-missingT   r   )capture_outputtexttimeoutr   r   )sys
executabler   TASKCTLappend
subprocessrun	WORKSPACEosenvironparent)task_idr   r   r   r   cmds         r   _run_archiver.   0   s     	GJC 
F##

()>> y!DrzzD+S1B1B-CD r   c                z    || j                          y | j                  t        j                  |d      d       y )NF)ensure_asciiutf-8encoding)touch
write_textjsondumps)pathpayloads     r   _make_markerr:   O   s1    

JJwU3g 	 	
r   c                   d}| d   | dz  }dddd}t        ||       |j                         j                  }t        j                  |j                               j                         }t        || d         }|j                  }d}||k(  }	|	st        j                  d	|	fd
||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }
t        j                  |j                         dz   d|
iz  }t#        t        j$                  |            dx}x}	}t'        j(                  |j*                  j-                               }|d   }||k(  }|st        j                  d	|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }
t#        t        j$                  |
            dx}}|d   }|j.                  }| d} ||      }|stdt        j                  |      t        j                  |      t        j                  |      t        j                  |      dz  }t#        t        j$                  |            dx}x}x}}|d   }|s8ddt        j                  |      iz  }t#        t        j$                  |            d}|d   }t1        |      }	|	j2                  } |       }|sddt        j                         v st        j                  t0              rt        j                  t0              ndt        j                  |      t        j                  |	      t        j                  |      t        j                  |      dz  }t#        t        j$                  |            dx}x}	x}}|d   }||k(  }|st        j                  d	|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }
t#        t        j$                  |
            dx}}|d    }||k(  }|st        j                  d	|fd||f      t        j                  |      d!t        j                         v st        j                  |      rt        j                  |      nd!dz  }dd|iz  }
t#        t        j$                  |
            dx}}|d"   }d}	||	k(  }|slt        j                  d	|fd#||	f      t        j                  |      t        j                  |	      d$z  }d%d&|iz  }t#        t        j$                  |            dx}x}}	|d'   }d(}	||	u }|slt        j                  d)|fd*||	f      t        j                  |      t        j                  |	      d$z  }d%d&|iz  }t#        t        j$                  |            dx}x}}	|j2                  } |       }	|	 }|sd+d,t        j                         v st        j                  |      rt        j                  |      nd,t        j                  |      t        j                  |	      d-z  }
t#        t        j$                  |
            dx}x}	}t5        | d.   j7                               }t9        |      }d/}||k(  }|st        j                  d	|fd0||f      d1t        j                         v st        j                  t8              rt        j                  t8              nd1d2t        j                         v st        j                  |      rt        j                  |      nd2t        j                  |      t        j                  |      d3z  }d4d5|iz  }t#        t        j$                  |            dx}x}}|d   }|j:                  }|j<                  }| d6} ||      }|sd7t        j                  |      t        j                  |      t        j                  |      t        j                  |      t        j                  |      d8z  }t#        t        j$                  |            dx}x}x}x}}y)9uC   audit jsonl에 path/size/sha256/reason/archived_path 모두 기록.ztask-archive-001r   .done.escalatedtestz2026-05-07T00:00:00Zstale_done_30min_test)triggertsr   r   ==z2%(py2)s
{%(py2)s = %(py0)s.returncode
} == %(py5)sresultpy0py2py5
>assert %(py7)spy7Nr,   )z%(py1)s == %(py3)s)py1py3zassert %(py5)srH   original_pathzJassert %(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.endswith
}(%(py5)s)
})rK   rL   rH   rJ   archived_pathzassert %(py1)srK   z_assert %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}.exists
}()
}r   )rF   rG   py4py6py8sizeexpected_sizesha256expected_shar   z%(py1)s == %(py4)srK   rO   assert %(py6)srP   okTisz%(py1)s is %(py4)sEassert not %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}srcrF   rG   rO   r      )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenarchived)rF   rK   rL   rP   zassert %(py8)srQ   z.done.escalated.zfassert %(py9)s
{%(py9)s = %(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.name
}.startswith
}(%(py7)s)
})rK   rL   rH   rJ   py9)r:   statst_sizehashlibrT   
read_bytes	hexdigestr.   
returncode
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgstderrAssertionError_format_explanationr6   loadsstdoutstripendswithr   existslistiterdirra   name
startswith)r   r,   r^   r9   rS   rU   rD   @py_assert1@py_assert4@py_assert3@py_format6@py_format8record@py_assert0@py_assert2@py_format4@py_assert6@py_format2@py_assert5@py_assert7@py_format9@py_format5@py_format7rb   @py_assert8@py_format10s                             r   ,test_archive_records_path_size_sha256_reasonr   X   s    G
l
	9
9C$)G
 gHHJ&&M>>#.."23==?L'3|#45F00!000000000600060000000006==0000000ZZ++-.F)''''''''''''''''''''''''/"H"++Hwi,GH+,GHHHHH"HHH+HHH,GHHHHHHHHHH/""""""""""""'14'(1(//1/1111111141114111'111(111/1111111111&>*>]****>]***>******]***]*******(+|++++|+++++++++|+++|+++++++(66666666666666666666666$<4<4<4<4 zzz||ssz|C&..01Hx=A=A=A33xx=AA;D;D&&D'2B'CD&'CDDDDD;DDDDDD&DDD'CDDDDDDDDDDDr   c                   d}| d   | dz  }| d   | dz  }|j                  t        j                  d|i      d       t        |dd	d
       t	        || d         }|j
                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  |j                        dz   d|iz  }	t        t        j                  |	            dx}x}}t        j                   |j"                  j%                               }
|
d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|
d   d   }d}||u }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|j&                  } |       }| }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}x}}|j&                  } |       }|sddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        t        j                  |            dx}}y) u[   archive 후 .done이 잔존하면 noop이지만, 동시 존재 시점에서 archive 가능.ztask-archive-002r   z.doner<   r,   r1   r2   staleconflict_testr?   r   r   rA   rC   rD   rE   rI   rJ   NrY   TrZ   r\   rW   rX   rP   
post_checkr]   escr_   zAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}done)r5   r6   r7   r:   r.   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   rx   )r   r,   r   r   rD   r}   r~   r   r   r   r   r   r   r   r   r   s                   r   )test_archive_post_check_conflict_detectedr   z   ss    G|'%00D
l
	9
9COO

Iw'(7   '_EF '3|#45F00!000000000600060000000006==0000000ZZ++-.F$<4<4<4<4,%--%----%---%----------zzz||ssz|;;;==44;=r   c           
     	   d}t        || d   d      }|j                  }d}||k7  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}}g }d}|j                  }	|j                  }
|	|
z   }||v }|}|s_d}|j                  }|j                  }||z   }|j                  } |       }||v }|}|s%d}|j                  }|j                  }||z   }||v }|}|sJt        j                  d|fd||f      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |	      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |
      dz  }dd|iz  }|j                  |       |st        j                  dfdf      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                        dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                        t        j                        t        j                  |      dz  }dd|iz  }|j                  |       |st        j                  dfdf      t        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                        dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                        dz  }dd|iz  }|j                  |       t        j                  |d      i z  }dd|iz  } t        t        j                  |             dx}x}x}x}x}	x}
x}x}x}x}x}x}x}x}x}x}x}x}}y) u>   ``--fail-when-missing`` 플래그 시 marker 부재면 exit 1.ztask-archive-missingr   T)r   r   )!=)z2%(py2)s
{%(py2)s = %(py0)s.returncode
} != %(py5)srD   rE   assert %(py7)srJ   Nu   없음missingu   차단in)zX%(py3)s in (%(py7)s
{%(py7)s = %(py5)s.stdout
} + %(py10)s
{%(py10)s = %(py8)s.stderr
}))rL   rH   rJ   rQ   py10z%(py13)spy13)z%(py16)s in %(py28)s
{%(py28)s = %(py26)s
{%(py26)s = (%(py20)s
{%(py20)s = %(py18)s.stdout
} + %(py23)s
{%(py23)s = %(py21)s.stderr
}).lower
}()
})py16py18py20py21py23py26py28z%(py30)spy30)z]%(py33)s in (%(py37)s
{%(py37)s = %(py35)s.stdout
} + %(py40)s
{%(py40)s = %(py38)s.stderr
}))py33py35py37py38py40z%(py43)spy43r`   zassert %(py46)spy46)r.   ri   rj   rk   rl   rm   rn   ro   rr   rs   ru   rq   lowerr%   _format_boolop)!r   r,   rD   r}   r~   r   r   r   r   r   @py_assert9@py_assert11r   @py_assert15@py_assert19@py_assert22@py_assert24@py_assert25@py_assert27@py_assert17@py_assert32@py_assert36@py_assert39@py_assert41@py_assert34@py_format12@py_format14@py_format29@py_format31@py_format42@py_format44@py_format45@py_format47s!                                    r   /test_archive_fail_closed_when_missing_with_flagr      s[   $G\"dF !!!!!!!!!!!!6!!!6!!!!!!!!!!!!!=8 = = =5 =856 =) ===%=%e= H H =) H ; ==$mm=.4mm=+m;=;<= =+<+<=85 = =3<9  = =6<f= =$<$<  = =3<9  = =3<9 & = =6<f= =$<$< )/ = =3<9 )/ = =3<9 )6 = = =6<f=6<=+<+<=) H = =3<9 ;D = =6<f= =$<$< 	= =3<9 	= =3<9 	= =6<f= =$<$< = =3<9 = =3<9 &= =3<9H = =3<9H = = =6<f=6<=+<+<=;= =3<9= =6<f= =$<$<f= =3<9f= =3<9m= =6<f= =$<$<f= =3<9f= =3<9m= = =6<f=6<=.<n= = = =)<)<= = = = = = =r   c                   d}t        || d         }|j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd	|iz  }t        t        j                  |            d
x}x}}t        j                  |j                  j                               }|d   }	d}|	|u }
|
slt        j                  d|
fd|	|f      t        j                  |	      t        j                  |      dz  }dd|iz  }t        t        j                  |            d
x}	x}
}|d   }	d}|	|u }
|
slt        j                  d|
fd|	|f      t        j                  |	      t        j                  |      dz  }dd|iz  }t        t        j                  |            d
x}	x}
}|d   }	d}|	|k(  }
|
slt        j                  d|
fd|	|f      t        j                  |	      t        j                  |      dz  }dd|iz  }t        t        j                  |            d
x}	x}
}y
)u/   기본 동작: marker 부재 시 noop (exit 0).ztask-archive-noopr   r   rA   rC   rD   rE   r   rJ   NrY   TrZ   r\   rW   rX   rP   noopr   	no_markerrV   )r.   ri   rj   rk   rl   rm   rn   ro   rr   rs   r6   rt   ru   rv   )r   r,   rD   r}   r~   r   r   r   r   r   r   r   r   s                r   &test_archive_noop_when_missing_defaultr      s   !G'3|#45F!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!ZZ++-.F$<4<4<4<4&>!T!>T!!!!>T!!!>!!!T!!!!!!!(*{*{****{******{*******r   c                    d}| d   | dz  }t        |ddd       t        || d         }|j                  }d}||k(  }|st        j                  d|fd	||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}t        j                  |j                  j                               }	dD ]  }
|
|	v }|st        j                  d|fd|
|	f      dt        j                         v st        j                  |
      rt        j                  |
      nddt        j                         v st        j                  |	      rt        j                  |	      nddz  }t        j                  d|
       dz   d|iz  }t        t        j                  |            d} |	d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)u  ESCALATED_AUDIT_LOG (orchestration-audit/escalated-archive.jsonl) 추가 검증.

    실제 시스템 audit log 위치: ``$WORKSPACE/memory/orchestration-audit``.
    여기서는 archive_path 기록만 검증하고 시스템 jsonl 추가 부수효과는
    별도 테스트 (test_finish_task_pipeline) 가 검증한다. 임시 환경은
    WORKSPACE_ROOT 가 tmp_path 라 해도 taskctl 모듈 상수가 import-time 결정되어
    실제 시스템 dir에 기록된다 (이는 행위 자체의 문제는 아니며 격리 한계).
    ztask-archive-jsonlr   r<   r   
jsonl_testr   r   rA   rC   rD   rE   r   rJ   N)
r@   r,   actorrM   rN   rR   rT   r   commandrY   r   )z%(py0)s in %(py2)skrec)rF   rG   zmissing audit field: z
>assert %(py4)srO   r   ztaskctl archive-escalatedrV   rW   rX   rP   )r:   r.   ri   rj   rk   rl   rm   rn   ro   rr   rs   r6   rt   ru   rv   rp   )r   r,   r^   rD   r}   r~   r   r   r   r   r   @py_format3r   r   r   r   s                   r   !test_archive_audit_jsonl_appendedr      s    #G
l
	9
9C'\BC'3|#45F!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!
**V]]((*
+C 5 Cx444qC444444q444q444444C444C4444044444445 y>888>88888>8888>88888888888r   c                J   d}| d   | dz  }t        |d       |j                  } |       }|j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      t        j                  |      d	z  }d
d|iz  }	t        t        j                  |	            dx}x}x}x}}t        || d         }
|
j                  }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  |
      rt        j                  |
      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}t        j                  |
j                  j!                               }|d   }d}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|d   }d}||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}y)uN   빈 .done.escalated (0 byte) 도 archive 가능. reason = unparseable_payload.ztask-archive-emptyr   r<   Nr   rA   )z`%(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.stat
}()
}.st_size
} == %(py9)sr^   )rF   rG   rO   rP   rc   zassert %(py11)spy11rC   rD   rE   r   rJ   rR   rV   rW   rX   rP   r   )unparseable_payloadunknownrb   r   )z%(py1)s in %(py4)s)r:   rd   re   rj   rk   rl   rm   rn   ro   rr   rs   r.   ri   r6   rt   ru   rv   )r   r,   r^   r}   r   r   r   r   r   r   rD   r~   r   r   r   r   r   r   r   s                      r   3test_archive_empty_marker_recorded_with_unparseabler      s2   "G
l
	9
9Cd88"8:":""""""""""""3"""3"""8""":"""""""""""""'3|#45F!!!!!!!!!!!!6!!!6!!!!!!!!!!!!!ZZ++-.F&>Q>Q>Q>Q(         	     	    	      	  r   )r   r   r   zpytest.MonkeyPatchreturndict)r,   r   r   r   r   z
str | Noner   boolr   zPath | Noner   zsubprocess.CompletedProcess)r8   r   r9   zdict | Noner   None)r   r   r   r   ) __doc__
__future__r   builtinsrl   _pytest.assertion.rewrite	assertionrewriterj   rf   r6   r)   r&   r"   pathlibr   pytest__file__resolveparentsr(   r$   fixturer   r.   r:   r   r   r   r   r   r    r   r   <module>r      s   	 #     	  
  N""$,,Q/	
i
,
.  2 # 	
  
 !>
ED*	=+9@r   