
     i*                        d Z ddlmZ ddlZddlmZmZ ddlmZmZ ddl	m
Z
  ej                  e      Z G d de      Zy)	ut  
Genesis Persistent Context Architecture — ColdLedgerInterceptor
Story 5.06 — Track B

Extends BaseInterceptor to automatically record every dispatch lifecycle event
(start / complete / error / correction) to the L4 Postgres Cold Ledger.

Design principles:
  - All writes are fire-and-forget via _fire_and_forget()
  - Never raises — on ColdLedger failure, logs a warning and continues
  - Never blocks the interceptor chain (ledger.write_event is synchronous but
    errors are swallowed; async methods return immediately after the call)
  - Priority 5: runs after telemetry (priority 0), before hydration (priority 10)
    )annotationsN)datetimetimezone)BaseInterceptorInterceptorMetadata)
ColdLedgerc                  d    e Zd ZdZ edd      ZddZddZddZddZ	dd	Z
	 	 	 	 	 	 	 	 dd
Zy)ColdLedgerInterceptoru  Records dispatch lifecycle events to the L4 Cold Ledger (Postgres).

    Writes one row per lifecycle hook via ColdLedger.write_event().
    All writes are best-effort — a ColdLedger failure logs a WARNING
    and the interceptor chain continues unblocked.

    Args:
        ledger: Fully-initialised :class:`~core.storage.cold_ledger.ColdLedger`
                instance (owns the psycopg2 connection pool).
    cold_ledger   )namepriorityc                    || _         y )N)ledger)selfr   s     =/mnt/e/genesis-system/core/storage/cold_ledger_interceptor.py__init__zColdLedgerInterceptor.__init__)   s	        c           	        K   |j                  dd      }| j                  d||j                  dd      |j                  dd      t        j                  t        j
                        j                         d       |S w)zKWrite event_type='dispatch_start' then pass task_payload through unchanged.
session_idunknowndispatch_start	task_typetier)r   r   	timestamp
event_typer   payloadget_fire_and_forgetr   nowr   utc	isoformat)r   task_payloadr   s      r   pre_executez!ColdLedgerInterceptor.pre_execute0   sw     !%%lI>
'!)--k9E$((;%\\(,,7AAC 	 	
 s   A<A>c                   K   |j                  dd      }| j                  d||j                  dd      t        j                  t        j
                        j                         d       yw)	zCWrite event_type='dispatch_complete' with a minimal result summary.r   r   dispatch_completesuccessT)r)   r   r   Nr   )r   resultr%   r   s       r   post_executez"ColdLedgerInterceptor.post_execute>   s]     !%%lI>
*!!::i6%\\(,,7AAC 	 	
s   A*A,c           	        K   |j                  dd      }| j                  d|t        |      j                  t	        |      t        j                  t        j                        j                         d       |S w)zDWrite event_type='dispatch_error' with error class name and message.r   r   dispatch_error)error_classerror_messager   r   )
r    r!   type__name__strr   r"   r   r#   r$   )r   errorr%   r   s       r   on_errorzColdLedgerInterceptor.on_errorJ   sk     !%%lI>
'!#E{33!$U%\\(,,7AAC 	 	
 s   A8A:c                   K   |j                  dd      }| j                  d||j                  dd      t        j                  t        j
                        j                         d       |S w)z?Write event_type='dispatch_correction' with the attempt number.r   r   dispatch_correctionattemptr   )r7   r   r   r   )r   correction_payloadr   s      r   on_correctionz#ColdLedgerInterceptor.on_correctionX   sg     '++L)D
,!-11)Q?%\\(,,7AAC 	 	
 "!s   A+A-c                    	 | j                   j                  |||       y# t        $ r!}t        j	                  d||       Y d}~yd}~ww xY w)u*  Best-effort synchronous write — never raises, never blocks the chain.

        On any exception from ColdLedger.write_event(), logs a WARNING at the
        ``cold_ledger_interceptor`` logger and returns silently.  The interceptor
        chain is never interrupted by a storage failure.
        z=ColdLedgerInterceptor: write_event failed (event_type=%s): %sN)r   write_event	Exceptionloggerwarning)r   r   r   r   excs        r   r!   z&ColdLedgerInterceptor._fire_and_forgeti   sG    	KK##J
GD 	NNO 	s     	A
AA
N)r   r   returnNone)r%   dictr@   rB   )r*   rB   r%   rB   r@   rA   )r3   r<   r%   rB   r@   rB   )r8   rB   r@   rB   )r   r2   r   r2   r   rB   r@   rA   )r1   
__module____qualname____doc__r   metadatar   r&   r+   r4   r9   r!    r   r   r
   r
      sS    	 #BH

""+.9=	r   r
   )rE   
__future__r   loggingr   r   "core.interceptors.base_interceptorr   r   core.storage.cold_ledgerr   	getLoggerr1   r=   r
   rG   r   r   <module>rM      s;    #  ' S /			8	$^O ^r   