
    3j                       d Z ddlm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
 ddlmZmZmZmZ ddlmZmZmZmZ ddlmZmZ dd	lmZ dd
lmZmZmZmZmZm 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+ dZ,dZ-h dZ.dZ/ G d de0      Z1e G d d             Z2e G d d             Z3 G d d      Z4d dZ5d!dZ6dZ7de, dZ8	 	 	 	 	 	 d"dZ9y)#u  anu_v3.generic_batch_coordinator — parallel_batch_coordinator v0 generalized.

task-2553+30 TRACK B (NO-CRON variant, 9-R.1/9-R.2/9-R.3).

Goal (회장 verbatim, §2): generalize parallel_batch_coordinator v0 so that for
ANY future parallel batch, ANU auto-integrates per-track state · callback ·
fallback · dependency · loop progress · final authority packet · closeout
eligibility into ONE batch_state — code/file automation, not documentation.

Generalization approach (§4):
  * REUSE / EXTEND the +29 read-only registry layer as a generic tier.
  * NEW standalone generic module (this file) + NEW generic schemas.
  * additive only — zero edit / zero API break of:
        anu_v3.parallel_batch_coordinator  (+17/+19 entry, never imported here)
        anu_v3.batch_join_policy           (frozen anchor — imported read-only)
        anu_v3.parallel_runtime_registry   (+29 — imported read-only)
        anu_v3.batch_runtime_join_policy   (+29 — imported read-only)
  * generic batch_state authority == NEW separate path
        memory/events/task-2553.generic-batch-state.json
    distinct from the chair durable v1 memory/events/...parallel-batch-state.json
    (read-only, never mutated/coupled).

9-R.1 (read-only decision logic): every coordinator component below —
next-action resolver · final authority packet selector · consolidated summary
generator · result-ready classifier · overlap/forbidden checker — only
derive / propose / read. They NEVER execute, confirm, write, report, merge,
or touch cron. The single file emission helper (`emit_generic_batch_state`)
is an explicit, hard-guarded I/O function OUTSIDE the decision boundary; the
chair / ANU performs the actual closeout confirmation (closeout.confirmed is
hard-pinned False here).

9-R.2 (fixture verbs): the +26~+29 batch-closeout artifacts are read / parsed
/ referenced only. This module never modifies / registers / overwrites them;
the generic fixture is a NEW normalized copy.

9-R.3 (single dispatch): pure stdlib, no subprocess dispatch / delegation /
cron. Loop iteration is an in-process state derivation, never a new dispatch.

§7 NO-CRON: zero cron register/remove. Self-completion / recovery is
recognised purely by result.json + .done existence (dogfooding, §12).
    )annotationsN)	dataclassfield)Path)DictListOptionalSequence)PacketCandidateTrackArtifactscross_track_contaminationfinal_authority_packet_selector)BatchDependencyMatrix	TrackSpec)CallbackTrackRecord)ACCEPTEDHOLD_FOR_CHAIRMERGEDRUNNINGTrackLoopStateis_terminal)Callback4TupleIndexTuple4)ParallelRuntimeRegistryTaskRuntimeRecord)RuntimeObservationclassify_runtimeis_recovery_eligiblerecovery_notezanu_v3.generic_batch_state.v0zanu_v3.generic_batch_plan.v0>   DONEPASSACCEPTr   z#task-2553.parallel-batch-state.jsonc                      e Zd ZdZy)FrozenWriteRefusedu   Emission was attempted against the chair durable v1 path or any
    git-tracked path. Generic batch_state authority MUST be the separate
    NEW untracked path (§4 / §9 / 9-R.2).N)__name__
