
    j}                    
   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ZddlZddlZ ej&                  e      j+                         j,                  d   Zedz  dz  Zej2                  Z e       Zes ej8                  de       dz   d	 ej:                         v s ej<                  e      r ej>                  e      nd	 ej>                  e       ej>                  e      d
z  Z  e! ejD                  e             dxZZejF                  r\ejF                  d    e$e      k7  rD	 ejF                  jK                   e$e             ejF                  jO                  d e$e              e(ejR                  jU                               D ]&  Z+e+dk(  se+jY                  d      sejR                  e+= ( dZ-ej\                  j_                  e- e$e            Z0g ZdZ1e0e1uZeZ2ere0jf                  Z4dZ5e4e5uZ6e6Z2e2sB ejn                  defde0e1f      d ej:                         v s ej<                  e0      r ej>                  e0      nd ej>                  e1      dz  Z8dde8iz  Z9eju                  e9       er ejn                  de6fde4e5f      d ej:                         v s ej<                  e0      r ej>                  e0      nd ej>                  e4       ej>                  e5      dz  Z;dde;iz  Z<eju                  e<        ejz                  ed      i z  Z>dde>iz  Z? e! ejD                  e?            dxZ2xZxZxZ1xZ4xZ6Z5ej\                  j                  e0      ZAeAejR                  e-<   e0jf                  j                  eA       eAj                  ZCeAj                  ZDeAj                  ZEeAj                  ZFeAj                  ZGeAj                  ZHeAj                  ZIeAj                  ZJeAj                  ZKeAj                  ZLeAj                  ZNeAj                  ZOeAj                  ZPeAj                  ZQeAj                  ZRedz  dz  ZSedz  dz  ZTd1dZU G d dej                        ZW G d  d!ej                        ZX G d" d#ej                        ZY G d$ d%ej                        ZZ G d& d'ej                        Z[ G d( d)ej                        Z\ G d* d+ej                        Z] G d, d-ej                        Z^ G d. d/ej                        Z_e`d0k(  r ej                          yy# e&$ r Y w xY w)2u  task-2661 Phase 2b callback fire delay remediation — regression 8.

회장 verbatim regression 8 (task-2661 md):

  R1: normal callback uses absolute --at timestamp ≤ 30s from done time
  R2: --at "10s" is not used anywhere in production path
  R3: fallback/dead-man delay remains unchanged
  R4: delay > 60s normal callback requires reason or reclassification
  R5: task-2659 timing fixture prevents 14:10 → 14:25 normal callback delay recurrence
  R6: callback envelope byte limit 유지 (UTF-8 ≤ 3900)
  R7: docstring reflects live runtime: second suffix unsupported · absolute timestamp supported
  R8: API overloaded is logged separately and does not mask scheduler format failure

Phase 4 enforce 아님 — R4 는 verdict 변경 0, stderr warning 만 검증.
    )annotationsN   dispatchz"normal_fallback_callback_helper.pyzmissing helper: zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}_HELPER_PATH)py0py2py4z	dispatch."dispatch_helper_worktree_task_2661)is not)z%(py2)s is not %(py5)s_spec)r   py5z%(py7)spy7)z5%(py11)s
{%(py11)s = %(py9)s.loader
} is not %(py14)s)py9py11py14z%(py16)spy16zassert %(py19)spy19scriptszfinish-task.shutilszanu_callback_registrar.pyc                 v   t         j                  d      } t        j                  d|       }|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      S )	Nutf-8encodingzJ--kind normal[\s\S]*?--prompt\s+\"\$T2626_ENVELOPE\"\s+--at\s+\"([^\"]+)\"z5finish-task.sh normal callback --at pattern not foundz
>assert %(py0)sr   m   )FINISH_TASK_SH	read_textresearch
@pytest_ar_format_assertmsg@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationgroup)textr   @py_format1s      R/home/jay/workspace/tests/callback_fire_delay_remediation_p2b/test_regression_8.py!_extract_normal_at_from_finish_shr,   J   ss    ##W#5D
		U	A EEEEEEEEE1EEE1EEEEE771:    c                  (    e Zd ZdZddZddZddZy)R1NormalAbsoluteAtUnder30su?   R1: normal callback --at = absolute timestamp · delta ≤ 30s.c                X    t        d      }| j                  t        |      d|d       y )N   z&build_absolute_at_for_normal_delay -> z not absolute)"build_absolute_at_for_normal_delay
