
    jU6                    J   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mZ ddZd Zdd	Z G d
 dej0                        Z G d dej0                        Z G d dej0                        Z G d dej0                        Z G d dej0                        Z G d dej0                        Zedk(  r ej@                          yy)u  Regression 6 (회장 verbatim · task-2658).

R1: legacy `.worktrees/` 위치 worktree 존재 → SPAWN_VERIFIED
R2: cokacdir `/home/jay/.cokacdir/workspace/<sid>/wt-<task>-<team>/` → SPAWN_VERIFIED
R3: .worktrees 없고 cokacdir 에만 → SPAWN_VERIFIED (★ false negative 금지 핵심)
R4: executor process 부재 + result/report/done 모두 존재
        → CALLBACK_RECOVERED_AFTER_VISIBILITY_GAP (★ 2 source 교차 강제)
R5: 전 source 부재 + fire 시각으로부터 hard_timeout(30분) 경과 → TRUE_SILENT_DROP
R6: schedule_history pending → SPAWN_PENDING (★ TRUE_SILENT_DROP 단정 금지)

테스트는 sys.path 를 worktree 의 utils 디렉터리 부모로 끌어들여
`utils.anu_spawn_visibility_guard` 를 import 한다 — pyright LSP 가
worktree 를 인덱싱 못 해 import 미해결 경고를 띄울 수 있으나 (task-2657
사례 동일) 실 import 와 pytest 는 정상 동작한다.
    )annotationsN)Path   )HARD_TIMEOUT_SECONDSSpawnVisibilityStatusclassify_spawn_visibilitycollect_sourcesc                    | dz  dz  }| dz  dz  }| dz  dz  }| dz  dz  }||||dz  |dz  |dz  fD ]  }|j                  d	d	
        ||||fS )ur   테스트용 격리 root 구성.

    Returns (legacy_root, cokacdir_root, schedule_history_dir, memory_dir).
    	workspacez
.worktreescokacdirschedule_historymemoryeventsreportsz.callback_inboxT)parentsexist_ok)mkdir)tmplegacyr   historyr   ds         5tests/anu_spawn_visibility_guard/test_regression_6.py_make_layoutr   &   s    
 ;-FZ+-HJ!33G;)Fh():FY<NPVYjPjk -	t,-8Wf,,    c                      y)N r   r   r   r   	_empty_psr   4   s    r   c                      fd}|S )Nc                 "    d  d d  d fS )Nz21234 python3 /home/jay/.cokacdir/workspace/SID/wt--z/runner.py --task-id task-z --team r   )
task_shortteams   r   listerz_ps_with.<locals>.lister9   s0    @AdV T(\$9
 	
r   r   )r!   r"   r#   s   `` r   _ps_withr$   8   s    
 Mr   c                      e Zd ZdZd Zy)RegressionR1LegacyWorktreeuC   R1: legacy `.worktrees/` 위치 worktree 존재 → SPAWN_VERIFIED.c                   dd l }|j                         5 }t        |      }t        |      \  }}}}|dz  j	                  d       t        ddd ||||t        dd            }| j                  |j                  d	       | j                  |j                  d
       t        |dd      }	| j                  |	j                  t        j                  d|	j                   d|	j                   d       d d d        y # 1 sw Y   y xY w)Nr   wt-2657-dev6Tr   	task-2657dev62657schedule_idlegacy_rootcokacdir_rootschedule_history_dir
memory_dirprocess_listeru   legacy worktree 검출 실패u   executor process 검출 실패x   elapsed_since_fire_secondsfirst_response_not_refusalu   R1 FAIL — got  ())tempfileTemporaryDirectoryr   r   r   r	   r$   
assertTruelegacy_worktree_presentexecutor_process_presentr   assertEqualstatusr   SPAWN_VERIFIEDreason
selfr:   tmpdirr   r   r   r   r   snapshotdecisions
             r   test_r1z"RegressionR1LegacyWorktree.test_r1E   s    ((* 	fv,C0<S0A-FHgvn$++D+9& "&%,!'7	H OOH<<>]^OOH==?_`0+.+/H %44"8??"32hoo5FaH3	 	 	s   CC88DN)__name__
__module____qualname____doc__rH   r   r   r   r&   r&   B   s
    M r   r&   c                      e Zd ZdZd Zy)RegressionR2CokacdirWorktreeu7   R2: cokacdir 위치 worktree 존재 → SPAWN_VERIFIED.c                <   dd l }|j                         5 }t        |      }t        |      \  }}}}d}||z  dz  j	                  d       |dz  j	                  d       t        dd|||||t        dd      	      }	| j                  |	j                  d
       | j                  |	j                  d       t        |	dd      }
