
    Ai+;                        d Z ddlZddlmc mZ ddlZddlZddl	Z	ddl
mZ ddlmZmZ ddlmZmZmZ ej&                  j)                  dd       ddlmZ d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Ze dk(  ri e!d        e!d        e!d        e         e         e         e         e         e         e         e         e!d        e!d        e!d       yy)u  
Tests for Story 2.04 (Track B): scatter_gather_memory() — Concurrent 3-Layer Fetch

Black-box tests:
  BB1: All 3 fetches succeed (mock) → all 3 fields populated in MemoryContext
  BB2: Redis times out → working_state=None, other fields still populated
  BB3: All 3 time out → all fields None, latency_ms still recorded (> 0)
  BB4: Empty target_entities → kg_topology=None (short-circuit)

White-box tests:
  WB1: asyncio.gather called once (not 3 sequential awaits) — verify via mock
  WB2: Each fetch wrapped in asyncio.wait_for (individual timeout enforcement)
  WB3: latency_ms > 0 always (measures wall clock)
  WB4: Partial failure (1 of 3) still returns MemoryContext with populated fields
    N)Path)OptionalList)	AsyncMockpatch	MagicMockz/mnt/e/genesis-system)MemoryContextc                 H    t        j                         j                  |       S )z$Run async coroutine in test context.)asyncioget_event_looprun_until_complete)coros    6/mnt/e/genesis-system/tests/track_b/test_story_2_04.py_runr       s    !!#66t<<    c                  n   ddl m}  dt        dt        t           fd}dt        t           dt        t           fd}dt        dt        t           fd	}t        j                  | d
|      5  t        j                  | d|      5  t        j                  | d|      5  t        | j                  ddgdd            }ddd       ddd       ddd       t        t              }|s-t        j                  dt        |             dz   dt        j                         v st        j                   t              rt        j"                  t              nddt        j                         v st        j                   |      rt        j"                  |      nddt        j                         v st        j                   t              rt        j"                  t              ndt        j"                  |      dz  }t%        t        j&                  |            d}|j(                  }d}||u}|st        j*                  d|fd||f      dt        j                         v st        j                   |      rt        j"                  |      ndt        j"                  |      t        j"                  |      dz  }	t        j                  d      dz   d|	iz  }
t%        t        j&                  |
            dx}x}}|j,                  }d}||u}|st        j*                  d|fd ||f      dt        j                         v st        j                   |      rt        j"                  |      ndt        j"                  |      t        j"                  |      dz  }	t        j                  d!      dz   d|	iz  }
t%        t        j&                  |
            dx}x}}|j.                  }d}||u}|st        j*                  d|fd"||f      dt        j                         v st        j                   |      rt        j"                  |      ndt        j"                  |      t        j"                  |      dz  }	t        j                  d#      dz   d|	iz  }
t%        t        j&                  |
            dx}x}}d}|j(                  }|j0                  } |       }||v }|st        j*                  d$|fd%||f      t        j"                  |      dt        j                         v st        j                   |      rt        j"                  |      ndt        j"                  |      t        j"                  |      t        j"                  |      d&z  }t        j                  d'      d(z   d)|iz  }t%        t        j&                  |            dx}x}x}x}}d*}|j,                  }||v }|st        j*                  d$|fd+||f      t        j"                  |      dt        j                         v st        j                   |      rt        j"                  |      ndt        j"                  |      d,z  }	t        j                  d-      dz   d|	iz  }
t%        t        j&                  |
            dx}x}}d.}|j.                  }||v }|st        j*                  d$|fd/||f      t        j"                  |      dt        j                         v st        j                   |      rt        j"                  |      ndt        j"                  |      d,z  }	t        j                  d0      dz   d|	iz  }
t%        t        j&                  |
            dx}x}}t3        d1       y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)2zGBB1: When all 3 layers return data, MemoryContext has all 3 fields set.r   scatter_gathertask_idreturnc                    K   yw)Nz3Task: t1, Focus: redis, Hypothesis: test hypothesis r   s    r   