assertTrueis_absolute_at)selfats     r+   9test_build_absolute_at_returns_cokacdir_compatible_formatzTR1NormalAbsoluteAtUnder30s.test_build_absolute_at_returns_cokacdir_compatible_formatZ   s,    /324RF-H	
r-   c                
   | j                  t        d       t        j                  dddddd      }t	        |      }t        ||      }| j                  |       | j                  |dd	| d
       | j                  |d       y )Nr1              
   3   nowzdelta u   s must be ≤ 30sr   )	assertEqualDEFAULT_AT_NORMAL_DELAY_SECONDS_dtdatetimer2   absolute_at_delay_secondsassertIsNotNoneassertLessEqualassertGreaterEqual)r5   	fixed_nowr6   deltas       r+   +test_build_absolute_at_default_delay_is_30szFR1NormalAbsoluteAtUnder30s.test_build_absolute_at_default_delay_is_30sa   s{    8"=LLq"b"b9	/I>)")<U#UB&7H(IJq)r-   c           	     @   g d}t        j                         t        j                         }}t        j                  t        j                  }}||ct        _        t        _        	 t        |      }||ct        _        t        _        | j                  |dd| d|j                                t        j                  |j                               }|j                  d      xs g }d}	t        |      D ]&  \  }
}|dk(  s|
dz   t        |      k  s||
dz      }	 n | j                  |	d	|        | j                  t        |	      d
|	d       t!        |	      }| j                  |       | j#                  |dd| d       y# ||ct        _        t        _        w xY w)uP   helper_main launch --kind normal → argv has --at = absolute timestamp ≤ 30s.)launch--kindnormal	--task-idztask-2661-r1--executor-keyzexecutor-r1--owner-keyc119085addb0f8b7	--chat-id
6937032012--promptzztask_id=task-2661-r1
collector_role=ANU
callback_kind=normal
owner_key=c119085addb0f8b7
canonical_root=/home/jay/workspace--canonical-root/home/jay/workspacer   helper_main rc= stderr=argvN--atr   argv missing --at: normal --at=z& must be absolute timestamp (Phase 2b)r1   znormal --at delta u   s > 30s (회장 verbatim))ioStringIOsysstdoutstderrhelper_mainrA   getvaluejsonloadsget	enumeratelenrF   r3   r4   rE   rG   )r5   r[   buferr	saved_out	saved_errrcdecargv_outat_valueitokrJ   s                r+   8test_helper_main_normal_kind_emits_absolute_at_under_30szSR1NormalAbsoluteAtUnder30s.test_helper_main_normal_kind_emits_absolute_at_under_30sj   su   
 ;;="++-S"zz3::9	!$c
CJ	:T"B%.	"CJ
Q/"Xclln=O PQjj(776?(b) 	FAsf}QX!6#AE?	 	X)<XJ'GH8$8,&LM	
 *(3U#UB*<UGC\(]^! &/	"CJ
s   %F FNreturnNone)__name__
__module____qualname____doc__r7   rK   ru    r-   r+   r/   r/   W   s    I
*$_r-   r/   c                  0    e Zd ZdZddZddZddZddZy) R2NoTenSecondLiteralInProductionuC   R2: `--at "10s"` 재사용 금지 (cokacdir runtime reject anchor).c                |    t         j                  d      }| j                  d|d       | j                  d|d       y )Nr   r   z
--at "10s"uO   scripts/finish-task.sh contains forbidden `--at "10s"` (회장 verbatim 위반)z
--at '10s'z6scripts/finish-task.sh contains forbidden `--at '10s'`r   r   assertNotInr5   r)   s     r+   'test_finish_task_sh_does_not_use_at_10szHR2NoTenSecondLiteralInProduction.test_finish_task_sh_does_not_use_at_10s   sC    '''9D_	

 	$D	
r-   c                    t         j                  d      }t        j                  d|      }| j	                  |d       y)u<   smoking gun B: `--at "10m"` 가 normal kind 옆에 잔존 0.r   r   z)--kind normal[\s\S]{0,400}?--at\s+\"10m\"ui   scripts/finish-task.sh 의 normal callback 옆에 `--at "10m"` 잔존 — task-2659 14:25 idle gap 재발N)r   r   r   r   assertIsNone)r5   r)   r   s      r+   2test_finish_task_sh_does_not_use_at_10m_for_normalzSR2NoTenSecondLiteralInProduction.test_finish_task_sh_does_not_use_at_10m_for_normal   sA    '''9II8
 	.	
