+
    jHàj~©  ã                  ó<  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RI	H
t
 ^ RIt^ RIHtHtHt ^ RIHt ^ RIHtHtHt ^ RIHt R	 tR
 tR tREtRFtR R lt^t]P>                  ! R4      t RGR R llt!R R lt"]#! 4       t$R]%R&   R R lt&]#! 4       t'R]%R &   R! R" lt(R# R$ lt)R% R& lt* ! R' R(4      t+R) R* lt,R+ R, lt-R- R. lt.R/t/R0 R1 lt0R2 R3 lt1R4 R5 lt2R6 R7 lt3R8 R9 lt4R: R; lt5R< R= lt6R]1RR> R]5RR? R]6RR@ R]2R]3R]4/	t7RA]%RB&    ! RC RD4      t8R# )Ha  Kanban notifier: claim terminal task events per subscription and deliver them.

``GatewayKanbanWatchersMixin._kanban_notifier_watcher`` owns the loop and
the GC cadence; the per-tick claim (``_notifier_collect``) and the
per-subscription delivery (``_KanbanNotification``) live here.
)ÚannotationsN)Úpartial)ÚPath)ÚAnyÚCallableÚOptional)Út)Ú_list_boardsÚ_to_thread_process_serviceÚlogger)Úsession_owned_by_profilec                 ó   € ^ RI Hp  V # )é    ©Úkanban_db_connect)Ú
hermes_clir   r   s    ÚE/home/ubuntu/.hermes/hermes-agent/gateway/kanban_watchers_notifier.pyÚ_kbcr      s   € Ý,ØÐó    c                 ó   € ^ RI Hp  V # )r   ©Úkanban_db_notify)r   r   r   s    r   Ú_kbnr      s   € Ý+ØÐr   c                 ó.   € ^ RI Hp  V P                  4       # )u>  Machine-flow board resolution: env pins outrank the enumerated slug.

The slug here came from ``list_boards()``, not from a user â€” on a box whose
env pins ``HERMES_KANBAN_DB`` every board must resolve to the pinned file
or the notifier reads per-slug DBs nobody writes (see
``kanban_db.pin_first_board_resolution``).©Ú	kanban_db)r   r   Úpin_first_board_resolutionr   s    r   Ú
_pin_firstr   "   s   € õ %Ø×/Ñ/Ó1Ð1r   Ú	completedÚblockedÚgave_upÚcrashedÚ	timed_outÚstatusÚblock_loop_detectedÚreview_requestedÚchanges_requestedc               ó   € V ^8„  d   QhRR/# ©é   ÚreturnÚbool© )Úformats   "r   Ú__annotate__r.   5   s   € ÷ ]ñ ]˜Dñ ]r   c                ó  € V P                   R9   d   R# V P                   R9   d)   V P                  ;'       g    / P                  R4      R8g  # V P                   R8H  ;'       d)    V P                  ;'       g    / P                  R4      R9   # )zEInfrastructure attention is distinct from an explicit owner decision.TÚkindÚneeds_inputr#   >   r!   r    r"   >   r   r$   >   Útriager   )r0   ÚpayloadÚget)Úevs   &r   Údiagnostic_eventr6   5   su   € à	‡w�wÐ5Ô5ÙØ	‡w�wÐ4Ô4Ø—
‘
× Ð ˜b×%Ñ% fÓ-°Ñ>Ð>Ø�7‰7�hÑ×\Ð\ B§J¡J×$4Ð$4°"×#9Ñ#9¸(Ó#CÐG\Ñ#\Ð\r   zY(?<![\w:/])(?:/(?:Users|home|private|tmp|var|etc|workspace)/[^\s,;]+|[A-Za-z]:\\[^\s,;]+)c               ó$   € V ^8„  d   QhRRRRRR/# )r)   Úvaluer   ÚlimitÚintr*   Ústrr,   )r-   s   "r   r.   r.   P   s!   € ÷ ñ ˜sð ¨3ð ¸ñ r   c                ó  € ^ RI Hp T! V f   RM
\        V 4      RRR7      pRP                  \        P                  RV4      P                  4       4      p\        V4      V8”  d"   VRV^,
           P                  4       R,           pV# )	zBReturn a mobile-friendly review reason safe for external delivery.)Úredact_sensitive_textNÚ T)ÚforceÚredact_url_credentialsÚ z[local path]u   â€¦)	Úagent.redactr=   r;   ÚjoinÚ_LOCAL_PATH_REÚsubÚsplitÚlenÚrstrip)r8   r9   r=   Úreasons   &&  r   Ú_safe_review_reasonrJ   P   sq   € å2á"¨ª¡2¼CÀ»JÈdÐkoÔp€FØ�X‰X”n×(Ñ(¨¸Ó@×FÑFÓHÓI€FÜ
ˆ6ƒ{�UÔØ˜˜% !�)Ð$×+Ñ+Ó-°Õ5ˆØ€Mr   c               ó$   € V ^8„  d   QhRRRRRR/# )r)   Úadapterr   rE   Údictr*   úOptional[str]r,   )r-   s   "r   r.   r.   [   s!   € ÷ /ñ /˜Cð / dð /¨}ñ /r   c                óò  € VP                  R4      p\        V\        4      '       d0   R	 F)  pVP                  V4      pV'       g   K  \        V4      u # 	  \	        V RR4      p\        V4      '       g   R#  T! \        VP                  R4      ;'       g    R4      4      pT'       d   \        T4      # R#   \         d5   p\        P                  ! RTP                  R4      TRR7        Rp?R# Rp?ii ; i)
u›  Return the tenant scope (Slack workspace) a subscription's wake keys to.

``build_session_key()`` includes ``scope_id`` on multi-tenant platforms,
so the wake must carry the same scope as inbound messages. Persisted
``delivery_metadata`` wins (it records the creating scope); the adapter's
live chat â†’ scope map only covers rows without metadata. ``None`` means
unscoped, matching an unscoped platform's key.
Údelivery_metadataÚscope_id_for_chatNÚchat_idr>   z4kanban notifier: scope lookup failed for chat %s: %sT)Úexc_info)Úscope_idÚguild_idÚslack_team_idÚteam_id)	r4   Ú
isinstancerM   r;   ÚgetattrÚcallableÚ	Exceptionr   Údebug)rL   rE   Údelivery_metaÚkeyr8   ÚresolverÚresolvedÚexcs   &&      r   Ú_wake_scope_idrb   [   sÕ   € ð —G‘GÐ/Ó0€MÜ�-¤×&Ò&ÛGˆCØ!×%Ñ% cÓ*ˆEß‰uÜ˜5“zÒ!ñ Hô �wÐ 3°TÓ:€HÜ�H×ÒÙðÙœC §¡¨	Ó 2× 8Ð 8°bÓ9Ó:ˆ÷
 %Œ3ˆx‹=Ð.¨$Ð.øô	 ô ä�ŠÐKÈSÏWÉWÐU^ÓM_ÐadÐosÕtÝûðús   Á8B7 ÂB7 Â7C6Ã)C1Ã1C6z
set[tuple]Ú_ANCHORLESS_WARNEDc               ó$   € V ^8„  d   QhRRRRRR/# )r)   rE   rM   Úplatformr;   r*   ÚNoner,   )r-   s   "r   r.   r.   y   s!   € ÷ ñ ¨$ð ¸#ð À$ñ r   c                óD  € V P                  R4      ;'       g    / p\        V P                  R4      4      ;'       g.    V P                  R4      ;'       g    VP                  R4      R
9   pV'       d   VP                  R4      '       d   R# V P                  R4      YP                  R4      V P                  R4      ;'       g    R3pV\        9   d   R# \        P                  V4       \        P
                  ! R	V P                  R4      WP                  R4      4       R# )u  A thread-shaped subscription without ``parent_chat_id`` cannot match a channel-level
