
    j@                        d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	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mZmZmZmZmZmZmZ dd
l m!Z!m"Z"m#Z# dZ$dZ% ed       G d d             Z&ddZ'	 	 	 	 	 	 ddZ( G d d      Z)y)u  anu_v3.runtime_reconcile_checkpoint — ANU runtime reconcile checkpoint.

task-2553+31 ANU_RUNTIME_RECONCILE_CHECKPOINT orchestrator (§1/§2/§11).

Solves the operationalization gap: tools existed (+29 registry / +30 generic
coordinator) but did not run automatically — ANU only discovered completion
when the chair asked. This module is the read-only checkpoint that ANU can
auto-wire at an active-dispatch turn boundary OR call before responding
(§11 결선) so a finished NO-CRON task with no normal callback is detected
WITHOUT a chair question (§1/§15 dogfooding).

DESIGN BOUNDARY (§10, regression 12/15):
  * read-only detection only — ZERO write / cron / merge / dispatch / closeout
  * batch_state output == ONE additive versioned PROPOSAL artifact (9-R.1)
  * next_action == recommendation only
  * callback primary/safety/cancel-on-success paths preserved, NOT replaced (§2)
    )annotationsN)	dataclass)Path)DictListOptional)ActiveDispatchScannerDispatchRecord)TaskArtifactDetector)resolveTERMINALNONTERMINALALL_CLASSIFICATIONSNO_CRON_TASK_DONERESULT_READY_NO_NORMAL_CALLBACKNORMAL_COLLECTOR_COMPLETEDDUPLICATE_CALLBACK_IGNOREDTRACK_MISMATCHRUNNINGWAIT_FOR_RESULTFALLBACK_PENDINGSTALE_OR_BOT_STUCK_CANDIDATE)build_proposalemit_runtime_batch_stateFrozenWriteRefusedz-anu_v3.runtime_reconcile_checkpoint.result.v1i  T)frozenc                      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Zded<   dZded<   dZded<   dZded<   ddZ	y)RuntimeTaskObservationuB   Normalized read-only observation for one track (구현목표 1-8).strtask_idbooldispatch_okresult_presentdone_presentnormal_collector_registerednormal_collector_executedby_design_no_normal_collectorfallback_state terminal_outcomeFstaletrack_mismatchNzOptional[List[str]]track_mismatch_reasonsc                *   | j                   | j                  | j                  | j                  | j                  | j
                  | j                  | j                  | j                  | j                  | j                  t        | j                  xs g       dS )Nr    r"   r#   r$   r%   r&   r'   r(   r*   r+   r,   r-   )r    r"   r#   r$   r%   r&   r'   r(   r*   r+   r,   listr-   )selfs    :/home/jay/workspace/anu_v3/runtime_reconcile_checkpoint.pyto_jsonzRuntimeTaskObservation.to_jsonJ   s~    ||++"11 --+/+K+K)-)G)G22"11 $ 5 5ZZ"11&*4+F+F+L"&M
 	
    returnDict[str, object])
__name__
__module____qualname____doc____annotations__r*   r+   r,   r-   r3    r4   r2   r   r   9   sd    LL!%%###''cE4 ND 26/6
r4   r   c                   | j                   rt        S | j                  rt        S | j                  xs | j
                  }|rT| j                  dk(  rt        S | j
                  r-| j                  r!| j                  dk(  r| j                  st        S t        S | j                  s| j                  st        S | j                  dk(  rt        S t         S )u  Deterministic taxonomy classifier (9-R.2/9-R.4; §5/§6 정합).

    Precedence:
      1 TRACK_MISMATCH                 (4-tuple integrity first; reg 8-11)
      2 NORMAL_COLLECTOR_COMPLETED     (primary path; reg 5, fixture 4)
      3 has result:
          a fallback FIRED             -> DUPLICATE_CALLBACK_IGNORED (reg 7)
          b NO-CRON done & no fallback -> NO_CRON_TASK_DONE (reg 1, fixture 1)
          c otherwise                  -> RESULT_READY_NO_NORMAL_CALLBACK
                                          (reg 2/6, fixture 2/3)
      4 no result:
          a stale / dispatch !ok       -> STALE_OR_BOT_STUCK_CANDIDATE (reg 4)
          b fallback PENDING           -> FALLBACK_PENDING
          c else                       -> RUNNING (reg 3)
    FIREDNONEPENDING)r,   r   r&   r   r#   r$   r(   r   r'   r%   r   r   r+   r"   r   r   r   )obs
has_results     r2   classify_observationrD   \   s      
$$))##7s'7'7J(--11""f,33$$..
yy++
Y&Nr4   c                t   g }| j                  d      r%|j                  | j                  d      xs dg       | d   }| j                  di       xs i }|r|j                  d|      |k7  r|j                  d       |r4|j                  d      r#|d   |j                  k7  r|j                  d       |j                  d	      }|r||k7  r|j                  d
       |j                  d      }|r||k7  r|j                  d       t	               }|D cg c]  }||v r|j                  |      r| c}S c c}w )u   Detect 4-tuple contamination (구현목표 13; reg 8-11).

    Honours an explicit ``track_mismatch`` flag/reasons in the fixture, then
    cross-checks task_id / dispatch_cron_id / collector / fallback ownership.
    r,   r-   zexplicit track_mismatch flagr    callback_bindingztask_id mismatchdispatch_cron_idzdispatch_cron_id mismatchnormal_collector_owner_taskz*normal collector belongs to different taskfallback_owner_taskz"fallback belongs to different task)getextendappendrG   setadd)	trackdispatchreasonsownerbindingnc_ownerfb_ownerseenrs	            r2   _four_tuple_mismatchrX      s#    Gyy!"uyy!9: ;9:	<)Eii*B/52G;;y%(E1NN-.$67&'8+D+DDNN67;;<=E)NNGH;;45E)NN?@DA!qDyDHHQKAAAAs   	D5D5.D5c                      e Zd ZdZed	 	 	 	 	 ddZ	 	 	 	 	 	 ddZdddd	 	 	 	 	 	 	 	 	 dd	Z	 	 	 	 	 	 dd
Zdd	 	 	 	 	 ddZ	ddZ
y)RuntimeReconcileCheckpointuC   Read-only checkpoint orchestrator. Auto-wireable entrypoint (§11).)stale_secondsc                   t        |      | _        || _        t        | j                        | _        t        | j                        | _        y )N)r   	repo_rootr[   r   detectorr	   scanner)r1   r]   r[   s      r2   __init__z#RuntimeReconcileCheckpoint.__init__   s7     i*,T^^<,T^^<r4   c                   |d   }| j                   j                  |      }t        |j                  d|j                              }t        |j                  d|j
                              }t        ||      }t        |t        |j                  d|r|j                  n*t        |j                  dd            j                         dv             ||t        |j                  dd	            t        |j                  d
