+
    jHàjc>  ã                  ó¢   € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHtH	t	H
t
Ht ^ RIHt ^ RIHt ]P                   ! R4      t^t ! R R4      tR# )	aî  Completion ownership for GatewayRunner: the session a pinned completion belongs to.

Split out of ``gateway/run_notifications.py`` (itself split out of ``gateway/run.py``); bound onto
``GatewayRunner`` through ``GatewayNotificationsMixin``. A completion may be pinned to a delegate
child's execution transcript: ownership follows only ``model_config._delegate_from`` to the
human-facing session, shared by delivery preflight and route resolution, and no route moves until
that owner is proven.
)ÚannotationsN)ÚAnyÚOptionalÚSequenceÚcast)ÚSessionEntry)ÚStateDbReplacedErrorzgateway.runc                  ór   € ] tR t^ tRtR R ltR R ltRR R lltRR	/R
 R lltRR R llt	R R lt
RtR# )Ú!GatewayNotificationOwnershipMixinzNOwnership proof and route resolution for pinned async and process completions.c               ó(   € V ^8„  d   QhRRRRRRRR/# )	é   Ú
session_dbr   Úsession_entryúOptional[SessionEntry]Úpinned_session_idÚstrÚreturnztuple[str, Optional[str]]© )Úformats   "ÚH/home/ubuntu/.hermes/hermes-agent/gateway/run_notifications_ownership.pyÚ__annotate__Ú.GatewayNotificationOwnershipMixin.__annotate__#   s,   € ÷  ñ  Øð Ø.Dð ØY\ð à	"ñ ó    c              ƒ  óæ  "  €  VP                  V4      G Rj  x€L
 pV'       d   WC8X  d   R
# VP                  V4      G Rj  x€L
 pVe   VP                  R4      '       d   R
# Ve   VP                  W409   d   RV3# VP                  VP                  4      G Rj  x€L
 pVf   R
# VP                  R4      '       d^   VP                  R4      R8X  dH   VP                  VP                  4      G Rj  x€L
 pV'       d   WrP                  8X  d   R
# Wt8X  d   RV3# \
        P                  R	Y4TP                  4       R#  EL% Lþ L¦ LR  \         d    \
        P                  RTRR7       R
u # i ; i5i)zHDistinguish uncertain compression ownership from a proven foreign route.NÚended_atÚdeliverÚ
end_reasonÚcompressionz;Async-delegation compression ownership lookup failed for %sT©Úexc_infozoAsync-delegation completion for compression lineage %s -> %s does not own current route %s; dropping injection.)ÚretryN)ÚterminalN)Úget_compression_tipÚget_sessionÚgetÚ
session_idÚ	ExceptionÚloggerÚdebugÚwarning)Úselfr   r   r   Útarget_session_idÚtip_rowÚ	route_rowÚ	route_tips   &&&&    r   Ú#_resolve_compression_lineage_targetÚEGatewayNotificationOwnershipMixin._resolve_compression_lineage_target#   sk  é € ð	!Ø&0×&DÑ&DÐEVÓ&W× WÐß$Ð(9Ô(NØ$Ð$Ø&×2Ñ2Ð3DÓE×EˆGØŠ '§+¡+¨j×"9Ò"9Ø$Ð$ØÒ$¨×(@Ñ(@ÐEVÐDjÔ(jØ Ð"3Ð3Ð3à(×4Ñ4°]×5MÑ5MÓN×NˆIØÒ Ø$Ð$Ø�}‰}˜Z×(Ò(¨Y¯]©]¸<Ó-HÈMÔ-YØ",×"@Ñ"@À×AYÑAYÓ"Z×Z�	ß  I×1IÑ1IÔ$IØ(Ð(ØÔ1Ø$Ð&7Ð7Ð7ô 	�‰ðAà°-×2JÑ2Jô	
ð
  Ðò5 !Xñ Fñ Oñ [øô
 ô 	!Ü�L‰LÐVÐXiÐtxˆLÔyØ Ò ð	!üs¿   ‚E1„E ˜D=™E ¥E ¬E1­E ÁE ÁE Á!E Á"E1Á#E Á<E1Á=E ÂEÂ	E Â%E1Â&E Â=4E Ã1EÃ2E Ã>E ÄE1Ä	E Ä$E1Ä=E Å E ÅE ÅE Å%E.Å+E1Å-E.Å.E1c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# )
r   r   r   Úentryr   r   r   Ú
pinned_rowzOptional[dict]r   r   )r   s   "r   r   r   D   s4   € ÷ ñ ØðØ&<ðØQTðØbpðà	ñr   c              ƒ  ó   "  € ^ RI Hp Ve    VP                  VP                  8w  g   Vf   R# Y4rvVP	                  R4      R8X  dF    VP                  V4      G Rj  x€L
 pWbP                  8X  d   VP                  V4      G Rj  x€L
 MRpWbP                  8w  g2   Ve.   VP	                  R	4      '       d   VP	                  R4      R8X  d   R# V#  Lt LM  \        P                  \        3 d    \        P                  RTRR7        R# i ; i5i)
