+
    jHàj=  ã                  óô   € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHtH	t	 ^ RI
Ht ^ RIHtHt ^ RIHtHtHt R tR tRt]	 ! R	 R
4      4       tR R lt ! R R4      t]P2                  R 4       tR R ltR# )a  Embedded kanban dispatcher: settings resolution and per-tick board work.

``GatewayKanbanWatchersMixin._kanban_dispatcher_watcher`` owns the loop,
the singleton lock and the health telemetry; everything that only needs the
``kanban_db`` module and the resolved settings lives here.
)ÚannotationsN)ÚasdictÚ	dataclass)ÚPath)ÚAnyÚOptional)Ú_board_slugsÚ_positive_int_settingÚloggerc                 ó   € ^ RI Hp  V # )é    ©Úkanban_db_connect)Ú
hermes_clir   r   s    ÚG/home/ubuntu/.hermes/hermes-agent/gateway/kanban_watchers_dispatcher.pyÚ_kbcr      s   € Ý,ØÐó    c                 ó   € ^ RI Hp  V # )r   ©Úkanban_db_dispatch)r   r   r   s    r   Ú_kbdr      s   € Ý-ØÐr   c                  ól   € ] tR t^!t$ RtR]R&   R]R&   R]R&   R]R	&   R]R
&   R]R&   R]R&   R]R&   RtR# )Ú_DispatcherSettingszE``kanban.*`` dispatch settings, read once at boot (restart to apply).ÚfloatÚintervalr   Ú	max_spawnzOptional[int]Úmax_in_progressÚintÚfailure_limitÚstale_timeout_secondsÚboolÚreconcile_orphanszOptional[str]Údefault_assigneeÚmax_in_progress_per_profile© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__Ú__static_attributes__r$   r   r   r   r   !   s3   ‡ áOàƒOØƒNØ"Ó"ØÓØÓØÓØ#Ó#Ø!.×.r   r   c               ó$   € V ^8„  d   QhRRRRRR/# )é   Ú
kanban_cfgÚdictÚkbr   Úreturnr   r$   )Úformats   "r   Ú__annotate__r3   /   s'   € ÷ Gñ G¨Tð G°sð GÐ?Rñ Gr   c                óÊ  €  \        V P                  R^<4      ;'       g    ^<4      p\        VR4      pV P                  R4      pVe   \        P                  ! RV4       \        V R4      p\        4       P                  V4      pVf   Ve   \        P                  ! R	V4       V P                  R
VP                  4      p \        V4      pV^8  d.   \        P
                  ! RWaP                  4       VP                  pV P                  R^ 4      p \        T;'       g    ^ 4      p	V P                  R4      ;'       g    RP                  4       ;'       g    Rp
V
'       d   \        P                  ! RV
4       \        VVVVV	\        V P                  RR4      4      V
\        V R4      R7      #   \        \        3 d-    \        P
                  ! RT P                  R4      4       Rp ELÄi ; i  \        \        3 d2    \        P
                  ! RYaP                  4       TP                  p ELei ; i  \        \        3 d    \        P
                  ! RT4       ^ p	 EL:i ; i)zAParse and log the dispatcher settings in their established order.Údispatch_interval_secondszIkanban dispatcher: invalid dispatch_interval_seconds=%r, using default 60g      N@g      ð?r   Nzkanban dispatcher: max_spawn=%sr   z˜kanban dispatcher: kanban.max_in_progress unset; using memory-derived default max_in_progress=%d (set kanban.max_in_progress in config.yaml to override)r   zDkanban dispatcher: invalid kanban.failure_limit=%r; using default %dzGkanban dispatcher: kanban.failure_limit=%r is below 1; using default %dÚdispatch_stale_timeout_secondsz^kanban dispatcher: invalid kanban.dispatch_stale_timeout_seconds=%r; disabling stale detectionr"   Ú zZkanban dispatcher: default_assignee=%r (unassigned ready tasks will route to this profile)r!   Tr#   )r   r   r   r   r   r!   r"   r#   )r   ÚgetÚ