r-   c                D    | j                  t        t        d      d       y)uH   helper module 에 `DEFAULT_AT_NORMAL = '10s'` 잔존 0 (Phase 2 흔적).DEFAULT_AT_NORMALur   helper exposes DEFAULT_AT_NORMAL — Phase 2 잔존, Phase 2b 는 DEFAULT_AT_NORMAL_DELAY_SECONDS (int) 만 사용N)assertFalsehasattr_helper_moduler5   s    r+   .test_helper_module_does_not_export_10s_defaultzOR2NoTenSecondLiteralInProduction.test_helper_module_does_not_export_10s_default   s"     	N$78?	
r-   c                |    t         j                  d      }| j                  d|d       | j                  d|d       y)u1   금지 12 — `--in` / `--delay` 옵션 사용 0.r   r   z--in 10suH   `--in 10s` 옵션 — cokacdir 증거 없음 (회장 verbatim 비채택)z--delay 10suK   `--delay 10s` 옵션 — cokacdir 증거 없음 (회장 verbatim 비채택)Nr   r   s     r+   !test_in_or_delay_options_not_usedzBR2NoTenSecondLiteralInProduction.test_in_or_delay_options_not_used   sC    '''9V	
 	4Y	
r-   Nrv   )ry   rz   r{   r|   r   r   r   r   r}   r-   r+   r   r      s    M




r-   r   c                  (    e Zd ZdZddZddZddZy)R3FallbackUnchangedu?   R3: fallback default '10m' 변경 0 (회장 verbatim ANCHOR-1).c           	         | j                  t        dd       t        t              }| j                  |ddt        d| d       y )N10muI   DEFAULT_AT_FALLBACK 변경 금지 — Phase 3 별도 회장 승인 강제X  zfallback default z -> u   s, must be ≥ 600s)rA   DEFAULT_AT_FALLBACKparse_at_secondsrH   )r5   secss     r+   +test_default_at_fallback_constant_unchangedz?R3FallbackUnchanged.test_default_at_fallback_constant_unchanged   sM    W	
   34# 36d4&@ST	
r-   c           	        g d}t        j                         t        j                         }}t        j                  t        j                  }}||ct        _        t        _        	 t        |      }||ct        _        t        _        | j                  |dd| d|j                                t        j                  |j                               }|j                  d      xs g }d }	t        |      D ]&  \  }
}|dk(  s|
dz   t        |      k  s||
dz      }	 n | j                  |	d|        | j                  |	d	d
|	d       t        |	      }| j                  |d       y # ||ct        _        t        _        w xY w)N)rM   rN   fallbackrP   ztask-2661-r3rQ   zexecutor-r3rR   rS   rT   rU   rV   z|task_id=task-2661-r3
collector_role=ANU
callback_kind=fallback
owner_key=c119085addb0f8b7
canonical_root=/home/jay/workspacerW   rX   r   rY   rZ   r[   r\   r   r]   r   zfallback default --at=u    must equal '10m' (변경 0)r   )r_   r`   ra   rb   rc   rd   rA   re   rf   rg   rh   ri   rj   rF   r   rH   )r5   r[   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   r   s                r+   0test_helper_main_fallback_kind_default_unchangedzDR3FallbackUnchanged.test_helper_main_fallback_kind_default_unchanged   sY   
 ;;="++-S"zz3::9	!$c
CJ	:T"B%.	"CJ
Q/"Xclln=O PQjj(776?(b) 	FAsf}QX!6#AE?	 	X)<XJ'GHe$XL0LM	
  )c*! &/	"CJ
s   %E& &E?c                    t         dz  dz  }t         dz  dz  }| j                  |j                         d|        | j                  |j                         d|        y)u   utils/anu_callback_fallback.py 와 utils/completion_callback_fallback_cancel.py
        는 본 task 범위 외 — import 만 검증 (signature/behavior 변경 0).r   zanu_callback_fallback.pyz&completion_callback_fallback_cancel.pyzmissing N)	REPO_ROOTr3   exists)r5   fallback_modulecancel_modules      r+    test_no_fallback_module_modifiedz4R3FallbackUnchanged.test_no_fallback_module_modified   sa     $g-0JJ!G+.VV..0H_<M2NO,,.(=/0JKr-   Nrv   )ry   rz   r{   r|   r   r   r   r}   r-   r+   r   r      s    I	
#+JLr-   r   c                  8    e Zd ZdZddZddZddZddZddZy)	R4NormalDelayReasonLintuI   R4: normal delay > 60s + reason 없음 → lint warning (enforce 아님).c                    t        dd      }| j                  |d   d|       | j                  |d   d       | j                  |d   d       y )	NrO   r   warningzexpected warning, got codeNORMAL_DELAY_REASON_REQUIREDdelay_secondsr   )lint_normal_callback_delayr3   rA   r5   outs     r+   5test_lint_warns_normal_relative_suffix_over_thresholdzMR4NormalDelayReasonLint.test_lint_warns_normal_relative_suffix_over_threshold  sR    (59I*@(HIV&DE_-s3r-   c                    t        j                  dddddd      }|t        j                  d      z   j                  d      }t	        d	||
      }| j                  |d   d|       | j                  |d   d       y)u6   absolute timestamp 도 (target - now) 환산 후 lint.r9   r:   r;   r<   r   x   seconds%Y-%m-%d %H:%M:%SrO   r?   r   z(expected warning for 120s absolute, got r   r   N)rC   rD   	timedeltastrftimer   r3   rA   )r5   rI   far_future_atr   s       r+   .test_lint_warns_normal_absolute_over_thresholdzFR4NormalDelayReasonLint.test_lint_warns_normal_absolute_over_threshold  sx    LLq"b!Q7	"S]]3%??IIJ]^(=iPI*RSVRY(Z[V&DEr-   c                r    t        ddd      }| j                  |d          | j                  |d   d       y )NrO   r   zpost-cron CI sync needed)reasonr   r   REASON_PROVIDEDr   r   rA   r   s     r+   %test_lint_silent_when_reason_providedz=R4NormalDelayReasonLint.test_lint_silent_when_reason_provided  s=    (e$>
 	Y(V&78r-   c                    t        j                  dddddd      }|t        j                  d      z   j                  d      }t	        d	||
      }| j                  |d   d|       | j                  |d   d       y )Nr9   r:   r;   r<   r   r1   r   r   rO   r?   r   zexpected silent for 30s, got r   WITHIN_THRESHOLD)rC   rD   r   r   r   r   rA   )r5   rI   near_atr   s       r+   *test_lint_silent_within_threshold_absolutezBR4NormalDelayReasonLint.test_lint_silent_within_threshold_absolute"  sx    LLq"b!Q7	s}}R88BBCVW(7	JY+H)PQV&89r-   c                n    t        dd      }| j                  |d          | j                  |d   d       y )Nr   r   r   r   SKIP_NON_NORMALr   r   s     r+   test_lint_skip_fallback_kindz4R4NormalDelayReasonLint.test_lint_skip_fallback_kind)  s5    (U;Y(V&78r-   Nrv   )	ry   rz   r{   r|   r   r   r   r   r   r}   r-   r+   r   r   
  s    S4F9:9r-   r   c                       e Zd ZdZddZddZy)R5Task2659TimingGuardu   R5: task-2659 chronology fixture (.done 14:10:51 → callback 14:25:00 = 14m gap)
    에 대해 Phase 2b 후 done→fire 가 절반 이하 idle gap 으로 축소.
    c           	     .   t        j                  dddddd      }t        j                  dddddd      }t        d	|
      }t         j                  j                  |d      }|t        j                  d      z   }t        ||z
  j                               }t        ||z
  j                               }| j                  |dd       | j                  ||dz  d| d| d       t        ||z
  j                               }| j                  |d	d| d       y )Nr9   r:   r;   r<   r=   r>      r   r1   r?   r   )minutesiH  u:   fixture sanity: pre-remediation 14m gap (task-2659 박제)r   zpost-remediation idle gap z$s must be < half of pre-remediation u   s (task-2659 재발 금지)u   register→fire u(   s > 30s (normal callback 진행 trigger))
rC   rD   r2   strptimer   inttotal_secondsrH   
assertLessrG   )	r5   	done_emitregister_atpost_at	post_firepre_fireidle_gap_postidle_gap_preregister_to_fires	            r+   >test_task_2659_replay_post_remediation_under_30s_from_registerzTR5Task2659TimingGuard.test_task_2659_replay_post_remediation_under_30s_from_register7  s   LLq"b"b9	ll4BB:4R[ILL))'3FG	r!::Y2AACDHy0??AB'H	
 	<1,( 8+n,GI	

 	K 7FFHIb/00XY	
r-   c                    t         j                  d      }| j                  |dd       t               }| j                  |dd|d       y)	u   finish-task.sh 의 normal --at 가 (date -d '+30 seconds' '+%Y-%m-%d %H:%M:%S')
        결과를 사용하는 절대시각 인지 검증.r   r   zDdate\s+-d\s+'(\+30 seconds|\+\d+\s+seconds)'\s+'\+%Y-%m-%d %H:%M:%S'u`   finish-task.sh 에 (date -d '+N seconds' '+%Y-%m-%d %H:%M:%S') 절대시각 생성 패턴 없음z^\$\{?[A-Z_][A-Z0-9_]*\}?$r^   zM must reference an absolute-timestamp variable, not a relative-suffix literalN)r   r   assertRegexr,   )r5   r)   	normal_ats      r+   9test_finish_task_sh_uses_absolute_at_command_substitutionzOR5Task2659TimingGuard.test_finish_task_sh_uses_absolute_at_command_substitutionR  s]     '''9Sn	
 67	49- (, ,	
r-   Nrv   )ry   rz   r{   r|   r   r   r}   r-   r+   r   r   2  s    
6
r-   r   c                  (    e Zd ZdZddZddZddZy)R6EnvelopeByteLimitMaintaineduC   R6: CALLBACK_PROMPT_MAX_BYTES = 3900 유지 + envelope-only 유지.c                2    | j                  t        dd       y )Ni<  u;   CALLBACK_PROMPT_MAX_BYTES 변경 금지 (회장 §5.5/§10))rA   CALLBACK_PROMPT_MAX_BYTESr   s    r+   (test_callback_prompt_max_bytes_unchangedzFR6EnvelopeByteLimitMaintained.test_callback_prompt_max_bytes_unchangedl  s    %tI	
r-   c                    d}t        |      }| j                  |t        d| dt                | j                  t	        |      d       y )Na3  task_id=task-9999-very-long-task-identifier-padded-for-margin
result_path=memory/events/task-9999.result.json
report_path=memory/reports/task-9999.md
collector_role=ANU
callback_kind=normal
source_attribution=FINISH_TASK_SH_BOT_COMPLETION_NORMAL
owner_key=c119085addb0f8b7
canonical_root=/home/jay/workspacez	envelope z	 bytes > u3   라벨 보강 후에도 envelope-only 유지 필요)callback_prompt_utf8_bytesrG   r   r3   is_envelope_only)r5   envelope_templateutf8s      r+   -test_finish_task_sh_envelope_under_3900_byteszKR6EnvelopeByteLimitMaintained.test_finish_task_sh_envelope_under_3900_bytesr  sY    1 	 **;<+vY'@&AB	
 	./A	