a   The closed (/new, exit) physical session of a local conversation a completion is noted on
(#134889 LC-7, ``session_completion_notes``), else ``""``. The pinned session, or the compression
tip it rotated to, must be the one the conversation's route still names: a local /new opens a new
route, so the replacement never matches, and messaging routes never qualify. Only a close ends a
local tip (``session.detach {end_reason}`` stamps the client's own reason: ``cli_close``,
``tui_close``, ``tui_shutdown``...), so any end but compression is one.)ÚPlatformNÚ r   r   z%Closed local tip lookup failed for %sTr   r   )Úgateway.configr5   ÚplatformÚLOCALr$   r"   r%   r#   Úsqlite3ÚErrorr   r'   r(   )r*   r   r2   r   r3   r5   ÚtargetÚrows   &&&&&   r   Ú_closed_local_targetÚ6GatewayNotificationOwnershipMixin._closed_local_targetD   së   é € õ 	,ØŠ=˜EŸN™N¨h¯n©nÔ<À
Ò@RÙØ'�Ø�7‰7�<Ó  MÔ1ðØ)×=Ñ=Ð>OÓP×P�Ø>D×HXÑHXÔ>X˜J×2Ñ2°6Ó:×:Ð:Ð^b�ð ×&Ñ&Ô&¨#ª+¸S¿W¹WÀZ×=PÒ=PØ—7‘7˜<Ó(¨MÔ9ÙØˆñ QÙ:øÜ—M‘MÔ#7Ð8ô Ü—‘ÐDÐFWÐbf�ÔgÚðüsT   ‚ADÁC ÁCÁ(C ÂCÂC Â*DÂ6DÃC ÃC Ã3DÄDÄ
DÄDc               ó    € V ^8„  d   QhRRRR/# )r   r%   r   Úcurrent_session_idr   )r   s   "r   r   r   ]   s   € ÷ .,ñ .,¸ð .,ÐRUñ .,r   c              ƒ  ó   "  € ^ RI Hp \        \        V 4      P                  pVf   RVR3# \        4       p\        \        ^,           4       EFW  pW9   d   RVR3u # VP                  V4        VP                  V4      G Rj  x€L
 pTf   RTR3u # TP                  R4      '       d   TP                  R	4      T9   d   RY3u # Y8X  d   R
Y3u # TP                  R4      p \        T\        4      '       d   \         P"                  ! T4      pTf   / p\        T\(        4      '       g   RTR3u # RT9  d!   TP                  R4      R8X  d   RMR
p	Y‘T3u # TR,          p
\        T
\        4      '       d"   T
P+                  4       '       d   T\        8X  d   RTR3u # T
pEKZ  	  RVR3#  EL*  \         d#    \        P                  RTRR7       RTR3u u # i ; i  \$        \&        3 d    RTR3u u # i ; i5i)a  Nonmutating delegation proof shared by preflight and route resolution.