| j                  |
j                  t        j                  d|
j                   d|
j                   d       d d d        y # 1 sw Y   y xY w)Nr   426931FEr(   Tr)   r*   r+   r,   r-   u   cokacdir worktree 검출 실패u$   schedule_workspace_dir 검출 실패r4   r5   u   R2 FAIL — got r8   r9   )r:   r;   r   r   r   r	   r$   r<   cokacdir_worktree_presentschedule_workspace_dir_presentr   r?   r@   r   rA   rB   rD   r:   rE   r   r   r   r   r   sidrF   rG   s              r   test_r2z$RegressionR2CokacdirWorktree.test_r2k   s   ((* 	fv,C0<S0A-FHgvC^n,33D3An$++D+9&"&%,!'7	H OOH>>@abOOHCCEkl0+.+/H %44"8??"32hoo5FaH7	 	 	s   C4DDN)rI   rJ   rK   rL   rU   r   r   r   rN   rN   h   s
    A"r   rN   c                      e Zd ZdZd Zd Zy)*RegressionR3CokacdirOnlyFalseNegativeBlocku   R3: .worktrees 없고 cokacdir 에만 → SPAWN_VERIFIED.

    ★ false negative 금지 핵심 (task-2657 사고 직접 재발 방지)
    c                   dd l }|j                         5 }t        |      }t        |      \  }}}}d}||z  dz  j	                  d       t        dd|||||t        dd      	      }	| j                  |	j                  d
       | j                  |	j                  d       t        |	dd      }
| j                  |
j                  t        j                  d|
j                   d|
j                    d       d d d        y # 1 sw Y   y xY w)Nr   rP   r(   Tr)   r*   r+   r,   r-   u<   legacy 가 비어 있어야 한다 (테스트 셋업 오류)u3   cokacdir worktree 검출 실패 — false negative!r4   r5   u"   R3 FAIL (false negative!) — got r8   r9   )r:   r;   r   r   r   r	   r$   assertFalser=   r<   rQ   r   r?   r@   r   rA   rB   rS   s              r   test_r3z2RegressionR3CokacdirOnlyFalseNegativeBlock.test_r3   s   ((* %	fv,C0<S0A-FHgvC^n,33D3A&"&%,!'7	H 00N OO22E
 1+.+/H %444X__4ERGXXYZC%	 %	 %	s   CC==Dc                   ddl }|j                         5 }t        |      }t        |      \  }}}}d}||z  dz  j	                  d       t        ddd||||t        d	d      
      }	| j                  |	j                  d       t        |	dd      }
| j                  |
j                  t        j                         ddd       y# 1 sw Y   yxY w)uJ   R3 보강: schedule_id 미제공 시 광역 glob 으로도 SPAWN_VERIFIED.r   NAAA12345r(   Tr)   r*   r+   r,   r-   uH   schedule_id 없이도 광역 glob 으로 cokacdir worktree 잡아야 함r4   r5   )r:   r;   r   r   r   r	   r$   r<   rQ   r   r?   r@   r   rA   rS   s              r   )test_r3_without_schedule_id_fallback_globzTRegressionR3CokacdirOnlyFalseNegativeBlock.test_r3_without_schedule_id_fallback_glob   s    ((* 	Tfv,C0<S0A-FHgvC^n,33D3A& "&%,!'7	H OO22Z 1+.+/H
 X__.C.R.RS5	T 	T 	Ts   B'CCN)rI   rJ   rK   rL   rZ   r]   r   r   r   rW   rW      s    
(TTr   rW   c                      e Zd ZdZd Zy)%RegressionR4CallbackRecoveredAfterGapu   R4: process 부재 + result/report/done 모두 존재
       → CALLBACK_RECOVERED_AFTER_VISIBILITY_GAP (★ 2 source 교차 강제).c                   dd l }|j                         5 }t        |      }t        |      \  }}}}d}|dz  | dz  j	                  dd       |dz  | dz  j	                  t        j                  |d	d
      d       |dz  | dz  j	                  dd       t        |dd ||||t              }	| j                  |	j                  d       | j                  |	j                         | j                  |	j                         | j                  |	j                         | j                  t!        |	j#                               dd       t%        |	ddd      }
