
    vi8                    ,   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 ddl	m
Z
 ddlmZ ddlZ ee      j                         j                   d   Zej$                  j'                  d eedz               ej$                  j'                  d ee             ej$                  j'                  d eed	z  dz               ddlZdd
lmZmZmZmZ edz  dz  dz  ZddZddZddZddZ ddZ!ddZ"ddZ#ddZ$ddZ%ddZ&ddZ'e(dk(  r e'        yy)u  Capture the 6 verification scenarios (A1..A6) as on-disk evidence.

This script drives the controller in-process against ``FakeGitHub`` fixtures
that mimic the real REST/GraphQL responses (matching the schemas at
``GET /repos/{r}/pulls/{n}`` and ``GET /repos/{r}/commits/{sha}/check-runs``).

Output layout (relative to workspace):

    memory/reports/task-2441-auto-merge/
      A1-all-checks-success/
        pr-create.json            ← PR snapshot before merge
        pr-after-merge.json       ← PR snapshot after merge (merged=true)
        check-runs.json           ← all 8 required checks success
        main-head-before.txt      ← main HEAD before cycle
        main-head-after.txt       ← main HEAD after merge
        controller.txt            ← controller decision log
      ...

Why this exists: the GitHub-side evidence requested in task-2444 §[5] can
only be produced once a real PR has actually been opened and merged via the
workflow. To exercise the controller pre-deployment we replay the same
responses through the in-process FakeGitHub fixtures so reviewers can audit
the controller's behaviour against the real API schema.
    )annotationsN)Path)Any)mock   scriptstests)
FakeGitHubREPOall_success_check_runsmake_prmemoryreportsztask-2441-auto-mergec                     t        j                         } t        j                  |       }|j	                  t        j
                  d             t        j                  j                  |       t        j                  | fS )Nz'%(asctime)s [%(levelname)s] %(message)s)	ioStringIOloggingStreamHandlersetFormatter	FormatteramcLOGGER
addHandler)bufhandlers     U/home/jay/workspace/.worktrees/task-2444-dev2/tests/scripts/capture_a1_a6_evidence.py_attach_loggerr   5   sW    
++-C##C(G**+TUVJJ'"::s?    c                    t        | j                        D ]=  }t        |t        j                        s|j
                  |u s-| j                  |       ? |j                         S N)listhandlers
isinstancer   r   streamremoveHandlergetvalue)loggerr   hs      r   _detach_loggerr)   =   sP    &//" $a../AHHO  #$ <<>r   c                    | j                   j                  dd       t        |t              r| j	                  |       y | j	                  t        j                  |dd      dz          y )NTparentsexist_okr   )indent	sort_keys
)parentmkdirr#   str
write_textjsondumps)pathpayloads     r   _writer9   D   sM    KKdT2'3 

71ELMr   c                :   	
 g g 
g 	dd fd}d fd} fd}d fd}d
fd}	 fd}t         j                  j                  t        d|      5  t         j                  j                  t        d|      5  t         j                  j                  t        d	 fd
      5  t        j                  t
         j                   j                  ||||d       }d d d        d d d        d d d        
	fS # 1 sw Y   xY w# 1 sw Y   #xY w# 1 sw Y   'xY w)Nc                x    j                   d   }| |d}|r|j                  |       j                  |       |S )N)stage	main_head)main_head_historyupdateappend)r=   extrashaentryauditfakes       r   head_recorderz!_run_cycle.<locals>.head_recorderQ   s=    $$R(*/c BLLU
r   c                    d| dj                  dd      }j                  |       j                  D ]!  }|d   | k(  sd|d<   d| d	z   d
|d<   ||d<   # t        j                  g ddd      S )Nzmerge-08x(   0numberTmerged2026-05-04T00:00:0
   Z	merged_atmerge_commit_shar    )args
returncodestdoutstderr)ljustadvance_mainprs
subprocessCompletedProcess)pr_num_reponew_shaprF   s       r   safe_merge_fnz!_run_cycle.<locals>.safe_merge_fnY   s    6#,'--b#6'" 	0A{f$"(#5frk]!!D+(/$%		0
 **qTVWWr   c                f    j                   D cg c]  }|d   r	|d   d   dk(  s| c}S c c}w )NrM   baserefmain)rZ   )r^   r`   rF   s     r   list_prsz_run_cycle.<locals>.list_prsc   s1    88Va1X;1V9U;Kv;UVVVs   
...c                P    | j                   j                  dt                     v S )N_cancelled_set)__dict__getset)tidrF   s    r   cancelled_markerz$_run_cycle.<locals>.cancelled_markerf   s"    dmm''(8#%@@@r   c                ,    j                  | |f       y r    )rA   )r]   labelr^   labelss      r   label_blockedz!_run_cycle.<locals>.label_blockedi   s    vuo&r   c                |    j                  | d          j                  D ]  }|d   | d   k(  sd|d<   d|d<    y )NrL   FrM   closedstate)rA   rZ   )prr^   r`   rs   rF   s      r   handle_cancelledz$_run_cycle.<locals>.handle_cancelledl   sH    bl# 	&A{bl*#(%'
	&r   rq   handle_cancelled_pr
