
    jP              
      *   U 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m	Z	 ddl
m
Z
mZ ddlmZmZmZmZmZmZmZmZ ddlmZmZmZmZmZ dZd	Zd
Zdddddddddd	Zde d<    G d de!      Z"e G d d             Z#e G d d             Z$d.dZ% ejL                  d      d/d        Z'd0d!Z(	 	 	 	 	 	 	 	 d1d"Z)d2d#Z*d3d$Z+	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d4d%Z,dd&	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d5d'Z-d6d(Z.dd)dd*	 	 	 	 	 	 	 	 	 	 	 d7d+Z/	 	 	 	 	 	 d8d,Z0d9d-Z1y):a   ANU v3.1 - ANU-Codex Micro Refinement Convergence Loop (Phase 1 Core).

Reference: ANU v3 master spec section 5.4-5.8.
Task: task-2662 (CHAIR-AUTH-V3-1-CODEX-MICRO-LOOP-20260525-JJONGS-START-001).

Scope (allowed, per task-2662 md):
    - document / contract / fixture / test layer refinement only
    - GO_READY / HOLD_FOR_CHAIR packet generation
    - safe round repetition with NO hard cap (section 5.4)
    - safety_gates 8-flag enforcement (immediate HOLD on any trigger)
    - allowed_write_paths enforcement on changed_files

Scope (forbidden, per task-2662 md 14-item ban list):
    1.  dev bot automatic dispatch
    2.  branch push without chair approval
    3.  automatic GitHub write
    4.  merge
    5.  auto-merge
    6.  production mutation
    7.  real write mode
    8.  OWNER PAT manipulation
    9.  credential change
    10. Axis 1/2/3 runtime change
    11. live settings.json change
    12. dispatch.py change
    13. HARNESS_ENFORCED full declaration
    14. ANU-Work production deployment declaration

This module is a pure-logic refinement loop driver.  It does NOT perform any
of the forbidden operations.  It only:
    (a) accepts a `micro_refinement_target` payload + a sequence of round
        outcomes (each carrying a Codex verdict, proposed changes, and a
        safety probe);
    (b) enforces the 8 safety_gates and the allowed_write_paths boundary;
    (c) collapses the round history into a `micro_refinement_result`;
    (d) emits a GO_READY or HOLD_FOR_CHAIR packet shaped per sections 5.7/5.8.
    )annotationsN)	dataclassfield)datetimetimezone)AnyCallableDictIterableListMappingOptionalSequence)
CODEX_FAIL
CODEX_PASSCODEX_PASS_WITH_RECOMMENDATIONSCODEX_UNKNOWNevaluateGO_READYHOLD_FOR_CHAIR)
critical_7security_high_or_criticalpermission_expansiongithub_write_requireddev_bot_reactivation_requiredreal_write_requiredforbidden_write_targetscope_expansion
CRITICAL_7SECURITY_HIGHPERMISSION_EXPANSIONGITHUB_WRITE_REQUIREDDEV_BOT_REACTIVATION_REQUIREDREAL_WRITE_REQUIREDFORBIDDEN_WRITE_TARGETSCOPE_EXPANSIONALLOWED_WRITE_PATH_VIOLATION)	r   r   r   r   r   r   r   r   allowed_write_path_violationzDict[str, str]GATE_TO_HOLD_REASONc                      e Zd ZdZy)MicroRefinementTargetErrorz;Raised when a micro_refinement_target payload is malformed.N)__name__
__module____qualname____doc__     V/home/jay/workspace/.worktrees/task-2662-dev2/utils/anu_codex_micro_refinement_loop.pyr+   r+   T   s    Er1   r+   c                  p    e Zd ZU dZded<    ee      Zded<    ee      Z	ded<    ee      Z
ded	<   y
)RoundOutcomeap  One ANU-Codex refinement round.

    `codex_payload` carries the Codex verdict for this round.
    `proposed_changes` is the list of file paths the round wants to write to
    (allowed_write_paths boundary is enforced against this list).
    `safety_probe` is the 8-gate snapshot for this round.
    `actions` is a human-readable list of refinement actions taken.
    Mapping[str, Any]codex_payload)default_factorySequence[str]proposed_changeszMapping[str, bool]safety_probeactionsN)r,   r-   r.   r/   __annotations__r   tupler9   dictr:   r;   r0   r1   r2   r4   r4   X   s>     %$&+E&BmB',T'BL$B"59G]9r1   r4   c                     e Zd ZU dZded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   ded<   dZded<   dZded<   dZded<   dZded<   d!d Z	y)"MicroRefinementResultz4Internal representation; serialize via `.as_dict()`.strtask_idintroundsfinal_verdictcodex_final_verdictboolr   r   r   r   r   forbidden_write_target_touchedscope_expansion_detectedr   	List[str]changed_fileszList[Dict[str, Any]]remaining_findingsround_historyevidence_pathstriggered_gatesoffending_pathsdecision_itemsNOptional[str]chair_command	ready_forgo_ready_packet_pathhold_packet_pathc                &   i ddd| j                   d| j                  d| j                  d| j                  d| j                  d| j
                  d	| j                  d
