
    9jA                       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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lmZmZmZ ddlmZ dd	lm Z  dd
l!m"Z"  ee      j                         j                  d   dz  dz  Z#ddZ$ddZ%ddZ&dd	 	 	 	 	 	 	 ddZ'd Z(d Z)d Z*y)u  task-2556 §1/§5/§6/§7 — PR #107 실증 fixture 회귀.

회장 §명시 2026-05-12 본질 1:1:
  PR #107 이 실증한 갭 = idle PR 을 자동 감지해 runner 를 호출하는 daemon/scheduler entry
  point 부재. 본 test 는 ``executor_scheduler.ExecutorScheduler.run_one_cycle`` 이 PR #107
  과 같은 상황 (createdAt + 30min, Gemini reviews 0) 에서 자동으로 owner trigger 를
  발사하는지 회귀 검증.

검증 포인트:
  1. snapshot_provider 호출 1 회.
  2. diagnoser 가 FIRST_GEMINI_TRIGGER_MISSING 으로 분류.
  3. emit_owner_trigger_decision → decision.json 생성.
  4. invoke_from_scheduler → owner_trigger_only.trigger_gemini_review 호출.
  5. POSTED marker 생성.
  6. audit JSONL 에 OWNER_TRIGGER_DISPATCHED 박제.
  7. chat_notifications == 0.
  8. bot_should_exit == True (default polling state — recheck 0 이지만 must_exit_now 는
     False, 즉 첫 cycle 종료 후 외부 cron 재진입).
    )annotationsN)Path   )ACTION_OWNER_TRIGGER_DISPATCHEDExecutorSchedulerSCHEDULER_AUDIT_REL_PATHSchedulerCycleResult)GeminiReviewMetaIdlePRSnapshot"STATE_FIRST_GEMINI_TRIGGER_MISSINGMergeQueueExecutor)OwnerTriggerAudit)OwnerTriggerOnly   fixtureszpr107_first_gemini_missing.jsonc                 T    t        j                  t        j                  d            S )Nutf-8encoding)jsonloadsFIXTURE_PATH	read_text     G/home/jay/workspace/anu_v2/tests/test_executor_scheduler_pr107_pilot.py_load_fixturer   3   s    ::l,,g,>??r   c                    t        d | j                  dg       D              }t        | d   | d   | d   | d   || d   | j                  dd	      | j                  d
d            S )Nc              3  B   K   | ]  }t        |d    |d           yw)	commit_idsubmitted_at)r!   r"   N)r
   ).0rs     r   	<genexpr>z"_build_snapshot.<locals>.<genexpr>8   s+       	1[>.@QRRs   gemini_reviewsnumberhead_shahead_ref
created_atci_required_all_successstateOPENauthor_is_botT)r'   r(   r)   r*   r&   r+   r,   r.   )tuplegetr   )snapshot_dictreviewss     r   _build_snapshotr3   7   s     ""#3R8 G X&z*z* . -.G H0#''>	 	r   c                *    t        d d d d |       S )Nc                    i S Nr   )argsenvs     r   <lambda>z'_build_merge_executor.<locals>.<lambda>J   s    B r   c                     y)N r   )r7   s    r   r9   z'_build_merge_executor.<locals>.<lambda>K       r   c                     y)Nr   r   )pathss    r   r9   z'_build_merge_executor.<locals>.<lambda>L   r<   r   c                     y r6   r   )payloads    r   r9   z'_build_merge_executor.<locals>.<lambda>M   r<   r   )	gh_runner
git_runnerpytest_runneraudit_writertask_md_rootr   )tmp_paths    r   _build_merge_executorrG   H   s    &"%) r   %ghp_owner_test_token_xxxxxxxxxxxxxxxxtokenc               J    fd}t        |       }t        | |fd|      S )Nc                8    j                  | ||d       dddS )N)methodpathbodyr   zhttps://example/comments/1)idhtml_url)append)rM   rN   rO   headers
http_callss       r   	http_postz'_build_owner_trigger.<locals>.http_postX   s$    VT4HI%ABBr   c                      S r6   r   rI   s   r   r9   z&_build_owner_trigger.<locals>.<lambda>`   s    u r   )workspace_rootrU   token_provideraudit)r   r   )rF   rT   rJ   rU   rY   s    ``  r   _build_owner_triggerrZ   R   s.    C h'E$	 r   c           	     z(    t               }t        |d          g }t        |       }t        | |      }| dz  dz  }t	        | | fd||dd      }|j                  d	d
i|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 }|j                  }
t!        |
      }d}||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z  }dd|iz  }t        t        j                  |            d x}