__module____qualname____doc__     B/home/jay/workspace/scripts/../anu_v3/generic_batch_coordinator.pyr$   r$   a   s    /r*   r$   c                     e Zd ZU 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
<    ee	      Z
ded<    ee	      Zded<    ee	      Zded<    ee	      Zded<    ee	      Zded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   d Zd!ed"<    ee	      Zd#ed$<   y)%GenericTrackPlanstrtrack_idtask_id executordispatch_cron_idNOptional[str]normal_collector_cron_idfallback_callback_cron_id)default_factory	List[str]expected_filesforbidden_write_targets
depends_onown_artifactscited_artifactsokdispatch_statusFboolnormal_collector_executedby_design_no_normal_collectorresult_presentdone_presentPENDINGfallback_statefallback_fire_kstUNKNOWNterminal_outcomehold_for_chair   intretry_ceilingzList[Dict[str, str]]authority_packets)r%   r&   r'   __annotations__r2   r3   r5   r6   r   listr9   r:   r;   r<   r=   r?   rA   rB   rC   rD   rF   rG   rI   rJ   rM   rN   r)   r*   r+   r-   r-   k   s    MLHcc.2m2%'s' %d ;NI;).t)DYD!$7J	7$T:M9:!&t!<OY<OS&+t+*/!4/ ND L$#NC#'+}+%c% ND M3.3D.I+Ir*   r-   c                  "    e Zd ZU ded<   ded<   y)GenericBatchPlanr.   batch_labelzList[GenericTrackPlan]tracksN)r%   r&   r'   rO   r)   r*   r+   rR   rR      s    ""r*   rR   c                     e Zd ZdZddZedd       Zedd       ZddZddd	 	 	 	 	 	 	 	 	 ddZ	dd	Z
dd
	 	 	 	 	 	 	 ddZd dZd Zd ZddZ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"d       Zy)#GenericBatchCoordinatorzSingle generic entry: given any parallel batch plan it derives the
    fully integrated generic batch_state. Pure / read-only (9-R.1).c                   || _         | j                  |      | _        t               | _        |j
                  D ]R  }| j                  j                  t        |j                  |j                  |j                  |j                               T t               | _        |j
                  D ]  }| j                  j                  t        |j                  |j                   |j                  |j                  t#        |j$                        |j&                  |j                  |j(                  |j*                  |j,                  |j.                  |j0                  |j2                  |j4                  |j6                                t9        |j
                  D cg c]D  }t;        |j<                  |j$                  |j>                  |j@                  |jB                        F c}      | _"        |j
                  D ci c]>  }|j<                  tG        |j<                  | jI                  |      |jJ                        @ c}| _&        y c c}w c c}w )N)r0   r3   r5   r6   )r0   r2   r3   r6   expected_artifactsr?   !expected_normal_collector_cron_idrA   rB   rC   rD   rF   rG   rI   rJ   )r/   r9   r:   r;   r<   )r/   staterM   )'plan_derive_batch_idbatch_idr   _indexrT   registerr   r0   r3   r5   r6   r   _regregister_dispatchr   r2   rP   r9   r?   rA   rB   rC   rD   rF   rG   rI   rJ   r   r   r/   r:   r;   r<   
_depmatrixr   _initial_loop_staterM   _loop)selfr[   tps      r+   __init__z GenericBatchCoordinator.__init__   s   	--d3 *+++ 	BKK  JJ%'%8%8-/-H-H.0.J.J		 ,-	++ 	BII''!JJ[[%'%8%8.0.J.J'+B,=,='>$&$6$6686Q6Q.0.J.J242R2R#%#4#4!##%#4#4&(&:&:%'%8%8#%#4#4	, 0 ++	  [[#%#4#4,.,F,F!}}"$"2"2	
( kk1
  KK..r2 .. 1

	1
s   A	I6AIc                   | j                   dz   dj                  t        d | j                  D                    z   }t	        j
                  |j                  d            j                         d d }d| j                    d| S )N|c              3  R   K   | ]  }|j                    d |j                    ! yw):N)r/   r0   ).0ts     r+   	<genexpr>z;GenericBatchCoordinator._derive_batch_id.<locals>.<genexpr>   s#     D1ajj\199+.Ds   %'utf-8   zbatch--)rS   joinsortedrT   hashlibsha256encode	hexdigest)r[   basisdigests      r+   r\   z(GenericBatchCoordinator._derive_batch_id   sw      3&DDD*
 
 W 56@@B3BG(()6(33r*   c                    | j                   s| j                  dk(  rt        S | j                  dk(  rt        S | j                  dv rt        S t
        S )u~   Map an observed terminal outcome onto a valid 13-state position
        (read-only derivation — no transition side effects).HOLDr   )r"   r!   r    )rJ   rI   r   r   r   r   )rf   s    r+   rc   z+GenericBatchCoordinator._initial_loop_state   sL      3 3v =!!(*M"<<Or*   c                   i }| j                   j                  D ]  }t        |j                  xr |j                  xr |j
                        }|rUt        |j                  |j                  |j                  |j                  xs d|j
                        j                         }n:|j                  |j                  |j                  |j                  |j
                  d}|||j                  <    |S )a  track_id-keyed 5-field callback_track_record view. by-design /
        NO-CRON tracks may carry a null normal cron and empty fallback cron;
        the strict +17 CallbackTrackRegistry is NOT used for those so its
        non-empty invariant stays intact (zero API break).r1   )r/   r0   r3   r5   r6   )
