
    @j;                    4   d Z ddlmZ ddl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 ddlZ ee      j!                         j"                  d   Zedz  dz  Z ej(                  d	e      Zeej,                  J  ej.                  e      Zee	j2                  d	<   ej,                  j5                  e       dd
ZddddZd dZd Zd Zd Z d Z!d Z"d Z#d Z$d Z%d Z&d Z'd Z(d Z)d Z*e+dk(  r% e	jX                   ejZ                  edg             yy)!u\  task-2777 — read-only anu_control_status.py (자동화 조종석) 회귀 테스트.

검증 불변식(작업지시서 + spec §6):
  ① read-only 보장 — 격리 tmp root 실행 전후 모든 파일의 sha256+mtime 불변 ·
     파일 생성 0 · append 0 (driver_runs/flag/ledger/state 무변경).
  ② absent graceful — state/audit/jsonl/ledger 부재 시 crash 0.
  ③ level 판정 정확 — 전 flag OFF + LIVE_PENDING 1 + LIVE_PROCESSED 0 + ACTIVE=false
     → L2_DONE_L3_BLOCK_EVIDENCE_ACTIVE_FALSE.
  ④ JSON schema 안정 — 필수 key 존재 · 값 타입 안정.
  ⑤ raw key 미출력 — sealed key env(sentinel) 가 stdout/json/report 에 0.
  ⑥ no driver execution — driver_runs.jsonl 신규 append 0(① 로 입증).
  ⑦ no flag write — driver/event_strategy/callback/epoch/kill 생성·수정 0.
  ⑧ dirty count — git read-only 명령만(비-git tmp root → 'unknown', mutation 0).
  ⑨ human summary smoke · ⑩ --json smoke · ⑪ cron UNKNOWN(raw key 미사용).

★ read-only: 본 테스트 자체도 production state 를 건드리지 않는다. 전부 tmp root.
    )annotationsN)redirect_stdout)Path   scriptszanu_control_status.pyanu_control_statusc                d    | j                   j                  dd       | j                  |d       y )NTparentsexist_okutf-8encoding)parentmkdir
write_text)pathtexts     0tests/regression/test_anu_control_status_2777.py_writer   *   s)    KKdT2OOD7O+    Twith_sourcesc          	     >   | dz  }|j                  dd       |s|S t        |dz  dz  dz  d       |dz  dz  d	z  }t        j                  d
ddddd      t        j                  ddd ddd      g}t        |dj	                  |      dz          t        |dz  dz  dz  t        j                  ddd      dz          t        d      D ]!  }t        |dz  dz  dz  dd|z    dz  d       # t        d       D ]!  }t        |dz  dz  d!z  dd"|z    dz  d       # |S )#NrepoTr
   memorystatep0b_driver_enabledz	disabled
	p0b_statedriver_runs.jsonlz2026-06-28T10:00:00+09:00LIVE_PENDING_OWNER_PROOFSELFz	scan-liveenabled)tsverdictowner_key_classdriver
activationz2026-06-28T12:59:18+09:00NOOP_DISABLEDzsystemd-pathdisabled
zcallback_launch_audit.jsonlz2026-06-26T00:00:00+09:00
REAL_FIRED)r$   event   reports p0b_inbox_backlog_archive_260627ztask-i  z.result.jsonz{}r   )phase_x_pending_fixture_quarantine_260628i  )r   r   jsondumpsjoinrange)tmp_pathr   rootrunslinesis         r   _build_rootr;   /   s|   fDJJtdJ+ 4(?W$';;\J (?[(+>>D

-:T%I
 	 	

-/#~Z
 		E 45!D() x+%(EE

5MNQUU 1X 
8Oi'*LLdQhZ|,-	

 1X 
8Oi'*UUdQhZ|,-	

 Kr   c                T   i }t        | j                  d            D ]  }|j                         s|j                         }|j	                         }t        j                  |      j                         |j                  |j                  f|t        |j                  |             <    |S )N*)sortedrglobis_file
read_bytesstathashlibsha256	hexdigestst_mtime_nsst_sizestrrelative_to)r7   snappdatasts        r   	_snapshotrN   a   s    DDJJsO$ 99;<<>DBt$..0

