
     j/                    d   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mZ ddlmZ  ee      j#                         j$                  d   Zej(                  j+                  d ee              eej0                        D  cg c]  } | dk(  s| j3                  d      s|  c} D ]  Zej0                  j7                  ed         dd	lmZ ddlmZ  eej                   xs d
      Z  ee      Z!e!e v Z"e"s
 ejF                  de"fde!e f      d ejH                         v s ejJ                  e      r ejL                  e      ndd ejH                         v s ejJ                  e      r ejL                  e      nd ejL                  e!      d ejH                         v s ejJ                  e       r ejL                  e       nddz  Z' ejP                  de        dz   de'iz  Z) e* ejV                  e)            dxZ!Z"edz  Z, ee      Z-d Z.d Z/d Z0d Z1d Z2d Z3d Z4yc c} w )uP  task-2524+1 회귀 테스트 — automation observability v0

검증 7건:
1. mutation 정적 검사 PASS (gh pr merge / cokacdir --cron / --apply / git push 부재)
2. chat=6937032012 격리 (다른 chat record 자동 필터)
3. token raw value 0 노출 (ghs_/ghp_/github_pat_ prefix 부재)
4. 7 source 정합 (observability 7 키 모두 존재)
5. 기존 자동화 탭 회귀 (load_automation_status 응답에 observability 키 존재)
6. dead code 제거 검증 (routes_post.py 토글 2 함수 부재 + server.py router 등록 부재)
7. task-2526 영역 무수정 (parallel_safe 정합)
    )annotationsN)Path)patch   	dashboardz
dashboard.)
DataLoader in)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} in %(py5)sstrPROJECT_ROOT_loaded_path)py0py1py3py5z$wrong dashboard.data_loader loaded: z
>assert %(py7)spy7c            
        t         dz  dz  t         dz  dz  g} g d}| D ]  }|j                  } |       }|st        j                  d|       dz   dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        t        j                  |            d	x}}|j                  d
      }|D ]  }t        j                  ||t        j                  t        j                  z        }| }|st        j                  d| d|j                   d|       dz   ddt	        j
                         v st        j                  |      rt        j                  |      ndiz  }	t        t        j                  |	            d	}  t         dz  j                  d
      }
t        j                   d|
t        j                        }|s{t        j                  d      dz   ddt	        j
                         v st        j                  |      rt        j                  |      ndiz  }t        t        j                  |            |j#                  d      }dD ]Y  }t        j                   } |||      }| }|s1t        j                  d| d      dz   dt	        j
                         v st        j                  t              rt        j                  t              ndt        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d	x}x}}\ y	)uC   변경 4 파일에서 mutation 명령어 부재 (read-only 강제).