x}x}}|j                  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}}|j&                  }|d    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}}|j(                  }|t*        k(  }|st        j"                  d|fd#|t*        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      d$t        j                         v st        j                  t*              rt        j                  t*              nd$d%z  }	d&d'|	iz  }t        t        j                  |            d x}}|j,                  }|t.        k(  }|st        j"                  d|fd(|t.        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      d)t        j                         v st        j                  t.              rt        j                  t.              nd)d%z  }	d&d'|	iz  }t        t        j                  |            d x}}|j0                  }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}}|j2                  }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!        |      }
d}|
|k(  }|st        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                  |      d/z  }d0d1|iz  }t        t        j                  |            d x}
x}}|d   d2   }d3}||k(  }
|
slt        j"                  d|
fd4||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}|d   d6   }d7}||k(  }
|
slt        j"                  d|
fd4||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}|d   d8   }d8d9i}||k(  }
|
slt        j"                  d|
fd4||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}|d:z  }|d;z  }|d<z  }|j4                  } |       }|sd=d>t        j                         v st        j                  |      rt        j                  |      nd>t        j                  |      t        j                  |      d%z  }	t        t        j                  |	            d x}}|j4                  } |       }|sd=d?t        j                         v st        j                  |      rt        j                  |      nd?t        j                  |      t        j                  |      d%z  }	t        t        j                  |	            d x}}|j4                  } |       }|sd=d@t        j                         v st        j                  |      rt        j                  |      nd@t        j                  |      t        j                  |      d%z  }	t        t        j                  |	            d x}}t7        j8                  |j;                  dAB            }|dC   }dD}||k(  }
|
slt        j"                  d|
fd4||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}|dE   }dF}||u }
|
slt        j"                  dG|
fdH||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}|dI   }dJ}||u }
|
slt        j"                  dG|
fdH||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}|dK   }d}||k(  }
|
slt        j"                  d|
fd4||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}|dL   }d}||k(  }
|
slt        j"                  d|
fd4||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}|dM   }|d   dN   }|j<                  } |       }||k(  }
|
st        j"                  d|
fdO||f      t        j                  |      t        j                  |      t        j                  |      t        j                  |      dPz  }dd|iz  }t        t        j                  |            d x}x}
x}x}}| t>        z  }|j4                  } |       }|sd=dQt        j                         v st        j                  |      rt        j                  |      ndQt        j                  |      t        j                  |      d%z  }	t        t        j                  |	            d x}}|j;                  dAB      jA                         D cg c]  }|s|	 }}t!        |      }
d}|
|k(  }|st        j"                  d|fd-|
|f      dt        j                         v st        j                  t               rt        j                  t               nddRt        j                         v st        j                  |      rt        j                  |      ndRt        j                  |
      t        j                  |      d/z  }d0d1|iz  }t        t        j                  |            d x}
x}}t7        j8                  |d         }|dS   }d}||k(  }
|
slt        j"                  d|
fd4||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}|d   }|t.        k(  }
|
st        j"                  d|
fdT|t.        f      t        j                  |      d)t        j                         v st        j                  t.              rt        j                  t.              nd)dUz  }dVdW|iz  }t        t        j                  |            d x}}
|dX   }d}||k(  }
|
slt        j"                  d|
fd4||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}|dC   }dY}||k(  }
|
slt        j"                  d|
fd4||f      t        j                  |      t        j                  |      d5z  }	d&d'|	iz  }t        t        j                  |            d x}x}
}y c c}w )ZNsnapshotrT   memoryeventsc                 
     gS r6   r   r\   s   r   r9   zPtest_pr107_pilot_first_gemini_missing_dispatches_owner_trigger.<locals>.<lambda>q   	    8* r   