r[   rT   r@   r3   r5   r6   r   r/   r0   to_dict)re   outrf   strictrecs        r+   callback_track_registryz/GenericBatchCoordinator.callback_track_registry   s    
 -/))"" 	#B## 1//100F
 )[[JJ%'%8%8-/-H-H-NB.0.J.J ')  !#!zz(*(;(;020K0K131M1M  #C-	#. 
r*   N)event_task_idevent_cron_idc               @    | j                   j                  ||||      S )ud   4-tuple ownership check (+29 reuse). Non-empty == TRACK_MISMATCH
        reasons (§5 regression 5).)claimed_task_id
event_kindr   r   )r^   classify_event)re   r   r   r   r   s        r+   validate_callback_identityz2GenericBatchCoordinator.validate_callback_identity  s,     {{))+!''	 * 
 	
r*   c                *   t        fd| j                  j                  D        d      }| dgS g }|j                  s|j	                   d       |j
                  xr |j                  dv }|j                  s|s|j	                   d       |S )a  Generic per-track 4-tuple consistency. dispatch cron always
        required; fallback cron required UNLESS the track is by-design
        NO-CRON (by_design_no_normal_collector & fallback_state in
        {NONE,CANCELLED}). Keeps the strict +29 validate_tuple unedited.c              3  B   K   | ]  }|j                   k(  s|  y wN)r0   )rl   rm   r0   s     r+   rn   z<GenericBatchCoordinator.tuple_consistency.<locals>.<genexpr>  s     G!))w2F1Gs   Nz: no track registeredz: dispatch_cron_id empty)NONE	CANCELLEDz!: fallback_callback_cron_id empty)nextr[   rT   r3   appendrB   rF   r6   )re   r0   rf   reasons
no_cron_oks    `   r+   tuple_consistencyz)GenericBatchCoordinator.tuple_consistency  s    
 Gdii..GN:i4566""NNgY&>?@55 
":K:K P
 ;

 ++JNNgY&GHIr*   )fallback_task_idc               r    | j                   j                          | j                   j                  |||      S )u   Classify a fallback firing against registry truth (+29 reuse):
        result ready + no normal -> DUPLICATE_CALLBACK_IGNORED (§5 reg 4);
        4-tuple mismatch -> TRACK_MISMATCH (§5 reg 5). read-only.)r   fallback_cron_idr   )r`   reconcile_allclassify_fallback)re   r   r   r   s       r+   classify_fallback_firez.GenericBatchCoordinator.classify_fallback_fire,  s9     			!yy**+-- + 
 	
r*   c                6    | j                   j                         S r   )rb   r}   re   s    r+   dependency_matrixz)GenericBatchCoordinator.dependency_matrix;  s    &&((r*   c                6    | j                   j                         S r   )rb   expected_files_overlapr   s    r+   r   z.GenericBatchCoordinator.expected_files_overlap>  s    5577r*   c                6    | j                   j                         S r   )rb   forbidden_write_overlapr   s    r+   r   z/GenericBatchCoordinator.forbidden_write_overlapA  s    6688r*   c           	     R   i }| j                   j                  D ]  }| j                  |j                        }|rd}d}d}n|t	        |j
                  dk(  |j                  |j                  |j                  |j                  |j                        }t        |      }t        |      }t        ||j                        }i d|j                  d|j                  d|j                  d	|j
                  d