| j                  d| j                  d| j                  d| j                  d| j                  dt        | j                        dt        | j                        dt        | j                        dt        | j                         | j"                  | j$                  dS )Nschemaz!anu_v3.micro_refinement_result.v1rB   rD   rE   rF   r   r   r   r   r   rH   rI   r   rK   rL   rM   rN   )rU   rV   )rB   rD   rE   rF   r   r   r   r   r   rH   rI   r   listrK   rL   rM   rN   rU   rV   )selfs    r2   as_dictzMicroRefinementResult.as_dict   s\   
9
t||
 dkk
 T//	

 "4#;#;
 $//
 #D$=$=
 $T%?%?
 ,T-O-O
 "4#;#;
 -d.Q.Q
 '(E(E
 ()G)G
 T$"4"45
 !$t'>'>"?
  T$"4"45!
" d4#6#67#
$ %)$=$= $ 5 5'
 	
r1   )returnDict[str, Any])
r,   r-   r.   r/   r<   rS   rT   rU   rV   r[   r0   r1   r2   r@   r@   i   s    >LK#''$((""##,,''((#'M='#I}#*.-.&*m*
r1   r@   c                   | j                  d      dk7  rt        d      | j                  d      }t        |t              r|j	                  d      st        d      | j                  d      dk7  rt        d	      | j                  d
      dk7  rt        d      | j                  d      dvrt        d      | j                  d      xs i }t
        D cg c]	  }||vs| }}|rt        d|       |j                         D ]  \  }}|dk7  st        d|d|d       t        | j                  d      t              st        d      t        | j                  d      t              st        d      yc c}w )zOLightweight schema check against schemas/anu_v3_1_micro_refinement_target.json.rX   z!anu_v3.micro_refinement_target.v1zschema mismatchrB   ztask-z"task_id must look like 'task-XXXX'goal_condition'CODEX_PASS_OR_PASS_WITH_RECOMMENDATIONSz>goal_condition must be CODEX_PASS_OR_PASS_WITH_RECOMMENDATIONSround_limit_policy NO_HARD_CAP_FOR_MICRO_REFINEMENTzFround_limit_policy must be NO_HARD_CAP_FOR_MICRO_REFINEMENT (ANCHOR-3)
max_rounds)Nr   z>max_rounds must be null or 0 for micro refinement (hard cap 0)safety_gateszsafety_gates missing keys: holdzsafety_gates[z] must be 'hold' (got )allowed_write_pathsz"allowed_write_paths must be a listforbidden_write_targetsz&forbidden_write_targets must be a listN)getr+   
isinstancerA   
startswithSAFETY_GATE_KEYSitemsrY   )targetrB   gateskmissingkeyvals          r2   validate_targetrt      s    zz(BB():;;jj#Ggs#7+=+=g+F()MNNzz"#'PP()ijjzz&'+MM(T
 	
 zz,y0(L
 	
 JJ~&,"E*=Qaunq=G=(+Fwi)PQQKKM S&=,w&<SG1E 
 fjj!67>()MNNfjj!:;TB()QRR C >s   	E: E:   )maxsizec                   t        j                  dd|       } d| v r| j                  dd      } d| v rd}| j                  d|      } g }| D ]  }||k(  r|j                  d       |dk(  r|j                  d       1|d	k(  r|j                  d
       H|dv r%|j                  t        j                  |             q|j                  |        ddj                  |      z   dz   }t        j                  |      S )u  Convert a glob pattern to a compiled regex.

    Semantic rules (POSIX glob, ANCHOR-2):
      *   → [^/]*   (same-directory-only, does NOT cross path separators)
      **  → .*      (recursive, crosses path separators)
      ?   → [^/]    (single char, does NOT cross path separator)
      other chars → re.escape'd literally

    Separator normalisation: both pattern and path use POSIX ``/``.
    z\\+/z// z**z.**z[^/]*?z[^/]z\.+^${}[]|()^ $)resubreplaceappendescapejoincompile)patternDOUBLE_STAR_SENTINELpartsch	regex_strs        r2   _glob_to_regexr      s     ffVS'*G
'///$, '/ "ood$89GE 
%%LL3YLL!3YLL ?"LL2'LL
 bggen$s*I::i  r1   c                    t         j                  j                  |       j                  t         j                  d      }|D ]  }t        |      j                  |      s y y)Nrx   TF)ospathnormpathr   sepr   match)r   patterns	norm_pathr   s       r2   _path_matches_anyr      sQ      &..rvvs;I '"((3 r1   c                    g }g }| D ]>  }t        ||      r|j                  |       !t        ||      r.|j                  |       @ ||dS )zAPer ANCHOR-4: changed_files must stay inside allowed_write_paths.)out_of_boundsforbidden_hit)r   r   )rK   rg   rh   r   r   r   s         r2   enforce_allowed_write_pathsr      s_      "M!M 'T#:;  & ':;  &' +]KKr1   c                z    g }t         D ]/  }t        | j                  |d            s|j                  |       1 |S )NF)rl   rG   ri   r   )probe	triggeredrr   s      r2   _safety_probe_truthy_keysr     s?    I "		#u%&S!" r1   c                 f    t        j                  t        j                        j	                  d      S )Nz%Y-%m-%dT%H:%M:%SZ)r   nowr   utcstrftimer0   r1   r2   _isoformat_nowr   	  s!    <<%../CDDr1   c                    |t         t        fvrt        d|      |st        d      d| ||dddd||t        |      t        |      t	               dS )z0Section 5.7. ANCHOR-5: must carry chair_command.z9GO_READY requires PASS or PASS_WITH_RECOMMENDATIONS, got z*chair_command must be non-empty (ANCHOR-5)zanu_v3.go_ready_packet.v1FFINAL_GO_ONLY)rX   rB   rT   codex_verdictr   r   forbidden_actionrequired_chair_decisionrS   rD   rK   rN   generated_at)r   r   
