
    ,j8                    
   U d Z ddlmZ ddlmZmZ ddlmZmZm	Z	m
Z
mZ dZ eeh      Zded<   ddZd	Zd
ZdZdZdZdZdZdZdZe G d d             Z	 	 	 	 	 	 ddZddZd ee      d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZg dZy)u  utils.callback_source_cross_checker — 4 source cross-check for callback
authority verification (task-2646 CALLBACK_REGISTRATION_AUTHORITY_GATE).

ANCHOR-3: 4 source cross-check:
  1. schedule_history_records  — /home/jay/.cokacdir/schedule_history/<id>.log
  2. cron_history_records      — ANU key + suspect self-key cron-history
  3. envelope                  — callback prompt original text (collector_key)
  4. result_artifact           — result.json / report / ledger entry

ANCHOR-4: one-shot cron fire after cron-list 0 → CRON_LIST_AUTODELETED_FIRED
  (never conclude CALLBACK_MISSING from cron-list alone)

Layer A / NO-CRON / NO-WRITE / NO-SUBPROCESS: pure function, zero IO.
All inputs are pre-parsed dicts/lists supplied by the caller.
    )annotations)	dataclassfield)AnyDictListOptionalSequencec119085addb0f8b7	frozensetDEFAULT_ANU_KEYSc                6    t        |       xr | t        |      v S )z;True iff key is a non-empty configured independent ANU key.)boolset)keyanu_keyss     T/home/jay/workspace/.worktrees/task-2646-dev3/utils/callback_source_cross_checker.py
is_anu_keyr      s    9-H--    z&utils.callback_source_cross_checker.v1PASSFAILCALLBACK_MISSINGCRON_LIST_AUTODELETED_FIREDSCHEDULE_HISTORY_PENDINGSOURCE_CROSS_CHECK_PARTIALOWNER_KEY_VERIFIEDRESULT_ARTIFACT_SELF_ATTESTEDc                      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<    ee      Zded<   edd       Z	ddZ
y)CrossCheckResultz!Result of a 4-source cross-check.strschemaverdictstateintsource_count_presentsource_count_absentr   schedule_history_presentz	List[str]cron_history_owner_keysOptional[str]envelope_collector_keyresult_artifact_presentOptional[bool]cron_list_presentactual_owner_key)default_factoryreasonsc                (    | j                   t        k(  S )N)r"   VERDICT_PASSselfs    r   okzCrossCheckResult.okC   s    |||++r   c                4   | j                   | j                  | j                  | j                  | j                  | j
                  t        | j                        | j                  | j                  | j                  | j                  t        | j                        dS )Nr!   r"   r#   r%   r&   r'   r(   r*   r+   r-   r.   r0   )r!   r"   r#   r%   r&   r'   listr(   r*   r+   r-   r.   r0   r3   s    r   to_jsonzCrossCheckResult.to_jsonG   sz    kk||ZZ$($=$=#'#;#;(,(E(E'+D,H,H'I&*&A&A'+'C'C!%!7!7 $ 5 5DLL)
 	
r   Nreturnr   )r;   dict)__name__
__module____qualname____doc____annotations__r   r8   r0   propertyr5   r9    r   r   r   r   2   sj    +KLJ""&&))!!%%##t4GY4, ,
r   r   c                    | j                         D ]  \  }}|s	t        ||      s|c S  | j                         D ]  \  }}|s	|c S  y)u  Extract actual owner key from cron-history records.

    Priority:
    1. ANU key found → return that key
    2. suspect self-key found → return that key
    3. Neither found → return None

    cron_history_records format: {key: [record, ...]}
    A non-empty list means access was granted (key is owner).
    An empty list or missing key means access denied (not that key).
    N)itemsr   )cron_history_recordsr   r   recordss       r   $_extract_owner_key_from_cron_historyrH   X   s\     -224 Wz#x0J
 -224 WJ r   c                P    | sy| j                  d      xs | j                  d      S )z)Extract collector_key from envelope dict.Ncollector_key	owner_key)get)envelopes    r   _extract_envelope_collector_keyrN   s   s%    <<(EHLL,EEr   N)r-   r   c                $   g }t        |      }|j                         D 	
cg c]
  \  }	}
|
s	|	 }}	}
t        |      }t        |      }|du}t        |      }t        ||||g      }d|z
  }t	        ||      }t        d |D              }|r:|r8|j                  d| d       t        t        t        t        |||||||||      S |du r:|r8|j                  d| d	       t        t        t        t        |||||||||      S |d