ValueErrorÚ	TypeErrorr
   ÚwarningÚmaxÚinfor	   r   Úresolve_max_in_progressÚDEFAULT_FAILURE_LIMITr   Ústripr   r    )r.   r0   r   r   r   Úeffective_max_in_progressÚraw_failure_limitr   Ú	raw_staler   r"   s   &&         r   Ú_resolve_dispatcher_settingsrD   /   sC  € ðÜ˜Ÿ™Ð(CÀRÓH×NÐNÈBÓOˆô
 �8˜SÓ!€Hà—‘˜{Ó+€IØÒÜ�ŠÐ5°yÔAô
 ,¨JÐ8IÓJ€OÜ $£× >Ñ >¸Ó OÐØÒÐ#<Ò#HÜ�ŠðFð &ô		
ð #Ÿ™ ¸×8PÑ8PÓQÐð1ÜÐ-Ó.ˆð
 �qÔÜ�ŠÐ`Ø(×*BÑ*Bô	Dà×0Ñ0ˆð —‘Ð?ÀÓC€Ið"Ü # I§N N°Ó 3Ðð #Ÿ™Ð'9Ó:×@Ð@¸b×GÑGÓI×QÐQÈTÐßÜ�Šð 2Ø3Cô	Eô ØØØ1Ø#Ø3ô ˜zŸ~™~Ð.AÀ4ÓHÓIØ)ô %:¸*ÐFcÓ$dôð øôm œ	Ð"ô Ü�ŠÐbØ!—~‘~Ð&AÓBô	Dà‹ðûô4 ”zÐ"ô 1Ü�ŠÐ]Ø(×*BÑ*Bô	Dà×0Ñ0‹ð1ûô ”zÐ"ô "Ü�Šð 3Ø4=ô	?à !Óð"ús@   ‚F/  F/ Ã G/ ÄH4 Ä H4 Æ/9G,Ç+G,Ç/>H1È0H1È4*I"É!I"c                  ó    € ] tR t^yt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4       tRtR# )Ú_KanbanDispatchera[  Per-tick board work for the embedded dispatcher (runs in worker threads).

Boards are enumerated every tick so a board created mid-run is picked up
without a restart. Corrupt-looking board DBs are quarantined per
fingerprint and retried after ``CORRUPT_BOARD_RETRY_AFTER_SECONDS``:
transient WAL/open races can look like "malformed" for one tick.
i,  c               ó$   € V ^8„  d   QhRRRRRR/# )r-   r0   r   Úsettingsr   r1   ÚNoner$   )r2   s   "r   r3   Ú_KanbanDispatcher.__annotate__„   s'   € ÷ gñ g˜3ð gÐ*=ð gÀ$ñ gr   c                	ó,   € Wn         W n        / V n        R # ©N)r0   rH   Údisabled_corrupt_boards)Úselfr0   rH   s   &&&r   Ú__init__Ú_KanbanDispatcher.__init__„   s   € ØŒØ ŒØdfˆÖ$r   c               ó   € V ^8„  d   QhRR/# )r-   r1   Úlistr$   )r2   s   "r   r3   rJ   ‰   s   € ÷ %ñ %˜dñ %r   c                	ó,   € \        V P                  4      # rL   )r   r0   )rN   s   &r   r   Ú_KanbanDispatcher._board_slugs‰   s   € Ü˜DŸG™GÓ$Ð$r   c               ó    € V ^8„  d   QhRRRR/# )r-   ÚslugÚstrr1   z"tuple[str, int | None, int | None]r$   )r2   s   "r   r3   rJ   Œ   s   € ÷ :ñ :¨ð :Ð1Sñ :r   c                	ó²  € ^ RI Hp VP                  4       ;_uu_ 4        V P                  P	                  V4      pRRR4        \        XP                  4       P                  4       4      p VP                  4       pYEP                  TP                  3#   + '       g   i     La; i  \         d    \        X4      p LTi ; i  \         d	    TRR3u # i ; i)r   ©Ú	kanban_dbN)r   rZ   Úpin_first_board_resolutionr0   Úkanban_db_pathrW   Ú
expanduserÚresolveÚ	ExceptionÚstatÚOSErrorÚst_mtime_nsÚst_size)rN   rV   Ú_kbÚpathÚresolvedr`   s   &&    r   Úboard_db_fingerprintÚ&_KanbanDispatcher.board_db_fingerprintŒ   s²   € Ý/Ø×+Ñ+×-Õ-Ø—7‘7×)Ñ)¨$Ó/ˆD÷ .ð	!Ü˜4Ÿ?™?Ó,×4Ñ4Ó6Ó7ˆHð	*Ø—9‘9“;ˆDð ×*Ñ*¨D¯L©LÐ9Ð9÷ .×-ûô ô 	!Ü˜4“yŠHð	!ûô ô 	*Ø˜d DÐ)Ò)ð	*ús/   ŸBÁ'B' Á,C ÂB$	Â'C Â?C ÃCÃCc               ó    € V ^8„  d   QhRRRR/# )r-   Úexcr_   r1   r    r$   )r2   s   "r   r3   rJ   š   s   € ÷ rñ r¨Yð r¸4ñ rr   c                	ó  a€ \        S\        4       P                  4      '       d   R # \        S\        P                  4      ;'       dC    \
        ;QJ d#    V3R l\         4       F  '       g   K   R # 	  R# ! V3R l\         4       4      # )Tc              3  óZ   <"  € T F   q\        S4      P                  4       9   x € K"  	  R # 5irL   )rW   Úlower)Ú.0Úmrj   s   & €r   Ú	<genexpr>Ú>_KanbanDispatcher.is_corrupt_board_db_error.<locals>.<genexpr>�   s"   øé € Ð=qÑ]pÐXYÄ3ÀsÃ8Ç>Á>ÓCSÖ>SÓ]pùs   ƒ(+F)Ú