|j                   d|j"                  dt%        |j&                        ddd|j                  d|j                  d|j                  d|j                  d|j                  d|j(                  d|d|d||j*                  |j,                  |d||j                  <    |S )u  Per-track runtime record. Classification is derived directly via
        the +29 result_ready_recovery leaf (read-only reuse) so a by-design
        NO-CRON track (empty fallback cron, §7) is NOT mis-flagged by the
        strict +29 validate_tuple — the strict +29 module stays unedited
        (zero API break, §9). Cross-track 4-tuple ownership is still enforced
        via Callback4TupleIndex (regression 5).TRACK_MISMATCHFr1   r>   )dispatch_okrC   rD   rA   rB   rF   r0   r2   r3   r?   rY   r6   rX   normal_collector_registeredrA   rB   rC   rD   rF   rG   classificationrecovery_eligibler   )rI   rJ   track_mismatch_reasons)r[   rT   r   r0   r   r?   rC   rD   rA   rB   rF   r   r   r   r2   r3   r5   r6   rP   r9   rG   rI   rJ   )re   r~   rf   r   r   rec_eligiblenoteobss           r+   track_runtime_recordsz-GenericBatchCoordinator.track_runtime_recordsE  s    -/))"" )	B,,RZZ8G!1$(!#!3!3t!;#%#4#4!#.0.J.J242R2R#%#4#4 "2#!63NC$"B$D$D2::BKK #B$7$7 "2#5#5	
 4R5P5P ,R-I-I %d2+<+<&= .u ,R-I-I 01Q1Q !""3"3  !""3"3 $R%9%9 !.  $\!"  #$ %'$7$7"$"3"3*1)C

O))	T 
r*   c           
         t        | j                  j                  D cg c].  }t        |j                  |j
                  |j                        0 c}      S c c}w )N)r/   r<   r=   )r   r[   rT   r   r/   r<   r=   )re   rf   s     r+   contaminationz%GenericBatchCoordinator.contaminationz  sV    ( ))**  [["$"2"2$&$6$6	
 		
s   3Ac                   g }| j                   j                  D ]M  }|j                  r|j                  D ]  }|j                  t	        |j
                  |j                  |j                  dd      |j                  dd      |j                  d|j                  xs d      |j                  dd      |j                  d|j                        	              |j                  s|j                  s|j                  t	        |j
                  |j                  |j                  rd
ndd|j                  xs d|j                  r|j                  d   nd|j                  	             P t        |      }|j                         D ci c]V  \  }}||j
                  |j                  |j                   |j"                  |j$                  |j&                  |j(                  d	X c}}S c c}}w )Nsourcefallbackschemazgeneric.result.v0tsr1   pathstatus)r0   r/   r   r   r   r   r   normalr   )r[   rT   rN   r   r   r0   r/   getrG   rI   rC   rD   rA   r9   r   itemsr   r   r   r   r   )re   
candidatesrf   pchosenr0   cs          r+   rN   z)GenericBatchCoordinator.authority_packets  s   ,.
))"" 	B##-- A%%'$&JJ%'[[#$55:#>#$553F#G uuT2+?+?+E2F!"vr!2#$5523F3F#G
 ""boo!!# "

!#+-+G+Gx'2//52686G6Gb//2R!22	!	8 1< %lln
  99JJ((((dd(( 
 	
 
s   AG'c                z   | j                         }t        | j                               }g }g }g }| j                  j                  D ]  }||j
                     }|j                  s|j                  dk(  r|j                  |j
                         I|j                  t        v r|j                  |j
                         w|j                  |j
                          g }|r|r|j                  d|d|d       |rd}	|j                  d       n|rd}	n|rd}	nd}	t        |      t        |      t        |      ||	d	S )
u  Independence join — a settled track whose fallback is still
        PENDING is NON-blocking (§5 regression 3); a HOLD track never demotes
        an independent settled track (§5 regression 7). Generic settled set
        includes ACCEPT (registry track). Pure read-only derivation.r{   zheld=z" do NOT block independent settled=z (join by independence)
BATCH_HOLDz'cross_track_contamination -> BATCH_HOLDWAIT_FOR_FALLBACKBATCH_ACCEPT)independent_done_tracksheld_trackswaiting_tracksblocking_relationsbatch_next_action)r   r@   r   r[   rT   r0   rJ   rI   r   _SETTLEDrs   )
re   recordscontaminatedindependentheldwaitingrf   r   blockingactions
             r+   rr   zGenericBatchCoordinator.join  s+   
 ,,.D..01!#))"" 	'B"**%C  B$7$76$ABJJ'""h.""2::.NN2::&	' !KOO,0+? !FOOEF!F(F#F'-k':!$<$Wo"*!'
 	
r*   c                     j                         ryt         fd j                  j                  D              ryt        d  j                  j                  D              ryt         fd j                  j                  D              ryy)	aT  Single batch-level next action (read-only resolve, 9-R.1).

        Precedence: contamination -> BATCH_HOLD_CONTAMINATION; any
        HOLD/HOLD_FOR_CHAIR -> CHAIR_DECISION_REQUIRED; any non-terminal loop
        -> CONTINUE_LOOP; pending fallback w/o result -> AWAIT_PENDING_CALLBACK;
        all terminal & clean -> CONSOLIDATE_FOR_CHAIR.BATCH_HOLD_CONTAMINATIONc              3     K   | ]j  }|j                   xsX t        j                  |j                     j                        xr* j                  |j                     j                  t
        k(   l y wr   )rJ   r   rd   r/   rZ   r   rl   rf   re   s     r+   rn   z<GenericBatchCoordinator.batch_next_action.<locals>.<genexpr>  si      
   @4::bkk2889 @