``profile_routes`` entry, so the fail-closed route gate skips it on every tick. Say so ONCE per
row at WARNING â€” a subscription that can never deliver was invisible below DEBUG (#110919).rP   Ú	thread_idÚ	chat_typeÚparent_chat_idNÚtask_idrR   r>   z÷kanban notifier: subscription for %s on %s thread %s has no parent_chat_id anchor and matched no profile route; it will not be delivered. Re-subscribe with `hermes kanban notify-subscribe ... --parent-chat-id <channel id> [--guild-id <guild id>]`.>   ÚforumÚtopicÚthreadÚ
forum_postú
forum-post)r4   r+   rc   Úaddr   Úwarning)rE   re   ÚmetadataÚthread_liker^   s   &&   r   Ú _warn_anchorless_thread_sub_onceru   y   sî   € ð �w‰wÐ*Ó+×1Ð1¨r€HÜ�s—w‘w˜{Ó+Ó,÷ @ð @°·±¸Ó1E×1bÐ1bÈÏÉÐVaÓIbð h@ñ 1@€Kç˜(Ÿ,™,Ð'7×8Ò8ÙØ�7‰7�9Ó˜x¯©°Ó);¸S¿W¹WÀ[Ó=Q×=WÐ=WÐUWÐ
X€CØ
Ô Ô ÙÜ×Ñ˜3ÔÜ
‡N‚Nð	Bð 	�‰�	Ó˜H§g¡g¨iÓ&8ö	r   Ú_UNROUTABLE_WARNEDc          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r)   rE   rM   re   r   Úmessager;   Ú
extra_argsr*   rf   r,   )r-   s   "r   r.   r.   ‘   s1   € ÷ 	4ñ 	4 4ð 	4°3ð 	4Àð 	4ÐSVð 	4Ð[_ñ 	4r   c           	     óH  € V P                  R4      YP                  R4      V P                  R4      ;'       g    R3pV\        9   d   R# \        P                  V4       \        P                  ! W P                  R4      \        VRV4      V P                  R4      .VO5!   R# )zÜA routed subscription the credential gate fail-closes is a permanent dead-end: delivery
rewinds every tick with only a DEBUG line. Say so ONCE per row at WARNING, mirroring
``_warn_anchorless_thread_sub_once`` (#115460).rk   rR   rh   r>   Nr8   )r4   rv   rq   r   rr   rY   )rE   re   rx   ry   r^   s   &&&* r   Ú_warn_unroutable_sub_oncer{   ‘   s„   € ð �7‰7�9Ó˜x¯©°Ó);¸S¿W¹WÀ[Ó=Q×=WÐ=WÐUWÐ
X€CØ
Ô Ô ÙÜ×Ñ˜3ÔÜ
‡N‚N�7ŸG™G IÓ.´¸À'È8Ó0TØ—7‘7˜9Ó%ð4Ø(2ö4r   c               ó    € V ^8„  d   QhRRRR/# )r)   Úmappingr   r*   zset[str]r,   )r-   s   "r   r.   r.   �   s   € ÷ Wñ W˜Sð W Xñ Wr   c           
     ót   € V  Uu0 uF'  p\        VR\        V4      4      P                  4       kK)  	  up# u upi )zNLower-cased platform names of an adapters mapping (Platform enums or strings).r8   )rY   r;   Úlower)r}   re   s   & r   Ú_platform_namesr€   �   s0   € áNUÓVÉgÀ(ŒG�H˜g¤s¨8£}Ó5×;Ñ;Ö=ÉgÑVÐVùÒVs   …-5c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r)   Úrunnerr   re   rE   rM   Úowner_profilerN   r*   r,   )r-   s   "r   r.   r.   ¢   s1   € ÷ :;ñ :; cð :;°Sð :;¸tð :;ÐTað :;Ðfiñ :;r   c           
     ót  € V P                  W4      p\        V RR4      p\        VRR4      '       g   V# V P                  P                  V4      pVe   WFJd   V# T;'       g    \        V RR4      p\        V RR4      ;'       g    V P	                  4       pT;'       g    Tp\        V R/ 4      ;'       g    / P                  V4      ;'       g    / p	\        VR\        V4      4      P                  4       \        V	4      9   d   R# VP                  R	4      ;'       g    / p
V
P                  R
4      ;'       g    V
P                  R4      pV
P                  R4      pVP                  R4      VP                  R4      ;'       g    RríVP                  R4      ;'       g    Rp\        V4      ;'       g.    VP                  R4      ;'       g    V
P                  R4      R9   p\        VRR4      ;'       g    .  EF   pVP                  VP                  W½WìVR7      '       di   VP                  V8w  d'   \        W!RVVP                  VP                  4        R# ^ RIHp V! V4       UUu0 uF  w  ppVkK
  	  pppVV9   d   Vu # Ru # TP                  VP                  T;'       g    VP                  TYì;'       g    V'       d   VP                   MRT;'       g    VP"                  R7      '       g   EK    R# 	  Wx8w  d'   \        VRV4      R8X  d   \%        WWV4      '       d   V# Wx8X  d   V# R# u uppi )zWResolve a durable route without turning a missing secondary bot into primary authority.ÚconfigNÚmultiplex_profilesFÚ_kanban_notifier_profileÚ_primary_profile_nameÚ_profile_adaptersr8   rP   rT   rU   rj   rR   rh   Úuser_idri   Úprofile_routes)rU   rR   rh   rj   rŠ   zîkanban notifier: subscription for %s on %s chat %s is stamped with profile %s but a profile_routes entry pins that chat to profile %s; it will not be delivered. Re-subscribe with `hermes kanban notify-subscribe ... --notifier-profile %s`.)Ú_multiplex_profile_homesÚ
api_server>   rl   rm   rn   ro   rp   )Ú_authorization_adapterrY   Úadaptersr4   Ú_active_profile_namer;   r   r€   r+   Úmatchesr8   Úprofiler{   Úgateway.runrŒ   rU   rR   rŠ   r   )r‚   re   rE   rƒ   rL   r…   Úprimaryr’   Úprimary_profileÚown_adaptersrs   ÚguildÚparentÚchatrn   rŠ   rt   ÚrouterŒ   ÚnameÚ_homeÚserveds   &&&&                  r   Ú_adapter_for_subscriptionrž   ¢   sé  € à×+Ñ+¨HÓD€GÜ�V˜X tÓ,€FÜ�6Ð/°×7Ò7ØˆØ�o‰o×!Ñ! (Ó+€GØÒ˜wÓ5ØˆØ×PÐPœw vÐ/IÈ4ÓP€GÜ˜fÐ&=¸tÓD×eÐeÈ×HcÑHcÓHe€OØ×(Ð(˜€Gô
 ˜FÐ$7¸Ó<×BÐBÀ×GÑGÈÓP×VÐVÐTV€LÜˆx˜¤# h£-Ó0×6Ñ6Ó8¼OÈLÓ<YÔYÙØ�w‰wÐ*Ó+×1Ð1¨r€HØ�L‰L˜Ó$×@Ð@¨¯©°ZÓ(@€EØ�\‰\Ð*Ó+€FØ—7‘7˜9Ó% s§w¡w¨{Ó';×'CÐ'C¸tˆ&Ø�g‰g�iÓ ×(Ð( D€GÜ�v“,÷ ð  3§7¡7¨;Ó#7×#TÐ#T¸8¿<¹<ÈÓ;Tð Zñ #€Kô ˜Ð!1°4Ó8×>Ð>¸BÓ>ˆØ�=‰=˜Ÿ™°%Ø#)È'ð ÷ Sò Sà�}‰} Ô'Ü)Øðdð ˜UŸ]™]¨E¯M©Mô;ò Ý<Ù.FÀvÔ.NÔOÑ.N™{˜t U“dÑ.NˆFÑOØ%¨Ô/�7Ò9°TÒ9Ø�=‰=˜Ÿ™°%×2IÐ2I¸5¿>¹>ÐSWØ#)×:lÐ:l×VaÀUÇ]Â]ÐgkØ!(×!9Ð!9¨E¯M©Mð ÷ ;õ ;ò ñ# ?ð0 Ô!¤g¨h¸ÀÓ&JÈlÔ&ZÜ(¨¸$×?Ò?ØˆØÔ0ˆ7Ð:°dÐ:ùó Ps   É*L4c                  ób   € ] tR t^âtRtR R ltR R ltR R ltR R	 ltR
 R lt	R R lt
RtR# )Ú
_CollectorzUOne tick's claim state: which profiles/platforms this gateway serves and the GC gate.c               ó0   € V ^8„  d   QhRRRRRRRRRR	R
R/# )r)   r‚   r   ÚkbÚnotifier_profilerN   Úgc_duer+   Úgc_retention_daysr:   r*   rf   r,   )r-   s   "r   r.   Ú_Collector.__annotate__å   sA   € ÷ Kñ K˜sð K¨ð KÀ-ð KÐY]ð KÐruð KÐz~ñ Kr   c               	ó6  a€ SV n         W n        W0n        W@n        WPn        . V n        SP                  4       V n        \        SR / 4      V n	        V0V n
        V P                  P                  R V P                   4       4       \        SRR4      p\        VRR4      '       d0   V P                  P                  V3R lVP                   4       4       \        SP                  4      P                  ! R V P                  P!                  4        4       !  V n        R# )r‰   c              3  ó–   "  € T F?  p\        V4      P                  4       '       g   K$  \        V4      P                  4       x € KA  	  R # 5i©N)r;   Ústrip)Ú.0Úps   & r   Ú	<genexpr>Ú&_Collector.__init__.<locals>.<genexpr>ï   s2   é € Ð%fÑ>S¸ÔWZÐ[\ÓW]×WcÑWc×We¤n¤c¨!£f§l¡l§n nÓ>Sùs
   ‚!A	¨!A	r…   Nr†   Fc              3  ó°   <"  € T FK  pVP                   '       g   K  VP                  \        SP                  4      9   g   K=  VP                  x € KM  	  R # 5ir©   )Úenabledre   r€   r�   r’   )r«   rš   r‚   s   & €r   r­   r®   ò   s?   øé € ð *Ù+@ %Ø—=•=ô Ø%*§^¡^´ÀvÇÁÓ7WÑ%Wô �—–Ó+@ùs   ƒAœ!AÁAc              3  ó8   "  € T F  p\        V4      x € K  	  R # 5ir©   )r€   )r«   Úms   & r   r­   r®   ú   s   é € ÐIÑ*H QŒo˜a× Ð Ó*Hùs   ‚)r‚   r¢   r£   r¤   r¥   Ú
deliveriesÚ_owns_kanban_dispatcher_lockÚinclude_unownedrY   Úprofile_adaptersÚnotifier_profilesÚupdater‹   r€   r�   ÚunionÚvaluesÚactive_platforms)Úselfr‚   r¢   r£   r¤   r¥   r…   s   &f&$$$ r   Ú__init__Ú_Collector.__init__å   sð   ø€ ØˆŒØŒØ 0ÔØŒØ!2ÔØ&(ˆŒØ%×BÑBÓDˆÔÜ '¨Ð0CÀRÓ HˆÔØ"2Ð!3ˆÔØ×Ñ×%Ñ%Ñ%f¸d×>SÒ>SÓ%fÔfÜ˜ ¨4Ó0ˆÜ�6Ð/°×7Ò7Ø×"Ñ"×)Ñ)ô *Ø+1×+@Ò+@ó*ô ô !0°·±Ó @× FÒ FÙI¨$×*?Ñ*?×*FÑ*FÔ*HÓIñ!KˆÖr   c               ó   € V ^8„  d   QhRR/# )r)   r*   ú
list[dict]r,   )r-   s   "r   r.   r¦   ü   s   € ÷ ñ ˜ñ r   c                	ó   € V P                   '       g#   \        P                  ! R 4       V P                  # V P                  p\        4       ;_uu_ 4        \        4       p\        V4       FÛ  pVP                  R4      ;'       g    VP                  pVP                  R4      p V'       d1   \        \        V4      P                  4       P                  4       4      M'\        VP                  V4      P                  4       4      pWb9   d   \        P                  ! RWF4       K¹  VP!                  V4       V P#                  V4       KÝ  	  RRR4       V P                  #   \         d	    RT 2p Lki ; i  + '       g   i     T P                  # ; i)z5kanban notifier: no connected adapters; skipping tickÚslugÚdb_pathzslug:z;kanban notifier: skipping duplicate board slug %s for DB %sN)r»   r   r\   r³   r¢   r   Úsetr	   r4   ÚDEFAULT_BOARDr;   r   Ú
expanduserÚresolveÚkanban_db_pathr[   rq   Úcollect_board)r¼   r¢   Úseen_db_pathsÚ
board_metarÂ   rÃ   Úresolved_db_paths   &      r   ÚcollectÚ_Collector.collectü   sG  € Ø×$×$Ð$Ü�LŠLÐPÔQØ—?‘?Ð"ð
 �W‰WˆÜ�\�\Ü&)£eˆMÜ*¨2Ö.�
Ø!—~‘~ fÓ-×AÐA°×1AÑ1A�Ø$Ÿ.™.¨Ó3�ð6ßT[¤s¬4°«=×+CÑ+CÓ+E×+MÑ+MÓ+OÔ'PÔadÐeg×evÑevÐw{Óe|÷  fEñ  fEó  fGó  bHÐ$ð $Ô4Ü—L’LÐ!^Ð`dÔwÙØ×!Ñ!Ð"2Ô3Ø×"Ñ" 4Ö(ñ /÷ ð �‰Ðøô !ô 6Ø).¨t¨f ~Ò$ð6ú÷ Ž\ð �‰Ðús>   Á0E2ÂE2Â#EÂ+AEÄAE2ÅE/	Å,E2Å.E/	Å/E2Å2F	c               ó    € V ^8„  d   QhRRRR/# )r)   rÂ   r;   r*   r+   r,   )r-   s   "r   r.   r¦     s   € ÷ ñ  Cð ¨Dñ r   c                ó0  €  \        4       P                  WP                  V P                  R7      pT^ 8X  d,   \
        P                  ! RT\        T P                  4      4       T^ 8g  #   \         d#   p\
        P                  ! RY4        Rp?R# Rp?ii ; i)zŽCheap read-only probe before the writable connect() (schema init, WAL
sidecars, checkpoints); a probe failure falls back to the writable open.)Úboardr·   rµ   zekanban notifier: read-only subscription probe failed for board %s (%s); falling back to writable openNTzIkanban notifier: board %s has no subscriptions owned by %s; skipping open)r   Úcount_notify_subsr·   rµ   r[   r   r\   Úsorted)r¼   rÂ   Úcountra   s   &&  r   Ú_board_has_subsÚ_Collector._board_has_subs  sŽ   € ð	Ü“F×,Ñ,Ø×.DÑ.DÐVZ×VjÑVjð -ó lˆEð �AŒ:Ü�LŠLÐdØœv d×&<Ñ&<Ó=ô?à˜‰zÐøô ô 	Ü�LŠLð LØMQôXåûð	ús   ‚/A( Á(BÁ3BÂBc               ó$   € V ^8„  d   QhRRRRRR/# )r)   Úconnr   rÂ   r;   r*   rf   r,   )r-   s   "r   r.   r¦   $  s&   € ÷ añ a 3ð a¨cð a°dñ ar   c                ó  €  \        4       P                  WP                  R7      pV'       d%   \        P                  ! RW2V P                  4       R# R#   \
         d#   p\        P                  ! RY$4        Rp?R# Rp?ii ; i)z`Best-effort stale-sub sweep: a failed sweep never blocks delivery; the next hourly gate retries.)Úmax_age_daysz^kanban notifier: purged %d stale done/blocked-task subscription(s) on board %s (retention %dd)z5kanban notifier: stale-sub GC failed for board %s: %sN)r   Úpurge_stale_done_notify_subsr¥   r   Úinfor[   r\   )r¼   rØ   rÂ   Ú_purgedÚ_gc_excs   &&&  r   Ú_gc_stale_subsÚ_Collector._gc_stale_subs$  sm   € ð	aÜ“f×9Ñ9¸$×McÑMcÐ9ÓdˆGßÜ—’Ð|Ø#¨4×+AÑ+AöCñ øô ô 	aÜ�LŠLÐPÐRV×`Ò`ûð	aús   ‚AA ÁBÁA<Á<Bc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r)   rØ   r   rÂ   r;   rE   rM   r*   zOptional[dict]r,   )r-   s   "r   r.   r¦   .  s.   € ÷ wñ w 3ð w¨cð w¸ð wÀñ wr   c                ó
  € VP                  R4      ;'       g    RpVP                  R4      ;'       g    RP                  4       pWPP                  9  d4   \        P                  ! RVP                  R4      T;'       g    R4       R# ^ RIHp \        V P                  V! V4      Y4;'       g    V P                  4      f   \        W54       R# \        4       P                  YR,          VR,          VR	,          VP                  R
4      ;'       g    R\        R7      w  rxp	V	'       g   R# V P                  P                  WR,          4      p
\        P                  ! R\!        V	4      VR,          W'V4       RVRVRVRV	RV
RV/# )zIClaim one subscription's unseen events; None when skipped or nothing new.r£   Nre   r>   zIkanban notifier: subscription for %s on %s skipped; adapter not connectedrk   z	<missing>)ÚPlatformrR   rh   )rk   re   rR   rh   ÚkindsuF   kanban notifier: claimed %d event(s) for %s on board %s cursor %sâ†’%srE   Ú
old_cursorÚcursorÚeventsÚtaskrÑ   )r4   r   r»   r   r\   Úgateway.configrã   rž   r‚   r£   ru   r   Úclaim_unseen_events_for_subÚTERMINAL_KINDSr¢   Úget_taskrG   )r¼   rØ   rÂ   rE   rƒ   re   rã   rå   ræ   rç   rè   s   &&&&       r   Ú_claim_for_subÚ_Collector._claim_for_sub.  sN  € àŸ™Ð 2Ó3×;Ð;°tˆØ—G‘G˜JÓ'×-Ð-¨2×4Ñ4Ó6ˆØ×0Ñ0Ô0Ü�LŠLÐdØŸ™ Ó+¨X×-DÐ-D¸ôFáÝ+Ü$ T§[¡[±(¸8Ó2DÀc×KqÐKqÐ\`×\qÑ\qÓrÒzÜ,¨SÔ;ÙÜ%)£V×%GÑ%GØ˜i�.°3°zµ?ÈCÐPYÍNØ—g‘g˜kÓ*×0Ð0¨b¼ð &Hó &
Ñ"ˆ
˜F÷ ÙØ�w‰w×Ñ ¨)¥nÓ5ˆÜ�ŠÐ]Ü˜“[ # i¥.°$ÀFô	Là�s˜L¨*°hÀÈÐRXÐZ`ÐbfÐhoÐquÐvÐvr   c               ó    € V ^8„  d   QhRRRR/# )r)   rÂ   r;   r*   rf   r,   )r-   s   "r   r.   r¦   E  s   € ÷ ñ  #ð ¨$ñ r   c                óö  € V P                  V4      '       g   R#  \        4       P                  VR7      p T P                  '       d   T P                  Y!4       \        4       P                  Y P                  T P                  R7      pT'       g   \        P
                  ! RT4       T F7  p T P                  Y!T4      pTe   T P                  P                  T4       K7  K9  	  TP#                  4        R#   \         d#   p\        P
                  ! RY4        Rp?R# Rp?ii ; i  \         d3   p\        P                  ! RTP!                  R4      Y4        Rp?Kµ  Rp?ii ; i  TP#                  4        i ; i)zFClaim events on one board, appending delivery dicts to ``deliveries``.N©rÑ   z)kanban notifier: cannot open board %s: %s)r·   rµ   z.kanban notifier: board %s has no subscriptionsz;kanban notifier: subscription for %s on board %s failed: %srk   )rÕ   r   Úconnectr[   r   r\   r¤   rß   r   Úlist_notify_subsr·   rµ   rí   r³   Úappendrr   r4   Úclose)r¼   rÂ   rØ   ra   ÚsubsrE   ÚclaimedÚsub_excs   &&      r   rÉ   Ú_Collector.collect_boardE  s5  € à×#Ñ# D×)Ò)Ùð	Ü“6—>‘>¨�>Ó-ˆDð	Ø�{�{ˆ{Ø×#Ñ# DÔ/ô “6×*Ñ*¨4×CYÑCYÐko×kÑkÐ*ó  AˆDßÜ—’ÐMÈtÔTÛ�ðFØ"×1Ñ1°$¸cÓB�GØÒ*ØŸ™×.Ñ.¨wÖ7ñ +ñ ð �J‰JŽLøô- ô 	Ü�LŠLÐDÀdÔPÝûð	ûô" !ô Fä—N’NÐ#`Ø#&§7¡7¨9Ó#5°t÷Fò FûðFûð
 �J‰J�LúsS   ›C6 ¶E& ÁA$E& Â-1D&ÃE& Ã6D#ÄDÄD#Ä&E#Ä1'EÅE& ÅE#Å#E& Å&E8)
r»   r³   r¤   r¥   rµ   r¢   r£   r·   r¶   r‚   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r½   rÍ   rÕ   rß   rí   rÉ   Ú__static_attributes__r,   r   r   r    r    â   s+   † Ù_õKõ.õ2õaõw÷.ñ r   r    c               ó0   € V ^8„  d   QhRRRRRRRRRR	R
R/# )r)   r‚   r   r¢   r£   rN   r¤   r+   r¥   r:   r*   rÀ   r,   )r-   s   "r   r.   r.   d  s=   € ÷ 	ñ 	˜cð 	 sð 	Àð 	ÐX\ð 	Ðqtð 	ð  zDñ 	r   c               ó:   € \        WW#VR7      P                  4       # )a  Claim unseen terminal events for every owned subscription on every board.

Each gateway polls only subscriptions owned by profiles whose adapters it
hosts; legacy rows without a profile stamp are visible only to the process
holding the singleton dispatcher lock.
)r£   r¤   r¥   )r    rÍ   )r‚   r¢   r£   r¤   r¥   s   &&$$$r   Ú_notifier_collectr  d  s!   € ô ØÐ%5ÐXiôç�gƒiðr   c               ó$   € V ^8„  d   QhRRRRRR/# )r)   r5   r   r^   r;   r*   r,   )r-   s   "r   r.   r.   t  s&   € ÷ Oñ O�ð O˜3ð O 3ñ Or   c                ó¢   € V P                   '       d=   V P                   P                  V4      '       d   V P                   P                  V4      # R# )z)Shared "payload present and truthy" read.N)r3   r4   )r5   r^   s   &&r   Ú_payloadr  t  s4   € à"$§*§* *°·±·±À×1DÒ1Dˆ2�:‰:�>‰>˜#ÓÐNÈ$ÐNr   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r)   r5   r   r^   r;   Úmsg_keyr9   r:   r*   r,   )r-   s   "r   r.   r.   y  s6   € ÷ Añ Aˆcð A˜ð A cð A°#ð A¸#ñ Ar   c                ó^   € \        W4      pV'       d   \        V\        V4      RV R7      # R# )zwCatalog message ``msg_key`` (``{value}`` placeholder) rendered with the truncated payload
value, or ``""`` when absent.N)r8   r>   )r  r   r;   )r5   r^   r  r9   r8   s   &&&& r   Ú_clipr	  y  s-   € ô �RÓ€Eß38Œ1ˆWœC ›J v¨Ð.Ô/Ð@¸bÐ@r   z
{}c               ó$   € V ^8„  d   QhRRRRRR/# )r)   Útextr;   r9   r:   r*   r,   )r-   s   "r   r.   r.   ƒ  s!   € ÷ 7ñ 7�cð 7 #ð 7¨#ñ 7r   c                óp   € V P                  4       P                  4       pV'       d   V^ ,          RV # V RV # )r   N)rª   Ú
splitlines)r  r9   Úliness   && r   Ú_first_liner  ƒ  s4   € Ø�J‰J‹L×#Ñ#Ó%€Eß$ˆ5��8�F�UÐÐ6¨$¨v°¨,Ð6r   c               ó   € V ^8„  d   QhRR/# ©r)   r*   Útupler,   )r-   s   "r   r.   r.   ˆ  s   € ÷ 	oñ 	o˜Uñ 	or   c                óX  € R p\        V R4      pV'       d   \        \        V4      ^È4      pMNVP                  '       d=   VP                  P                  '       d!   \        VP                  P                  ^ 4      pVe   RV 2MRp\        RVP                  VP                  VR7      VR 3# )NÚsummaryÚ
r>   zgateway.kanban.ping.completed©ÚheadÚtitleÚhandoff)r  r  r;   rè   Úresultr   r  r  )r5   ÚnÚwake_handoffÚpayload_summaryr  s   &&   r   Ú_fmt_completedr  ˆ  s‡   € à€LÜ˜r 9Ó-€OßÜ"¤3 Ó#7¸Ó=‰Ø	
��ˆ�A—F‘F—M—M�MÜ" 1§6¡6§=¡=°#Ó6ˆØ%1Ò%=��<�.Ñ!À2€GÜÐ,°1·6±6ÀÇÁÐRYÔZÐ\hÐjnÐnÐnr   c               ó   € V ^8„  d   QhRR/# r  r,   )r-   s   "r   r.   r.   ”  s   € ÷ 
vñ 
v Eñ 
vr   c                óÄ   € R pRp\        V R4      pV'       d$   \        V4      pRVR,           2p\        V^È4      p\        RVP                  VP
                  VR7      VR3# )r>   Nr  r  :NéÈ   Nz$gateway.kanban.ping.review_requestedr  )r  r;   r  r   r  r  )r5   r  r  r  r  s   &&   r   Ú_fmt_review_requestedr"  ”  sf   € ð €GØ€LÜ�r˜9Ó%€GßÜ�g“,ˆØ�w˜t•}�oÐ&ˆÜ" 7¨CÓ0ˆÜÐ3¸!¿&¹&ÈÏÉÐY`ÔaÐcoÐquÐuÐur   c               ó   € V ^8„  d   QhRR/# r  r,   )r-   s   "r   r.   r.   ¡  s   € ÷ "ñ " Uñ "r   c                ó®  € V P                   ;'       g    / p\        VP                  R 4      4      p\        VP                  R4      ^04      p\        VP                  R4      ^04      pT;'       g    \        R4      pV'       d   \        RVR7      MRpV'       d   V\        RVR7      ,          p\        R	VP                  VP
                  WgR