test-owner	test-reporW   decision_dirsnapshot_providerowner_triggermerge_executorownerrepoOWNER_GEMINI_TRIGGER_TOKENrH   nowr8   rm   z5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstanceresultr	   )py0py1py2py4r   ==)zP%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.pr_actions
})
} == %(py8)slen)rq   rr   py3py5py8zassert %(py10)spy10r   k   )z1%(py2)s
{%(py2)s = %(py0)s.pr_number
} == %(py5)sactionrq   rs   ry   assert %(py7)spy7expected_diagnosistask_idz/%(py2)s
{%(py2)s = %(py0)s.task_id
} == %(py5)s)z-%(py2)s
{%(py2)s = %(py0)s.state
} == %(py4)sr   )rq   rs   rt   assert %(py6)spy6)z.%(py2)s
{%(py2)s = %(py0)s.action
} == %(py4)sr   POSTED)z5%(py2)s
{%(py2)s = %(py0)s.runner_result
} == %(py5)sz:%(py2)s
{%(py2)s = %(py0)s.chat_notifications
} == %(py5)s)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)srT   )rq   rr   rx   r   zassert %(py8)srz   rM   POSTz%(py1)s == %(py4)srr   rt   rN   z//repos/test-owner/test-repo/issues/107/commentsrO   z/gemini reviewz%task-2556.owner_trigger_decision.jsonz!task-2556.owner-trigger.requestedztask-2556.owner-trigger.postedzAassert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}decision_pathrequested_markerposted_markerr   r   schemaz anu_v2.owner_trigger_decision.v1allowedTis)z%(py1)s is %(py4)sgemini_evidence_freshFnudge_count_for_pr_headprcurrent_headr(   )zD%(py1)s == %(py8)s
{%(py8)s = %(py6)s
{%(py6)s = %(py4)s.lower
}()
})rr   rt   r   rz   
audit_pathaudit_lines	pr_number)z%(py1)s == %(py3)s)rr   rx   zassert %(py5)sry   chat_notificationszanu_v2.executor_scheduler.v1)!r   r3   rG   rZ   r   run_one_cyclero   r	   @py_builtinslocals
@pytest_ar_should_repr_global_name	_safereprAssertionError_format_explanation
pr_actionsrw   _call_reprcomparer   r   r,   r   r}   r   runner_resultr   existsr   r   r   lowerr   
splitlines)!rF   fixturerT   ri   rh   rf   	schedulerrp   @py_assert3@py_format5@py_assert2@py_assert4@py_assert7@py_assert6@py_format9@py_format11r}   @py_assert1@py_format6@py_format8@py_format7@py_assert5@py_assert0r   r   r   decisionr   lnr   	audit_rec@py_format4r\   s!                                   @r   >test_pr107_pilot_first_gemini_missing_dispatches_owner_triggerr   e   sd   oGwz23HJ*84N(jIMh&1L!!,#%I $$)+RSEN % F
 f233333333:333:333333f333f333333233323333333333  &3 !&Q&!Q&&&&!Q&&&&&&3&&&3&&&&&&v&&&v&&& &&&!&&&Q&&&&&&&q!F"s"s""""s""""""6"""6""""""s""""""">>EW%9:9EE>EEEEE>EEEEEEE6EEE6EEE>EEEEEEEEEEE<<=<=====<=======6===6===<====================;=;;;;;=;;;;;;;6;;;6;;;=;;;;;;;;;;;;;;;;;;+8+8++++8++++++6+++6++++++8+++++++ $$))$))))$))))))6)))6)))$)))))))))) z?a?a?a33zz?aa=",f,"f,,,,"f,,,",,,f,,,,,,,a= U$UU $UUUUU $UUUU UUU$UUUUUUUUa= >V-=$>> $>>>>> $>>>> >>>$>>>>>>>> !#JJM#&II #CCM!!!!!!!!!=!!!=!!!!!!!!!!!!!""$"$$$$$$$$$$$$$$"$$$$$$$$$$!!!!!!!!!=!!!=!!!!!!!!!!!!! zz-1171CDHHC!CC!CCCCC!CCCCCCC!CCCCCCCCI&$&$&&&&$&&&&&&$&&&&&&&+,55,5555,555,5555555555-.3!3.!3333.!333.333!3333333D> S >S    >S   >   S       N#Nwz'::'FN'F'L'LN'L'NN#'NNNNN#'NNNN#NNN'FNNN'LNNN'NNNNNNNN 44J:: * 4 4g 4 F Q Q SZ"WY2ZKZ{ q q    q      3   3      {   {      q       

;q>*I[!(S(!S((((!S(((!(((S(((((((XA"AAAAA"AAAAAAAAAA"AAAA"AAAAAAAA)*/a/*a////*a///*///a///////X@"@@"@@@@@"@@@@@@@"@@@@@@@@ [s   CAP8CAP8c                    ddl m}  t               }t        |d         } |        }|j	                  ||d         }|j
                  }|d   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}}|j                  }|d   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}}|j                  }|d   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}}|j                   }d}||u }|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}}y)uJ   PR #107 fixture 의 expected diagnosis 가 IdlePRDiagnoser 와 1:1 일치.r   )IdlePRDiagnoserr\   rm   )rm   r   r,   ru   )z-%(py2)s
{%(py2)s = %(py0)s.state
} == %(py5)sdiagr~   r   r   Nr   r   elapsed_since_created_seconds)zE%(py2)s
{%(py2)s = %(py0)s.elapsed_since_created_seconds
} == %(py5)sTr   )z>%(py2)s
{%(py2)s = %(py0)s.requires_owner_trigger
} is %(py5)s)anu_v2.idle_pr_diagnoserr   r   r3   diagnoser,   r   r   r   r   r   r   r   r   r   r   requires_owner_trigger)
r   r   r\   	diagnoserr   r   r   r   r   r   s
             r   =test_pr107_pilot_diagnosis_only_when_owner_trigger_dispatchedr      s%   8oGwz23H!IhGEN;D::?!56w??:?????:???????4???4???:???????????<<C7#78CC<CCCCC<CCCCCCC4CCC4CCC<CCCCCCCCCCC--o9M1NOn1oo-1ooooo-1ooooooo4ooo4ooo-ooo1oooooooo&&.$.&$....&$......4...4...&...$.......r   c           	        t               }t        |d         t        |       }t        | g       }t	        | | dz  fd||dd      }|j                  dd	i|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        z  }|j!                  d      j#                         D ]  }|st%        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}} y)u3   회장 §8 / 금지 15 — scheduler chat 노출 0.r\   r]   r_   c                 
     gS r6   r   ra   s   r   r9   zAtest_pr107_pilot_chat_notifications_always_zero.<locals>.<lambda>   rb   r   rc   rd   re   rl   ghp_test_xxxxxxxxxxxxxxxxxxxxrm   rn   r   ru   r   rp   r~   r   r   Nr   r   r   r   r   r   r   )r   r3   rG   rZ   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )rF   r   ri   rh   r   rp   r   r   r   r   r   r   linerecr   r   r   r   r\   s                     @r   /test_pr107_pilot_chat_notifications_always_zeror      s   oGwz23H*84N(bAM!(,#%I $$)+JKEN % F $$))$))))$))))))6)))6)))$))))))))))44J$$g$6AAC .jj'(-A-(A----(A---(---A-------	.r   )returndict)r1   r   r   r   )rF   r   r   r   )rF   r   rT   listrJ   strr   r   )+__doc__
__future__r   builtinsr   _pytest.assertion.rewrite	assertionrewriter   r   syspathlibr   __file__resolveparentsWORKSPACE_ROOTr   rN   insertanu_v2.executor_schedulerr   r   r   r	   r   r
   r   r   anu_v2.merge_queue_executorr   anu_v2.owner_trigger_auditr   anu_v2.owner_trigger_onlyr   r   r   r3   rG   rZ   r   r   r   r   r   r   <module>r      s   ( #    
  h'')11!4~chh&HHOOAs>*+  
 ; 8 6 H~%%'//2Z?Bcc@" 9	  	
 &DAN
/.r   