A current route is an explicit ownership boundary, not a route to repair.
Generic parent pointers also describe compression and branches; only
``_delegate_from`` authorizes walking out of an execution transcript.
©Ú_USER_BOUNDARY_END_REASONSNr    r!   z)Completion ownership lookup failed for %sTr   r   r   r   Úmodel_configÚ_delegate_fromÚsourceÚsubagent)Úgateway.runrD   r   r   Ú_session_dbÚsetÚrangeÚ_MAX_DELEGATE_PROVENANCE_HOPSÚaddr#   r&   r'   r(   r$   Ú
isinstancer   ÚjsonÚloadsÚ	TypeErrorÚ
ValueErrorÚdictÚstrip)r*   r%   rA   rD   r   ÚseenÚhopsr=   ÚconfigÚverdictÚparents   &&&        r   Ú_lookup_completion_ownerÚ:GatewayNotificationOwnershipMixin._lookup_completion_owner]   sô  é € õ 	;Üœ#˜t“_×0Ñ0ˆ
ØÒØ˜J¨Ð,Ð,Ü‹uˆÜÔ7¸!Õ;×<ˆDØÔ!Ø! :¨tÐ3Ò3Ø�H‰H�ZÔ ð1Ø&×2Ñ2°:Ó>×>�ð Š{Ø! :¨tÐ3Ò3ð �w‰w�z×"Ò" s§w¡w¨|Ó'<Ð@ZÔ'ZØ! :Ð2Ò2ØÔ/Ø  *Ð1Ò1Ø—W‘W˜^Ó,ˆFð4Ü˜f¤c×*Ò*Ü!ŸZšZ¨Ó/�Fð Š~Ø�Ü˜f¤d×+Ò+Ø! :¨tÐ3Ò3Ø vÔ-Ø(+¯©°Ó(9¸ZÔ(G™*ÈY�Ø¨CÐ/Ò/ØÐ,Õ-ˆFÜ˜f¤c×*Ò*°&·,±,·.².ÀDÔLiÔDiØ! :¨tÐ3Ò3Ø‹JñC =ðD ˜: tÐ+Ð+ò; ?øÜô 1Ü—‘ÐHÈ*Ð_c�ÔdØ 
¨DÐ0Ô0ð1ûô œzÐ*ô 4Ø! :¨tÐ3Ô3ð4üsm   ‚A,G>Á/F0ÂF-ÂF0Â!G>Â*9G>Ã$,G ÄA>G>ÆG>Æ-F0Æ0(GÇG>ÇGÇG>Ç G;Ç6G>Ç:G;Ç;G>ÚlogTc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   ÚevtrT   Úrefusalr   r]   Úboolr   r   )r   s   "r   r   r   �   s)   € ÷ ñ ¨ð ¸ð ÀTð ÐUYñ r   c          
   ƒ  óF  "  € \        VP                  R4      ;'       g    R4      P                  4       pV'       g   R# \        VP                  R4      ;'       g    R4      p\        \        V 4      P                  WE4      G Rj  x€L
 w  rgpVR8w  d   R# V'       g   R# \        P                  RVP                  R	4      ;'       g    R
VP                  R4      ;'       g    RT\        \        V 4      P                  P                  V4      ;'       g    RV4       R#  L™5i)að  True (logged once with ``log``) when a refused notice is pinned to a permanently-gone session.

The session authority admits a notice only into its pinned session or that session's
compression continuation, so after /new it refuses the notice on every retry and the drain
would spin on it (#141562). This is the completion pre-flight's verdict, applied after the
refusal. A dropped notice is gone for good; a /resume reopens the pinned session, so the
process's later notices are admitted again.
Úparent_session_idr6   FÚsession_keyNr!   TzíDropping %s notification of process %s: pinned session %s is permanently gone (closed at a user boundary such as /new, or no longer an owner); the route now runs %s and refuses it (%s). Output remains available via process(action='log').ÚtypeÚwatchr%   z	<unknown>z<none>)
r   r$   rU   r   r   Ú_classify_completion_ownerr'   r)   Úsession_storeÚpeek_session_id)	r*   r_   r`   r]   Úpinnedrd   rY   Ú_ownerÚ_targets	   &&&$     r   Ú_watch_pin_goneÚ1GatewayNotificationOwnershipMixin._watch_pin_gone�   sé   é € ô �S—W‘WÐ0Ó1×7Ð7°RÓ8×>Ñ>Ó@ˆßÙÜ˜#Ÿ'™' -Ó0×6Ð6°BÓ7ˆÜ)-¬c°4«×)SÑ)SÐTZÓ)h×#hÑ ˆ˜Ø�jÔ ÙßÙÜ�‰ðSð �G‰G�F‹O×&Ð&˜w¨¯©°Ó(=×(LÐ(LÀÈfÜ”�d‹O×)Ñ)×9Ñ9¸+ÓF×RÐRÈ(ÐT[ô	
ñ ñ $iùs4   ‚:D!½D!Á)D!ÂDÂD!Â)D!ÃD!Ã"2D!ÄD!c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   r   r   r   r   Úproven_session_idÚcompletion_idsúSequence[str]r   r   r   )r   s   "r   r   r   ¨   s=   € ÷ ^ñ ^Ø)ð^Ø>Að^ØVYð^à%ð^ð 
 ñ^r   c              ƒ  ój  "  € ^ RI Hp \        \        V P                  4      pVf   \
        P                  R4       R# V'       d   W1P                  8X  d   V# V P                  VP                  4      pV P                  W!P                  4      G Rj  x€L
 w  r‚p	VR8w  g   V	f   V P                  W„4      G Rj  x€L
 # Tp