post_checkc                :    dd| dz   ddj                   d   dS )NTrN   rO   rP   r<   )rM   rQ   branch_deletedrR   )r?   )pnbrreporF   s      r   <lambda>z_run_cycle.<locals>.<lambda>u   s/    ,>rBwiq*I#9O9OPR9SD r   c                      y)Ng    mA r   r   r   r~   z_run_cycle.<locals>.<lambda>   s    r   )r}   apigraphqlrf   ra   rG   cancelled_marker_existsnowr    )r=   r3   rB   zdict[str, Any] | None)r]   intr^   r3   )rl   r3   returnbool)r]   r   ro   r3   r^   r3   r   None)r   patchobjectr   process_open_prsr   r   r   )rF   rG   ra   rf   rm   rq   rv   resultrE   rs   rp   s   `       @@@r   
_run_cycler   L   s    "$E$&FFXWA'& 
		3	? 
			3 57G	H
			3 / 

 %%LL''$4$	

 
 
  5&&((!
 
 
 
 
 
s<   &D;)D$7C9D#D9D>DD	
DDc                 8   t         dz  } t        ddd      }t        |g|d   d   t               iddgid	
      }t	        j
                  t	        j                  |            }t        | dz  |       t        | dz  d|j                  |d   d      i       t        | dz  |j                  d          t               \  }}t        |      \  }}}}	t        ||      }
t	        j
                  t	        j                  |            }t        | dz  |       t        | dz  |j                  d          t        | dz  dj                  d |D              dz          t        | dz  d|
 d|j                  D cg c]  }|j                   c} d|j                  D cg c]  }|j                    c} d|j                  d   j"                   d|j                  d   j$                   d       |d   du sJ |j                  d   |j                  d   k7  sJ y c c}w c c}w )NzA1-all-checks-successe   ztask/task-9991-dev2(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabranchrC   headrC   T(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbrZ   
check_runsreview_threadsr>   zpr-create.jsoncheck-runs.jsonr   main-head-before.txtr<   zpr-after-merge.jsonmain-head-after.txtaudit-log.jsonlr0   c              3  J   K   | ]  }t        j                  |d         ywT)r/   Nr5   r6   .0es     r   	<genexpr>zcase_A1.<locals>.<genexpr>        BqTZZT22B   !#controller.txtz== A1 controller log ==

merged=z
merged_at=z
main_head_before=r   z
main_head_after=z"
branch_deleted=true (post_check)
rM   )REPORTSr   r
   r   r5   loadsr6   r9   r   r?   r   r   r)   joinrM   	pr_numberrQ   main_head_beforemain_head_after)outru   rF   	pr_creater'   r   r   rE   rp   rs   log_textpr_afterms                r   case_A1r      s   
+
+C	2	ABDvJu%'='?@dV}	D 

4::b>*I
3!!9-
3""\4??2f:eCT3U$VW
3'')?)?)CD "KFC$.t$4!FE66fc*Hzz$**R.)H
3&&1
3&&(>(>r(BC
3""99BEBBTIK
3!!&xj 1+1==9aakk9: ;.4mm<<= >%}}Q/@@A B$mmA.>>? @0	12 H%%%!!!$(>(>r(BBBB :<s   1HHc                 0   t         dz  } t        dddd      }t        d      }t        |g|d   d	   |idd
dii      }t	        | dz  |       t	        | dz  d|i       t	        | dz  |j
                  d          t               \  }}t        |      \  }}}}	t        ||      }
t	        | dz  |j
                  d          t	        | dz  |       t	        | dz  d|
 d|j                  D cg c]  }|j                   c} d|j                  D cg c]%  }|j                  |j                  |j                  f' c} d|j
                  d   |j
                  d   k(   d	       |d   du sJ |j
                  d   |j
                  d   k(  sJ y c c}w c c}w )NzA2-ci-failuref   ztask/task-9992-dev2(ccccccccccccccccccccccccccccccccccccccccblockedr   rC   mergeable_state)cancel-kill-switchfailurer   rC   r   rZ   r   pr_full_overridespr-status.jsonr   r   r   r<   r   labels.jsonr   z== A2 controller log ==