7      pVRV3# )rI   ÚreviewerÚimplementerz*gateway.kanban.ping.changes_default_reasonz#gateway.kanban.ping.reviewer_suffix)r%  r>   z&gateway.kanban.ping.implementer_suffix)r&  z%gateway.kanban.ping.changes_requested)Ú	board_tagrk   rI   Ú
provenanceN)r3   rJ   r4   r   r'  rk   )	r5   r  r3   rI   r%  r&  Úreason_textr(  Úmsgs	   &&       r   Ú_fmt_changes_requestedr+  ¡  s´   € Ø�j‰j×Ð˜B€GÜ  §¡¨XÓ!6Ó7€FÜ" 7§;¡;¨zÓ#:¸BÓ?€HÜ% g§k¡k°-Ó&@À"ÓE€KØ×KÐKœAÐJÓK€KßPX”Ð8À8ÕLÐ^`€JßØ”aÐ@ÈkÔZÕZˆ
Ü
Ð3Ø—k‘k¨1¯9©9¸[ôa€Cà��kÐ!Ð!r   c               ó   € V ^8„  d   QhRR/# r  r,   )r-   s   "r   r.   r.   ¯  s   € ÷ ñ  uñ r   c                ó¸   € \        V R4      pVR8H  p\        RVP                  \        V'       d   RMR4      \        V RR^È4      \        V RR	^ 4      R
7      pVRR3# )aÂ  Re-blocked for the same cause past the limit and routed to `triage`.

It emits no blocked/status event, so ping loudly here. A repeated-block
circuit breaker establishes that orchestration attention is needed; it
does NOT establish that a human decision or owner input exists. Use
neutral orchestration wording unless the block was typed as a genuine
owner-input request (`needs_input`, the only kind that carries a concrete
question for the owner).
r0   r1   zgateway.kanban.ping.triagez#gateway.kanban.ping.triage_decisionz$gateway.kanban.ping.triage_attentionÚrecurrencesz&gateway.kanban.ping.triage_recurrencesrI   ú!gateway.kanban.ping.reason_suffix)r  Úwhyr.  rI   N)r  r   r  r	  )r5   r  r0   Údecisionr*  s   &&   r   Ú_fmt_block_loop_detectedr2  ¯  sh   € ô �B˜Ó€DØ�}Ñ$€HÜ
Ø$¨1¯6©6Ü·xÑ3ÐEkÓlÜ˜"˜mÐ-UÐWZÓ[Ü�R˜Ð#FÈÓLô	€Cð ��dˆ?Ðr   c               ó   € V ^8„  d   QhRR/# r  r,   )r-   s   "r   r.   r.   Ä  s   € ÷ pñ p˜5ñ pr   c                óÔ   € \        V R 4      pV'       d   \        R\        V4      R7      M
\        R4      p\        V RR^ 4      p\        RVP                  W4VP
                  R7      RR3# )	Úfailuresz"gateway.kanban.ping.failed_n_times)rÔ   z gateway.kanban.ping.kept_failingÚerrorzgateway.kanban.ping.last_errorzgateway.kanban.ping.gave_up)r  rÔ   Úlastrk   N)r  r   r:   r	  r  rk   )r5   r  r5  rÔ   r7  s   &&   r   Ú_fmt_gave_upr8  Ä  sf   € ô ˜˜JÓ'€HßMUŒQÐ3¼3¸x»=ÕIÜÐ6Ó7ð 
ä��WÐ>ÀÓD€DÜÐ*°·±¸uÐYZ×YbÑYbÔcÐeiÐkoÐoÐor   c               ó   € V ^8„  d   QhRR/# r  r,   )r-   s   "r   r.   r.   Î  s   € ÷ Rñ R˜Uñ Rr   c                ó  € \        \        V R 4      ;'       g    ^ 4      pV'       d   \        ^\        V^<,          4      4      M^ pV'       d   \	        RVR7      M
\	        R4      p\	        RVP
                  VR7      RR3# )Úlimit_secondsz!gateway.kanban.ping.limit_minutes)Úminutesz!gateway.kanban.ping.limit_genericzgateway.kanban.ping.timed_out)r  ÚspanN)r:   r  ÚmaxÚroundr   r  )r5   r  r9   r<  r=  s   &&   r   Ú_fmt_timed_outr@  Î  sg   € Ü”˜˜_Ó-×2Ð2°Ó3€Eß+0Œc�!”U˜5 2�:Ó&Ô'°a€GßFMŒ1Ð0¸'ÕBÔSTÐUxÓSy€DÜÐ,°1·6±6ÀÔEÀtÈTÐQÐQr   c           
     óP   € \        R VP                  \        V RR^ 4      R7      RR3# )zgateway.kanban.ping.blockedrI   r/  )r  rI   N)r   r  r	  ©r5   r  s   &&r   Ú<lambda>rC  Ú  s*   € Ü	Ð
'¨a¯f©f¼UÀ2ÀxÐQtÐvyÓ=zÔ{Øˆdñr   c                ó6   € \        R VP                  R7      RR3# )zgateway.kanban.ping.crashed)r  N)r   r  rB  s   &&r   rC  rC  ß  s   € œaÐ =ÀAÇFÁFÔKÈTÐSWÑXr   c                ó`   € \        R VP                  \        V R4      ;'       g    RR7      RR3# )zgateway.kanban.ping.statusr#   r>   )r  r#   N)r   r  r  rB  s   &&r   rC  rC  á  s.   € œQÐ;À!Ç&Á&ÔQYÐZ\Ð^fÓQg×QmÐQmÐkmÔnÐptÐvzÑ{r   z6dict[str, Callable[[Any, _KanbanNotification], tuple]]Ú_EVENT_FORMATTERSc                  óÔ   € ] tR tRtRtR R ltR R ltR R ltR	 R
 ltR R lt	R R lt
R R ltR R ltR R ltR R ltR R ltR tR R ltR R ltR R ltR  R! ltR"tR## )$Ú_KanbanNotificationië  a  Deliver one subscription's claimed events, then settle the cursor.

Both legs of notify+wake must succeed before settling. Sent pings have a
separate durable checkpoint so wake retries do not resend them. Admission
is at-least-once queueing, not an execution or final-response receipt.
c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r)   r‚   r   ÚdrM   Úplatform_clsÚsub_fail_countsr*   rf   r,   )r-   s   "r   r.   Ú _KanbanNotification.__annotate__ó  s1   € ÷ %ñ %˜sð % tð %¸cð %ÐTXð %Ð]añ %r   c               	ó   € Wn         W n        W0n        W@n        VR ,          ;V n        pVR,          ;V n        pVP                  R4      V n        VR,          ;'       g    RP                  4       V n	        VR,          V n
        VP                  R4      ;'       g    RV n        V'       d   VP                  MVR,          R,          V n        V P                  '       d   \        RV P                  R	7      MRV n        V'       d*   VP                  '       d   \        R