.DQ]]4()*	 Kr   c                h   t        | d      }t        |      }t        j                  t	        |            }t        j                  |      }t        j                  |      }t        j                         }t        |      5  t        j                  dt	        |      g      }t        j                  dt	        |      dg      }d d d        dk(  rdk(  sJ t        |      }t        |j                               t        |j                               k(  sJ d       ||k(  sJ d       y # 1 sw Y   gxY w)NTr   --root--jsonr   u*   파일 집합 변동(생성/삭제) 발생u/   파일 내용/mtime 변경(append/write) 발생)r;   rN   acsbuild_statusrH   format_jsonformat_humanioStringIOr   mainsetkeys)	r6   r7   beforerL   _bufrc1rc2afters	            r    test_readonly_invariant_no_writera   p   s    xd3Dt_F CI&DAA
++-C		 8hh#d),-hh#d)X678 !8q  dOEv{{}UZZ\!22`4``2U?MMM?8 8s    AD((D1c                   t        | d      }t        |      }t        j                  t	        |            }t        |t              sJ |d   du sJ |d   d   dk(  sJ |d   d   d	k(  sJ |d   d
   d	k(  sJ |d   d   d	k(  sJ |d   d   d	k(  sJ t        t        j                  |      t              sJ t        t        j                  |      t              sJ t        |      |k(  sJ y )NFr   activeflagsr'   r*   countsr,   r   LIVE_PROCESSEDr!   archive)	r;   rN   rR   rS   rH   
isinstancedictrU   rT   )r6   r7   r[   rL   s       r   %test_absent_sources_graceful_no_crashrj      s   xe4Dt_FCI&DdD!!!>U"""="j000>,'1,,,>*+q000>45:::>)$)))c&&t,c222cood+S111T?f$$$r   c                   t        | d      }t        j                  t        |            }|d   du sJ |d   d   dk(  sJ |d   d   d	k(  sJ |d   d
   dk(  sJ |d   d   dk(  sJ |d   d   dk(  sJ |d   dk(  sJ |d   dk(  sJ y )NTr   rc   Fre   r!      rf   r   r,   rg   r.   pending_fixture_quarantiner   automation_level&L2_DONE_L3_BLOCK_EVIDENCE_ACTIVE_FALSElast_verdictr)   r;   rR   rS   rH   r6   r7   rL   s      r   test_level_l2_done_l3_blockrs      s    xd3DCI&D>U""">45:::>*+q000>,'1,,,>)$)))>671<<<"#'OOOO?222r   c                     dddddd} t         j                  d| ddd      dk(  sJ t         j                  d| ddd      d	k(  sJ t         j                  d| ddd      d
k(  sJ t         j                  di | ddiddd      d
k(  sJ y )Nr*   F)r'   event_strategycallbackepoch_presentkillrl   r   )r!   rf   )rc   rd   re   ro   L0_L2_READY_ACTIVE_FALSEINDETERMINATE_REVIEW_REQUIREDTr'   r#   )rR   compute_level)
base_flagss    r   test_level_compute_unit_casesr}      s    5J
 J,-C   
22 2 2
 J,-C   
$$ $ $
 J,-C   
)) ) )
 >j>(I>,-C   
)) ) )r   c                F   t        | d      }t        j                  t        |            }g d}|D ]  }||v rJ d|         t	        |d   t              sJ t	        |d   t
              sJ t	        |d   t              sJ t	        |d   t              sJ t	        |d	   t              sJ t	        |d
   t              sJ t	        |d   t              sJ t	        |d   t              sJ t	        |d   t              sJ t	        |d   t              sJ t	        |d   t              sJ t	        |d   t              sJ t        j                  |      }t        j                  |      }|d   |d   k(  sJ |d   j                         D ]  }t	        |t              rJ  y )NTr   )rn   rc   rd   re   rp   last_evidencegitsystemdcroninboxrg   pending_approvalsnext_allowed_actionforbidden_actionswarningsu   필수 key 누락: rn   rc   rd   re   r   r   r   rg   r   r   r   r   )r;   rR   rS   rH   rh   boolri   listrT   r2   loadsvaluesint)r6   r7   rL   requiredksparsedvs           r   (test_json_schema_required_keys_and_typesr      s   xd3DCI&DH
  4Dy3/s33y4d-.444d8nd+++d7mT***d8nd+++d5k4(((d9ot,,,d7mT***d9ot,,,d./666d013777d./666d:&---AZZ]F$%.@)AAAA(^""$ "!S!!!"r   c                b   d}|j                  d|       |j                  dd       t        | d      }t        j                  t	        |            }t        j                  |      }t        j                  |      }||fD ]  }||vsJ d|vrJ  t	        |d         j                  d      sJ y )	N!SENTINEL_ANU_KEY_DO_NOT_LEAK_2777COKACDIR_KEY_ANUCOKACDIR_KEY_DEV!SENTINEL_DEV_KEY_DO_NOT_LEAK_2777Tr   r   UNKNOWN)setenvr;   rR   rS   rH   rU   rT   