r-   c                \    | j                  dt               | j                  dt               y )Nsource_attributioncallback_kind)assertInENVELOPE_ALLOWED_KEYSr   s    r+   6test_source_attribution_label_in_envelope_allowed_keyszTR6EnvelopeByteLimitMaintained.test_source_attribution_label_in_envelope_allowed_keys  s!    *,ABo'<=r-   Nrv   )ry   rz   r{   r|   r   r   r   r}   r-   r+   r   r   i  s    M

*>r-   r   c                  (    e Zd ZdZddZddZddZy)R7DocstringReflectsLiveRuntimeu8   R7: utils/anu_callback_registrar.py docstring 정확화.c                Z   t         j                  d      }t        j                  d|t        j                        }| j                  |d       |j                  d      }| j                  d|d       | j                  d	|d
       | j                  |dd       | j                  d|d       y )Nr   r   Adef\s+_delay_to_at_value\([^)]*\)\s*->\s*str:\s*\"\"\"(.*?)\"\"\"flagsz&_delay_to_at_value docstring not foundr   UNSUPPORTEDz>docstring must state second suffix UNSUPPORTED in live runtimeabsolute timestampz;docstring must mention absolute timestamp as supported formzYYYY-MM-DD\s+HH:MM:SSz1docstring must show the absolute timestamp format1mzBdocstring must state 1m is the smallest legal relative-suffix form)	ANU_REGISTRARr   r   r   DOTALLrF   r(   r   r   r5   r)   r   docs       r+   Jtest_registrar_delay_to_at_value_docstring_marks_second_suffix_unsupportedziR7DocstringReflectsLiveRuntime.test_registrar_delay_to_at_value_docstring_marks_second_suffix_unsupported  s    &&&8IIP		
 	Q HIggaj3L	
 	 #I	
 	)?	
 	#P	