VP                  R7      MRp\        RV P                  WpP                  R7      V n        VR,          VR,          VR,          VP                  R4      ;'       g    R3V n        VP                  R4      ;'       g    RpVR9   V n        VR8g  V n        R;V n        ;V n        ;V n        V n        RV n        RV n        RV n        \7        4       V n        R# )rE   rè   rÑ   re   r>   rk   r£   :Néx   Nzgateway.kanban.ping.board_tagrñ   z gateway.kanban.ping.assignee_tag)Úassigneezgateway.kanban.ping.head)r'  Úassignee_tagrk   rR   rh   Údelivery_modeÚnotifyÚwakeNT)znotify+wakerT  )r‚   rJ  rK  rL  rE   rè   r4   Ú
board_slugr   Úplatform_strrk   Úsub_profiler  r   r'  rP  r  Úsub_keyÚ
wake_agentÚsend_passiver  Úwake_review_detailÚsession_keyÚsynthÚplatrL   Úis_push_adapterrÄ   Ú
wake_kinds)	r¼   r‚   rJ  rK  rL  rE   rè   ÚtagÚmodes	   &&&$$    r   r½   Ú_KanbanNotification.__init__ó  s   € ØŒØŒØ(ÔØ.ÔØ˜5�Ð!ˆŒ�3Ø˜V�9Ð$ˆŒ	�DØŸ%™% ›.ˆŒØ  �_×2Ð2°×9Ñ9Ó;ˆÔØ˜9•~ˆŒØŸ7™7Ð#5Ó6×<Ð<¸"ˆÔß$(�d—j’j¨c°)­n¸dÕCˆŒ
ØVZ×Ve×VeÐVeœÐ:À$Ç/Á/ÕRÐkmˆŒçOSÐX\×Xe×XeÐXeŒaÐ2¸T¿]¹]ÕKÐkmˆÜÐ0¸D¿N¹NÐY\×frÑfrÔsˆŒ	à˜I�¨¨J­¸¸Y½ÈÏÉÐQ\ÓI]×IcÐIcÐacÐdˆŒØ�w‰w�Ó'×3Ð3¨8ˆØÐ"9Ñ9ˆŒØ  F™NˆÔð WYÐXˆÔÐX˜DÔ3ÐX°dÔ6FÈÌØˆŒ	Ø ˆŒØ#ˆÔÜ"›uˆŽr   c               ó   € V ^8„  d   QhRR/# ©r)   r*   rf   r,   )r-   s   "r   r.   rM    s   € ÷ 
ñ 
˜dñ 
r   c           	   ƒ  	óæ   "  € \        V P                  P                  V P                  V P                  R ,          V P                  P                  R^ 4      V P                  4      G Rj  x€L
  R#  L5i)ræ   rå   N)r
   r‚   Ú_kanban_rewindrE   rJ  r4   rU  ©r¼   s   &r   ÚrewindÚ_KanbanNotification.rewind  sP   é € Ü(Ø�K‰K×&Ñ&¨¯©°$·&±&¸Õ2BÀDÇFÁFÇJÁJÈ|Ð]^ÓD_Ðae×apÑapó