startswith)r6   monkeypatchsentinelr7   rL   humanjsblobs           r   test_no_raw_key_in_outputr      s    2H)84)+NOxd3DCI&DT"E		B ?t###2$>>>? tF|''	222r   c                   t        | d      }|dz  dz  }dD ]  }||z  j                         sJ  |dz  j                  d      }t        j	                  t        |             t        j                  d	t        |      g       t        j                  d	t        |      d
g       dD ]  }||z  j                         sJ d|         |dz  j                  d      |k(  sJ y )NTr   r   r   )p0b_event_strategy_enabledp0b_callback_launch_enabledp0b_activation_epochp0b_killr   r   r   rP   rQ   u   flag 파일 생성됨: )r;   exists	read_textrR   rS   rH   rX   )r6   r7   r   fdriver_befores        r   test_no_flag_writer      s    xd3D8Og%E2 (AI%%'''( 11<<g<NMSYHHhD	"#HHhD	8,-2 GAI%%'F+B1#)FF'G ((33W3EVVVr   c                   t        | d      }|dz  dz  dz  }|j                         }t        j                  t	        |             t        j                  dt	        |      dg       |j                         |k(  sJ d       y )	NTr   r   r   r    rP   rQ   u.   driver_runs.jsonl 변경(append/실행) 발생)r;   rA   rR   rS   rH   rX   )r6   r7   r8   before_bytess       r   test_no_driver_runs_appendr   	  sr    xd3D(?[(+>>D??$LSYHHhD	8,-??,^.^^,r   c                    t        | d      }t        j                  t        |            }|d   d   dk(  sJ |d   d   dk(  sJ |dz  j	                         rJ y )NTr   r   tracked_dirtyunknownbranchz.git)r;   rR   rS   rH   r   rr   s      r   !test_dirty_count_readonly_non_gitr     si    xd3DCI&D;'9444;x I---v%%''''r   c                     dj                  g d      } t        j                  |       dk(  sJ t        j                  d       dk(  sJ y )Nr+   )z M memory/foo.pyz D memory/bar.pyzM  scripts/baz.pyz?? memory/new.txtzMM scripts/qux.pyr   r   )r4   rR   _tracked_dirty_count)	porcelains    r   test_tracked_dirty_parser_unitr     sI    		  I ##I.!333##D)Y666r   c                ,   t        | d      }t        j                         }t        |      5  t        j                  dt        |      g       d d d        |j                         }d|v sJ d|v sJ d|v sJ d|v sJ t        j                         }t        |      5  t        j                  dt        |      dg       d d d        t        j                  |j                               }|d	   d
u sJ |d   dk(  sJ y # 1 sw Y   xY w# 1 sw Y   LxY w)NTr   rP   u   ANU 자동화 조종석z9automation level : L2_DONE_L3_BLOCK_EVIDENCE_ACTIVE_FALSEzACTIVE : falseWIRED(gated, ACTIVE=false)rQ   rc   Frn   ro   )
r;   rV   rW   r   rR   rX   rH   getvaluer2   r   )r6   r7   r]   r   buf2r   s         r   test_human_and_json_smoker   )  s	   xd3D
++-C		 ((CI&'(LLNE$---F%OOOu$$$'5000;;=D		 2(CIx012ZZ(F(u$$$$%)QQQQ( (2 2s   !C>"D
>D
Dc                l    t        | d      }t        j                  t        |            }|d   dv sJ y )NTr   r   )UNKNOWN_KEY_REQUIREDUNKNOWN_NO_KEYrq   rr   s      r   test_cron_unknown_no_raw_keyr   =  s5    xd3DCI&D<EEEEr   c                   t        | d      }t        j                  t        |            }d|v sJ |d   sJ d       |d   j	                         D ]3  \  }}|dk(  sJ d|j                         vr d|j                         v r3J  y )NTr   wired_gated_axesu   gated 축 비어있음r   rc   zactive=false)r;   rR   rS   rH   itemslower)r6   r7   rL   axislabels        r   test_wired_not_active_labelsr   D  s    xd3DCI&D%%%"#=%==#./557 Oe4444tzz|+~/NNNOr   __main__z-v)r   r   r   rH   returnNone)r6   r   r   r   r   r   )r7   r   r   ri   ).__doc__
__future__r   rC   importlib.utilutil_ilurV   r2   sys
contextlibr   pathlibr   pytest__file__resolver   _ROOT	_MOD_PATHspec_from_file_location_specloadermodule_from_specrR   modulesexec_moduler   r;   rN   ra   rj   rs   r}   r   r   r   r   r   r   r   r   r   __name__exitrX    r   r   <module>r      s=  " #   	  
 &   	X ((+I 77	$$$%99EU\\5 55dE"$'  !    ,
 9= .dN,%(
3)8"@3"W*_(	7R(FO zCHH[V[[(D)*+ r   