r-   c                    t         j                  d      }t        j                  d|t        j                        }| j                  |       |j                  d      }| j                  |dd       y)	uL   legacy 'cokacdir accepts ... second granularity (10s)' 거짓 라인 제거.r   r   r   r   r   z&second\s+granularity\s+\(`?`?10s`?`?\)zFdocstring still falsely claims 'second granularity (10s)' is supportedN)r   r   r   r   r   rF   r(   assertNotRegexr   s       r+   >test_registrar_docstring_does_not_falsely_claim_second_supportz]R7DocstringReflectsLiveRuntime.test_registrar_docstring_does_not_falsely_claim_second_support  sc    &&&8IIP		
 	Qggaj:T	
r-   c                V    t         j                  d      }| j                  |dd       y)u'   ANCHOR-4: 함수 시그니처 변경 0.r   r   z<def\s+_delay_to_at_value\(delay_seconds:\s*int\)\s*->\s*str:zD_delay_to_at_value signature must remain (delay_seconds: int) -> strN)r   r   r   r   s     r+   +test_registrar_function_signature_unchangedzJR7DocstringReflectsLiveRuntime.test_registrar_function_signature_unchanged  s,    &&&8KR	
r-   Nrv   )ry   rz   r{   r|   r   r   r   r}   r-   r+   r   r     s    B
6