d	            t        |j                  dd	            t        |j                  dd            j                         t        |j                  dd            t        |j                  dd	            t        |      |      S )a(  Fold fixture truth + live read-only artifact detection.

        Fixture values are authoritative for deterministic regression; when a
        fixture omits result/done presence the live detector fills it (still
        read-only). Existing +26/+27/+30 artifacts are read/reference only.
        r    r#   r$   r"   dispatch_statusok)rc   firedsuccessr%   Fr&   r'   r(   r@   r*   r)   r+   r/   )r^   detectr!   rJ   r#   r$   rX   r   r"   r   lowerupper)r1   rO   rP   tidliver#   r$   mismatch_reasonss           r2   _observe_trackz)RuntimeReconcileCheckpoint._observe_track   s`    I}}##C(eii(8(,(;(;= >EIInd6G6GHI/x@%UYY(0$$EII/67==?-./ 0
 *%(,		7?)A&*		5u='?*.		95A+Cuyy)96BCIIK +=r!BCuyy%01 01#3'
 	
r4   r)   r   F)generated_ts_kstprior_versionemitc                  t        |      }t        j                  |j                  d            }t	        |t
              r|j                  d|      n|}t        j                  |      D ci c]  }|j                  | }}i }	|D ]  }
|
d   }| j                  |
|j                  |            }t        |      }t        |      }|j                         }||d<   |t        v |d<   |t        k(  |d<   |j                         |d<   |
j                  d	      |d	<   ||	|<    | j                   d
z  dz  dz  }|j#                         r1t%        j&                  |j)                               j+                         nd}t-        |	t/        |      t%        j&                  |j)                               j+                         t/        |      |||      }| j1                  |	|      }t2        ddd|t/        |      |	||dddddddd
}|r>| j                   d
z  dz  dz  }t5        ||| j                         }t/        |      |dd|d<   |S c c}w )a  Read-only reconcile. Returns the full result document.

        emit=False (default) writes NOTHING. emit=True writes ONLY the
        allowlisted additive PROPOSAL artifact via the hard-guarded emitter
        (9-R.1); any other path raises FrozenWriteRefused.
        zutf-8)encodingtracksr    classificationterminalrecovery_eligiblenext_actionexpectedmemoryeventsz#task-2553.parallel-batch-state.jsonr)   )source_fixturesource_fixture_sha256frozen_v1_reffrozen_v1_sha256rm   rn   task-2553+31 ANU_RUNTIME_RECONCILE_CHECKPOINT	READ_ONLYr   zccheckpoint is read-only detection; emit (opt-in) is the single hard-guarded additive PROPOSAL only.)writecronmergerP   closeout_confirmnote)
schemar    
checkpointmoderm   rz   track_recordsbatch_state_proposalconsolidated_summaryzero_side_effect_proofz7task-2553.runtime-reconcile-checkpoint.batch-state.jsonz#ADDITIVE_VERSIONED_PROPOSAL (9-R.1))pathsha256kindbatch_state_proposal_emitted)r   jsonloads	read_text
isinstancedictrJ   r	   from_fixturer    rl   rD   r   r3   r   r   r]   is_filehashlibr   
read_bytes	hexdigestr   r   _consolidated_summaryRESULT_SCHEMAr   )r1   fixture_pathrm   rn   ro   rawrr   d
dispatchesr   rO   ri   rB   rs   narec	frozen_v1frozen_v1_shaproposalconsolidatedresultoutshas                          r2   runzRuntimeReconcileCheckpoint.run   sz    L)jj///AB+5c4+@3'c +77E
 IIqL

 

 *, 	%E	"C%%eZ^^C-@AC1#6N(B++-C$2C !,8C