÷ 	
ô 	
ùs   ‚A&A1Á(A/Á)A1c               ó   € V ^8„  d   QhRR/# re  r,   )r-   s   "r   r.   rM    s   € ÷ sñ s˜tñ sr   c              ƒ  	ó°   "  € \        V P                  P                  V P                  V P                  R ,          V P
                  4      G Rj  x€L
  R#  L5i)ræ   N)r
   r‚   Ú_kanban_advancerE   rJ  rU  rh  s   &r   ÚadvanceÚ_KanbanNotification.advance  s;   é € Ü(¨¯©×)DÑ)DÀdÇhÁhÐPT×PVÑPVÐW_ÕP`Ðbf×bqÑbqÓr×rÔrùs   ‚AAÁAÁAc               ó   € V ^8„  d   QhRR/# re  r,   )r-   s   "r   r.   rM    s   € ÷ _ñ _˜Tñ _r   c              ƒ  	óŒ   "  € \        V P                  P                  V P                  V P                  4      G R j  x€L
  R #  L5ir©   )r
   r‚   Ú_kanban_unsubrE   rU  rh  s   &r   ÚunsubÚ_KanbanNotification.unsub  s)   é € Ü(¨¯©×)BÑ)BÀDÇHÁHÈdÏoÉoÓ^×^Ô^ùs   ‚9A»A¼Ac               ó   € V ^8„  d   QhRR/# re  r,   )r-   s   "r   r.   rM    s   € ÷ 5ñ 5 ñ 5r   c                	óR   € V P                   P                  V P                  R 4       R # r©   )rL  ÚpoprX  rh  s   &r   Úclear_failuresÚ"_KanbanNotification.clear_failures  s   € Ø×Ñ× Ñ  §¡¨tÖ4r   c               ó0   € V ^8„  d   QhRRRRRRRRRR	R
R/# )r)   Úfmtr;   Úprefixr  Údrop_fmtra   r[   rS   r+   r*   rf   r,   )r-   s   "r   r.   rM     s9   € ÷ 
 ñ 
 ¨ð 
 °eð 
 Àsð 
 ÐQZð 
 Ðfjð 
 Ðosñ 
 r   c              ƒ  óÚ  "  € V P                   P                  V P                  ^ 4      ^,           pW`P                   V P                  &   \        P                  ! V.VOVN\
        NVN5RV/  V\
        8¼  dW   \        P                  ! W0P                  V P                  V4       V P                  4       G Rj  x€L
  V P                  4        R# V P                  4       G Rj  x€L
  R#  L0 L5i)zfBump the failure counter; drop the sub past the limit, else rewind the claim so the next tick retries.rS   N)rL  r4   rX  r   rr   ÚMAX_SEND_FAILURESrk   rV  rs  rx  ri  )r¼   r{  r|  r}  ra   rS   Úfailss   &&&&&& r   Údelivery_failedÚ#_KanbanNotification.delivery_failed   sµ   é € à×$Ñ$×(Ñ(¨¯©°qÓ9¸AÕ=ˆØ-2×Ñ˜TŸ\™\Ñ*Ü�Š�sÐV˜VÐV UÐVÔ,=ÐV¸sÒVÈXÒVØÔ%Ô%Ü�NŠN˜8§\¡\°4×3DÑ3DÀeÔLØ—*‘*“,×ÐØ×ÑÖ!à—+‘+“-×Òñ ñ  ùs$   ‚B4C+Â6C'Â7)C+Ã C)Ã!C+Ã)C+c               ó$   € V ^8„  d   QhRRRRRR/# )r)   r{  r;   ra   r[   r*   rf   r,   )r-   s   "r   r.   rM  ,  s&   € ÷ Nñ N cð N°	ð N¸dñ Nr   c              ƒ  	ób   "  € R pV P                  WP                  3W2R4      G Rj  x€L
  R#  L5i)zRkanban notifier: dropping subscription %s on %s after %d consecutive wake failuresTN)r�  rk   )r¼   r{  ra   r}  s   &&& r   Ú_wake_failedÚ _KanbanNotification._wake_failed,  s(   é € ØgˆØ×"Ñ" 3¯©¨¸ÈÓM×MÔMùs   ‚$/¦-§/c               ó    € V ^8„  d   QhRRRR/# )r)   r5   r   r*   rN   r,   )r-   s   "r   r.   rM  2  s   € ÷ 