r   	
skipped=
main_head unchanged: r   r0   rM   F)r   r   r   r
   r9   r?   r   r   r)   rM   r   skippedreasonro   )r   ru   runsrF   r'   r   r   rE   rp   rs   r   r   ss                r   case_A2r      s   
O
#C	2R[	\B!"CDDDvJu%t,!2I >?D
 3!!2&
3""\4$89
3'')?)?)CD "KFC$.t$4!FE66fc*H
3&&(>(>r(BC
3'
3!!&xj 1+1==9aakk9: ;AGPAQXXqww7PQ R##'#9#9!#<@V@VWY@Z#Z"[[]_` h<5   !!!$(>(>r(BBBB :Ps   *F*Fc                    t         dz  } t        dddd      }ddd	d
dd	ddd	g}t        |g|d   d   |i      }t        | dz  |       t        | dz  |dd       t        | dz  |j                  d          t               \  }}t        |      \  }}}}	t        ||      }
t        | dz  |j                  d          t        | dz  |       t        | dz  d|
 d|j                  D cg c]%  }|j                  |j                  |j                  f' c} d| d       |d   du sJ |g k(  sJ |j                  d   |j                  d   k(  sJ y c c}w )Nz
A3-pendingg   ztask/task-9993-dev2(ddddddddddddddddddddddddddddddddddddddddunknownr   zci/guardsuccess)name
conclusionguardr   r   rC   )rZ   r   r   r   z"5 of 8 required checks IN_PROGRESS)r   _noter   r<   r   r   r   z== A3 controller log ==
r   z
labels (should be empty): r0   rM   Fr   )r   r   r
   r9   r?   r   r   r)   r   r   r   ro   )r   ru   r   rF   r'   r   r   rE   rp   rs   r   r   s               r   case_A3r      s   
L
 C	2R[	\B95	2%Y?D 2$BvJu,=t+DED
3!!2&
3""4Bf$gh
3'')?)?)CD "KFC$.t$4!FE66fc*H
3&&(>(>r(BC
3'
3!!&xj 1AGPAQXXqww7PQ R((.xr34
 h<5   R<<!!!$(>(>r(BBBB Qs   )*Ec                    t         dz  } t        dddd      }t        d      }t        |g|d   d	   |idd
dii      }t	        | dz  |       t	        | dz  d|i       t	        | dz  |j
                  d          t               \  }}t        |      \  }}}}	t        ||      }
t	        | dz  |j
                  d          t	        | dz  |       t	        | dz  d|
 d|j                  D cg c]%  }|j                  |j                  |j                  f' c} dd|D cg c]  \  }}|	 c}}v  d       d|D cg c]  \  }}|	 c}}v sJ |j
                  d   |j
                  d   k(  sJ y c c}w c c}}w c c}}w )NzA4-gemini-blockedh   ztask/task-9994-dev2(eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeer   r   )zgemini-review-gater   r   rC   r   r   r   r   r   r   r<   r   r   r   z== A4 controller log ==
r   z
gemini-blocked label applied: zgemini-blockedr0   r   )r   r   r   r
   r9   r?   r   r   r)   r   r   r   ro   )r   ru   r   rF   r'   r   r   rE   rp   rs   r   r   _lbls                 r   case_A4r      s   
'
'C	2R[	\B!"CDDDvJu%t,!2I >?D
 3!!2&
3""\4$89
3'')?)?)CD "KFC$.t$4!FE66fc*H
3&&(>(>r(BC
3'
3!!&xj 1AGPAQXXqww7PQ R,-=TZA[&!S#A[-[+]]_ab
 &939999!!!$(>(>r(BBBB	 QA[9s   **E1E6<E<c                    t         dz  } t        ddd      }t        |g|d   d   t               idg i      }d	h|_        t        | d
z  |       t        | dz  |j                  d          t               \  }}t        |      \  }}}}t        ||      }	i |ddi}
t        | dz  |
       t        | dz  dt         d|d   d    d       t        | dz  |j                  d          t        | dz  d|	 d| d|j                  D cg c]  }|j                   c} d|j                  d   |j                  d   k(   d	       |dgk(  sJ |d   du sJ |j                  d   |j                  d   k(  sJ y c c}w )NzA5-cancelledi   ztask/task-9995-dev1(ffffffffffffffffffffffffffffffffffffffffr   r   rC   )rZ   r   r   z	task-9995zpr-status-before.jsonr   r<   rt   rs   zpr-state-after-close.jsonzbranch-404.txtzGET /repos/z
/branches/rd   u2    → 404 (deleted by gh pr close --delete-branch)
r   r   z== A5 controller log ==
z
closed=r   r   r   r0   rM   F)r   r   r
   r   rh   r9   r?   r   r   r)   r   rM   r   )r   ru   rF   r'   r   r   rE   rp   rs   r   r   r   s               r   case_A5r     s   