ValueErrorrY   r   rB   r   rD   rK   rN   rS   rT   s          r2   _build_go_ready_packetr     sy     Z)HIIGGXY
 	
 EFF-& %!#2&m,~.&( r1   )hold_reasonc                $   |s|t        d      ||d   }t        j                  |d      }d|v xs" t        |j                  dd            xs |dk(  }	d| ||	t	        |      t	        |      dd d	|t	        |      t	        |      t               d
S )zPSection 5.8. ANCHOR-5: must name trigger gate via hold_reason + triggered_gates.NuC   HOLD packet requires ≥1 triggered_gate or an explicit hold_reasonr   r   r   Fzanu_v3.hold_for_chair_packet.v1   	ASK_CHAIR)rX   rB   r   r   rO   rQ   recommended_next_actionrD   rN   rP   r   )r   r)   ri   rG   rY   r   )
rB   rO   rD   rN   rP   rQ   r6   r   primarycritical_7_flags
             r2   _build_hold_packetr   0  s     {2Q
 	
 !!$)--g|D' 	'!!,67	',&  4"%0~.r2#.~.0&( r1   c                H    | t         j                  | d      t        |      dS )Nr   )gatereasonrP   )r)   ri   rY   )r   	offendings     r2   _decision_item_for_gater   X  s&    %))$=	? r1   DISPATCH)chair_command_builderrT   rN   c                :   t        |        |st        d      | d   }| d   }| d   }t        |xs g       }g }	g }
g }g }g }t        }i }d}d}t	        |d      D ]  \  }}t        |j                  xs i       }t        |j                  xs i       }t        |j                  xs g       }t        |||      }g }|d	   r%|j                  d
       |j                  |d	          |d   r%|j                  d       |j                  |d          t        |      D ]  }||vs|j                  |        t        |j                  dd            rd|vr|j                  d       t        ||||D ci c]  }|d c}      }|j                   }|}|	j                  ||j                   t        |j"                        t        |      d       |s|D ]  }||
vs|
j                  |        |rYd}|}|}t        |d	         t        |d         d}|D ]/  }|j                  |g       }|j                  t%        ||             1  n|j                   t&        t(        fv s n |s|t&        t(        fvrg }|s|t&        t(        fvrt*        nt,        }||n
t/        |	      } t0        D !ci c]  }!|!|!|v 	 }"}!|"d   xs t        |j                  dd            |"d<   t3        d+i d|d| d|d|d|"d   d|"d   d|"d   d|"d   d|"d   d|"d
   d|"d   d|"d   d|