r-   r   c                  (    e Zd ZdZddZddZddZy)R8ApiOverloadedSeparateLoggingu  R8: API overloaded (Anthropic stop_sequence) 와 scheduler format failure
    (cokacdir invalid --at) 는 별도 channel/marker 로 분리되어야 한다.

    helper 는 외부 Anthropic API 호출을 하지 않으므로, helper 자체 안에서
    API overload 와 scheduler reject 가 mix될 가능성은 없다. 본 fixture 는:
      (a) lint warning stream (stderr · '[task-2661 lint warning]' prefix)
      (b) launcher status (stdout JSON · contract_fields.callback_registration_status)
      (c) cokacdir reject (외부 cron register 실패 — argv 보존)
    세 channel 이 독립적으로 분리되어 있음을 단언한다.
    c                ,   g d}t        j                         t        j                         }}t        j                  t        j                  }}||ct        _        t        _        	 t        |      }||ct        _        t        _        | j                  |dd       | j                  d|j                                t        j                  |j                               }| j                  |d   d       | j                  |d   d       | j                  d|j                                d	D ]M  }| j                  ||j                  dd
             |j                  dg       D ]  }	| j                  ||	        O y# ||ct        _        t        _        w xY w)uZ   normal delay > 60s warning 은 stderr 에만 가고, launcher verdict/status 는 변경 0.)rM   rN   rO   rP   ztask-2661-r8arQ   zexecutor-r8arR   rS   rT   rU   rV   z{task_id=task-2661-r8a