ñ 
˜sð 
 }ñ 
r   c                óŽ   € \         P                  VP                  4      pVf   R# V! W4      w  r4pVe   W@n        Ve   WPn        V# )uO   Render one event; accumulates wake handoff/review detail. None â†’ silent kind.N)rF  r4   r0   r  r[  )r¼   r5   Ú	formatterr*  r  Úreview_details   &&    r   Úformat_eventÚ _KanbanNotification.format_event2  sK   € ä%×)Ñ)¨"¯'©'Ó2ˆ	ØÒÙÙ&/°Ó&9Ñ#ˆ�mØÒØ 'ÔØÒ$Ø&3Ô#Øˆ
r   c               ó   € V ^8„  d   QhRR/# re  r,   )r-   s   "r   r.   rM  >  s   € ÷ Hñ H ñ Hr   c           	     ó  a € S P                   S P                  r!S P                  '       dD   S P                  R,           Uu0 uF%  q3P                  \
        9   g   K  VP                  kK'  	  upM	\        4       S n        \        ;QJ d0    V 3R lS P                  R,           4       F  '       d   K   RM%	  RM!! V 3R lS P                  R,           4       4      S n	        S P                  '       g   R# S P                  '       d   \        VRR4      ;'       g    RS n        M-VR,          ;'       g    \        VRR4      ;'       g    RS n        \
         Uu. uF#  qDS P                  9   g   K  \        R	V 24      NK%  	  pp\        R
4      P                  V4      ;'       g    \        R4      p\        RVR,          TS P                  V'       d   VP                   MRS P"                  R7      pS P$                  '       d&   VR\        RS P$                  R7      ,           ,          pS P&                  '       d&   VR\        RS P&                  R7      ,           ,          pVR,           \        R4      ,           S n        R# u upi u upi )zDSet ``wake_kinds`` / ``session_key`` / ``synth`` for the wake paths.rç   c              3  ór   <"  € T F,  qP                   SP                  9   g   K  \        V4      x € K.  	  R # 5ir©   )r0   r`  r6   )r«   r5   r¼   s   & €r   r­   Ú6_KanbanNotification.build_wake_text.<locals>.<genexpr>B  s1   øé € Ð"qÑBR¸B×V]ÑV]Ðae×apÑapÑVpÔ#7Ô#3°B×#7Ð#7ÓBRùs   ƒ7¤7FTNÚ
session_idr>   rR   zgateway.kanban.wake.z!gateway.kanban.wake.status_joinerz"gateway.kanban.wake.status_defaultzgateway.kanban.wake.messagerk   )rk   r#   r  rP  rÑ   r  zgateway.kanban.wake.handoff)r  z!gateway.kanban.wake.review_detail)rI   z

zgateway.kanban.wake.guidance)rè   rE   rY  rJ  r0   Ú_WAKE_KINDSrÄ   r`  ÚallÚwake_diagnosticr_  rY   r\  r   rC   r  rP  rU  r  r[  r]  )r¼   rè   rE   r5   ÚkÚ_partsÚ_statusr]  s   f       r   Úbuild_wake_textÚ#_KanbanNotification.build_wake_text>  sÕ  ø€ à—I‘I˜tŸx™xˆcØ\`×\k×\kÐ\k¨T¯V©V°HÖ-=ÓXÑ-= rÇÁÌKÑAWœ7˜2Ÿ7œ7Ñ-=ÒXÔqtÓqvˆŒß"›sÔ"qÀ$Ç&Á&ÈÖBRÓ"qŸsŸsšsÔ"qÀ$Ç&Á&ÈÖBRÓ"qÓqˆÔØ��ˆÙØ××ÐÜ& t¨\¸4Ó@×FÐFÀBˆDÕð
  # 9�~×XÐX´¸¸|ÈTÓ1R×XÐXÐVXˆDÔå9DÓ]¹°AÈTÏ_É_ÑH\Ô/”!Ð*¨1¨#Ð.Ö/¹ˆÐ]ÜÐ7Ó8×=Ñ=¸fÓE×pÐpÌÐKoÓIpˆÜØ)Ø˜	•N¨7¸$¿*¹*ß&*�T—]’]°¸$¿/¹/ô
ˆð ××ÐØ�TœAÐ;ÀT×EVÑEVÔWÕWÕWˆEØ×"×"Ð"Ø�TœAÐAÈ$×JaÑJaÔbÕbÕbˆEØ˜V•^¤aÐ(FÓ&GÕGˆŽ
ùò3 Yùò ^s   Á I<ÁI<ÅJÅ-Jc               ó   € V ^8„  d   QhRR/# re  r,   )r-   s   "r   r.   rM  \  s   € ÷ zñ z˜4ñ zr   c                	óÂ   € \         P                  ! R V P                  V P                  V P                  R,          V P
                  ;'       g    RV P                  4       R# )z@kanban notifier: woke agent for %s on %s/%s profile=%s events=%srR   ÚdefaultN)r   rÜ   rk   rV  rE   rW  r`  rh  s   &r   Ú	_log_wokeÚ_KanbanNotification._log_woke\  sF   € Ü�ŠÐVØ—L‘L $×"3Ñ"3°T·X±X¸iÕ5HÈ$×JZÑJZ×JgÐJgÐ^gÐim×ixÑixö	zr   c               ó   € V ^8„  d   QhRR/# )r)   r*   rN   r,   )r-   s   "r   r.   rM  `  s   € ÷ 
 ñ 
  mñ 
 r   c                ó–   € V P                   '       g   R# \        \        V P                  RR4      RR4      '       g   R# V P                   # )zþThe subscription's profile when THIS gateway is a multiplexer serving it, else ``None``.