dt        |j                  dg       xs g       d |	d!|d"|d#|d$|}#|t,        k(  rX|xs t4        }$ |$| |      }%t7        ||| |
||%|%      }&|%|#_        ||#_        d|#_        d|#_        |#jA                         }'|&|'d&<   |'S d}(t        |      })|)s|tB        t        fv rd'}(tE        ||)| |||xs |)rt%        |)d(   |      gng ||()      }&|#jA                         }'|&|'d*<   |'S c c}w c c}!w ),zDrive a micro refinement convergence loop end-to-end.

    Returns a `micro_refinement_result.v1` dict that embeds the GO_READY or
    HOLD_FOR_CHAIR packet under `go_ready_packet` / `hold_for_chair_packet`.
    u-   round_outcomes must contain ≥1 RoundOutcomerB   rg   rh   FN   )startr   r   r   r(   r   T)rB   review_roundr6   safety_signal)roundr   r;   safety_gates_triggered)r   r(   rD   rE   rF   r   r   r   r   rH   rI   r   r   rK   rL   recommendationsrM   rN   rO   rP   rQ   r   go_ready_packetREPEATED_DISAGREEMENTr   )rB   rO   rD   rN   rP   rQ   r6   r   hold_for_chair_packetr0   )#rt   r   rY   r   	enumerater>   r6   r:   r9   r   r   extendr   rG   ri   evaluate_codex_decisionrF   r;   r   r   r   VERDICT_HOLD_FOR_CHAIRVERDICT_GO_READYlenrl   r@   _default_chair_command_builderr   rS   rT   rU   rV   r[   r   r   )*rn   round_outcomesr   rT   rN   rB   rg   rh   evidence_listrM   aggregate_changedrO   rP   rQ   last_codex_verdictlast_codex_payloadhold_triggeredhold_round_indexidxoutcomer6   r:   proposed
path_checkround_gatesr   rp   decisionpgate_to_paths
gate_pathsrE   rounds_executedrr   
gate_flagsresultbuilderrS   packetresult_dictr   packet_gatess*                                             r2   run_micro_refinementr   `  s    FHIIYG)/0E)F-34M-N#N$8b9M*,M#%!#O!#O+-N+,.N&*!.: ?WW228b9G006B7006B70)+B

 "$o&78"":o#>?o&=>"":o#>?-l; 	)D;&""4(	) !!,67LP[<[|,*',78q1d78	
 &99*!)!=!=0*.{*;		
  0--%,,Q/0 !N")O +/z//J*K04Z5P0QM $ Q*..tR8
%%&=dJ&OPQ ''J8W+XX?B 0'9   /
Dc7dd 	  -8c->P  <LLC#..LJL),7  4|U3<J| #  $ /	
 l+ ((>? ))@A '11P&Q ''<= (22J'K ",,=!> #--H"I (   2 6 67H" M SQST $  %!" (#$ (%& &'F. (('I+I(:;',"+('
  -$&*#"&nn&)/%&( % &*O, 2z=6Q Q1K#("(+) eO[(a/JKac,#

 nn&/5+,q 9n Ms   1
P)Pc                    | d   }d| d| dS )uA   Section 5.7 + ANCHOR-5: chair_command is what 회장 copy-pastes.rB   zAPPROVE FINAL_GO z	 verdict=zC policy=v3_1_codex_micro_refinement_loop_core_pr_only_no_auto_merger0   )rn   r   rB   s      r2   r   r     s,    
 YG
G9Im_ =M 	Mr1   c                4    t        j                  | ddd      S )zFJSON-serialize a result dict deterministically for evidence writeback.FT   )ensure_ascii	sort_keysindent)jsondumps)r   s    r2   serialize_resultr   &  s     ::kaPPr1   )rn   r5   r\   None)r   rA   r\   zre.Pattern[str])r   rA   r   zIterable[str]r\   rG   )rK   r8   rg   r8   rh   r8   r\   zDict[str, List[str]])r   r5   r\   rJ   )r\   rA   )rB   rA   r   rA   rD   rC   rK   r8   rN   r8   rS   rA   rT   rA   r\   r]   )rB   rA   rO   r8   rD   rC   rN   r8   rP   r8   rQ   zSequence[Mapping[str, Any]]r6   r5   r   rR   r\   r]   )r   rA   r   r8   r\   r]   )rn   r5   r   zSequence[RoundOutcome]r   z1Optional[Callable[[Mapping[str, Any], str], str]]rT   rA   rN   zOptional[Sequence[str]]r\   r]   )rn   r5   r   rA   r\   rA   )r   r5   r\   rA   )2r/   
__future__r   	functoolsr   r   r   dataclassesr   r   r   r   typingr   r	   r
   r   r   r   r   r   utils.codex_cc_decision_loopr   r   r   r   r   r   r   r   rl   r)   r<   r   r+   r4   r@   rt   	lru_cacher   r   r   r   r   r   r   r   r   r   r   r0   r1   r2   <module>r      sS  $L #   	 	 ( ' S S S   ) 	  !024%D06($B
' ^ 
F F : : :  0
 0
 0
fSB S!$! "$!NL L&L +L 	L$E     	 
 !  "       X "&%% #% 	%
 "% #% 0% %% % %P PT.2ww +w M	w
 w ,w wt		.1		Qr1   