componentsAutomationView.js!AutomationObservabilitySection.js)gh\s+pr\s+mergecokacdir\s+--cron	--apply\bzsubprocess.*git\s+pushzsubprocess.*commitz9fetch\(['\"][^'\"]*['\"]\s*,\s*\{[^}]*method:\s*['\"]POSTz8fetch\(['\"][^'\"]*['\"]\s*,\s*\{[^}]*method:\s*['\"]PUTz;fetch\(['\"][^'\"]*['\"]\s*,\s*\{[^}]*method:\s*['\"]DELETEz	missing: C
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}targetr   py2py4Nutf-8encodingzmutation pattern 'z' found in z: z
>assert not %(py0)sr   matchesdata_loader.pyu7   # ── observability v0.*?def toggle_pipeline_enabledzcollector section not foundz
>assert %(py0)scollector_sectionr   )r   r   r   z
git\s+pushzgit.*commitz' found in collectorszW
>assert not %(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.search
}(%(py3)s, %(py4)s)
}repatsection_text)r   r   r   r   py6)	DASHBOARDexists
@pytest_ar_format_assertmsg@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanation	read_textr&   findall	MULTILINEDOTALLnamesearchgroup)targetsforbidden_patternsr   @py_assert1@py_assert3@py_format5contentr'   r#   @py_format2
dl_contentr%   @py_format1r(   @py_assert5@py_assert7@py_format8s                    >/home/jay/workspace/tests/dashboard/test_observability_2524.py test_observability_mutation_zerorH   .   s    	L #66L #FFG	  ^}}4}444)F8 4444444v444v444}444444444""G"4% 	^Cjjgr||bii/GHG;];]]"4SEV[[MQST[S\ ]]]]]]]w]]]w]]]]]]	^^ ..9979KJ		B
		
 ;;;;;;;;;;;;;;;;;$**1-Lf a99`9S,/`//`/``3EcUJ_1```````2```2```9``````S```S``````,```,```/``````a    c           	     >	   | dz  j                          dz  }ddddddd	d
dddddd	ddddddd	g}|j                  dj                  d |D              dz   d       | dz  }|dz  j                  d       t        |      }t	        d      5 }t
        fd}||_        |j                  d      }dd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}
}	|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}
}	t        j                  |d()      }d}||v}
|
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}||v}
|
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}}
|d0   }t%        |      }	d1}|	|k(  }|st        j                  d&|fd2|	|f      d3t        j                          v st        j"                  t$              rt        j                  t$              nd3t        j                  |      t        j                  |	      t        j                  |      d4z  }d5d6|iz  }t        t        j                  |            dx}x}	x}}|d0   d7   d8   }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# 1 sw Y   xY w)9uE   다른 chat record는 schedule_history 응답에서 자동 필터됨.schedule_historyzTEST0001.logz2026-05-10T09:00:00+09:00TEST0001l   L5: okownerd   )tsschedule_idchat_idstatuspromptduration_msz2026-05-10T09:01:00+09:00l   c(	 OTHER_CHAT_LEAK_PROBE   z2026-05-10T09:02:00+09:00i5:BerrorOTHER_CHAT_ERROR_PROBEi,  
c              3  F   K   | ]  }t        j                  |        y w)N)jsondumps).0rs     rG   	<genexpr>z:test_chat_isolation_filters_other_chats.<locals>.<genexpr>`   s     !AA$**Q-!As   !r    r!   	workspacememoryTparentszdashboard.data_loader.Pathc                "    | dk(  rS  |       S )Nz$/home/jay/.cokacdir/schedule_history )arghistory_diroriginals    rG   
_path_sidez;test_chat_isolation_filters_other_chats.<locals>._path_sidej   s    <<""C= rI   )rR   N	available)is)z%(py1)s is %(py4)s)r   r   zassert %(py6)sr)   rR   ==)z%(py1)s == %(py4)sFensure_asciinot inz%(py1)s not in %(py3)sblobr   r   assert %(py5)sr   records   )z0%(py4)s
{%(py4)s = %(py0)s(%(py2)s)
} == %(py7)slen)r   r   r   r   zassert %(py9)spy9r   rQ   )mkdir
write_textjoinr   r   r   side_effect'_collect_schedule_history_chat_filteredr,   _call_reprcomparer1   r2   r3   r\   r]   r.   r/   r0   ry   )tmp_pathlog_pathrw   ra   dl	mock_pathrj   result@py_assert0r>   @py_assert2r?   @py_format7rt   @py_format4@py_format6r=   @py_assert6rD   rF   @py_format10rh   ri   s                        @@rG   'test_chat_isolation_filters_other_chatsr   V   su   //K^+H*:R\hlx  QT  	U*:R\hl  yP  ad  	e*:R\ho  |T  eh  	iG
 		!A!AADHSZ[;&I   .	I	B	+	, 
P		!
 !+	;;J;O
P +&$&$&&&&$&&&&&&$&&&&&&&)*
*
****
******
*******::f51D"."$...."$..."......$...$.......#/#4////#4///#//////4///4///////i &3 !&Q&!Q&&&&!Q&&&&&&3&&&3&&& &&&!&&&Q&&&&&&&)Q.<*<.*<<<<.*<<<.<<<*<<<<<<<)
P 
Ps   &RRc           
     v   | dz  }|dz  j                  d       t        |      }t        d      5 } t        dddd	d	d
             |_        |j                         }ddd       t        j                  d      }d}||v}|st        j                  d|fd||f      t        j                  |      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x}}d}||v}|st        j                  d|fd||f      t        j                  |      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x}}d}||v}|st        j                  d|fd||f      t        j                  |      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x}}y# 1 sw Y   SxY w)u:   load_automation_status 응답 JSON에 token prefix 부재.ra   rb   Trc   $dashboard.data_loader.subprocess.runRrf   rx   r	   
returncodestdoutstderrNFro   ghs_rq   rs   rt   ru   zreal token prefix ghs_ leaked
>assert %(py5)sr   ghp_zreal token prefix ghp_ leakedgithub_pat_z$real token prefix github_pat_ leaked)r{   r   r   typereturn_valueload_automation_statusr\   r]   r,   r   r1   r.   r/   r0   r-   r2   r3   )
r   ra   r   mock_runr   rt   r   r   r   r   s
             rG   "test_token_raw_value_zero_exposurer      s   ;&I   .	I	B	5	6 -( \S"Q"XZ.[ \ ^**,- ::f51D>6>>>6>>>6>>>>>>>>>>>>>>>>>>>>>6>>>6>>>6>>>>>>>>>>>>>>>>>>>>L=$LLL=LLL=LLLLLLLLLLLLL&LLLLLLL- -s   ,J..J8c           
        | dz  }|dz  j                  d       t        |      }t        d      5 } t        dddd	d	d
             |_        |j                         }d d d        d}|v }|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   }	h d}
|	j                  } |       }t        |      }||
k(  }|s~t        j                  d|fd||
f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |	      rt        j                  |	      ndt        j                  |      t        j                  |      t        j                  |      dt        j                         v st        j                  |
      rt        j                  |
      nddz  }t        j                   dt        |	j                                d|
       dz   d|iz  }t        t        j                  |            d x}x}x}}y # 1 sw Y   exY w)Nra   rb   Trc   r   r   rf   rx   r	   r   observabilityr
   z%(py1)s in %(py3)sr   ru   rv   r   >   pr_state	ci_gemini	lifecycle
critical_7
task_timertoken_sourcerK   rm   )za%(py7)s
{%(py7)s = %(py0)s(%(py5)s
{%(py5)s = %(py3)s
{%(py3)s = %(py1)s.keys
}()
})
} == %(py9)ssetobsexpected_keys)r   r   r   r   r   rz   z7 source mismatch: z != z
>assert %(py11)spy11)r{   r   r   r   r   r   r,   r   r1   r.   r/   r0   r2   r3   keysr   r-   )r   ra   r   r   r   r   r   r   r   r   r   @py_assert4r   @py_assert8r   @py_format12s                   rG   !test_observability_7_keys_presentr      s   ;&I   .	I	B	5	6 -( \S"Q"XZ.[ \ ^**,- $?f$$$$?f$$$?$$$$$$f$$$f$$$$$$$

!CM xxgxzg3z?g?m+ggg?mgggggg3ggg3ggggggsgggsgggxgggzggg?ggggggmgggmgggg/B3sxxz?BSSWXeWf-gggggggg- -s   ,K  K
c           
        | dz  }|dz  j                  d       t        |      }t        d      5 } t        dddd	d	d
             |_        |j                         }ddd       t        t              }|sddt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }t        t        j                  |            d}d}||v }|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}||v }|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}||v }|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}}y# 1 sw Y   xY w)uM   load_automation_status() 응답 200 등가 + observability 키 + active flag.ra   rb   Trc   r   r   rf   rx   r	   r   Nz5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancer   dict)r   r   r   r   r   r
   r   ru   rv   r   last_updatedactive)r{   r   r   r   r   r   r   r   r.   r/   r,   r0   r1   r2   r3   r   )r   ra   r   r   r   r>   r?   r   r   r   r   s              rG   &test_load_automation_status_regressionr      s   ;&I   .	I	B	5	6 -( \S"Q"XZ.[ \ ^**,- fd########:###:######f###f######d###d##########$?f$$$$?f$$$?$$$$$$f$$$f$$$$$$$#>V####>V###>######V###V#######8v8v8vv- -s   ,M55M?c                 Z   t         dz  j                  d      } d}|| v}|st        j                  d|fd|| f      t        j                  |      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x}}d}|| v}|st        j                  d|fd|| f      t        j                  |      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x}}d}|| v}|st        j                  d|fd|| f      t        j                  |      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x}}d}|| v}|st        j                  d|fd|| f      t        j                  |      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x}}t         dz  j                  d      }d}||v}|st        j                  d|fd||f      t        j                  |      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x}}d}||v}|st        j                  d|fd||f      t        j                  |      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x}}t         dz  dz  j                  d      }d}||v}|st        j                  d|fd||f      t        j                  |      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x}}d}||v}|st        j                  d|fd||f      t        j                  |      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x}}d }||v}|st        j                  d|fd||f      t        j                  |      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x}}d}||v}|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}||v}|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}}y)#uG   routes_post.py 토글 2 함수 부재 + server.py router 등록 부재.routes_post.pyr    r!   z!def handle_post_automation_togglerq   rs   routes_postru   z7handle_post_automation_toggle still present (dead code)r   r   Nz(def handle_post_automation_system_togglez>handle_post_automation_system_toggle still present (dead code)handle_post_automation_togglez9handle_post_automation_toggle still referenced in __all__$handle_post_automation_system_togglez@handle_post_automation_system_toggle still referenced in __all__	server.pyz/api/automation/toggle	server_pyz./api/automation/toggle router still registeredz/api/automation/system-togglez5/api/automation/system-toggle router still registeredr   r   COMPLETED_FEATURESavz$COMPLETED_FEATURES dead code presenthandleSystemTogglez$handleSystemToggle dead code presenthandlePipelineTogglez&handlePipelineToggle dead code presentrv   )r*   r4   r,   r   r1   r.   r/   r0   r-   r2   r3   )r   r   r   r   r   r   r   s          rG   test_dead_code_removedr      s   //::G:LK. B.kA B0A0AB.k B B8A	 / B B;A6B B)A)A 7B B B8A	 7B B B0A0AAB B B.A.AB B5 I5[H I7H7HI5[ I I?Hy 6 I IBH&I I0H0H >I I I?Hy >I I I7H7HHI I I5H5HI I* D*+= D2C2CD*+ D D:C) + D D=CVD D+C+C 3> D D:C) 3> D D2C2CCD D D0C0CD D1 K1D K9J9JK1 K KAJ 2 K KDJFK K2J2J :E K KAJ :E K K9J9JJK K K7J7JK K [(33W3EI#f#94fff#9fff#ffffff9fff9ffff6fffffff*t*);ttt*)ttt*tttttt)ttt)tttt=ttttttt l
"%8
8	C	CW	C	UBQr)QQQrQQQQQQQQQrQQQrQQQQ+QQQQQQQQr)QQQrQQQQQQQQQrQQQrQQQQ+QQQQQQQ!U!+UUU!UUU!UUUUUUUUUUUUU-UUUUUUU#-#2----#2---#------2---2-------*4*"4444*"444*444444"444"4444444rI   c                 >   t         dz  dz  t         dz  dz  t         dz  dz  dz  t         dz  d	z  d
z  g} t        dz  dz  t        dz  dz  t        dz  t        dz  t        dz  t        h}|D ]  }|j                  } |       }|st	        j
                  d|       dz   dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }t        t	        j                  |            dx}} | 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} y)uL   parallel_safe — task-2526 / task-2523 영역의 본 task 변경분 부재.scriptszsafe_cron_dispatch.pyutilszcron_targeting_audit.pytests
regressionz&test_cron_session_safety_guard_2526.pyrb   specszcron-targeting-spec.mdr   r   r   r$   r   r   zexpected file missing: r   fr   Nrq   )z%(py0)s not in %(py2)sfpexpected_files)r   r   u   task-2526 영역 침범: z
>assert %(py4)sr   )r   r*   
TESTS_2524r+   r,   r-   r.   r/   r0   r1   r2   r3   r   )forbidden_pathsr   r   r=   r>   r?   r   @py_format3s           rG   test_task_2526_area_untouchedr      s    	y #::w!::w-0XXx'),DD	O 	L #66L #FF$$$$KN  9xx8xz8z884QC8888888q888q888x888z8888889  J'IIIrIIIIIIrIIIrIIIIIIIIIIIII+DRD)IIIIIIIJrI   )5__doc__
__future__r   builtinsr.   _pytest.assertion.rewrite	assertionrewriter,   r\   r&   syspathlibr   unittest.mockr   __file__resolverd   r   pathinsertr   listmodules
startswith	_mod_namepopdashboard.data_loaderr   data_loader_dashboard_data_loader_modr   r   r   r   r/   r0   r1   r   r-   rF   r2   r3   r*   r   rH   r   r   r   r   r   r   )ms   0rG   <module>r      s  
 #    	 
   H~%%'//2 3|$ %!#++.a!{2BallS_F`!a %IKKOOIt$% - ;-66<"=
< L(  L                      )   )    +<.9     ;&	(^
"aP$=TM&h2$58JA bs   H-#H-