O"AA #$ "$C#ii
3C
O!$M#	%  NNX%034 	   " NN9//12<<>(* 	
 "|,")..'')#++49;i.*-'	
 11-J $%< 0!,/*$,$0Aq$%M'%
$ )H4KL  +8S$..ICCC=6F12 O
s   ,H?c                   i }|j                         D ])  \  }}|j                  |d   g       j                  |       + |j                  t        g       }|j                  t
        g       }t        |      ||||j                  t        g       |j                  t        g       |j                  t        g       |d   |d   |d   t        d |j                         D              dS )Nrs   batch_next_actioncloseout_proposalcallback_paths_statusc              3  L   K   | ]  }|j                  d       d|d   fv   yw)rw   Nrs   )rJ   ).0r   s     r2   	<genexpr>zCRuntimeReconcileCheckpoint._consolidated_summary.<locals>.<genexpr>M  s1      + 
#c2B.C'DD+s   "$)tracks_totalby_classificationno_cron_task_doneresult_ready_no_normal_callbacknormal_collector_completedduplicate_callback_ignoredr,   r   r   r   fixture_self_check_pass)items
setdefaultrL   rJ   r   r   lenr   r   r   allvalues)r1   r   r   by_classri   r   no_cron_doneresult_readys           r2   r   z0RuntimeReconcileCheckpoint._consolidated_summary8  s     *,%++- 	GHC$4 5r:AA#F	G||$5r:||$CRH.!)!-/;7<7<&ll>2>!)*=!>!)*=!>%-.E%F'* +(//1+ (
 	
r4   )rm   c               l    | j                  ||d      }|d   }dddt        |d         |d   |d   |d	S )
uF  ANU pre-response entrypoint (§11).

        Designed to be called at an active-dispatch turn boundary OR by ANU
        before answering, so a finished NO-CRON task with no normal callback
        is detected WITHOUT a chair question. Read-only (emit=False).
        Returns a compact decision packet ANU can act on.
        F)rm   ro   r   Tz6active-dispatch turn boundary OR ANU pre-response callr   r   r   )auto_wireablewiringchair_question_requiredno_cron_completion_detectedr   r   decision_packet)r   r!   )r1   r   rm   rescss        r2   checkpoint_entrypointz0RuntimeReconcileCheckpoint.checkpoint_entrypointT  s`     hh|6F!  #'(!N',+/3F0G+H45!#$7!8"	
 		
r4   c                ,   | j                   j                  d      }| j                  dz  dz  dz  }| j                  dz  dz  dz  }|j                         }|j                         }t	        dd||ddddd	
	      }t        |      }d||||t        k(  dddS )uW  +31 self-completion detector (ultimate dogfooding, §15).

        The checkpoint detects its OWN completion by reading its result.json
        + .done existence — no cron, no chair question. This is the very
        mechanism §15 mandates: ANU calls this entrypoint manually to
        recognize +31 done without asking the chair.
        r~   rx   ry   ztask-2553+31.donez2task-2553.runtime-reconcile-checkpoint.result.jsonTFr@   DONE)	r    r"   r#   r$   r%   r&   r'   r(   r*   uB   read-only result.json + .done existence (NO-CRON dogfooding, §15))r    result_json_presentr$   rs   self_completion_detectedr   	mechanism)r^   rf   r]   r   r   rD   r   )r1   rB   done_presult_pr#   r$   self_obsclss           r2   detect_self_completionz1RuntimeReconcileCheckpoint.detect_self_completionp  s     mm"">2NNX%03FF 	 NNX%0BC 	 "))+~~')")%(-&+*.!#

 #8,%#1(!(+/@(@',6	
 		
r4   N)r]   r   r[   intr6   None)rO   r   rP   Optional[DispatchRecord]r6   r   )
r   r   rm   r   rn   r   ro   r!   r6   r7   )r   zDict[str, dict]r   r7   r6   r7   )r   r   rm   r   r6   r7   r5   )r8   r9   r:   r;   DEFAULT_STALE_SECONDSr`   rl   r   r   r   r   r=   r4   r2   rZ   rZ      s    M 3		=	= 		=
 
	=&
&
%=&
	&
Z !#XX 	X
 X X 
Xv
,
8I
	
@ !#	

 	

 

8'
r4   rZ   )rB   r   r6   r   )rO   r   rP   r   r6   z	List[str])*r;   
__future__r   r   r   dataclassesr   pathlibr   typingr   r   r   anu_v3.active_dispatch_scannerr	   r
   anu_v3.task_artifact_detectorr   #anu_v3.runtime_next_action_resolverr   r   r   r   r   r   r   r   r   r   r   r   r   "anu_v3.runtime_batch_state_updaterr   r   r   r   r   r   rD   rX   rZ   r=   r4   r2   <module>r      s   " #   !  ' ' P >     @   $
 
 
D&RBB3BB@r
 r
r4   