RpV	P                  R4      '       d¹   \        V	P                  R4      ;'       g    R4      pWÅ9   d   \
        P                  R	W,4       R# VR
8w  d.   \
        P                  RT;'       g    RW!P                  4       V# RpV P                  WaV4      G Rj  x€L
 w  rŠVR8w  g   V
f   V P                  W„4      G Rj  x€L
 # W¡P                  8X  d   V# VP                  pV P!                  VP                  V4      '       g$   \
        P                  RVP                  W-4       R# V'       d0   V P"                  P%                  VP                  WÚ4      G Rj  x€L
 pM/V P"                  P'                  VP                  W­R7      G Rj  x€L
 pVf$   \
        P                  RVP                  V
4       R# \
        P                  RW­VP                  4       V#  EL ELî ELD EL! LŠ L\5i)u
  Resolve an async completion to its verified owning gateway session.

Follow compression-rotation lineage (parent row ended, child continues), but never let a
late completion override an unrelated /new or restored route. Unknown ownership fails
closed; the result stays in the delegation records. An owner that cannot be confirmed right
now (``retry``) sends the completions admitted with the event back to the delivery queue.

A pinned *delegate* row is likewise canonicalized to its human-facing parent through
``model_config._delegate_from`` before any route check or mutation (#92611). Unresolvable
provenance â€” a cycle, a missing parent, a malformed config, or a chain longer than
``_MAX_DELEGATE_PROVENANCE_HOPS`` â€” drops the injection rather than falling back to the
current route entry. That is deliberate: routing an internal child's output into a session
whose ownership was never verified is the same class of defect this canonicalization fixes,
and the completion remains readable in the delegation records either way.
rC   Nz]Async-delegation completion has no session database; dropping injection (#55578 fail-closed).r   Fr   r   r6   z‘Async-delegation completion pinned to user-closed session %s (end_reason=%r); dropping injection instead of resurrecting it (#55578 fail-closed).r   zhAsync-delegation completion pinned to %s-ended session %s; retargeting to the chat's current session %s.ÚidleTz‘Async-delegation completion for routing key %s was invalidated while resolving pinned session %s; leaving the route on %s and dropping injection.)Úexpected_session_idz|Async-delegation completion could not bind routing key %s to owning session %s (route moved or unknown); dropping injection.z\Pinned async-delegation completion to owning session %s (was %s) for routing key %s (#57498))rI   rD   r   r   rJ   r'   r)   r%   Ú_current_session_run_generationrd   r[   Ú_requeue_uncertain_completionr$   r   Úinfor/   Ú_is_session_run_currentÚasync_session_storeÚadvance_compression_sessionÚswitch_session)r*   r   r   rp   rq   rD   r   Úrun_generationrY   r3   r+   Úfollows_compressionÚ_end_reasonÚprior_session_idÚswitcheds   &&&&&          r   Ú!_resolve_async_delegation_sessionÚCGatewayNotificationOwnershipMixin._resolve_async_delegation_session¨   sž  é € õ& 	;Üœ#˜t×/Ñ/Ó0ˆ
ØÒÜ�N‰Nð;ôñ ßÐ!2×6NÑ6NÔ!Nà Ð à×=Ñ=¸m×>WÑ>WÓXˆØ7;×7TÑ7TØ×7Ñ7ó8
÷ 2
Ñ.ˆ Jð �iÔ :Ò#5Ø×;Ñ;¸GÓT×TÐTØ-ÐØ#ÐØ�>‰>˜*×%Ò%Ü˜jŸn™n¨\Ó:×@Ð@¸bÓAˆKØÔ8Ü—‘ð,à->ôñ
 Ø˜mÔ+ô —‘ðDà×)Ð) 6Ð+<×>VÑ>Vôð
 %Ð$Ø"&ÐØ/3×/WÑ/WØÐ+<ó0÷ *Ñ&ˆGð ˜)Ô#Ð'8Ò'@Ø!×?Ñ?ÀÓX×XÐXØ× 8Ñ 8Ô8Ø Ð Ø(×3Ñ3ÐØ×+Ñ+¨M×,EÑ,EÀ~×VÒVÜ�N‰NðNà×)Ñ)Ð+<ôñ
 ßØ!×5Ñ5×QÑQØ×)Ñ)Ð+;ó÷ ‰Hð "×5Ñ5×DÑDØ×)Ñ)Ð+<ð Eó ÷ ˆHð ÒÜ�N‰NðRà×)Ñ)Ð+<ôñ
 Ü�‰ØjØ°×1JÑ1Jô	