``None`` keeps the historical path: a standalone ``hermes -p <name>`` gateway owns its own
listener and key, so its api_server wakes keep using the HTTP self-post.
Nr…   r†   F)rW  rY   r‚   rh  s   &r   Ú_served_wake_profileÚ(_KanbanNotification._served_wake_profile`  s@   € ð ××ÐÙÜ”w˜tŸ{™{¨H°dÓ;Ð=QÐSX×YÒYÙØ×ÑÐr   c                ó  € V P                   pV P                  4       pV'       g   \        P                  ! 4       # ^ RIHp ^ RIHp V! V P                  V P                  R,          VR7      pV! VP                  V4      4      # )zRRuntime scope of the subscription's profile under multiplex, else a no-op context.©Ú_async_profile_runtime_scope©ÚSessionSourcerR   )re   rR   r’   )r‚   r¡  Ú
contextlibÚnullcontextr“   r¥  Úgateway.sessionr§  r^  rE   Ú _resolve_profile_home_for_source)r¼   r‚   Úserved_profiler¥  r§  Úsources   &     r   Ú_owner_scopeÚ _KanbanNotification._owner_scopel  sd   € à—‘ˆØ×2Ñ2Ó4ˆßÜ×)Ò)Ó+Ð+Ý<Ý1Ù¨¯	©	¸4¿8¹8ÀIÕ;NÐXfÔgˆÙ+¨F×,SÑ,SÐTZÓ,[Ó\Ð\r   c               ó   € V ^8„  d   QhRR/# re  r,   )r-   s   "r   r.   rM  w  s   € ÷ *ñ *˜Dñ *r   c              ƒ  óŽ  "  € ^ RI Hp V P                  pV P                  '       g™   V P	                  4       ;_uu_4       GRj  x€L
  T! V P
                  V P                  V P                  V P                  4       V P                  '       d   RMRR7      G Rj  x€L
  RRR4      GRj  x€L
  V P                  4        R# ^ RIHp VP                  R4      ;'       g    / p\        VP                  R4      ;'       g    VP                  R4      ;'       g    R	4      P                  4       pT! V P                   VR
,          T;'       g    RVP                  R4      ;'       g    RVP                  R4      VP                  R4      V P"                  ;'       g    R\%        V P
                  V4      VP                  R4      R7	      p\&        P(                  ! V P
                  4      Vn        ^ RIHp V P"                  '       da   \1        \1        V P2                  RR4      RR4      '       d9   ^ RIHp V! V P"                  4      '       g   \9        RV P"                  : R24      hV! V P2                  P;                  V4      4      ;_uu_4       GRj  x€L
  T! V P
                  V P                  V P                  TV P                  '       d   RMRR7      G Rj  x€L
  RRR4      GRj  x€L
  V P                  4        R#  ELº ELh EL[  + GRj  x€L 
 '       g   i     ELs; i L“ LN L@  + GRj  x€L 
 '       g   i     LW; i5i)zoWake the creator session (raises on failure): push adapters get a full SessionSource, non-push a raw self-post.)Údeliver_wakeNÚ
diagnosticr  )r  r‘  r’   Únotification_categoryr¦  rP   ri   r>   rR   Úgrouprh   rŠ   Úuser_id_altrj   )	re   rR   ri   rh   rŠ   r¶  r’   rT   rj   r¤  r…   r†   F)Úprofile_existszKanban wake profile z no longer exists)r  r‘  r­  r´  )Úgateway.waker²  rE   r_  r®  rL   r]  r\  r¡  r”  r�  rª  r§  r4   r;   rª   r^  rW  rb   ÚweakrefÚrefÚ_transport_adapter_refr“   r¥  rY   r‚   Úhermes_cli.profilesr·  ÚRuntimeErrorr«  )	r¼   r²  rE   r§  Ú_delivery_metaÚ
_chat_typeÚ_sourcer¥  r·  s	   &        r   rT  Ú_KanbanNotification.wakew  sz  é € å-Ø�h‰hˆØ×#×#Ð#ð
 ×(Ñ(×*×*Õ*Ù" 4§<¡<°d·j±jÈT×M]ÑM]Ø+/×+DÑ+DÓ+FØIM×I]×I]ÐI]¹Ðckôm÷ mð m÷ +×*ð �N‰NÔÙÝ1ð Ÿ™Ð!4Ó5×;Ð;¸ˆÜ˜Ÿ™ Ó-×VÐV°×1CÑ1CÀKÓ1P×VÐVÐTVÓW×]Ñ]Ó_ˆ
ÙØ—Y‘Y¨¨I­À*×BWÐBWÐPWØ—g‘g˜kÓ*×2Ð2¨d¸C¿G¹GÀIÓ<NÐ\_×\cÑ\cÐdqÓ\rØ×$Ñ$×,Ð,¨´~ÀdÇlÁlÐTWÓ7XØ)×-Ñ-Ð.>Ó?ô	
ˆô *1¯ª°T·\±\Ó)BˆÔ&Ý<Ø××Ð¤¬°·±¸XÀtÓ(LÐNbÐdi× jÒ jÝ:Ù! $×"2Ñ"2×3Ò3Ü"Ð%9¸$×:JÑ:JÑ9MÐM^Ð#_Ó`Ð`Ù/°·±×0\Ñ0\Ð]dÓ0e×f×fÕfÙ˜tŸ|™|°$·*±*È×IYÑIYÐbiØEI×EY×EYÐEY±\Ð_gôi÷ ið i÷ g×fð 	�‰ÖòC +òm÷ +×*×*Ô*úñ< gñi÷ g×f×fÒfüsè   ‚AMÁK=ÁMÁALÂL ÂLÂMÂ(LÂ)3MÃMÃ=MÄ2MÅ	MÅ#4MÆB/MÉAMÊL#ÊMÊAL)ËL%ËL)ËMË&L'Ë'MÌ LÌMÌL 	ÌLÌ
L 	ÌL 	Ì
MÌ%L)Ì'MÌ)M	Ì/L2Ì0
M	Ì;M	Ì=Mc               ó$   € V ^8„  d   QhRRRRRR/# )r)   r5   r   r*  r;   r*   r+   r,   )r-   s   "r   r.   rM  £  s!   € ÷ "ñ " Cð "¨cð "°dñ "r   c           
   ƒ  óÎ  aaaa	a
"  € ^ RI Hp V P                  V P                  uo
oS
P	                  R4      p\        V\        4      '       d   \        V4      M/ o	S
P	                  R4      '       d$   S	P	                  R4      '       g   S
R,          S	R&   RoVVV	VV
3R lpV! WPP                  \        V4      R7      G Rj  x€L
 '       g   R# \        SRR	4      RJ d$   \        R
\        SRR4      ;'       g    R 24      h\        P                  ! RVP                  V P                  V P                  S
R,          V P                  4       VP                  R9   dH    V P                   P#                  SS
R,          S	\        VRR4      V P$                  R7      G Rj  x€L
  R	# R	#  Lä L
  \&         d.   p\        P                  ! RT P                  T4        Rp?R	# Rp?ii ; i5i)zMSend one text ping; raises on adapter exception or SendResult(success=False).)Úpresent_notificationrP   rh   Nc               “  óZ   <"  € SP                  SR ,          SSR7      G Rj  x€L
 o R#  L5i)rR   )rs   N)Úsend)Ú	_send_resrL   rs   r*  rE   s   €€€€€r   Ú	send_pingÚ2_KanbanNotification._send_event.<locals>.send_ping¬  s$   øé € à%Ÿl™l¨3¨y­>¸3È˜lÓR×RŠIÑRùs   ƒ+¢)£+)re   r³  FÚsuccessTz!adapter send() reported failure: r6  zunknown errorz?kanban notifier: delivered %s event for %s to %s/%s on board %srR   r3   )rL   rR   rs   Úevent_payloadrè   z4kanban notifier: artifact delivery for %s failed: %s)r   r%   )Úgateway.warning_notificationsrÄ  rE   rL   r4   rX   rM   rV  r6   rY   r½  r   r\   r0   rk   rU  r‚   Ú_deliver_kanban_artifactsrè   r[   )r¼   r5   r*  rÄ  rP   rÈ  Úart_excrÇ  rL   rs   rE   s   &&f    @@@@r   Ú_send_eventÚ_KanbanNotification._send_event£  s¨  üé € åFØ—x‘x §¡ˆˆˆWØŸG™GÐ$7Ó8ÐÜ>HÐIZÔ\`×>aÒ>a¤4Ð(9Ô#:ÐgiˆØ�7‰7�;×Ò¨¯©°[×(AÒ(AØ$'¨Õ$4ˆH�[Ñ!Øˆ	÷	Sñ 	Sñ *¨)×>OÑ>OÔ\lÐmoÓ\pÔq×qÖqÙô �9˜i¨Ó.°%Ó7ÜÐ!BÄ7È9ÐV]Ð_cÓCd×CwÐCwÐhwÐBxÐyÓzÐzÜ�ŠÐVØ—W‘W˜dŸl™l¨D×,=Ñ,=¸sÀ9½~ÈtÏÉô	`ð �7‰7Ð7Ô7ðlØ—k‘k×;Ñ;Ø#¨S°­^ÀhÜ")¨"¨i¸Ó">ÀTÇYÁYð <ó ÷ ð ó ñ- rñ øô ô lÜ—’ÐSÐUY×UaÑUaÐcj×kÐkÙûðlüsg   ‡A*G%Á2G%Â	8G%ÃF&Ã	G%Ã,G%Ã9A$G%Å?F* ÆF(ÆF* Æ"G%Æ(F* Æ*G"Æ5"GÇG%ÇG"Ç"G%c               ó   € V ^8„  d   QhRR/# r(   r,   )r-   s   "r   r.   rM  Ç  s   € ÷ #ñ # 4ñ #r   c              ƒ  óD  "  € V P                   R,           EF1  pV P                  V4      pVf   K  V P                  '       gA   V P                  '       d/   \        P
                  ! RV P                  V P                  4       Km  V P                  '       g   K�  VP                  V P                  P                  R^ 4      8:  d   K®   V P                  W4      G Rj  x€L
 RJ d   KÎ  \        \        V P                  P                   V P"                  RV P                  VP                  R7      4      G Rj  x€L
  V P%                  4        EK4  	  R
#  Lt L  \&         dA   pT P)                  RT P                  T P                  3R	TR4      G Rj  x€L 
   Rp? R# Rp?ii ; i5i)zOSend every text ping; False when a send failed (claim already rewound/dropped).rç   Nzmkanban notifier: adapter %s has no push channel; skipping text ping for %s, relying on wake self-post insteadÚlast_ping_event_idFÚrecord_notify_ping)Úevent_idz=kanban notifier: send failed for %s on %s (attempt %d/%d): %szRkanban notifier: dropping subscription %s on %s after %d consecutive send failuresT)rJ  r‹  r_  rY  r   r\   rV  rk   rZ  ÚidrE   r4   rÏ  r
   r   r‚   Ú_kanban_sub_oprU  rx  r[   r�  )r¼   r5   r*  ra   s   &   r   Ú_send_pingsÚ_KanbanNotification._send_pingsÇ  sf  é € à—&‘&˜×"Ñ"ˆBØ×#Ñ# BÓ'ˆCØŠ{Ùð
 ×'×'Ð'¨D¯O¯O¨OÜ—’ð0Ø15×1BÑ1BÀDÇLÁLôñ Ø×$×$Ð$áØ�u‰u˜Ÿ™Ÿ™Ð%9¸1Ó=Ô=ÙðØ×)Ñ)¨"Ó2×2°eÓ;ÙÜ0´Ø—K‘K×.Ñ.°·±ÐAUÐW[×W_ÑW_ØŸU™Uô2ó ÷ ð ð ×#Ñ#×%ñ5 #ñB ñ 3ñøô
 ô Ø×*Ñ*ØSÐVZ×VbÑVbÐdh×duÑduÐUvØhÐjmÐotó÷ ñ ö ûðüs   ‚A F ÁF Á?F Â/F ÃEÃEÃEÃ"F Ã$AEÄ2EÄ3EÅF ÅEÅEÅFÅ.FÆFÆFÆF ÆFÆF c               ó   € V ^8„  d   QhRR/# re  r,   )r-   s   "r   r.   rM  ì  s   € ÷ Iñ I˜tñ Ir   c           	   ƒ  	ó\  "  €  V P                  V P                  4      V n        \
        P                  ! \        T P                  T P                  T P                  T P                  ;'       g    R 4      G R j  x€L
 pTfG   \        P                  ! RT P                  T P                  4       T P                  4       G R j  x€L
  R # Yn        ^ RIHp T! T4      T n        T P'                  4       ;_uu_4       GR j  x€L
  T P)                  4       G R j  x€L
 '       g    R R R 4      GR j  x€L
  R # T P*                  R,          p^ RIHp T! T P                  4      '       * pT'       g   T.MIT Uu. uF  p\1        T4      '       g   K  TNK  	  upT Uu. uF  p\1        T4      '       d   K  TNK  	  up.p. pT F¢  p	T	'       g   K  / T P*                  CRT	/CT n        R;T n        T n        T	 F  pT P7                  T4       K  	  T P9                  4        T P:                  '       g   Kp  TP=                  T P>                  T P@                  T P:                  34       K¤  	  / T P*                  CRT/CT n        R R R 4      GR j  x€L
  T P$                  p