collector_role=ANU
callback_kind=normal
owner_key=c119085addb0f8b7
canonical_root=/home/jay/workspacer\   r   rW   rX   r   u1   lint warning 은 enforce 아님 — return code 0z[task-2661 lint warning]verdictPASSstatusANU_OWNED_READY)
Overloaded
overloadedstop_sequence reasonsN)r_   r`   ra   rb   rc   rd   rA   r   re   rf   rg   r   rh   )
r5   r[   rk   rl   rm   rn   ro   rp   krs
             r+   7test_lint_warning_only_in_stderr_not_in_launcher_statuszVR8ApiOverloadedSeparateLogging.test_lint_warning_only_in_stderr_not_in_launcher_status  sD   
 ;;="++-S"zz3::9	!$c
CJ	:T"B%.	"CJ
Q ST0#,,.Ajj(Y0X(9:3S\\^D> 	'AQ" 56WWY+ '  A&'	' &/	"CJ
s   %E: :Fc                   g d}t        j                         t        j                         }}t        j                  t        j                  }}||ct        _        t        _        	 t        |      }||ct        _        t        _        | j                  |d       t        j                  |j                               }| j                  |d   d       g d}t        j                         t        j                         }
}	t        j                  t        j                  }}|	|
ct        _        t        _        	 t        |      }||ct        _        t        _        | j                  |d       t        j                  |	j                               }| j                  |d   d       | j                  |d   |d          y# ||ct        _        t        _        w xY w# ||ct        _        t        _        w xY w)u   scheduler/format failure (CANONICAL_ROOT_INVALID, CALLBACK_PROMPT_TOO_LARGE)
        와 owner failure (SELF_KEY_FAIL_CLOSED) 는 별도 STATUS_ code 로 분리.)rM   rN   rO   rP   ztask-2661-r8brQ   zexecutor-r8brR   rS   rT   rU   rV   zrtask_id=task-2661-r8b
collector_role=ANU
callback_kind=normal
owner_key=c119085addb0f8b7
canonical_root=/elsewhererW   z
/elsewherer   r  CANONICAL_ROOT_INVALID)rM   rN   rO   rP   ztask-2661-r8crQ   self-key-sharedrR   r  rT   rU   rV   zztask_id=task-2661-r8c
collector_role=ANU
callback_kind=normal
owner_key=self-key-shared
canonical_root=/home/jay/workspacerW   rX   SELF_KEY_FAIL_CLOSEDN)r_   r`   ra   rb   rc   rd   assertNotEqualrf   rg   re   rA   )r5   	argv_rootrk   rl   rm   rn   rc_rootdec_root	argv_selfbuf2err2rc_selfdec_selfs                r+   @test_scheduler_format_failure_status_distinct_from_owner_failurez_R8ApiOverloadedSeparateLogging.test_scheduler_format_failure_status_distinct_from_owner_failure  ss   
	 ;;="++-S"zz3::9	!$c
CJ	:!),G%.	"CJ
GQ'::clln-(+-EF
	 [[]BKKMd"zz3::9	!%t
CJ	:!),G%.	"CJ
GQ'::dmmo.(+-CDHX.0BC9 &/	"CJ
. &/	"CJ
s   %F: 5G :GG/c                    t         j                  d      }dD ]5  }| j                  |j                         |j                         d|d       7 y)u   helper 는 Anthropic API 호출 자체를 하지 않으므로 'Overloaded' 등의
        키워드가 module source 에 출현하지 않는다 (channel separation 의 근거).r   r   )r  anthropic_overloadapi_overloadzhelper module references u    — channel separation 위반N)r   r   r   lower)r5   