ð ˆò}2
ò Uò,*ò Yññùs”   ‚AJ3ÁAJ3ÂJ#Â&J3Â8J&Â9J3ÃJ3Ã5AJ3Ä:+J3Å%J)Å&%J3ÆJ,ÆAJ3Ç*J3Ç;)J3È$J/È%/J3ÉJ1ÉAJ3Ê&J3Ê)J3Ê,J3Ê/J3Ê1J3c               ó$   € V ^8„  d   QhRRRRRR/# )r   rY   r   rq   rr   r   ÚNoner   )r   s   "r   r   r     s#   € ÷ ñ ¸3ð ÐP]ð Ðbfñ r   c              ƒ  ó  "  € VR8w  g	   V'       g   R# ^ RI Hp ^ RIHp \	        \
        V 4      pVP                  ;_uu_ 4        V F"  pVP                  P                  RVR3R4       K$  	  RRR4       V FN  p \        P                  ! W6VP                  4      G Rj  x€L
 p\        P                  RTV'       d   RMR4       KP  	  R#   + '       g   i     Lf; i L>  \         d    \        P                  RTRR	7       R
p Lci ; i5i)z¦Offer admitted completions again when the turn could not confirm their owner (``retry``),
so the next delivery re-runs the pre-flight; boundary verdicts stay dropped.r    N)Úrequeue_admitted_completion)Úprocess_registryÚasync_delegationr6   z(Could not requeue admitted completion %sTr   FzHAsync-delegation completion %s: owner not confirmed after admission; %s.zoffered againz,not offered again (result remains queryable))Útools.async_delegationr‡   Útools.process_registryrˆ   r   r   Ú_completion_delivery_lockÚ _completion_deliveries_deliveredÚpopÚasyncioÚ	to_threadÚcompletion_queuer&   r'   r(   r)   )r*   rY   rq   r‡   rˆ   ÚrunnerÚdelegation_idÚrequeueds   &&&     r   rw   Ú?GatewayNotificationOwnershipMixin._requeue_uncertain_completion  sç   é € ð �gÔ§^ÙÝFÝ;Ü”c˜4“ˆØ×-×-Ó-Û!/�Ø×7Ñ7×;Ñ;Ð=OÐQ^Ð`bÐ<cÐeiÖjñ "0÷ .ó ,ˆMð!Ü!(×!2Ò!2Ø/Ð@P×@aÑ@aó"c÷ c�ô
 �N‰NØZÐ\iß#+‘Ð1_öó ,÷ .×-úñ
cøäô !Ü—‘ÐGÈÐae�ÔfØ ’ð!üs^   ‚D’2DÁ)CÁ-DÁ;$C ÂCÂ C Â$DÂ=DÃC	ÃDÃC Ã %DÄDÄDÄDr   N)r6   )r6   r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r/   r>   r[   rm   r‚   rw   Ú__static_attributes__r   r   r   r
   r
       s3   † ÙXõ õB÷2.,ð`ÈD÷ ÷6^÷@ñ r   r
   )rš   Ú
__future__r   r�   rP   Úloggingr:   Útypingr   r   r   r   Úgateway.sessionr   Úhermes_state_errorsr   Ú	getLoggerr'   rM   r
   r   r   r   Ú<module>r¢      sM   ðñõ #ã Û Û Û ß 0Ó 0å (Ý 4ð 
×	Ò	˜=Ó	)€ð !#Ð ÷}ó }r   