N
"C	2	ABDvJu%'='?@RyD
 '-D
3(("-
3'')?)?)CD "KFC$.t$4!FE66fc*H("(gx(H
3,,h7
3!!jFE):(;;noq
3&&(>(>r(BC
3!!&xj 1HIFMM&Jqq{{&J%K L##'#9#9!#<@V@VWY@Z#Z"[[]_`
 cU??h<5   !!!$(>(>r(BBBB 'Ks   E6c                    t         dz  } t        ddd      t        ddd      t        d	d
d      g}t        ||D ci c]  }|d   d   t                c}|D ci c]  }|d   g 
 c}d      }t	        | dz  |       t	        | dz  |j
                  d          t               \  }}t        |      \  }}}}	t        ||      }
t	        | dz  |j                  D cg c]1  }|j                  |j                  |j                  |j                  d3 c}       t	        | dz  dj                  d |D              dz          t	        | dz  dj                  d t        |j
                        D              dz          t	        | dz  d|
 d|j                  D cg c]  }|j                   c} d|j                  D cg c]  }|j                   c} dt!        t#        |j
                               d	       |j                  D cg c]  }|j                   c}g d k(  sJ t!        t#        |j
                              d!k(  sJ y c c}w c c}w c c}w c c}w c c}w c c}w )"NzA6-three-prs   ztask/task-9961-dev2(1111111111111111111111111111111111111111r      ztask/task-9962-dev2(2222222222222222222222222222222222222222   ztask/task-9963-dev2(3333333333333333333333333333333333333333r   rC   rL   (0000000000000000000000000000000000000000r   zpr-list-before.jsonzmain-head-progression-start.txtr<   zmerge-sequence.json)ru   rQ   r   r   r   r0   c              3  J   K   | ]  }t        j                  |d         ywr   r   r   s     r   r   zcase_A6.<locals>.<genexpr>W  r   r   zmain-head-progression.txtc              3  2   K   | ]  \  }}d | d|   yw)zstep=z sha=Nr   )r   ir   s      r   r   zcase_A6.<locals>.<genexpr>Y  s!     WTQuQCuQC(Ws   r   z== A6 controller log ==
z
merged sequence: z
merged_at: z
main_head distinct shas: )r   r   r      )r   r   r
   r   r9   r?   r   r   r)   rM   r   rQ   r   r   r   	enumeratelenrk   )r   rZ   r`   rF   r'   r   r   rE   rp   rs   r   r   s               r   case_A6r   >  s_   
N
"C1x@1x@1x@C
 HKL1AfIe$&<&>>L145A(R5	D 3&&,
322D4J4J24NO "KFC$.t$4!FE66fc*H
3&& =CMMK78 ;;Q[[!"!3!3 ! 1 13 KL 3""99BEBBTIK
3,,99WYt?U?U5VWWZ^^`
3!!&xj 15;]]CCD E/5}}=!!++=> ?''*3t/E/E+F'G&HLM "(/AAKK/?BBBs4))*+q0005 M5K  D= 0s#   I
I6I
I<II c                     t         j                  dd       t        t        t        t
        t        t        fD ]"  } t        d| j                   d        |         $ t        d       y )NTr+   zrunning u   …u   ✓ all 6 scenarios captured)
r   r2   r   r   r   r   r   r   print__name__)fns    r   re   re   d  sS    MM$M.'7GD S)*
 

()r   __main__)r   z"tuple[logging.Logger, io.StringIO])r'   zlogging.Loggerr   zio.StringIOr   r3   )r7   r   r8   r   r   r   )rF   r
   r   zBtuple[Any, list[dict[str, Any]], list[tuple[int, str]], list[int]])r   r   ))__doc__
__future__r   r   r5   r   syspathlibr   typingr   unittestr   r[   __file__resolver,   	WORKSPACEr7   insertr3   auto_merge_controllerr   test_auto_merge_controllerr
   r   r   r   r   r   r)   r9   r   r   r   r   r   r   r   re   r   r   r   r   <module>r      s  2 # 	   
    N""$,,Q/	 3y9,- . 3y> " 3y7*Y67 8 #  h

*-C
CN7)~ CPCDCFCBCJ#1L* zF r   