isinstancer   ÚKanbanDbCorruptErrorÚsqlite3ÚDatabaseErrorÚanyÚ_CORRUPT_DB_MARKERS)rN   rj   s   &fr   Úis_corrupt_board_db_errorÚ+_KanbanDispatcher.is_corrupt_board_db_errorš   s[   ø€ Ü�cœ4›6×6Ñ6×7Ò7ÙÜ˜#œw×4Ñ4Ó5×qÐq¿#»#Ô=qÕ]pÓ=q¿#¼#Ðqº#Ðq¸#Ô=qÕ]pÓ=qÓ:qÐqr   c               ó$   € V ^8„  d   QhRRRRRR/# )r-   rV   rW   ÚfingerprintÚtupler1   r    r$   )r2   s   "r   r3   rJ   Ÿ   s!   € ÷ ñ  sð ¸ð À4ñ r   c                óZ  € V P                   P                  V4      pVf   R# Vw  rE\        P                  ! 4       V,
          pWB8X  d   W`P                  8  d   R# WB8X  d   \
        P                  ! RW4       M\
        P                  ! RV4       V P                   P                  VR4       R# )zFReturn False while *slug* stays quarantined; lift (and log) otherwise.NTFzdkanban dispatcher: board %s database fingerprint unchanged after %.0fs quarantine; retrying dispatchz?kanban dispatcher: board %s database changed; retrying dispatch)rM   r8   ÚtimeÚ	monotonicÚ!CORRUPT_BOARD_RETRY_AFTER_SECONDSr
   r=   Úpop)rN   rV   r{   Údisabled_entryÚdisabled_fingerprintÚdisabled_atÚages   &&&    r   Ú_quarantine_liftedÚ$_KanbanDispatcher._quarantine_liftedŸ   s–   € à×5Ñ5×9Ñ9¸$Ó?ˆØÒ!ÙØ,:Ñ)ÐÜ�nŠnÓ Õ,ˆØÔ.°3×9_Ñ9_Ô3_ÙØÔ.Ü�KŠKð DØEIõPô �KŠKÐYÐ[_Ô`Ø×$Ñ$×(Ñ(¨¨tÔ4Ùr   c               ó    € V ^8„  d   QhRRRR/# )r-   rV   rW   r1   zOptional[object]r$   )r2   s   "r   r3   rJ   °   s   € ÷ &!ñ &!¨ð &!Ð0@ñ &!r   c           	     óH  € RpV P                  V4      pV P                  W4      '       g   R# \        V P                  4      P	                  4        UUu/ uF  w  rEVR8w  g   K  WEbK  	  ppp ^ RIHp VP                  4       ;_uu_ 4        \        4       P                  VR7      p\        4       P                  ! V3RV/VB uuRRR4       Ve=   \        P                  ! \        4      ;_uu_ 4        VP                  4        RRR4       # # u uppi   + '       g   i     # ; i  + '       g   i     EM=; i  \         Ed,   pT P!                  T4      '       dž   T\"        P$                  ! 4       3T P&                  T&   \(        P*                  ! RY^ ,          4        Rp?TeR   \        P                  ! \        4      ;_uu_ 4        TP                  4        RRR4       R#   + '       g   i     R# ; iR# \(        P,                  ! RT4        Rp?TeR   \        P                  ! \        4      ;_uu_ 4        TP                  4        RRR4       R#   + '       g   i     R# ; iR# Rp?ii ; i TeR   \        P                  ! \        4      ;_uu_ 4        TP                  4        RRR4       R#   + '       g   i     R# ; iR#   TeP   \        P                  ! \        4      ;_uu_ 4        TP                  4        RRR4       i   + '       g   i     i ; ii ; i)z’Run one dispatch_once for a specific board.

The per-board DB is opened explicitly so boards never share a
connection or claim across each other.
Nr   rY   ©Úboardr‹   a	  kanban dispatcher: board %s database %s is not a valid SQLite database; pausing dispatch for this board until the file changes, the gateway restarts, or the quarantine timer expires. Move or restore the file, then run `hermes kanban init` if you need a fresh board.z*kanban dispatcher: tick failed on board %s)rg   r†   r   rH   Úitemsr   rZ   r[   r   Úconnectr   Údispatch_onceÚ
contextlibÚsuppressr_   Úcloserx   r~   r   rM   r
   ÚerrorÚ	exception)	rN   rV   Úconnr{   ÚkÚvÚkwargsrd   rj   s	   &&       r   Útick_once_for_boardÚ%_KanbanDispatcher.tick_once_for_board°   sF  € ð ˆØ×/Ñ/°Ó5ˆØ×&Ñ& t×9Ò9ÙÜ#)¨$¯-©-Ó#8×#>Ñ#>Ô#@ÔTÑ#@™4˜1ÀAÈÁO”$�!’$Ñ#@ˆÑTð	!õ 4Ø×/Ñ/×1Õ1Ü“v—~‘~¨D�~Ó1�Ü“v×+Ò+¨DÑG¸ÐGÀÑG÷ 2Ñ1ð$ ÒÜ×(Ò(¬×3Õ3Ø—J‘J”L÷ 4Ð3ð  ùó5 U÷6 4×3ú÷' 2×1Ð1ûô õ 	Ø×-Ñ-¨c×2Ò2Ø6AÄ4Ç>Â>ÓCSÐ5T�×,Ñ,¨TÑ2Ü—’ðOð
  a�.ôó ð ÒÜ×(Ò(¬×3Õ3Ø—J‘J”L÷ 4×3×3Ò3úñ  ô ×ÒÐIÈ4ÔPÛàÒÜ×(Ò(¬×3Õ3Ø—J‘J”L÷ 4×3×3Ò3úñ  ûð	úð 2ð$ ÒÜ×(Ò(¬×3Õ3Ø—J‘J”L÷ 4×3×3Ò3úñ  øˆtÒÜ×(Ò(¬×3Õ3Ø—J‘J”L÷ 4×3×3Ð3úð  úsµ   ÁDÁ#DÁ-D: Â7D&Ã
D: Ã2DÄD#Ä&D7	Ä1D: Ä5K Ä7D: Ä:I1ÅAI,ÆK Ç	G$Ç$G5	Ç:I,ÈK ÈK È;IÉI'	É,I1É1K ÊJ6Ê6K	Ë'L!Ë3L	Ì	L!ÌLÌ	L!c               ó   € V ^8„  d   QhRR/# )r-   r1   z"list[tuple[str, Optional[object]]]r$   )r2   s   "r   r3   rJ   Ø   s   € ÷ Xñ XÐ=ñ Xr   c                ól   € V P                  4        Uu. uF  qV P                  V4      3NK  	  up# u upi )z>Run one dispatch_once per board. Returns (slug, result) pairs.)r   r˜   )rN   rV   s   & r   Ú	tick_onceÚ_KanbanDispatcher.tick_onceØ   s3   € àCG×CTÑCTÔCVÓWÑCV¸4�t×/Ñ/°Ó5Ó6ÑCVÑWÐWùÒWs   “1c               ó   € V ^8„  d   QhRR/# )r-   r1   r    r$   )r2   s   "r   r3   rJ   Ü   s   € ÷ ñ  ñ r   c                óp  € \        4       pVP                  4       p^ RIHp VP	                  4       ;_uu_ 4        V P                  4        Fâ  pRp \        4       P                  VR7      pVP                  V4      '       g    V'       dc   VP                  V4      '       dL    Ve<   \        P                  ! \        4      ;_uu_ 4        VP                  4        RRR4        RRR4       R# Te>   \        P                  ! \        4      ;_uu_ 4        TP                  4        RRR4       Kâ  Kä  	  RRR4       R#   + '       g   i     Lj; i  \         d]     Tf   EK  \        P                  ! \        4      ;_uu_ 4        TP                  4        RRR4       EKT    + '       g   i     EKf  ; ii ; i  + '       g   i     EK  ; i  TeP   \        P                  ! \        4      ;_uu_ 4        TP                  4        RRR4       i   + '       g   i     i ; ii ; i  + '       g   i     R# ; i)u�  Is there a ready+assigned+unclaimed task on ANY board the dispatcher would spawn for?

Control-plane lanes (e.g. ``orion-cc``) are pulled by terminals via
``claim_task`` and never spawnable â€” a queue full of those is
"correctly idle", not "stuck". The review column is probed only when
review dispatch is on (same gate as the dispatcher): a task waiting
for a human reviewer is idle, not stuck.
rY   NrŠ   TF)r   Úreview_dispatch_enabledr   rZ   r[   r   r   r�   Úhas_spawnable_readyÚhas_spawnable_reviewr�   r�   r_   r‘   )rN   ÚkbdÚ_review_proberd   rV   r”   s   &     r   Úready_nonemptyÚ _KanbanDispatcher.ready_nonemptyÜ   s†  € ô ‹fˆØ×3Ñ3Ó5ˆÝ/Ø×+Ñ+×-Õ-Ø×)Ñ)Ö+�Ø�ð	)Ü›6Ÿ>™>°˜>Ó5�DØ×.Ñ.¨t×4Ò4¿È3×KcÑKcÐdh×KiÒKiØ#ð Ò'Ü'×0Ò0´×;Õ;Ø ŸJ™JœL÷ <ø÷ .Ñ-ð Ò'Ü'×0Ò0´×;Õ;Ø ŸJ™JœL÷ <Ñ;ñ (ñ ,÷ .ñ ÷ <×;ûô	 !ô ØàÕ'Ü'×0Ò0´×;Õ;Ø ŸJ™JœL÷ <×;×;Ô;úð	ú÷ <×;Ñ;ûð Ò'Ü'×0Ò0´×;Õ;Ø ŸJ™JœL÷ <×;×;Ð;úð (ú÷ .Ö-ñ ús³   ¹H$Á8EÂ	EÂ!&H$ÃD:Ã	H$Ã+&H$ÄF7Ä"H$Ä:E
ÅH$ÅF4	ÅGÅH$Å "H$ÆFÆH$ÆF0Æ)
H$Æ3F4	Æ4GÆ7G	Ç
H$Ç'H!	Ç3HÈ	H!	ÈHÈ	H!	È!H$È$H5	c               ó    € V ^8„  d   QhRRRR/# )r-   Úauto_decompose_per_tickr   r1   r$   )r2   s   "r   r3   rJ   ÷   s   € ÷ &ñ &¸3ð &À3ñ &r   c                óÆ  €  ^ RI Hp ^ p^ p^ RI Hp \        4       ;_uu_ 4        TP                  4       ;_uu_ 4        T P                  4        Fº  pYA8¼  d    M³\        P                  P                  R4      p T\        P                  R&    TP                  4       p	T	 F,  p
YA8¼  d    M%T^,          pYPP                  Y'T
4      ,          pK.  	  Tf#   \        P                  P                  RR4       K§  T\        P                  R&   K¼  	  RRR4       RRR4       T#   \         d#   p\        P                  ! RT4        Rp?^ # Rp?ii ; i  \         d$   p\        P                  ! RYs4       . p	 Rp?LÚRp?ii ; i  Tf"   \        P                  P                  RR4       i T\        P                  R&   i ; i  + '       g   i     L¸; i  + '       g   i     T# ; i)z×Auto-decompose up to N triage tasks across all boards into ready workgraphs.

Runs before dispatch fans out; the per-tick cap keeps a bulk triage
load from burst-spending the aux LLM. Returns the number decomposed.
)Úkanban_decomposez3kanban auto-decompose: import failed (%s); skippingNrY   ÚHERMES_KANBAN_BOARDz>kanban auto-decompose: list_triage_ids failed on board %s (%s))r   rª   r_   r
   r;   rZ   Ú_default_profile_secret_scoper[   r   ÚosÚenvironr8   Úlist_triage_idsÚdebugÚ_decompose_oner�   )rN   r¨   Ú_decomprj   Ú	attemptedÚ	successesrd   rV   Úprev_envÚ
triage_idsÚtids   &&         r   Úauto_decompose_tickÚ%_KanbanDispatcher.auto_decompose_tick÷   s†  € ð	Ý>ð ˆ	Øˆ	Ý/Ü*×,Õ,¨c×.LÑ.L×.NÕ.NØ×)Ñ)Ö+�ØÔ7Ùô Ÿ:™:Ÿ>™>Ð*?Ó@�ðEØ8<”B—J‘JÐ4Ñ5ð(Ø%,×%<Ñ%<Ó%>˜
ó  *˜Ø$Ô?Ù!Ø! Q�˜	Ø!×%8Ñ%8¸ÈÓ%LÕLš	ñ	  *ð  Ò'ÜŸ
™
Ÿ™Ð'<¸dÖCà<DœŸ
™
Ð#8Ó9ñ- ,÷ /O×,ð0 Ðøô= ô 	Ü�NŠNÐPÐRUÔVÝûð	ûô" %ô (ÜŸšÐ%eÐgkÔqØ%'�
ûð(ûð  Ò'ÜŸ
™
Ÿ™Ð'<¸dÕCà<DœŸ
™
Ð#8Ò9ú÷/ /O×.Nú×,Ö,ð0 Ðús{   ‚D ¤G½;F<	Á9E?
ÂE
Â2E?
Ã=F<	ÄGÄEÄ)EÅEÅE<ÅE7Å2E?
Å7E<Å<E?
Å?:F9Æ9F<	Æ<GÇGÇG 	c               ó(   € V ^8„  d   QhRRRRRRRR/# )r-   r²   r   rV   rW   r·   r1   r   r$   )r2   s   "r   r3   rJ      s(   € ÷ ñ  ð ¨3ð °Sð ¸Sñ r   c                ó¼  €  V P                  VRR7      pTP                  '       g%   \        P
                  ! RYTP                  4       ^ # TP                  '       d@   TP                  '       d.   \        P                  ! RY\        TP                  4      4       ^# \        P                  ! RY4       ^#   \         d    \        P                  ! RT4        ^ # i ; i)z=Decompose one triage task; returns 1 on success, 0 otherwise.zauto-decomposer)Úauthorz3kanban auto-decompose: decompose_task crashed on %sz*kanban auto-decompose [%s]: %s skipped: %su.   kanban auto-decompose [%s]: %s â†’ %d childrenu:   kanban auto-decompose [%s]: %s â†’ single task (no fanout))Údecompose_taskr_   r
   r“   Úokr°   ÚreasonÚfanoutÚ	child_idsr=   Úlen)r²   rV   r·   Úoutcomes   &&& r   r±   Ú _KanbanDispatcher._decompose_one  sµ   € ð	Ø×,Ñ,¨SÐ9JÐ,ÓKˆGð �z�zˆzä�LŠLÐEÀtÐRY×R`ÑR`ÔaÙØ�>�>ˆ>˜g×/×/Ð/Ü�KŠKÐHÈ$ÔUXÐY`×YjÑYjÓUkÔlñ ô �KŠKÐTÐVZÔ`Ùøô ô 	Ü×ÒÐRÐTWÔXÚð	ús   ‚B5 Â5"CÃC)rM   r0   rH   N)r%   r&   r'   r(   r)   r€   rO   r   rg   rx   r†   r˜   rœ   r¥   r¸   Ústaticmethodr±   r+   r$   r   r   rF   rF   y   sU   † ñð ),Ð%õgõ
%õ:õrõ
õ"&!õPXõõ6&ðP ôó ôr   rF   c               #  óì   "  € ^ RI Hp HpHp ^ RIHp ^ RIHp V ! 4       '       g   Rx € R# V! V! \        V! 4       4      4      \        V! 4       4      R7      p Rx € V! V4       R#   T! T4       i ; i5i)aj  Install the gateway launch profile's secret scope while multiplexing is on.

The tick runs via ``_to_thread_process_service`` in a fresh context, so no
per-turn scope exists and ``get_secret`` fails closed. The decomposer's aux
LLM reads ``auxiliary.*`` from ``get_hermes_home()``, so its credentials come
from that same home. No-op for single-profile gateways.
)Úis_multiplex_activeÚreset_secret_scopeÚset_secret_scope)Úget_hermes_home)Úowner_secret_scopeN)Úprofile_home)
Úagent.secret_scoperÇ   rÈ   rÉ   Úhermes_constantsrÊ   Ú!tui_gateway.launch_profile_policyrË   r   rW   )rÇ   rÈ   rÉ   rÊ   rË   Útokens         r   r¬   r¬   2  s`   é € ÷ ]Ñ\Ý0ÝDá× Ò ÛÙÙÑ/´±_Ó5FÓ0GÓHÔWZÑ[jÓ[lÓWmÔn€Eð"Ûá˜5Ö!øÑ˜5Õ!üs   ‚AA4ÁA' Á
A4Á'
A1Á1A4c               ó    € V ^8„  d   QhRRRR/# )r-   ÚresultszOptional[list]r1   r    r$   )r2   s   "r   r3   r3   I  s   € ÷ ñ  ð °4ñ r   c                ó  € RpT ;'       g    .  Fù  w  r#Vf   K  \        VRR4      '       g   K   Rp\        P                  ! RT\        VP                  4      VP
                  \        VP                  R4      '       d   \        VP                  4      M^ \        VP                  R4      '       d   \        VP                  4      M^ VP                  \        VP                  R4      '       d   \        VP                  4      M^ 4       Kû  	  V# )zALog per-board spawn summaries; returns whether any board spawned.FNÚspawnedTzckanban dispatcher [%s]: spawned=%d reclaimed=%d crashed=%d timed_out=%d promoted=%d auto_blocked=%dÚ__len__)Úgetattrr
   r=   rÂ   rÔ   Ú	reclaimedÚhasattrÚcrashedÚ	timed_outÚpromotedÚauto_blocked)rÒ   Úany_spawnedrV   Úress   &   r   Ú_log_spawn_resultsrß   I  sÇ   € à€KØ—m�m ’m‰	ˆØŒ?œw s¨I°t×<Ô<ØˆKä�KŠKðFà”c˜#Ÿ+™+Ó&¨¯©Ü$+¨C¯K©K¸×$CÒ$C”�C—K‘KÔ ÈÜ&-¨c¯m©m¸Y×&GÒ&G”�C—M‘MÔ"ÈQØ—‘Ü)0°×1AÑ1AÀ9×)MÒ)M”�C×$Ñ$Ô%ÐSTöñ	 $ð Ðr   )zfile is not a databasez database disk image is malformed)r)   Ú
__future__r   r�   r­   rt   r~   Údataclassesr   r   Úpathlibr   Útypingr   r   Úgateway.kanban_watchers_commonr   r	   r
   r   r   rw   r   rD   rF   Úcontextmanagerr¬   rß   r$   r   r   Ú<module>ræ      s‰   ðñõ #ã Û 	Û Û ß )Ý ß  ç VÑ Vòò
ð UÐ ð ÷
/ð 
/ó ð
/õG÷Tvñ vðr ×Ññ"ó ð"÷,r   