^ RIH!p X'       dF    T F.  w  T n        T n         T n        T PE                  4       G R j  x€L
  K0  	  T PG                  4        T P	                  4       G R j  x€L
  T
'       g   T PG                  4        T PL                  '       d8   T PL                  PN                  R	8X  d   T PQ                  4       G R j  x€L
  R # R # R #   \         d    T P	                  4       G R j  x€L 
   R # i ; i EL ELÐ EL— EL‚ ELnu upi u upi  EL#  + GR j  x€L 
 '       g   i     EL;; i L÷  T d    T P                  4       G R j  x€L 
   R # \H         d1   pT PK                  T
'       d   RMRT4      G R j  x€L 
   R p?R # R p?ii ; i EL. LÓ5i)
NzPkanban notifier: adapter %s disconnected before delivery for %s; rewinding claim)Úadapter_supports_pushrç   )Úwarning_notifications_enabledr>   )ÚWakeNotAcceptedzEkanban notifier: wake-only delivery failed for %s (attempt %d/%d): %szAkanban notifier: wake self-post failed for %s (attempt %d/%d): %sÚarchived))rK  rV  r^  Ú
ValueErrorrn  ÚasyncioÚ	to_threadrž   r‚   rE   rW  r   r\   rk   ri  rL   r¸  rÜ  r_  r®  rØ  rJ  rÌ  rÝ  r6   r  r[  r‹  r˜  r`  rô   r]  r”  rÞ  rT  rx  r[   r…  rè   r#   rs  )r¼   rL   rÜ  Úoriginal_eventsrÝ  rF   r5   Úwake_groupsÚwake_payloadsrç   Úis_pushrÞ  Ú_wk_errs   &            r   ÚdeliverÚ_KanbanNotification.deliverì  sS  é € ð	Ø×)Ñ)¨$×*;Ñ*;Ó<ˆDŒIô  ×)Ò)Ü% t§{¡{°D·I±I¸t¿x¹xÈ×IYÑIY×IaÐIaÐ]aóc÷ cˆàŠ?Ü�LŠLÐkØ×*Ñ*¨D¯L©Lô:à—+‘+“-×ÐÙØŒÝ6Ù4°WÓ=ˆÔð ×$Ñ$×&×&Õ&Ø×)Ñ)Ó+×+Ö+Ø÷ '×&Ñ&ð #Ÿf™f XÕ.ˆOÝSÙ5°d×6GÑ6GÓHÔHˆEß49˜OÑ,Ù-ÓF™o˜Ô1AÀ"×1E—�™oÑFÙ-ÓJ™o˜Ô5EÀb×5I—�™oÑJð@ˆKð ˆMÛ%�ßÙØ5˜DŸF™FÐ5 H¨fÑ5�”Ø>@Ð@�Ô! DÔ$;Û �BØ×%Ñ% bÖ)ñ !à×$Ñ$Ô&Ø—?—?’?Ø!×(Ñ(¨$¯*©*°d×6JÑ6JÈDÏOÉOÐ)\Ö]ñ &ð ;˜Ÿ™Ð: ¨/Ñ:ˆDŒF÷- '×&ð. ×&Ñ&ˆÝ0÷ ðÛIVÑE�D”J Ô 4°d´oØŸ)™)›+×%Ò%ñ JWà×#Ñ#Ô%ð �l‰l‹n×ÐßØ×ÑÔ!à�9�9ˆ9˜Ÿ™×)Ñ)¨ZÔ7Ø—*‘*“,×Òñ 8‰9øôK ô 	Ø—,‘,“.× Ñ Úð	úòcò
  ò 'Ú+ò 'ùò GùÚJ÷ '×&×&Ô&úñ< &øà"ô ð —k‘k“m×#Ñ#ÚÜô Ø×'Ñ'ß_fÑ[Ø\Øó÷ ñ õ
 ûðúò 	ñ
 ùs¥  ‚P,„ M! ¤AP,Á-
P,Á7NÁ8AP,Â?NÃ ;P,Ã;NÃ<P,Ã?N(ÄNÄ	N(ÄN(ÄP,Ä*NÄ+P,Ä17N(Å)N(Å0NÆNÆN(ÆN 
Æ,N 
Æ2A3N(È*AN(É7P,ÊN%ÊP,Ê"+O ËOËO Ë&P,Ë9P'Ë:P,Ì!P,Ì(.P,ÍP*Í
P,Í!N	Í?NÎ N	ÎP,ÎN	Î	P,ÎP,ÎP,ÎN(ÎP,Î
N(Î%P,Î(O	Î.N1Î/
O	Î:O	Î<	P,ÏO ÏP$Ï!O$Ï"P$Ï'P,Ï*P$Ï3P$Ï4PÐPÐPÐP,ÐP$Ð$P,Ð*P,)rL   rU  r'  rJ  r  r_  r^  rK  rV  r‚   rZ  r\  rE   rL  rX  rW  r]  rè   rk   r  rY  r”  r  r`  r[  N)rú   rû   rü   rý   rþ   r½   ri  rn  rs  rx  r�  r…  r‹  r˜  r�  r¡  r®  rT  rÏ  rØ  rè  rÿ   r,   r   r   rH  rH  ë  sg   † ñõ%õ>
õ
sõ_õ5õ
 õNõ
õHõ<zõ
 ò	]õ*õX"õH#÷JIñ Ir   rH  )r   r   r    r!   r"   r#   rß  Ú	unblockedr$   r%   r&   )r   r    r!   r"   r   r%   r&   r$   )é    )9Ú__conditional_annotations__rþ   Ú
__future__r   rá  r¨  ÚreÚ	functoolsr   Úpathlibr   r¹  Útypingr   r   r   Ú
agent.i18nr   Úgateway.kanban_watchers_commonr	   r
   r   r¸  r   r   r   r   rë   r’  r6   r  ÚcompilerD   rJ   rb   rÄ   rc   Ú__annotations__ru   rv   r{   r€   rž   r    r  r  r	  Ú_NLr  r  r"  r+  r2  r8  r@  rF  rH  )rì  s   @r   Ú<module>r÷     sP  øðôõ #ã Û Û 	Ý Ý Û ß *Ñ *å ç [Ñ [Ý 1òò
ò
2ð p€ð J€õ]ð, Ð à—’Ð|Ó}€÷õ/ñ6 "%£Ð �JÓ &õñ* "%£Ð �JÓ &õ	4õWõ
:;÷@ñ õD	õ Oõ
Að €õ7õ
	oõ
võ"õõ*põRð �Øñ ð ˆ|ØÑXØ�ØÑ{ØÐ-ØÐ/ØÐ3ðMÐ ÐIó ÷&Jó Jr   