helper_src	forbiddens      r+   2test_helper_module_has_no_anthropic_api_dependencyzQR8ApiOverloadedSeparateLogging.test_helper_module_has_no_anthropic_api_dependency-  sV     "++W+=
M 	I!:#3#3#5+I=8VW	r-   Nrv   )ry   rz   r{   r|   r  r  r   r}   r-   r+   r   r     s    	#'J2Dh	r-   r   c                  (    e Zd ZdZddZddZddZy)R9GeminiMedium2Recurrenceur  [task-2661 Phase 2b · R9] Gemini medium 2 unresolved threads (PR #148) 재발 방지.

    회장 verbatim 'PR #148 Gemini medium auto-remediation' (X1 채택 · 2026-05-25).
    Thread 1: parse_at_seconds raw digits ('10') → None (cokacdir grammar 미지원)
    Thread 2: lint sub-minute relative delay ('10s') → UNSUPPORTED_SUB_MINUTE_RELATIVE_DELAY warning
    c                   ddl m} | j                   |d             | j                   |d             | j                   |d             | j                   |d             | j                   |d      d       | j                   |d	      d
       | j                   |d      d       | j                   |d             y)u   parse_at_seconds raw digits ('10' / '60' / '120') 는 None 반환.
        cokacdir grammar 는 m/h/d suffix + absolute timestamp 만 지원.r   )r   10601203600r   r   1hi  1diQ z2026-05-25 16:50:12N)(dispatch.normal_fallback_callback_helperr   r   rA   )r5   r   s     r+   %test_thread_1_raw_digits_returns_nonez?R9GeminiMedium2Recurrence.test_thread_1_raw_digits_returns_noneA  s     	N*401*401*512*623)%0#6)$/6)$/7*+@ABr-   c                j   ddl m}m}  ||d      }| j                  |d          | j	                  |d   d       | j                  d|d           ||d	      }| j                  |d          | j	                  |d   d        ||d
      }| j                  |d          | j	                  |d   d       y)uP   lint 가 sub-minute relative delay ('Ns' suffix) 에 UNSUPPORTED warning 발급.r   CALLBACK_KIND_NORMALr   10sr   r   %UNSUPPORTED_SUB_MINUTE_RELATIVE_DELAYr   message30sr   r   N)r*  r.  r   r3   rA   r   r   )r5   r.  r   r   out_30sout_1ms         r+   /test_thread_2_sub_minute_relative_delay_warningzIR9GeminiMedium2Recurrence.test_thread_2_sub_minute_relative_delay_warningQ  s    	

 ))=uEI'V&MN*C	N;,-A5I	*+*QR ,,@$G	*+);<r-   c                    ddl m}m} t        j                  dddddd      }|t        j
                  d	      z   j                  d
      } ||||      }| j                  |d          | j                  |d   d       y)u   절대시각 (now+30s) 은 sub-minute 이어도 warning 없음 (정상 path).
        Phase 2b 정책 = absolute timestamp 이 sub-minute 의 유일한 허용 형태.r   r-  r9   r:   r;      2   r1   r   r   r?   r   r   r   N)	r*  r.  r   rC   rD   r   r   r   rA   )r5   r.  r   	now_fixedabsolute_atr   s         r+   ,test_thread_2_absolute_sub_minute_no_warningzFR9GeminiMedium2Recurrence.test_thread_2_absolute_sub_minute_no_warningf  s~    	

 LLq"b"a8	 3==#<<FF
 ) +9
 	Y(V&89r-   Nrv   )ry   rz   r{   r|   r+  r5  r;  r}   r-   r+   r"  r"  9  s    C =*:r-   r"  __main__)rw   str)ar|   
__future__r   builtinsr"   _pytest.assertion.rewrite	assertionrewriter    rD   rC   importlib.util	importlibr_   rf   pathlibr   ra   unittestPath__file__resolveparentsr   r   r   @py_assert1@py_assert3r!   r#   r$   r%   @py_format5r&   r'   pathr=  remove
ValueErrorinsertlistmoduleskeys_mod
startswith	_MOD_NAMEutilspec_from_file_locationr   @py_assert4@py_assert0loader@py_assert10@py_assert13@py_assert12_call_reprcompare@py_format6@py_format8append@py_format15@py_format17_format_boolop@py_format18@py_format20module_from_specr   exec_moduleCALLBACK_KIND_FALLBACKr.  r   r   rB   r   %NORMAL_DELAY_REASON_THRESHOLD_SECONDSrE   r2   r   mainrd   r4   r   r   r   r   r   r,   TestCaser/   r   r   r   r   r   r   r   r"  ry   r}   r-   r+   <module>ro     s6   #      	   	 
  GLL"**,44Q7	:%(LL ? ? ? ? 0? ? ? ? ? ?| ? ? ?| ? ? ? ? ? ? ? ? ? ? 88s9~-I' HHOOAs9~&!!#$ DzT__[9KK 1	..y#l:KL 5D 5uD 5U\\ 5 5\5 5 5 5uD 5 5 5 5 5u 5 5 5u 5 5 5D 5 5 5 5 5 5 5\ 5 5 5 5 5U 5 5 5U 5 5 5\ 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5007'I     ( (>> %:: *DD $88 "0"P"P &<< 88 & +DD %3%V%V "+FF !!..!22 +FF !22  Y&)99G#&AA7_!2!2 7_z0
x'8'8 0
l:L(++ :L@"9h// "9P1
H-- 1
n >H$5$5  >L3
X%6%6 3
rnX%6%6 nb=: 1 1 =:@ zHMMO k  s   7!T< <UU