mock_redisz/test_bb1_all_layers_succeed.<locals>.mock_redis-   s	     D   entitiesc                    K   yw)Nu+   KG Topology:
entity_1: type — descriptionr   r   s    r   mock_kgz,test_bb1_all_layers_succeed.<locals>.mock_kg0   s	     =r   intentc                    K   yw)Nz8Learned Constraints:
Scar abc: past mistake (score=0.95)r   r    s    r   mock_qdrantz0test_bb1_all_layers_succeed.<locals>.mock_qdrant3   s	     Jr   _fetch_redis_l1side_effect_fetch_kg_l2_fetch_qdrant_l3t1redistest intent  r   target_entitiesintent_string
timeout_msNzExpected MemoryContext, got z7
>assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancectxr	   )py0py1py2py4is notz9%(py2)s
{%(py2)s = %(py0)s.working_state
} is not %(py5)sr3   r5   py5z&BB1: working_state should be populated
>assert %(py7)spy7z7%(py2)s
{%(py2)s = %(py0)s.kg_topology
} is not %(py5)sz$BB1: kg_topology should be populatedz?%(py2)s
{%(py2)s = %(py0)s.learned_constraints
} is not %(py5)sz,BB1: learned_constraints should be populated)in)zg%(py1)s in %(py9)s
{%(py9)s = %(py7)s
{%(py7)s = %(py5)s
{%(py5)s = %(py3)s.working_state
}.lower
}()
})r4   py3r;   r=   py9z+BB1: working_state should contain task dataz
>assert %(py11)spy11zKG Topology)z3%(py1)s in %(py5)s
{%(py5)s = %(py3)s.kg_topology
})r4   rA   r;   z'BB1: kg_topology should contain KG datazLearned Constraints)z;%(py1)s in %(py5)s
{%(py5)s = %(py3)s.learned_constraints
}z1BB1: learned_constraints should contain scar datau=   BB1 PASSED — all 3 fields populated when all layers succeed)core.memoryr   strr   r   r   objectr   scatter_gather_memoryr1   r	   
@pytest_ar_format_assertmsgtype@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationworking_state_call_reprcomparekg_topologylearned_constraintslowerprint)r   r   r   r#   r2   @py_assert3@py_format5@py_assert1@py_assert4@py_format6@py_format8@py_assert0@py_assert6@py_assert8@py_assert2@py_format10@py_format12s                    r   test_bb1_all_layers_succeedrc   )   s   *E# E(3- E>S	 >hsm >K# K(3- K 
n&7Z	P 		nn'	J		n&8k	R	 >77$I'	 8 
 		 	 	 c=)U)UU-I$s)+UUUUUUU:UUU:UUUUUUcUUUcUUUUUU=UUU=UUU)UUUUUURDRD(RRRDRRRRRR3RRR3RRRRRRDRRR*RRRRRRRR??N$N?$&NNN?$NNNNNN3NNN3NNN?NNN$NNN(NNNNNNNN""^$^"$.^^^"$^^^^^^3^^^3^^^"^^^$^^^0^^^^^^^^^c''^'--^-/^7//^^^7/^^^7^^^^^^c^^^c^^^'^^^-^^^/^^^1^^^^^^^^VCOOV=O+VVV=OVVV=VVVVVVCVVVCVVVOVVV-VVVVVVVV pC$;$;p $;;ppp $;ppp ppppppCpppCppp$;ppp=pppppppp	
IJ'	 	 	 	 	 	s<   +^*^ ^=^^*^^^'	"^**^4c                     ddl m}  dt        dt        t           fd}dt        t           dt        t           fd}dt        dt        t           fd	}t        j                  | d
|      5  t        j                  | d|      5  t        j                  | d|      5  t        | j                  ddgdd            }ddd       ddd       ddd       j                  }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                   d      dz   d|iz  }	t#        t        j$                  |	            dx}x}}|j&                  }d}||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                   d      dz   d|iz  }	t#        t        j$                  |	            dx}x}}|j(                  }d}||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                   d      dz   d|iz  }	t#        t        j$                  |	            dx}x}}|j*                  }d}||kD  }|st        j                  d |fd!||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                   d"      dz   d|iz  }	t#        t        j$                  |	            dx}x}}t-        d#       y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)$uY   BB2: Redis timeout → working_state=None; kg_topology and learned_constraints still set.r   r   r   r   c                 J   K   t        j                  d       d {    y7 wN
   zshould not reachr   sleepr   s    r   