| j'                  |
j(                  t*        j,                  d|
j(                   d|
j.                   d       | j                  |
j0                  d       d d d        y # 1 sw Y   y xY w)Nr   r*   r   z.donedoneutf-8encodingz.axis-3-result-260525.jsonok)task_idcompletion_statusr   z.mdz# reportr+   r-   u   process 부재 셋업 오류r   u+   callback evidence 2 source 교차 미충족iX  TFr6   initial_anu_absent_observedr7   u   R4 FAIL — got r8   r9   )r:   r;   r   r   
write_textjsondumpsr	   r   rY   r>   r<   done_presentresult_presentreport_presentassertGreaterEquallencallback_evidence_sourcesr   r?   r@   r   'CALLBACK_RECOVERED_AFTER_VISIBILITY_GAPrB   crossed_sources_count)rD   r:   rE   r   r   r   r   r   rf   rF   rG   s              r   test_r4z-RegressionR4CallbackRecoveredAfterGap.test_r4   s   ((* -	Gfv,C0<S0A-FHgv!GhG9E!22>>vPW>XhG9,F!GGSS

wTJK  T  iWIS/1==jSZ=[& "&%,!(	H X>>@^_OOH112OOH334OOH334##H6689= 1+.,0+0	H %MM"8??"32hoo5FaH
 ##H$B$BAF[-	G -	G -	Gs   F'GGN)rI   rJ   rK   rL   ru   r   r   r   r_   r_      s    T0Gr   r_   c                      e Zd ZdZd Zy)RegressionR5TrueSilentDropu:   R5: 전 source 부재 + 30분 경과 → TRUE_SILENT_DROP.c                   dd l }|j                         5 }t        |      }t        |      \  }}}}t	        ddd||||t
              }| j                  |j                         d       | j                  |j                         d       t        |t        dz   dd	
      }	| j                  |	j                  t        j                  d|	j                   d|	j                   d       | j                  |	j                   j"                         | j                  |	j                   j$                  d       d d d        y # 1 sw Y   y xY w)Nr   r*   r+   DEADBEEFr-   r   <   TFrh   u   R5 FAIL — got r8   r9   )r:   r;   r   r   r	   r   r?   positive_sourcesrr   r   r   r@   r   TRUE_SILENT_DROPrB   r<   timeoutsilent_drop_eligibleblocking_exceptionsrC   s
             r   test_r5z"RegressionR5TrueSilentDrop.test_r5  s+   ((* 	Gfv,C0<S0A-FHgv&&"&%,!(	H X668"=X??A2F0+?"+D,0+0	H %66"8??"32hoo5FaH
 OOH,,AABX--AA2F?	G 	G 	Gs   DD88EN)rI   rJ   rK   rL   r   r   r   r   rw   rw     s    D"Gr   rw   c                      e Zd ZdZd Zy)+RegressionR6SchedulePendingBlocksSilentDropuT   R6: schedule_history pending → SPAWN_PENDING (★ TRUE_SILENT_DROP 단정 금지).c                   dd l }|j                         5 }t        |      }t        |      \  }}}}d}|| dz  j	                  t        j                  dd|d      dz   d	       t        d
d|||||t              }	| j                  |	j                         | j                  |	j                  d       t        |	dd      }
| j                  |
j                  t        j                   d|
j                   d|
j"                   d       t        |	t$        dz   d      }| j'                  |j                  t        j(                  d       | j+                  |j,                  j.                  d       d d d        y # 1 sw Y   y xY w)Nr   PENDING1z.logz2026-05-25T12:00:00+09:00pending)tsr@   r.   
rb   rc   r*   r+   r-   r4   Fr5   u   R6 FAIL — got r8   r9   rz   uC   R6 FAIL — pending 상태에서 TRUE_SILENT_DROP 으로 단정됨!u/   timeout gate 가 pending 예외를 통과시킴)r:   r;   r   r   rj   rk   rl   r	   r   r<   schedule_history_presentr?   schedule_history_last_statusr   r@   r   SPAWN_PENDINGrB   r   assertNotEqualr|   rY   r}   r~   )rD   r:   rE   r   r   r   r   r   rT   rF   decision_shortdecision_longs               r   test_r6z3RegressionR6SchedulePendingBlocksSilentDrop.test_r6C  s   ((* 2	fv,C0<S0A-FHgvC#d|#//

"=cfghkoo  0 
 '"&%,!(	H OOH==>XBBIN 7+.+0N
 %%%33">#8#8"9N<Q<Q;RRST 6+?"+D+0M
 $$%66U
 %%::A_2	 2	 2	s   EE77F N)rI   rJ   rK   rL   r   r   r   r   r   r   @  s
    ^5r   r   __main__)r   r   )r!   strr"   r   )!rL   
__future__r   rk   ossysunittestpathlibr   __file__resolver   
_REPO_ROOTr   pathinsert utils.anu_spawn_visibility_guardr   r   r   r	   r   r   r$   TestCaser&   rN   rW   r_   rw   r   rI   mainr   r   r   <module>r      s    #  	 
   (^##%--a0
z?#(("HHOOAs:' -#!2!2 #L%8#4#4 %PNT1B1B NTb4GH,=,= 4Gn%G!2!2 %GP8(2C2C 8v zHMMO r   