2;;'--?@
s   A0A3CHAIR_DECISION_REQUIREDc              3     K   | ]E  }|j                    xr2 |j                   xr# |j                  d k(  xr |j                  t        v G yw)rE   N)rC   rD   rF   rI   r   rl   rf   s     r+   rn   z<GenericBatchCoordinator.batch_next_action.<locals>.<genexpr>  s_      

 	 !!! 4OO#4!!Y.4 ##834
s   AAAWAIT_PENDING_CALLBACKc              3  x   K   | ]1  }t        j                  |j                     j                          3 y wr   )r   rd   r/   rZ   r   s     r+   rn   z<GenericBatchCoordinator.batch_next_action.<locals>.<genexpr>  s4      
 DJJr{{399::
s   7:CONTINUE_LOOPCONSOLIDATE_FOR_CHAIR)r   anyr[   rT   r   s   `r+   r   z)GenericBatchCoordinator.batch_next_action  s     - 
 ii&&	
 
 - 

 ii&&
 
 , 
ii&&
 
 #&r*   c                   | j                   j                  }t        | j                               }t        |      xr t	        d |D              }| j                         d   }|xr
 | xr |dk(  }|sd}nF|rd}nA|s=|D cg c],  }|j                  t        vs|j                  r|j                  . }}d| }nd}t        |      dd	|d
S c c}w )u   Evidence-based closeout eligibility, DERIVED from batch_state
        only (§5 regression 8). 9-R.1 / §7: registry/coordinator never
        confirms — confirmed is hard-pinned False; chair confirmation
        required out of band.c              3  ^   K   | ]%  }|j                   t        v xr |j                    ' y wr   )rI   r   rJ   r   s     r+   rn   z<GenericBatchCoordinator.closeout_proposal.<locals>.<genexpr>  s4      +
 8+EB4E4E0EE+
s   +-r   r   zno tracks in batch_statez.cross-task contamination present -> ineligibleztracks not all settled: u~   all tracks settled (MERGED/PASS/DONE/ACCEPT), no contamination — closeout PROPOSED; chair confirmation still required (§7).batch_stateF)eligiblederived_from	confirmedreason)
r[   rT   r@   r   allrr   rI   r   rJ   r0   )	re   rT   r   all_settledr   r   r   rf   	unsettleds	            r+   closeout_proposalz)GenericBatchCoordinator.closeout_proposal  s    
 !!D..016l 
s +
+
 (
 01P|#3P.8P/FEF !&&h6":K:K 

I 
 0	{;F(  X)	
 	
s    1Cc                8   | j                         }| j                  j                  D ci c]7  }|j                  |j                  ||j                     d   |j
                  d9 c}| j                         d   t        | j                         d         dS c c}w )Nr   )rI   r   rJ   r   r   )rT   r   closeout_eligible)	r   r[   rT   r0   rI   rJ   rr   r@   r   )re   r   rf   s      r+   consolidated_summaryz,GenericBatchCoordinator.consolidated_summary%  s    ,,. ))**  

(*(;(;&-bjj&9:J&K&(&7&7  "&-@!A!%d&<&<&>z&J!K
 	
s   <Bc                   | j                         }| j                         }| j                  j                         D ci c]  \  }}||j	                          }}}| j
                  j                  D ci c](  }|j                  | j                  |j                        * }}i dt        d| j                  d| j
                  j                  ddd| j                         d|d| j                         d	|d
|d| j                         D 	
cg c]  \  }}	}
||	|
d c}
}	}d| j                         d|d|d   d| j!                         d| j#                         d| j%                         S c c}}w c c}w c c}
}	}w )Nr   r]   rS   decision_logiczSread-only: derive/propose/read only; zero execute/confirm/write/merge/cron (9-R.1).r   callback_4tuple_consistencyr   r   track_loop_statesr   )citingownerartifactrN   join_policyr   batch_next_action_resolverr   r   )r   rr   rd   r   r}   r[   rT   r0   r   SCHEMAr]   rS   r   r   r   rN   r   r   r   )re   r   rr   tidstloop_statesrf   tuple_reasonsabr   s              r+   build_statez#GenericBatchCoordinator.build_state5  s   ,,.yy{-1ZZ-=-=-?
")#rC
 

 ii&&
 JJ..rzz::
 

f

 49900
  8	
 &t'C'C'E
 *=
  !7!7!9
 $W
  
 !%!3!3!5 Q1 qa8
  !7!7!9
  4!
"  &9!:#
$ )$*@*@*B%
&  !7!7!9'
( #D$=$=$?)
 	


s   E64-E<Fc                   | j                         }|d   }g }|j                  d| j                          |j                  d       |j                  d       |j                  d       |j                  d| j                  j                   d       |j                  d|d    d	       |j                  d
|d    d|d   d    d       |d   }|j                  d|sdn|        |j                  d       |j                  d       |d   j                         D ]+  \  }}|j                  d| d|d    d|d    d|d           - |j                  d       dj                  |      dz   S )Nr   u)   # Generic Batch Consolidated Summary — r1   zx> Code-generated (anu_v3.generic_batch_coordinator). Chair-only final decision fields. read-only decision logic (9-R.1).z- batch_label: ``z- batch_next_action: **r   z**z- closeout_eligible: **r   z** (confirmed: **r   r   u   ** — chair out-of-band, §7)r   z- cross_track_contamination: r   z## Per-track final viewrT   z- `u   ` → outcome **rI   z**, class `r   z`, hold=rJ   
)r   r   r]   r[   rS   r   rr   )re   r   cslinescontamr   r   s          r+   build_consolidated_summary_mdz5GenericBatchCoordinator.build_consolidated_summary_mdV  s   &'7G	
 	RG	
 	R'		(=(='>a@A%b)<&=%>bA	
 	%b)<&=%> ? 34[AB C&'	

 O$+#v02	
 	R./8**, 	HCLLcU*3/A+B*C D./0 1,-.0	 	Ryy$&&r*   c                j    t        |       j                         xr t        |      j                         S )uv   +30 recognises its own completion by result.json + .done
        existence — zero cron register/remove (§7, 9-R.1).)r   is_file)result_path	done_paths     r+   self_completion_recognizedz2GenericBatchCoordinator.self_completion_recognized}  s*     K ((*HtI/F/F/HHr*   )r[   rR   returnNone)r[   rR   r  r.   )rf   r-   r  r.   )r  zDict[str, Dict[str, object]])
r   r.   r   r.   r   r4   r   r4   r  r8   )r0   r.   r  r8   )r   r.   r   r.   r   r4   r  r.   )r  Dict[str, object])r  r.   )r   r   r  r   r  r@   )r%   r&   r'   r(   rg   staticmethodr\   rc   r   r   r   r   r   r   r   r   r   rN   rr   r   r   r   r   r   r  r)   r*   r+   rV   rV      s    G=
@ 4 4 	 	H (,'+
 
 	

 %
 %
 

"* +/
"%
9<
'
 

)892j

*
Z(
V'@#
L
 
B$'N II&*I	I Ir*   rV   c                   t        j                  t        |       j                  d            }|d   D cg c]  }t	        d$i d|j                  d|d         d|d   d|j                  dd      d|j                  dd      d	|j                  d	      xs |j                  d
      d|j                  dd      dt        |j                  d|j                  dg                   dt        |j                  dg             dt        |j                  dg             dt        |j                  dg             dt        |j                  dg             d|j                  dd      d|j                  dd      d|j                  dd      d|j                  dd      d|j                  dd      d|j                  dd      d|j                  d      d|j                  dd      d|j                  dd      d|j                  dd       d!t        |j                  d!g              }}t        |d"   |#      S c c}w )%Nro   encodingrT   r/   r0   r2   r1   r3   r5   rY   r6   r9   rX   r:   r;   r<   r=   r?   r>   rA   FrB   rC   rD   rF   rE   rG   rI   rH   rJ   rM   rK   rN   rS   )rS   rT   r)   )jsonloadsr   	read_textr-   r   rP   rR   )fixture_pathdatarm   rT   s       r+   load_plan_from_fixturer    s   ::d<(22G2DED> h=< ; 	 	
UU:q|4	
iL	
 UU:r*	
 UU#5r:		

 &'UU+E%F &:uu89	
 '(ee,G&L	
  &.BB(GH	
 %)/H")M$N	
 AEE,34	
 quu_b9:	
 !'8"!=>	
 EE"3T:	
  '(ee,G&O!	
" +,%%/+#	
( 55!159)	
* ~u5+	
, 55!19=-	
.  ee$78/	
0 UU#5yA1	
2 55!1593	
4 %%35	
6 #155)<b#AB7	
F @ ' As   HI	c                ^   	 t        j                  ddt        | j                        ddgdd      }|j                  dk7  ry|j
                  j                         }t        j                  dd|d	d
t        | j                               gdd      }|j                  dk(  S # t        $ r Y yw xY w)Ngitz-Cz	rev-parsez--show-toplevelT)capture_outputtextr   Fzls-filesz--error-unmatch)	
subprocessrunr.   parent
returncodestdoutstripresolve	Exception)r   topreporcs       r+   _is_git_trackedr    s    nnD#ahh-6GH

 >>Qzz!^^D$
,=s199;?OP

 }}!! s   ?B  AB   	B,+B,z.generic-batch-state.jsonz"schema": ""c                   t        |      }|j                  t        k(  rt        d      t	        |      rt        d| d      |j                         rK|j                  j                  t              }|s	 t        |j                  d      v }|st        d| d      |j                  j                  d	d	
       |j                  t        j                   | dd      dz   d       |S # t        t        f$ r d}Y ow xY w)uD  Write the NEW generic authority file. NOT a decision component —
    explicit I/O the runner/ANU performs (9-R.1 boundary).

    Hard write-guard envelope (§4 / §9 / 9-R.2) — precise, mirrors the +17
    coordinator guard so an unrelated existing file can NEVER be clobbered:

      * chair durable v1 name                 -> REFUSE (byte-0 immutable)
      * git-tracked path                      -> REFUSE (tracked HEAD invariant)
      * untracked & non-existent              -> ALLOW  (NEW deliverable)
      * untracked & existing, IS a sanctioned
        generic-state deliverable             -> ALLOW  (idempotent re-emit)
      * untracked & existing, NOT a sanctioned
        deliverable                           -> REFUSE (never clobber an
                                                 unrelated untracked file)
    uz   refusing to write chair durable v1 (§9 byte-0); generic authority MUST be the separate task-2553.generic-batch-state.jsonz#refusing to write git-tracked path uA    (§9 tracked HEAD invariant — only NEW untracked deliverables)ro   r  Fz9refusing to overwrite existing untracked non-deliverable zk (9-R.2: only a NEW untracked path or the coordinator's own generic-batch-state deliverable may be written)T)parentsexist_okrK   )ensure_asciiindentr   )r   name_FROZEN_DURABLE_V1r$   r  existsendswith_DELIVERABLE_SUFFIX_DELIVERABLE_MARKERr  OSErrorUnicodeDecodeErrorr  mkdir
write_textr
  dumps)r   out_pathr~   
sanctioneds       r+   emit_generic_batch_stater3    s&   $ x.C
xx%% P
 	
 s 1# 7= =
 	
 zz|XX&&':;
#0CMM$ 5B 5 

 $K% FG 
 JJTD1NN

;U1=D   J /0 #"
#s   6C* *C>=C>)r  
str | Pathr  rR   )r   r   r  r@   )r   r  r1  r4  r  r   ):r(   
__future__r   rt   r
  r  dataclassesr   r   pathlibr   typingr   r   r	   r
   anu_v3.batch_join_policyr   r   r   r   anu_v3.batch_dependency_matrixr   r   anu_v3.callback_track_registryr   anu_v3.track_loop_stater   r   r   r   r   r   anu_v3.callback_4tuple_indexr   r    anu_v3.parallel_runtime_registryr   r   anu_v3.result_ready_recoveryr   r   r   r   r   PLAN_SCHEMAr   r'  RuntimeErrorr$   r-   rR   rV   r  r  r*  r+  r3  r)   r*   r+   <module>rB     s  (R #    (  1 1  L >  E  
),
 0 ; / / J J J4 # # #sI sIt$V. 2 #F81- 1"1.81	1r*   