slow_redisz9test_bb2_redis_timeout_partial_result.<locals>.slow_redisT         mmB! 	    #!#r   c                    K   yw)Nu3   KG Topology:
some_entity: type — some descriptionr   r   s    r   fast_kgz6test_bb2_redis_timeout_partial_result.<locals>.fast_kgX   	     Er   r    c                    K   yw)Nz5Learned Constraints:
Scar x: known issue (score=0.80)r   r"   s    r   fast_qdrantz:test_bb2_redis_timeout_partial_result.<locals>.fast_qdrant[   s	     Gr   r$   r%   r'   r(   t2entitysome intent2   r-   Nisz5%(py2)s
{%(py2)s = %(py0)s.working_state
} is %(py5)sr2   r:   u5   BB2: Redis timed out → working_state should be Noner<   r=   r7   r>   z*BB2: kg_topology should still be populatedr?   z2BB2: learned_constraints should still be populated>z1%(py2)s
{%(py2)s = %(py0)s.latency_ms
} > %(py5)sz'BB2: latency_ms must always be recordeduK   BB2 PASSED — Redis timeout → working_state=None, other fields populatedrD   r   rE   r   r   r   rF   r   rG   rQ   rH   rR   rK   rL   rM   rN   rI   rO   rP   rS   rT   
latency_msrV   )
r   rj   rn   rq   r2   rY   rZ   rW   r[   r\   s
             r   %test_bb2_redis_timeout_partial_resultr~   P   s   *"# "(3- "FS	 Fhsm FH# H(3- H 
n&7Z	P 		nn'	J		n&8k	R	 >77%J'	 8 
 		 	 	 ]]$]]]]]]]]]3]]]3]]]]]]]]]&]]]]]]]]??T$T?$&TTT?$TTTTTT3TTT3TTT?TTT$TTT(TTTTTTTT""d$d"$.ddd"$dddddd3ddd3ddd"ddd$ddd0dddddddd>>HAH>AHHH>AHHHHHH3HHH3HHH>HHHAHHHHHHHHHHH	
WX!	 	 	 	 	 	<   +Q0Q# Q=Q#Q0Q Q##Q-	(Q00Q:c                     ddl m}  dt        t           fd}t	        j
                  | d|      5  t	        j
                  | d|      5  t	        j
                  | d|      5  t        | j                  d	d
gdd            }ddd       ddd       ddd       j                  }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t!        t        j"                  |            dx}x}}|j$                  }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t!        t        j"                  |            dx}x}}|j&                  }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t!        t        j"                  |            dx}x}}|j(                  }d}||kD  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t!        t        j"                  |            dx}x}}t+        d       y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)uJ   BB3: All 3 fetches timeout → all fields None, latency_ms still recorded.r   r   r   c                 J   K   t        j                  d       d {    y7 wrf   rh   args    r   slowz)test_bb3_all_layers_timeout.<locals>.slowy   rk   rl   r$   r%   r'   r(   t3anyz
any intent   r-   Nrv   rx   r2   r:   u3   BB3: All timed out → working_state should be Noner<   r=   z3%(py2)s
{%(py2)s = %(py0)s.kg_topology
} is %(py5)su1   BB3: All timed out → kg_topology should be None)z;%(py2)s
{%(py2)s = %(py0)s.learned_constraints
} is %(py5)su9   BB3: All timed out → learned_constraints should be Nonery   r{   z5BB3: latency_ms must be > 0 even when all layers failuE   BB3 PASSED — all layers timeout → all fields None, latency_ms > 0)rD   r   r   rE   r   rF   r   rG   rQ   rH   rR   rK   rL   rM   rN   rI   rO   rP   rS   rT   r}   rV   )r   r   r2   rY   rZ   rW   r[   r\   s           r   test_bb3_all_layers_timeoutr   u   s   *"8C= " 
n&7T	J 		nn$	G		n&8d	K	 >77"G&	 8 
 		 	 	 [[$[[[[[[[[[3[[[3[[[[[[[[[&[[[[[[[[??WdW?d"WWW?dWWWWWW3WWW3WWW?WWWdWWW$WWWWWWWW""gdg"d*ggg"dgggggg3ggg3ggg"gggdggg,gggggggg>>VAV>AVVV>AVVVVVV3VVV3VVV>VVVAVVVVVVVVVVV	
QR!	 	 	 	 	 	s;   P5	P(" PP(
P5P% P((P2	-P55P?c            
         ddl m}  dt        dt        t           fd}dt        dt        t           fd}t	        j
                  | d|	      5  t	        j
                  | d
|	      5  t        | j                  dg dd            }ddd       ddd       j                  }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t!        t        j"                  |            dx}x}}|j$                  }d}||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t!        t        j"                  |            dx}x}}|j&                  }d}||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d      dz   d|iz  }t!        t        j"                  |            dx}x}}t)        d       y# 1 sw Y   xY w# 1 sw Y   xY w)uJ   BB4: Empty target_entities list → _fetch_kg_l2 returns None immediately.r   r   r   r   c                    K   yw)Nz(Task: t4, Focus: none, Hypothesis: emptyr   r   s    r   r   z=test_bb4_empty_entities_short_circuits_kg.<locals>.mock_redis   s	     9r   r    c                    K   yw)Nz3Learned Constraints:
Scar y: edge case (score=0.70)r   r"   s    r   r#   z>test_bb4_empty_entities_short_circuits_kg.<locals>.mock_qdrant   ro   r   r$   r%   r(   t4rt   r,   r-   Nrv   r   r2   r:   uG   BB4: Empty target_entities → kg_topology must be None (short-circuit)r<   r=   r7   r9   z,BB4: working_state should still be populatedr?   z2BB4: learned_constraints should still be populatedu9   BB4 PASSED — empty target_entities → kg_topology=None)rD   r   rE   r   r   rF   r   rG   rS   rH   rR   rK   rL   rM   rN   rI   rO   rP   rQ   rT   rV   )	r   r   r#   r2   rY   rZ   rW   r[   r\   s	            r   )test_bb4_empty_entities_short_circuits_kgr      s   *:# :(3- :F# F(3- F 
n&7Z	P 	n&8k	R >77'	 8 
   ?? Rd R?d" R@Q@QR?d R RKQ6R R9Q9Q  R RHQ	  R RHQ	  R RHQ	 # R R@Q@QQR R R>Q>QR RXDXD(XXXDXXXXXX3XXX3XXXXXXDXXX*XXXXXXXX""d$d"$.ddd"$dddddd3ddd3ddd"ddd$ddd0dddddddd	
EF   s$   M&L8M8M	=MMc                    
 ddl m}  g 
t        j                  
fd}dt        dt
        t           fd}dt        t           dt
        t           fd}d	t        dt
        t           fd
}t        j                  | d|      5  t        j                  | d|      5  t        j                  | d|      5  t        d|      5  t        | j                  ddgdd             ddd       ddd       ddd       ddd       t        
      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                   t              rt        j"                  t              nddt        j                         v st        j                   
      rt        j"                  
      ndt        j"                  |      t        j"                  |      dz  }t        j$                  dt        
             dz   d|iz  }	t'        t        j(                  |	            dx}x}}t+        d       y# 1 sw Y   axY w# 1 sw Y   fxY w# 1 sw Y   kxY w# 1 sw Y   pxY w) zCWB1: scatter_gather_memory() must call asyncio.gather exactly once.r   r   c                  R   K   j                  d        | i | d {   S 7 w)N   append)coroskwargsgather_call_countoriginal_gathers     r   tracking_gatherz4test_wb1_gather_called_once.<locals>.tracking_gather   s+       #$e6v6666s   '%'r   r   c                    K   ywNstater   r   s    r   r   z/test_wb1_gather_called_once.<locals>.mock_redis   	     r   r   c                    K   ywNkgr   r   s    r   r   z,test_wb1_gather_called_once.<locals>.mock_kg   	     r   r    c                    K   ywNscarsr   r"   s    r   r#   z0test_wb1_gather_called_once.<locals>.mock_qdrant   r   r   r$   r%   r'   r(   zasyncio.gatherwb1xtestr,   r-   Nr   ==z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)slenr   r3   r4   rA   py6z7WB1: asyncio.gather should be called exactly once, got 
>assert %(py8)spy8u1   WB1 PASSED — asyncio.gather called exactly once)rD   r   r   gatherrE   r   r   r   rF   r   rG   r   rH   rR   rK   rL   rM   rN   rI   rO   rP   rV   )r   r   r   r   r#   r`   @py_assert5rZ   @py_format7@py_format9r   r   s             @@r   test_wb1_gather_called_oncer      s`   *nnO7# (3- S	 hsm # (3-  
n&7Z	P 
	nn'	J
	n&8k	R
 
_	=

 	^11 E 	 2 
 	
 
 
 
  ! [Q [!Q& [ [IZIZ[!Q [ [TZTZ[ [BZBZ  [ [QZQZ  [ [TZTZ[ [BZBZ ! [ [QZQZ ! [ [QZQZ " [ [QZQZ &' [ [IZIZ
A#FWBXAYZ[ [ [GZGZ[ [ 

=>
 
 
 
 
 
 
 
sT   I+I7I I	%I-I5I+I	IIII(	#I++I5c                     ddl m}  g t        j                  fd}dt        dt
        t           fd}dt        t           dt
        t           fd}d	t        dt
        t           fd
}t        j                  | d|      5  t        j                  | d|      5  t        j                  | d|      5  t        d|      5  t        | j                  ddgd	d             ddd       ddd       ddd       ddd       t              }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                   t              rt        j"                  t              nddt        j                         v st        j                         rt        j"                        ndt        j"                  |      t        j"                  |      dz  }t        j$                  dt                     dz   d|iz  }	t'        t        j(                  |	            dx}x}}d}
t+              D ]{  \  }}||
z
  }t-        |      }d}||k  }|sSt        j                  d |fd!||f      d"t        j                         v st        j                   t,              rt        j"                  t,              nd"d#t        j                         v st        j                   |      rt        j"                  |      nd#d$t        j                         v st        j                   |
      rt        j"                  |
      nd$t        j"                  |      t        j"                  |      d%z  }	t        j$                  d&| d'|       d(z   d)|	iz  }t'        t        j(                  |            dx}x}x}}~ t/        d*       y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)+z>WB2: asyncio.wait_for must be called 3 times (once per layer).r   r   c                 T   K   j                  |        | |       d {   S 7 wNr   )r   timeoutoriginal_wait_forwait_for_callss     r   tracking_wait_forz=test_wb2_wait_for_wraps_each_fetch.<locals>.tracking_wait_for   s(     g&&tW5555s   (&(r   r   c                    K   ywr   r   r   s    r   r   z6test_wb2_wait_for_wraps_each_fetch.<locals>.mock_redis   r   r   r   c                    K   ywr   r   r   s    r   r   z3test_wb2_wait_for_wraps_each_fetch.<locals>.mock_kg   r   r   r    c                    K   ywr   r   r"   s    r   r#   z7test_wb2_wait_for_wraps_each_fetch.<locals>.mock_qdrant   r   r   r$   r%   r'   r(   zasyncio.wait_forwb2yd   r-   N   r   r   r   r   r   z4WB2: asyncio.wait_for should be called 3 times, got r   r   g?g&.>)<)z;%(py5)s
{%(py5)s = %(py0)s((%(py1)s - %(py2)s))
} < %(py8)sabstexpected_timeout_s)r3   r4   r5   r;   r   zWB2: wait_for call z has wrong timeout: z
>assert %(py10)spy10uM   WB2 PASSED — asyncio.wait_for called 3 times with correct per-fetch timeout)rD   r   r   wait_forrE   r   r   r   rF   r   rG   r   rH   rR   rK   rL   rM   rN   rI   rO   rP   	enumerater   rV   )r   r   r   r   r#   r`   r   rZ   r   r   r   ir   rW   @py_assert7r^   @py_format11r   r   s                    @@r   "test_wb2_wait_for_wraps_each_fetchr      s   *N((6# (3- S	 hsm # (3-  
n&7Z	P 
	nn'	J
	n&8k	R
 
!/@	A

 	^11 E"	 2 
 	
 
 
 
 ~ U! U!# U UCTCTU! U UNTfU U<T<T  U UKT9  U UNTfU U<T<T  U UKT9  U UKT9  U UKT9 #$ U UCTCT
>s>?R>STU U UATATU U &.) =1)) 	=s)* 	=T 	=*T1 	= 	=+<+<	=*T 	= 	=6<f	= 	=$<$<  	= 	=3<9  	= 	=6<f	= 	=$<$<  	= 	=3<9  	= 	=6<f	= 	=$<$< * 	= 	=3<9 * 	= 	=3<9 + 	= 	=3<9 .2 	= 	=+<+<!!$8<	= 	= 	=)<)<	= 	= 	== 

YZ+
 
 
 
 
 
 
 
sT   O7O*7O O	%O-O*5O7OOO'"O**O4	/O77Pc                  h   ddl m}  dt        t           fd}t	        j
                  | d|      5  t	        j
                  | d|      5  t	        j
                  | d|      5  t        | j                  d	g d
d            }ddd       ddd       ddd       j                  }d}||kD  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  d|j                         dz   d|iz  }t!        t        j"                  |            dx}x}}|j                  }t%        |t&              }	|	sKt        j                  dt)        |j                               dz   dt        j                         v st        j                  t$              rt        j                  t$              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  t&              rt        j                  t&              ndt        j                  |	      dz  }
t!        t        j"                  |
            dx}}	t+        d|j                  dd       y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)z8WB3: latency_ms is always > 0 (real wall-clock elapsed).r   r   r   c                    K   y wr   r   r   s    r   instant_nonez6test_wb3_latency_always_positive.<locals>.instant_none  r   r   r$   r%   r'   r(   wb3 r,   r-   Nry   r{   r2   r:   z(WB3: latency_ms must always be > 0, got r<   r=   z%WB3: latency_ms must be a float, got zW
>assert %(py6)s
{%(py6)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.latency_ms
}, %(py4)s)
}r1   float)r3   r4   rA   r6   r   u   WB3 PASSED — latency_ms=z.3fzms (always positive))rD   r   r   rE   r   rF   r   rG   r}   rH   rR   rK   rL   rM   rN   rI   rO   rP   r1   r   rJ   rV   )r   r   r2   rY   rZ   rW   r[   r\   r`   r   r   s              r    test_wb3_latency_always_positiver     s   *8C=  
n&7\	R 		nn,	O		n&8l	S	 >77	 8 
 		 	 	 >> DA D>A D2C2CD>A D D=CVD D+C+C  D D:C)  D D:C)  D D:C)  D D2C2C
23>>2BCD D D0C0CD Dnn G:ne, G, G5F5F
/S^^0D/EFG G@FG G.F.F  G G=FY  G G@FG G.F.F  G G=FY  G G=FY % G G@FG G.F.F ', G G=FY ', G G=FY - G G G3F3FG G 
&s~~c&::N
OP!	 	 	 	 	 	s;   L'	L"LL	L'LLL$	L''L1c                     ddl m}  dt        dt        t           fd}dt        t           dt        t           fd}dt        dt        t           fd	}t        j                  | d
|      5  t        j                  | d|      5  t        j                  | d|      5  t        | j                  ddgdd            }ddd       ddd       ddd       j                  }d}||u }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                   d      dz   d|iz  }	t#        t        j$                  |	            dx}x}}|j&                  }d}||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                   d      dz   d|iz  }	t#        t        j$                  |	            dx}x}}|j(                  }d}||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                   d      dz   d|iz  }	t#        t        j$                  |	            dx}x}}|j*                  }d}||kD  }|st        j                  d |fd!||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                   d"      dz   d|iz  }	t#        t        j$                  |	            dx}x}}t-        d#       y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)$uH   WB4: One layer raises an exception → other two fields still populated.r   r   r   r   c                     K   t        d      w)NzRedis connection refused)RuntimeErrorr   s    r   raising_redisz<test_wb4_partial_failure_valid_return.<locals>.raising_redis0  s     566s   r   c                    K   yw)Nu1   KG Topology:
good_entity: GoodType — works finer   r   s    r   good_kgz6test_wb4_partial_failure_valid_return.<locals>.good_kg3  s	     Cr   r    c                    K   yw)Nz;Learned Constraints:
Scar z: something learned (score=0.85)r   r"   s    r   good_qdrantz:test_wb4_partial_failure_valid_return.<locals>.good_qdrant6  s	     Mr   r$   r%   r'   r(   wb4rs   r+   r,   r-   Nrv   rx   r2   r:   u2   WB4: Redis raised → working_state should be Noner<   r=   r7   r>   u5   WB4: KG succeeded → kg_topology should be populatedr?   uA   WB4: Qdrant succeeded → learned_constraints should be populatedry   r{   z&WB4: latency_ms must still be recordeduP   WB4 PASSED — partial failure (1/3) returns valid MemoryContext with 2/3 fieldsr|   )
r   r   r   r   r2   rY   rZ   rW   r[   r\   s
             r   %test_wb4_partial_failure_valid_returnr   ,  s   *7S 7Xc] 7DS	 Dhsm DN# N(3- N 
n&7]	S 		nn'	J		n&8k	R	 >77%J'	 8 
 		 	 	  = =$ =+<+<= = =6<f= =$<$<  = =3<9  = =3<9  = =3<9 !% = =+<+<<= = =)<)<= =?? @$ @?$& @.?.?@?$ @ @9?@ @'?'?  @ @6?i  @ @6?i  @ @6?i #' @ @.?.??@ @ @,?,?@ @"" L$ L"$. L:K:KL"$ L LEKVL L3K3K  L LBK)  L LBK) # L LBK) +/ L L:K:KKL L L8K8KL L>>GAG>AGGG>AGGGGGG3GGG3GGG>GGGAGGGGGGGGGGG	
\])	 	 	 	 	 	r   __main__z<============================================================u,   Story 2.04 — scatter_gather_memory() Testsu+   ALL 8 TESTS PASSED — Story 2.04 (Track B))"__doc__builtinsrK   _pytest.assertion.rewrite	assertionrewriterH   r   systimepathlibr   typingr   r   unittest.mockr   r   r   pathinsert!core.memory.zero_amnesia_enveloper	   r   rc   r~   r   r   r   r   r   r   __name__rV   r   r   r   <module>r      s      
   ! 5 5 * + ;= KNYJS>G@#?T)[`Q<!^P z	(O	
89	(O!)+!-/!&($&)+	(O	
78	(O! r   