k(  r<|du r8|j                  d| d       t        t        t        t        d
ddg |d|d|      S |r<|s:|s8|j                  d| d       t        t        t        t        ||dg |d|d|      S |dk(  r=|;|j                  d| d|d       t        t        t        t        dd
d||d|||      S |j                  d| d| d| d| d| d| d       t        t        t        t         |||||||||      S c c}
}	w )u)  Cross-check 4 sources to determine callback authority.

    Inputs (all pure data, no IO):
    - schedule_history_records: list of JSONL-parsed records from
      /home/jay/.cokacdir/schedule_history/<id>.log
    - cron_history_records: dict mapping key → list of records
      (ANU key + suspect self-key, each queried separately)
    - envelope: dict with collector_key/owner_key from cron prompt
    - result_artifact: dict from result.json/report/ledger (or None)
    - cron_list_present: None=unknown, True=in cron-list, False=absent

    Classification logic (ANCHOR-3, ANCHOR-4):
    - All 4 absent + cron_list False → CALLBACK_MISSING (FAIL)
    - cron_list False + schedule_history present → CRON_LIST_AUTODELETED_FIRED (PASS)
    - schedule_history pending records → SCHEDULE_HISTORY_PENDING (PASS/hold)
    - partial sources → SOURCE_CROSS_CHECK_PARTIAL (PASS/informational)
    - All 4 present + actual owner extracted → OWNER_KEY_VERIFIED (PASS)
    - result_artifact only (no schedule_history) → RESULT_ARTIFACT_SELF_ATTESTED (FAIL)
    N   c              3  `   K   | ]&  }|j                  d d      j                         dv  ( yw)status >   queuedpending	scheduledN)rL   lower).0rs     r   	<genexpr>z&cross_check_sources.<locals>.<genexpr>   s2       	
h!!#'IIs   ,.zschedule_history for cron_id=uR    has pending records → SCHEDULE_HISTORY_PENDING (hold, do not conclude missing).r7   FzAcron_list_present=False but schedule_history present for cron_id=u    → CRON_LIST_AUTODELETED_FIRED (one-shot cron fired and auto-deleted; not CALLBACK_MISSING). ANCHOR-4: cron-list alone cannot determine missing.r   z!All 4 sources absent for cron_id=u    AND cron_list_present=False → CALLBACK_MISSING (FAIL). Note: cron-list alone is not sufficient; confirmed only after 4 source cross-check (ANCHOR-3/ANCHOR-4).zVresult_artifact present but schedule_history and cron_history both absent for cron_id=u    → RESULT_ARTIFACT_SELF_ATTESTED (FAIL). Bot self-attestation alone cannot confirm authority (cross-verification required, ANCHOR-3).Tz"All 4 sources present for cron_id=z, actual_owner_key=uZ    extracted from cron_history → OWNER_KEY_VERIFIED (PASS, ANCHOR-3 cross-check complete).zPartial sources for cron_id=z: z/4 present (schedule_history=z, cron_history=z, envelope=z, result_artifact=u   ) → SOURCE_CROSS_CHECK_PARTIAL (insufficient for definitive verdict; gather more sources before concluding missing, ANCHOR-3/ANCHOR-4).)r   rE   rN   sumrH   anyappendr   SCHEMAr2   STATE_SCHEDULE_HISTORY_PENDING!STATE_CRON_LIST_AUTODELETED_FIREDVERDICT_FAILSTATE_CALLBACK_MISSING#STATE_RESULT_ARTIFACT_SELF_ATTESTEDSTATE_OWNER_KEY_VERIFIED STATE_SOURCE_CROSS_CHECK_PARTIAL)cron_idschedule_history_recordsrF   rM   result_artifactr-   r   r0   r'   kvr(   cron_history_presentr*   envelope_presentr+   r%   r&   r.   history_has_pendings                       r   cross_check_sourcesrn   z   s=   : G  $$<=*002*aa* *   78<XF-T9"?3 	   22 <h
  )   $7+G; 7L L	
   0!5 3%=$;#9$;/-
 	
" E!&>k "BB	
   3!5 3%=$;#9$;/-
 	
  q %6%%?/{ ;8 8	
   (!" !%*$&#9$)/!
 	
" '?H\"+ &77	
   5!5 3%*$&#9$(/!
 	
  q %5%A0 <  03 4LL	

   *!" !%)$;#9$(/-
 	
  NN
&wk
  !56 7,- .$% &23 4M	M	 .1/!9 75 7+) u*s
   
HH)r^   r2   ra   r   rn   r:   )rF   Dict[str, List[Dict[str, Any]]]r   Sequence[str]r;   r)   )rM   Optional[Dict[str, Any]]r;   r)   )rf   r    rg   zList[Dict[str, Any]]rF   ro   rM   rq   rh   rq   r-   r,   r   rp   r;   r   ) r@   
__future__r   dataclassesr   r   typingr   r   r   r	   r
   _ANU_KEY_2553r   r   rA   r   r^   r2   ra   rb   r`   r_   re   rd   rc   r   rH   rN   tuplern   __all__rC   r   r   <module>rx      s    # ( 6 6
 #'8 ) 8. 
2  , $A !!; #?  / &E # "
 "
 "
J9 6F )-#$45HH 3H :	H
 'H .H &H H HVr   