+
    jHàjŽU ã                   ó†  a € ERG EtL0 t R t^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHtHtHt  ^ RIt^ RIHt ^ RIHtHtHtHtH t H!t!H"t" ]PF                  PI                  ^ ]%! ]! ]&4      PN                  PN                  4      4       ^ RI(H)t)H*t* ^ RI+H,t,H-t- ^ RI.H/t/H0t0 ^ R	I1H2t2 ^ R
I3H4t4 ^ RI5H6t6H7t7 ^ RI8H9t9H:t: ^ RI;H<t=H>t> ^ RI?H@t@ ^ RIAHBtBHCtC ^ RIDHEtE ^ RIFHGtG ^ RIHHItI ]	P”                  ! ]K4      tLR tMR R ltNR R ltOERHR R lltPR R ltQR R ltRR R ltS ! R  R!]T4      tU]P¬                  ! R"4      tWR# R$ ltXR% R& ltYR' R( ltZR)t[R* R+ lt\R, R- lt]R.R/R/ R0 llt^R1 R2 lt_R3 R4 lt` ! R5 R6]a4      tbR7 R8 ltcR9 R: ltdR; R< lteR= R> ltf^ R?IgHhthHitiHjtjHktkHltlHmtmHntnHotoHptpHqtqHrtrHstsHtttHutu ^ R@IvHwtw ^ RAIxHytyHztz ^ RBI{H|t|H}t}H~t~HtH€t€H�t�H‚t‚HƒtƒH„t„H…t… ^ RCI†H‡t‡Hˆtˆ ^ RDI‰HŠtŠ REt‹RFtŒRG RH lt�RI RJ ltŽ/ t�] ^ k / t�] ^k ERHRK RL llt‘/ t’] ^k RM RN lt“RO RP lt”]•! 4       t–] ^k / t—] ^k ]•! 4       t˜] ^k / t™] ^k ]•! 4       tš] ^k ]EP6                  ! 4       tœ/ t�] ^k / tž] ^	k / tŸ] ^
k ] ! 4       t¡/ t¢] ^k ^ s£] ^k . t¤] ^k ^t¥RQt¦]•! 4       t§] ^k  ! RR RS]!4      t¨ ! RT RU4      t©RV RW ltªRX RY lt«RZ R[ lt¬R\ R] lt­R^ R_ lt®ERHR` Ra llt¯Rb Rc lt°RdRRe]¡/Rf Rg llt±ERHRdR/Rh Ri lllt²Rj Rk lt³/ t´] ^k Rl Rm ltµRn Ro lt¶Rp Rq lt·Rr Rs lt¸Rt Ru lt¹Rv Rw ltºRx Ry lt»ERHRz R{ llt¼R|R/R} R~ llt½ERHR R€ llt¾ERHR� R‚ llt¿Rƒ R„ ltÀR… R† ltÁR‡ Rˆ ltÂR‰ RŠ ltÃ]EPˆ                  ! ]Ã4       R‹ RŒ ltÅR� RŽ ltÆR� R� ltÇERHR‘ R’ lltÈRtÉ] ^k 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Ñ]ÑtÒR¢tÓ]Ó^,          tÔR£tÕR¤ R¥ ltÖR¦R/R§ R¨ llt× ! R© Rª4      tØR« R¬ ltÙR­ R® ltÚR¯ R° ltÛR± R² ltÜ] ! R³ R´4      4       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æERHRÇ RÈ lltçRÉ RÊ ltèERHRË RÌ lltéRÍ RÎ ltêRÏRÐ/RÑ RÒ lltë]ì]í]%]%] ]%,          3,          tîRÓ RÔ ltïERItð ! RÕ RÖ4      tñR× RØ ltò] ! RÙ RÚ4      4       tóRÛ RÜ ltôRÝ RÞ ltõ ! Rß Rà4      töRáRRâRRãRRäR/Rå Ræ llt÷R¦R/Rç Rè lltøRé Rê ltùRëRRìRRíRîRâRRãR/Rï Rð lltúRñtûRò Ró ltüRôRî/Rõ Rö lltý ! R÷ Rø]a4      tþ ! Rù Rú4      tÿ] ! Rû Rü4      4       Et Rý Rþ lEtRÿ ER  lEtER ER lEtER ER lEt]EP
                  ER 4       EtER ER lEtER ER	 lEtRëRRìRRíRîRâRER
RERRERR/ER ER llEt	ERR/ER ER llEt
 ! ER ER]T4      EtERRERERJERR/ER ER llEtER ER lEtER ER lEtER ER lEt ! ER ER]T4      EtER  ER! lEtER"Et/ Et] ^k ERKEtREs] ^k ]EP6                  ! 4       EtER# ER$ lEtER% ER& lEtER' EtER( ER) lEtER* ER+ lEtER, ER- lEtER. ER/ lEtER0 ER1 lEtER2 ER3 lEtER4 ER5 lEt ER6 ER7 lEt!^ ER8EI"EH#Et# ^ ER9EI$EH%Et%EH&Et&EH'Et'EH(Et(EH)Et) ^ ER:EI*EH+Et+EH,Et,EH-Et- ^ ER;EI.EH/Et/EH0Et0EH1Et1EH2Et2EH3Et3EH4Et4EH5Et5EH6Et6EH7Et7EH8Et8 ^ ER<EI9EH:Et:EH;Et;EH<Et<EH=Et=EH>Et>EH?Et? ]KER=8X  dá   ER>]EP€                  9   d¾   ]*! 4        ^ REIAEtAE]AEP„                  ! RîER?7      EtCE]CEP‰                  ER>]ER@ERA7       E]CEP‰                  ERB]ER@ERA7       E]CEP‹                  4       EtF ^ ERCEIGEHHEtH E]H! ]Ê! 4       ERDERE7       E]I! E]! E]FEP”                  E]FEP–                  4      '       d   ^ 4      h^4      hE]#! ER@ER@ERF7       R# R#   ] d    Rt ^ RIt ELÉ  ] d    Rt  ELÖi ; ii ; i  ]a d     Lxi ; i(L  z»Cron job scheduler: tick() runs due jobs (gateway calls it every 60s from a background thread).
A file lock (~/.hermes/cron/.tick.lock) keeps overlapping processes to one tick at a time.
N)Ú	dataclass)ÚdatetimeÚtimezoneÚUTC©ÚPath)ÚAnyÚCallableÚDictÚListÚOptionalÚProtocolÚUnion)ÚWORKER_MARKERÚfinish_worker_boot)Úget_hermes_homeÚhermes_home_key)Únote_cron_executionÚnote_cron_skipped)Úcron_env_setting)Úwindows_hide_flags)Úload_configÚload_config_readonly)Úget_fallback_chainÚscoped_fallback_chain)ÚnowÚsafe_strftime)Úrequest_hard_interrupt)Ú"enter_non_dispatcher_owned_contextÚ!exit_non_dispatcher_owned_context)Ú	ctx_bound)ÚAwakeIdleMeter)Úis_max_iteration_handoffc                ó0  € V '       d	   V'       g   R# T;'       g    RP                  4       pV'       g   R#  V P                  W4       V#   \         d@    \        T RR4      pTf   h T! T4      pT'       d   YS8X  d   h T P                  Y4       Tu # i ; i)aw  Persist a non-blank, unique title for a finished cron session; returns it (None if unset).
Runs BEFORE end_session()/close() so no write races the close. Duplicate title (unique-index
ValueError) -> get_next_title_in_lineage(); if unavailable, raise rather than end up untitled.

Centralizes the title write so the cron finally block can guarantee a non-blank, unique title is
persisted before end_session()/close() tear the connection down (issues #50535, #50536, #50537):
- #50535: never leaves the session blank. base_title already carries a cron-id fallback for nameless
jobs; this also guards a failed write. Recover by appending a #N suffix via get_next_title_in_lineage()
when supported, instead of swallowing the error and ending up untitled. - #50536: this runs
synchronously in the cron finally block ahead of the session close, so no in-flight title write can race
the close.
NÚ Úget_next_title_in_lineage)ÚstripÚset_session_titleÚ
ValueErrorÚgetattr)Ú
session_dbÚ
session_idÚ
base_titleÚtitleÚnext_title_fnÚdedupeds   &&&   Ú3/home/ubuntu/.hermes/hermes-agent/cron/scheduler.pyÚ_set_cron_session_titler1   :   s�   € ÷ ŸZÙØ×Ð˜2×$Ñ$Ó&€EßÙðØ×$Ñ$ ZÔ7ØˆøÜô 	ä 
Ð,GÈÓNˆØÒ ØÙ Ó&ˆß˜'Ô*ØØ×$Ñ$ ZÔ9ØŠð	ús   ¸A Á,BÁ8BÂBc                ó0   € V ^8„  d   QhR\         R\        /# ©é   ÚjobÚreturn©ÚdictÚbool)Úformats   "r0   Ú__annotate__r;   [   s   € ÷ jñ jœ4ð j¤Dñ jó    c                óx   a € \         ;QJ d    V 3R lR 4       F  '       g   K   R# 	  R# ! V 3R lR 4       4      # )zµTrue when the job carries its own provider, model or endpoint. Unpinned jobs store none of
these (they follow the main model at fire time), so any value is an explicit operator pin.c              3   ó    <"  € T FC  p\        SP                  V4      \        4      ;'       d    SV,          P                  4       x € KE  	  R # 5i©N)Ú
isinstanceÚgetÚstrr&   )Ú.0Úkr5   s   & €r0   Ú	<genexpr>Ú$_job_route_pinned.<locals>.<genexpr>^   s7   øé € ÐiÑGhÀ!Œz˜#Ÿ'™' !›*¤cÓ*×=Ð=¨s°1­v¯|©|«~Ô=ÓGhùs
   ƒ*A® ATF)ÚproviderÚmodelÚbase_url)Úany)r5   s   fr0   Ú_job_route_pinnedrK   [   s0   ø€ ÷ ‹3ÔiÑGhÓi�3Œ3ÐiŠ3Ðiˆ3ÔiÑGhÓiÓiÐir<   c                óR   € V ^8„  d   QhR\         R\        R\        \        ,          /# ©r4   r5   Úcfgr6   )r8   r   r   Úlist)r:   s   "r0   r;   r;   a   s*   € ÷ 	Xñ 	XœTð 	X¬ð 	X´¼µñ 	Xr<   c                óD   € \        \        V4      R\        V 4      RR7      # )aÉ  The fallback chain this job may walk, at credential resolution AND mid-run (#100437).

A pinned job never borrows the global ``fallback_providers`` chain, the same rule a pinned
``delegate_task`` child follows (``scoped_fallback_chain``): a chain entry is a different
provider and usually a different model, which is exactly what the pin ruled out. Same-provider
credential-pool rotation is not the chain and still applies. Unpinned jobs inherit the chain.
Núcron job)ÚpinnedÚowner)r   r   rK   )r5   rN   s   &&r0   Ú_job_fallback_chainrT   a   s'   € ô !Ü˜3Ó Ô.?ÀÓ.DÈJôXð Xr<   c                óF   € V ^8„  d   QhR\         \        ,          R\        /# r3   )r   r8   rB   )r:   s   "r0   r;   r;   m   s   € ÷ ñ ¤¬¥ð ¼#ñ r<   c                óÔ   € V e'   \        V 4      '       d   RV P                  R4       R2#  \        4       ;'       g    / p\        V4      pT'       d   R#  R#   \         d     R# i ; i)uç   Backup-provider clause for a provider-failure notice: "pinned, no fallback" vs "the backups
failed too" vs "none configured" (most installs). Fails open to "the backups failed too" if
config can't be read â€” never crash delivery.
zrThis job is pinned to its own provider/model, so it does not fall back to `fallback_providers`; `hermes cron edit Úidz? --unpin` lets it follow the main model and its fallback chain.z$No backup provider succeeded either.uœ   No backup provider is configured â€” add one with `hermes fallback add`, or set a cron-wide default via `cron.model` + `cron.model_provider` in config.yaml.)rK   rA   r   r   Ú	Exception)r5   rN   Úchains   &  r0   Ú_fallback_chain_phraserZ   m   s{   € ð
 ‚Ô,¨S×1Ò1ð7Ø7:·w±w¸t³}°oð F1ð1ð	
ð
6Ü‹m×!Ð!˜rˆÜ" 3Ó'ˆ÷ Ù5ð	^ñøô	 ô 6Ú5ð6ús   ¬A ½A ÁA'Á&A'c                ó0   € V ^8„  d   QhR\         R\        /# r3   ©r8   rB   )r:   s   "r0   r;   r;   …   s   € ÷ ñ œtð ¬ñ r<   c                óB  € V P                  R4      ;'       g    / P                  R4      pVR9  d   R#  \        4       ;'       g    / p\        \        V\        4      '       d   VP                  R4      ;'       g    / M/ P                  R^4      4      pV^ 8:  d   R# \        V P                  R4      ;'       g    ^ 4      ^,           pWC8  d   R# V P                  R4      ;'       g    V P                  R4      ;'       g    R	pR
V RV R2#   \
         d    ^p Lˆi ; i)zêReview nudge when a recurring job keeps failing, else "". The failure message is delivered
BEFORE mark_job_run records this run, hence stored ``failure_streak`` + 1. Threshold:
``cron.failure_nudge_threshold`` (default 3, 0 disables).ÚscheduleÚkindÚcronr$   Úfailure_nudge_thresholdÚfailure_streakÚnamerW   zthis jobz
This job has failed u^    runs in a row â€” worth a review. Fix its prompt/config, or pause it with `hermes cron pause z3` (resume/remove also available) to stop the noise.>   r`   Úinterval)rA   r   Úintr@   r8   rX   )r5   Úschedule_kindrN   Ú	thresholdÚstreakÚjob_refs   &     r0   Ú_failure_streak_nudgerj   …   s  € ð —W‘W˜ZÓ(×.Ð.¨B×3Ñ3°FÓ;€MØÐ0Ô0ÙðÜ‹m×!Ð!˜rˆÜÜ(2°3¼×(=Ò(=ˆc�g‰g�f‹o×#Ð# øÀ2×JÑJØ)¨1óó
ˆ	ð �A„~ÙÜ�—‘Ð)Ó*×/Ð/¨aÓ0°1Õ4€FØÔÙØ�g‰g�f‹o×<Ð< §¡¨£×<Ð<°*€Gà
   ð )FØFMÀYð O<ð	<ðøô ô ØŠ	ðús   µD Á5D Á<D ÄDÄDc                óT   € V ^8„  d   QhR\         \        \        3,          R,          /# ©r4   r6   N©ÚtuplerB   )r:   s   "r0   r;   r;   ¢   s    € ÷ ñ ¤5¬¬c¨¥?°TÕ#9ñ r<   c                 óB   €  ^ RI Hp  V ! 4       #   \         d     R# i ; i)z›Boot-vs-disk revision skew for THIS process, or None. Test seam over
``gateway.code_skew.detect_code_skew``; a broken import must never take delivery down.©Údetect_code_skewN)Úgateway.code_skewrq   rX   rp   s    r0   Ú_detect_gateway_code_skewrs   ¢   s%   € ðÝ6áÓ!Ð!øÜô Úðúó   ‚ ��c                ó2   € V ^8„  d   QhR\         R,          /# rl   ©rB   )r:   s   "r0   r;   r;   ­   s   € ÷ ñ ¤3¨¥:ñ r<   c                 óB   €  ^ RI Hp  V ! 4       #   \         d     R# i ; i)zRFull revision currently on disk; kept separate from display-shortened skew labels.©Úcurrent_code_shaN)rr   ry   rX   rx   s    r0   Ú_current_gateway_code_sharz   ­   s%   € ðÝ6áÓ!Ð!øÜô Úðúrt   c                   óB   a a€ ] tR t^·t oRtV3R lV 3R lltRtVtV ;t# )ÚCronTickYieldeduÌ  A stale-code ticker yielded this tick to a fresh gateway.

Raised by ``tick()`` BEFORE the tick lock when boot fingerprint â‰  disk, this process does NOT
own the runtime lock and its live holder reports the disk revision â€” the stale process must
stay out of the dispatch race (contention would starve the fresh ticker). Skew ``None`` never
yields (fail open). Raised, not returned, so ``record_ticker_error`` sees it and ``hermes cron
status`` isn't green.
c                ó*   <€ V ^8„  d   QhRS[ RS[ RR/# )r4   Úboot_revÚdisk_revr6   Nrv   )r:   Ú__classdict__s   "€r0   r;   ÚCronTickYielded.__annotate__Á   s"   ø€ ÷ 
ñ 
¡ð 
±ð 
¸ñ 
r<   c                óL   <€ Wn         W n        \        SV `  R V RV R24       R# )zDCron tick yielded to a fresh gateway process (stale code: booted on ú, disk is at Ú)N)r~   r   ÚsuperÚ__init__)Úselfr~   r   Ú	__class__s   &&&€r0   r†   ÚCronTickYielded.__init__Á   s1   ø€ Ø ŒØ ŒÜ‰ÑðØ!˜
 -°¨z¸ð<ö	
r<   )r~   r   )	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r†   Ú__static_attributes__Ú__classdictcell__Ú__classcell__©rˆ   r€   s   @@r0   r|   r|   ·   s   ù‡ € ñ÷
÷ 
ó 
r<   r|   z/stale code: booted on (\S+), disk is at (\S+)\)c                ón   € V ^8„  d   QhR\         R,          R\        \         \         3,          R,          /# )r4   Úrecorded_errorNr6   ©rB   rn   )r:   s   "r0   r;   r;   Í   s+   € ÷ 
?ñ 
?¬C°$­Jð 
?¼5ÄÄcÀ½?ÈTÕ;Qñ 
?r<   c                óâ   € V '       d&   V P                  \        P                  4      '       g   R# \        P	                  V 4      pV'       d#   VP                  ^4      VP                  ^4      3# R# )a?  ``(boot_rev, disk_rev)`` when a persisted ``ticker_last_error`` is a ``CronTickYielded``.

``hermes cron status`` runs in another process and only sees the marker text; a yielding
ticker still refreshes its heartbeat, so this is the one signal that separates "stale code,
firing nothing" from a healthy loop (#117275).
N)Ú
startswithr|   rŠ   Ú_STALE_YIELD_REÚsearchÚgroup)r”   Úmatchs   & r0   Ústale_code_yield_labelsrœ   Í   sR   € ÷  ×!:Ñ!:¼?×;SÑ;S×!TÒ!TÙÜ×"Ñ" >Ó2€Eß/4ˆE�K‰K˜‹N˜EŸK™K¨›NÐ+Ð>¸$Ð>r<   c                óT   € V ^8„  d   QhR\         \        \        3,          R,          /# rl   rm   )r:   s   "r0   r;   r;   Ú   s    € ÷ #ñ #¬U´3¼°8­_¸tÕ-Cñ #r<   c                 óú   € \        4       p V f   R# \        4       pVf   R#  ^ RIHpHp \        4       pV! V4      '       d   R# V! V4      pVe   VP                  R4      V8w  d   R#  V #   \         d     R# i ; i)u@  ``(boot_rev, disk_rev)`` when THIS profile's tick must yield to a fresher gateway, else None.

Yields only when ALL hold: code skew, this process is not the cron owner for the profile being
ticked, and another live host gateway whose served set covers that profile reports a fresh
heartbeat on the disk revision. Every probe failure returns None â€” yielding is a certainty
claim, never a guess.

The question is asked PER PROFILE. One process multiplexes every profile, so "do I own the
runtime lock" (process-global, stamped at boot for the launch home) cannot answer it: a
stale multiplexer that holds the lock must still keep ticking the profiles nobody else ticks,
and must still yield the ones a fresher gateway serves.

``gateway_state.json`` is per-HOME and last-writer-wins, not per-process: during a
``--replace`` takeover both the stale and the fresh gateway stamp it, so which one this
predicate reads is write-order dependent. The pid equality in ``live_gateway_ticking`` is what
binds the record to the current lock holder; the takeover window itself fails open (no yield).
N)Úlive_gateway_tickingÚowns_cron_tick_forÚcode_sha)rs   rz   Úcron.scheduler_ownershiprŸ   r    Ú_get_hermes_homerA   rX   )ÚskewÚdisk_sharŸ   r    ÚhomeÚholder_statuss         r0   Ú#_should_yield_tick_to_fresh_gatewayr¨   Ú   s‰   € ô$ %Ó&€DØ‚|ÙÜ(Ó*€HØÒÙð
ßUäÓ!ˆÙ˜d×#Ò#ÙÙ,¨TÓ2ˆØÒ  M×$5Ñ$5°jÓ$AÀXÔ$MÙð %Nð €Køô ô Úðús   ¢ A+ Á"A+ Á+A:Á9A:c                óJ   € V ^8„  d   QhR\         R\        R,          R\        /# )r4   r5   ÚerrorNr6   r\   )r:   s   "r0   r;   r;      s*   € ÷ Bñ B¬dð B¼3À½:ð BÌ#ñ Br<   c           	     ó  € ^ RI HpHpHpHpHp V P                  R4      ;'       g    V P                  R4      ;'       g    RpV P                  R4      ;'       g    TpT;'       g    RP                  4       p	V	P                  4       p
V
P                  R4      '       d	   V! Wx4      # \        P                  ! RV
4      '       d	   V! Wx4      # V P                  R4      '       g1   V! WxV! V	4      \        V 4      V P                  R	4      R
7      pVe   V# \        P                  ! RRV	R,          4      p\        P                  ! RRV4      P                  4       P                  R4      p\        V4      ^´8”  d   VR,          P                  4       R,           pV! WxV4      pV P                  R4      '       gB   \        P                  ! RV
4      '       d%    \!        4       pVe   Vw  ppVRV RV R2,          pV#   \"         d    Rp L*i ; i)a[  One-line failure notice for chat delivery (full details stay in the run output).

Deterministic scheduler/script shapes are matched first (their text can contain "timed out"
and would otherwise be blamed on the model service); everything else goes through the shared
``classify_api_error`` verdict and the copy table in ``scheduler_failure_copy``.)Úclassify_cron_failure_reasonÚgeneric_failure_noticeÚinactivity_noticeÚprovider_failure_noticeÚscript_timeout_noticerc   rW   rQ   zunknown errorzscript timed outzidle for \d+s\s*\(limit \d+s\)Úno_agentrG   )Úbackup_provider_phraserG   Nz8^(RuntimeError|Exception|ValueError|HTTPStatusError):\s*r$   :NiÐ  Nz\s+Ú Ú.:Né±   Nz...z2cannot import name|modulenotfounderror|importerrorz< Likely cause: the gateway is running stale code (booted on rƒ   u-   ) â€” run `hermes gateway restart` to fix it.)Úcron.scheduler_failure_copyr¬   r­   r®   r¯   r°   rA   r&   Úlowerr—   Úrer™   rZ   ÚsubÚrstripÚlenrs   rX   )r5   rª   r¬   r­   r®   r¯   r°   Újob_nameÚjob_idÚtextr·   ÚnoticeÚcleanedÚmessager¤   r~   r   s   &&               r0   Ú$_summarize_cron_failure_for_deliveryrÂ      sç  € ÷8õ 8ð �w‰w�v‹×=Ð= #§'¡'¨$£-×=Ð=°:€HØ�W‰W�T‹]×&Ð&˜h€FØ×$Ð$�_×+Ñ+Ó-€DØ�J‰J‹L€Eð
 ×ÑÐ*×+Ò+Ù$ XÓ6Ð6ô 
‡y‚yÐ2°E×:Ò:Ù  Ó2Ð2ð
 �7‰7�:×ÒÙ(ØÑ:¸4Ó@Ü#9¸#Ó#>ÈÏÉÐQ[ÓI\ô^ˆð ÒØˆMô �fŠfÐPÐRTÐVZÐ[`ÕVaÓb€GÜ�fŠf�V˜S 'Ó*×0Ñ0Ó2×9Ñ9¸#Ó>€GÜ
ˆ7ƒ|�cÔØ˜$•-×&Ñ&Ó(¨5Õ0ˆÙ$ X°wÓ?€Gð �7‰7�:×Ò¤2§9¢9Ø=¸u÷$ò $ð	Ü,Ó.ˆDð ÒØ!%ÑˆH�hØðØ�Z˜}¨X¨Jð 76ð6õˆGð €Nøô ô 	ØŠDð	ús   Ç
G8 Ç8HÈHg      @c                ó$   € V ^8„  d   QhR\         /# ©r4   r6   ©Úfloat)r:   s   "r0   r;   r;   H  s   € ÷ hñ h¤Uñ hr<   c                 ó2   € ^ RI Hp  V ! R\        \        4      # )z¹``cron.failure_repeat_alert_hours``: how long an ``alerted`` incident stays silent before one
reminder ping. ``0`` (or negative) re-alerts on every failing run (the pre-gate behaviour).©Ú_cron_config_numberÚfailure_repeat_alert_hours)Ú	cron.jobsrÉ   Ú"DEFAULT_FAILURE_REPEAT_ALERT_HOURSrÆ   rÈ   s    r0   Ú_failure_repeat_alert_hoursrÍ   H  s   € õ .áÐ;Ô=_ÔafÓgÐgr<   c                ó0   € V ^8„  d   QhR\         R\        /# )r4   Úincidentr6   r7   )r:   s   "r0   r;   r;   P  s   € ÷ @ñ @¤Tð @¬dñ @r<   c                ó   € \        4       pV^ 8:  d   R# V P                  R4      pV'       g   R#  ^ RIHpHp V! \
        P                  ! \        V4      4      4      pT! \        4       T4      TR,          8  #   \        \        3 d     R# i ; i)zéAn ``alerted`` incident withholds the per-run ping until the reminder cooldown has elapsed
since its last ping. A missing/unparseable ``alerted_at`` (ledger written before the column
existed) delivers rather than swallowing an alert.FÚ
alerted_at)Ú_elapsed_secondsÚ_ensure_awareé  )rÍ   rA   rË   rÒ   rÓ   r   ÚfromisoformatrB   Ú	TypeErrorr(   Ú_hermes_now)rÏ   ÚhoursrÑ   rÒ   rÓ   Úlasts   &     r0   Ú_repeat_alert_withheldrÚ   P  s~   € ô (Ó)€EØ�„zÙØ—‘˜lÓ+€JßÙðß=áœX×3Ò3´C¸
³OÓDÓEˆñ œK›M¨4Ó0°5¸4µ<Ñ?Ð?øô ”zÐ"ô Úðús   °-A8 Á8BÂBÚoutput_filec                ó–   € V ^8„  d   QhR\         R\        R\        \        ,          R\        \
        \        \        ,          3,          /# )r4   r5   rª   rÛ   r6   )r8   rB   r   r   rn   r9   )r:   s   "r0   r;   r;   c  s>   € ÷ ñ Ü	ðÜðÜ+3´C­=ðä
Œ4”œ#•ÐÕñr<   c               óˆ  €  ^ RI HpHp T! V R,          \        T;'       g    R4      V P	                  R4      VR7      w  rVV! V4      pV'       d   VP	                  R4      MRpVR8H  ;'       g    VR	8H  ;'       d    \        V4      p	W•3#   \         d+   p
\        P                  R
T R,          T
4       Ru Rp
?
# Rp
?
ii ; i)a}  Record a durable failure incident (grouped by job + error signature). Returns
``(withheld, incident_id)``; withheld=True when the signature's incident is already ``closed``
(operator ack) or ``alerted`` inside the ``cron.failure_repeat_alert_hours`` cooldown (a ping
already went out) -> suppress the per-run ping. Store errors log at debug; the caller delivers
as if none existed.)Úget_incidentÚupsert_incidentrW   r$   rc   )r¼   rÛ   ÚstateNÚclosedÚalertedú?Incident store unavailable for job %s (delivery unaffected): %s©FN)	Úcron.incidentsrÞ   rß   rB   rA   rÚ   rX   ÚloggerÚdebug)r5   rª   rÛ   rÞ   rß   Úincident_idÚ_is_newrÏ   rà   ÚwithheldÚexcs   &&$        r0   Ú_upsert_incident_for_failurerì   c  s³   € ðß@á.Ø��I”s˜5Ÿ;˜; BÓ'°#·'±'¸&³/È{ô \Ñˆá Ó,ˆß)1�—‘˜WÔ%°tˆØ˜HÑ$×aÐa¨°)Ñ);×)`Ð)`Ô@VÐW_Ó@`ˆØÐ$Ð$øÜô Ü�‰ØMØ��I�sô	ð Õûð	ús/   ‚B ¢AB Á0B Á=B ÂCÂB<Â6CÂ<Cc                ó(   € V ^8„  d   QhR\         RR/# ©r4   r5   r6   N©r8   )r:   s   "r0   r;   r;   {  s   € ÷ hñ h¬dð h°tñ hr<   c                ó    €  ^ RI Hp V! V R,          4       R#   \         d*   p\        P	                  RT R,          T4        Rp?R# Rp?ii ; i)z¨Best-effort: a successful run marks the job's open incidents ``resolved`` (never touches an
operator ``closed`` ack). Store errors log at debug; delivery is unaffected.)Ú!close_incidents_for_recovered_jobrW   rã   N)rå   rñ   rX   ræ   rç   )r5   rñ   rë   s   &  r0   Ú$_resolve_incidents_for_recovered_jobrò   {  sE   € ðhÝDá)¨#¨d­)Ö4øÜô hÜ�‰ÐVÐX[Ð\`ÕXaÐcf×gÒgûðhús   ‚ ™A¤AÁAc                ó>   € V ^8„  d   QhR\         \        ,          RR/# )r4   rè   r6   N)r   rB   )r:   s   "r0   r;   r;   †  s"   € ÷ 	Qñ 	Q¬´­ð 	Q¸$ñ 	Qr<   c                ó˜   € V '       g   R#  ^ RI Hp V! V R4       R#   \         d"   p\        P	                  RY4        Rp?R# Rp?ii ; i)zYBest-effort: mark incident ``alerted`` (no-op for closed; never resurrects an acked one).N)Úset_incident_staterâ   z&Failed marking incident %s alerted: %s)rå   rõ   rX   ræ   rç   )rè   rõ   rë   s   &  r0   Ú_mark_incident_alertedrö   †  s?   € çÙðQÝ5á˜;¨	Ö2øÜô QÜ�‰Ð=¸{×PÒPûðQús   Œ �A	¨AÁA	c                   ó   € ] tR tRtRtRtR# )ÚCronPromptInjectionBlockedi’  a
  Raised by _build_job_prompt when the assembled prompt (incl. runtime-loaded skill content,
unseen by create-time scanning) trips the injection scanner; run_job turns it into a clean
"job blocked" delivery.

Assembled-prompt scanning (including loaded skill content) plugs the gap from #3968: create-time
scanning only covers the user-supplied prompt field; skill content loaded at runtime was never scanned,
so a malicious skill could carry an injection payload that reached the non-interactive (auto-approve)
cron agent.
© N©rŠ   r‹   rŒ   r�   rŽ   r�   rù   r<   r0   rø   rø   ’  s   † õr<   rø   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r4   rN   r6   ©r8   rO   rB   )r:   s   "r0   r;   r;   ž  s   € ÷ ñ ¬ð ´$´sµ)ñ r<   c                óž  € T ;'       g    / P                  R4      ;'       g    / pVP                  R4      '       d   RR.pM. ROpT ;'       g    / P                  R4      ;'       g    / p^ RIHp V! VP                  R4      4      pV F?  p\        V4      P	                  4       pV'       g   K&  Wb9  g   K.  VP                  V4       KA  	  V# )	ua  Toolsets a cron-spawned agent must never receive: ``messaging``/``clarify`` always
(interactive); ``cronjob`` by default (loop prevention, not a security boundary â€”
``cron.allow_agent_scheduling: true`` lifts only that); ``agent.disabled_toolsets`` layered on
top so per-job ``enabled_toolsets`` cannot widen past config.yaml's denylist.

See #25752.
r`   Úallow_agent_schedulingÚ	messagingÚclarifyÚagent)Úparse_config_string_listÚdisabled_toolsets)Úcronjobrÿ   r   )rA   Úagent.skill_utilsr  rB   r&   Úappend)rN   Úcron_cfgÚdisabledÚ	agent_cfgr  Úuser_disabledrc   s   &      r0   Ú_resolve_cron_disabled_toolsetsr  ž  s©   € ð —	�	�r�‰˜vÓ&×,Ð,¨"€HØ‡|�|Ð,×-Ò-Ø Ð+‰â6ˆØ—�˜—‘ Ó(×.Ð.¨B€IÝ:á,¨Y¯]©]Ð;NÓ-OÓP€MÛˆÜ�4‹y�‰Ó ˆß‰4�DÖ(Ø�O‰O˜DÖ!ñ ð €Or<   c                óh   € V ^8„  d   QhR\         \        ,          R\        R\         \        ,          /# )r4   Úper_jobrN   r6   )rO   rB   r8   )r:   s   "r0   r;   r;   ¶  s)   € ÷ ñ ¬d´3­ið ¼dð ÄtÌCÅyñ r<   c                óú   € V  Uu. uF  q"R8w  g   K  VNK  	  ppRV 9   d   V# ^ RI Hp V! V4      p\        V4      V,          '       d   V# \        V4       F  pWc9  g   K  VP	                  V4       K  	  V# u upi )a  Layer enabled MCP servers onto a per-job ``enabled_toolsets`` allowlist (else a per-job list
silently drops every MCP server). Mirrors ``_get_platform_tools``: ``no_mcp`` sentinel -> none
(stripped); any MCP server already listed -> allowlist, add nothing; else union all enabled.Úno_mcp)Úenabled_mcp_server_names)Úhermes_cli.tools_configr  ÚsetÚsortedr  )r  rN   ÚtÚresultr  Úenabled_mcprc   s   &&     r0   Ú _merge_mcp_into_per_job_toolsetsr  ¶  sy   € ñ !Ó2™�A¨¡M�aˆa™€FÐ2Ø�7ÔØˆå@Ù*¨3Ó/€KÜ
ˆ6ƒ{�[× Ô ØˆÜ�{Ö#ˆØÖØ�M‰M˜$Öñ $ð €Mùò 3s
   …A8’A8c                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# rM   rü   )r:   s   "r0   r;   r;   È  s%   € ÷ ñ ¬ð ´4ð ¼DÄ½Iñ r<   c                ó  € V P                  R4      pVe*   V'       g   . # \        \        V4      T;'       g    / 4      #  ^ RIHp \        T! T;'       g    / R4      4      #   \         d   p\        RT 24      ThRp?ii ; i)u  Toolset list for a cron job. Precedence: per-job ``enabled_toolsets`` (+ MCP merge) >
``cron`` platform config (``_get_platform_tools``, which strips _DEFAULT_OFF_TOOLSETS so fresh
installs run without ``moa``). A lookup failure fails CLOSED: the run errors out.

1. Per-job ``enabled_toolsets`` (set via ``cronjob`` tool on create/update). Keeps the agent's
job-scoped toolset override intact â€” #6130. Enabled MCP servers are layered on per
``_merge_mcp_into_per_job_toolsets`` so a native-toolset allowlist does not silently strip MCP tools.
An explicitly-set EMPTY list is a zero-toolset allowlist, not a clear to the platform default â€”
it is falsy, so it must be compared with ``is not None``, else it fell through to the config
default and widened an unattended job back to every toolset (#82010). 2.
Mirrors gateway behavior (``_get_platform_tools(cfg, platform_key)``) so users can gate cron toolsets
globally without recreating every job. 3. Never ``None``: AIAgent reads ``None`` as "every
toolset", so an unreadable ``platform_toolsets.cron`` restriction would hand an unattended job
the full default set (#111380). The raise reaches ``run_job``'s failure path, which records the
error on the job and opens an incident, so the operator sees it instead of a widened run.
Úenabled_toolsetsN)Ú_get_platform_toolsr`   zœCron toolset resolution failed, so this run was refused rather than given every tool. Check `platform_toolsets.cron` in config.yaml (`hermes cron doctor`): )rA   r  rO   r  r  r  rX   ÚRuntimeError)r5   rN   r  r  rë   s   &&   r0   Ú_resolve_cron_enabled_toolsetsr  È  s�   € ð" �g‰gÐ(Ó)€GØÒßð ˆIÜ/´°W³¸s¿y¸yÀbÓIÐIðÝ?ÜÑ)¨#¯)¨)°°VÓ<Ó=Ð=øÜô Üð[Ø[^ÐZ_ðaó
ð ð	ûðús   Á A" ÁA" Á"BÁ-A<Á<Bc          	      óV   € V ^8„  d   QhR\         R\         R\        R\         R,          /# )r4   r5   rN   rH   r6   Nr\   )r:   s   "r0   r;   r;   ê  s2   € ÷ Vñ V¤tð V´$ð V¼sð VÄtÈdÅ{ñ Vr<   c           	     ój  € ^ RI HpHp V P                  R4      pVen   V! V4      pVe*   \        P                  RV P                  RR4      V4       V# \        P                  RV P                  RR4      VV P                  RR4      4       T! \        V\        4      '       d   TM/ \        V4      4      # )a  Effective reasoning config for a cron run. A per-job ``reasoning_effort`` pin beats global
and per-model config and is model-independent by design (also governs an auth-fallback swap);
clamping stays with provider transports. An unparseable pin warns and falls back to config.)Úparse_reasoning_effortÚresolve_reasoning_configÚreasoning_effortz-Job '%s': using per-job reasoning_effort '%s'rW   Ú?uê   Job '%s': invalid stored reasoning_effort %r â€” ignoring the pin and falling back to config resolution. Fix with `cronjob action=update job_id=%s reasoning_effort=<level>` (valid: none, minimal, low, medium, high, xhigh, max, ultra).)
Úhermes_constantsr   r!  rA   ræ   ÚinfoÚwarningr@   r8   rB   )r5   rN   rH   r   r!  rR   Úparseds   &&&    r0   Ú_resolve_job_reasoning_configr(  ê  s¤   € ÷ Rà�W‰WÐ'Ó(€FØÒÙ'¨Ó/ˆØÒÜ�K‰KÐGÈÏÉÐQUÐWZÓI[Ð]cÔdØˆMÜ�‰ð>ð �G‰G�D˜#ÓØØ�G‰G�D˜#Óô	 ñ $¬:°c¼4×+@Ò+@¡CÀbÌ#ÈeË*ÓUÐUr<   )Ú_ensure_cron_dirÚadvance_next_runsÚclaim_dispatchÚclaim_job_for_fireÚfire_claim_fenceÚclear_run_claimÚget_due_jobsÚheartbeat_fire_claimÚheartbeat_run_claimÚmark_job_runÚsave_job_outputÚself_removal_delivery_allowedÚself_removal_delivery_scopeÚuse_cron_store)Ústore_health)Úenter_cron_executionÚexit_cron_execution)
Ú_TERMINAL_STATESÚHANDOFF_ADOPTION_GRACE_SECONDSÚcreate_executionÚfinish_executionÚget_executionÚmark_execution_handoff_pendingÚmark_execution_runningÚrecover_interrupted_executionsÚsettle_unstarted_executionÚterminalize_dead_owner)ÚExecutionProgressStamperÚ_inactivity_watchdog_loop)Ú_classify_delivery_outcomez[SILENT]z[CRON_FAILURE]c                óF   € V ^8„  d   QhR\         R\        \         ,          /# ©r4   r¾   r6   ©rB   r   )r:   s   "r0   r;   r;     s   € ÷ 
6ñ 
6¤Sð 
6¬X´c­]ñ 
6r<   c                óî   € T ;'       g    RP                  4       pV'       d!   V^ ,          P                  4       \        8w  d   R# RP                  VR,          4      P	                  4       pT;'       g    R# )zÿReturn failure evidence when an agent response declares a cron failure.

Only the exact, standalone first line is control text. The caller keeps the complete response
in the saved run output while routing this evidence through normal failure bookkeeping.
r$   NÚ
:é   NNzCron agent reported failure.)Ú
splitlinesrº   ÚCRON_FAILURE_MARKERÚjoinr&   )r¾   ÚlinesÚevidences   &  r0   Ú_cron_failure_marker_errorrR    s[   € ð �ZˆZ�R×#Ñ#Ó%€Eß�E˜!•H—O‘OÓ%Ô)<Ô<ÙØ�y‰y˜˜r�Ó#×)Ñ)Ó+€HØ×5Ð5Ð5Ð5r<   c                ó0   € V ^8„  d   QhR\         R\        /# rH  ©rB   r9   )r:   s   "r0   r;   r;   #  s   € ÷ 0ñ 0¤Cð 0¬Dñ 0r<   c                ó   € ^ RI Hp V! V 4      # )uZ  True when a cron final response should suppress delivery: ``[SILENT]`` (or SILENT /
NO_REPLY / NO REPLY) as the whole response OR its own first/last line â€” NOT mid-sentence.
Shares the webhook-lane matcher in :mod:`gateway.response_filters` so the two cannot drift.

Recognizes the bracketed ``[SILENT]`` sentinel (whole-response, first line, or last line) plus the
bracketless ``SILENT`` / ``NO_REPLY`` / ``NO REPLY`` variants the model emits when it drops the brackets
(#51438, #46917). Whitespace-trimmed and case-insensitive. A token buried mid-sentence is treated as
real content and delivered.
)Úis_autonomous_silence_response)Úgateway.response_filtersrV  )r¾   rV  s   & r0   Ú_is_cron_silence_responserX  #  s   € õ Há)¨$Ó/Ð/r<   c                óh   € V ^8„  d   QhR\         R\        \        \         ,          ,          R\        /# ©r4   r½   r¦   r6   )rB   r   r   rn   )r:   s   "r0   r;   r;   9  s/   € ÷ hñ hœ#ð h¤X¬d´S­jÕ%9ð hÄUñ hr<   c                óN   € Ve   \        V4      V 3# \        \        4       4      V 3# )u   ``(home key, job id)`` â€” the identity of one in-flight cron run.

ONE gateway process ticks every profile, so a job id alone is not unique: two profiles
routinely carry identically named jobs (``daily-brief``) and sharing a key made the second
profile's run read as a duplicate of the first and get skipped. ``home`` defaults to the
active cron scope's home, which the ticker binds per profile for the whole tick.
)r   r£   )r½   r¦   s   &&r0   Ú_inflight_keyr\  9  s.   € ð &*Ò%5ŒO˜DÓ!Ð`fÐgÐg¼?ÔK[ÓK]Ó;^Ð`fÐgÐgr<   c                ó0   € V ^8„  d   QhR\         R\         /# )r4   r¦   r6   r   )r:   s   "r0   r;   r;   J  s   € ÷ ñ ¤$ð ¬4ñ r<   c                ó*   € V \         \        V 4      &   V # )zMRecord ``home`` under its key so a claim can be mapped back to a usable path.)Ú_inflight_home_pathsr   )r¦   s   &r0   Ú_remember_inflight_homer`  J  s   € à26Ôœ¨Ó.Ñ/Ø€Kr<   c                ó0   € V ^8„  d   QhR\         R\        /# )r4   Úhome_keyr6   )rB   r   )r:   s   "r0   r;   r;   P  s   € ÷ @ñ @¤#ð @¬$ñ @r<   c                óR   € \         P                  V 4      ;'       g    \        V 4      # )zOReal home Path for an in-flight key's home half (falls back to the key itself).)r_  rA   r   )rb  s   &r0   Ú_inflight_home_pathrd  P  s   € ä×#Ñ# HÓ-×?Ð?´°h³Ð?r<   g      >@c                   óH   a € ] tR tRt o RtV 3R lR ltV 3R lR ltRtV tR# )	Ú_CancelEventLikei‹  zYStructural type for cancellation sources (``threading.Event``, ``_CombinedCancelEvent``).c                ó    <€ V ^8„  d   QhRS[ /# rÄ   ©r9   )r:   r€   s   "€r0   r;   Ú_CancelEventLike.__annotate__Ž  s   ø€ ×!Ñ!™Ñ!r<   c                ó   € R # r?   rù   ©r‡   s   &r0   Úis_setÚ_CancelEventLike.is_setŽ  s   € ™cr<   c                ó   <€ V ^8„  d   QhRR/# rl   rù   )r:   r€   s   "€r0   r;   ri  �  s   ø€ ×Ñ�TÑr<   c                ó   € R # r?   rù   rk  s   &r0   r  Ú_CancelEventLike.set�  s   € ™3r<   rù   N)	rŠ   r‹   rŒ   r�   rŽ   rl  r  r�   r�   ©r€   s   @r0   rf  rf  ‹  s   ø‡ € Ùcç!Ð!ßÖr<   rf  c                   óZ   a € ] tR tRt o RtV 3R lR ltV 3R lR ltV 3R lR ltR	tV t	R
# )Ú_CombinedCancelEventi’  z¹Duck-typed ``threading.Event`` ORing several cancellation sources (fire-claim heartbeat
``lost_ownership`` + per-transport events). Workers only call is_set()/set(), so no pump thread.
c                ó4   <€ V ^8„  d   QhRS[ S[,          RR/# )r4   Úeventsr6   N)r   rf  )r:   r€   s   "€r0   r;   Ú!_CombinedCancelEvent.__annotate__—  s%   ø€ ÷ Hñ H¡Ñ)9Õ :ð H¸tñ Hr<   c                óH   € V Uu. uF
  q"f   K  VNK  	  upV n         R # u upi r?   ©Ú_events)r‡   ru  Úevents   &* r0   r†   Ú_CombinedCancelEvent.__init__—  s   € Ù+1ÓG©6 %Ÿ˜©6ÑGˆŽùÒGs   …�c                ó    <€ V ^8„  d   QhRS[ /# rÄ   rh  )r:   r€   s   "€r0   r;   rv  š  s   ø€ ÷ =ñ =™ñ =r<   c                ó’   € \         ;QJ d&    R  V P                   4       F  '       g   K   R# 	  R# ! R  V P                   4       4      # )c              3   ó@   "  € T F  qP                  4       x € K  	  R # 5ir?   )rl  )rC   rz  s   & r0   rE   Ú._CombinedCancelEvent.is_set.<locals>.<genexpr>›  s   é € Ð<©| e—<‘<—>�>«|ùs   ‚TF)rJ   ry  rk  s   &r0   rl  Ú_CombinedCancelEvent.is_setš  s3   € ß‹sÑ<¨t¯|ª|Ó<�sŒsÐ<ŠsÐ<ˆsÑ<¨t¯|ª|Ó<Ó<Ð<r<   c                ó   <€ V ^8„  d   QhRR/# rl   rù   )r:   r€   s   "€r0   r;   rv  �  s   ø€ ÷ ñ �Tñ r<   c                óL   € V P                    F  pVP                  4        K  	  R # r?   )ry  r  )r‡   rz  s   & r0   r  Ú_CombinedCancelEvent.set�  s   € Ø—\”\ˆEØ�I‰IŽKó "r<   rx  N)
rŠ   r‹   rŒ   r�   rŽ   r†   rl  r  r�   r�   rq  s   @r0   rs  rs  ’  s*   ø‡ € ñ÷Hð H÷=ð =÷ö r<   rs  c                ó:   € V ^8„  d   QhR\         \        ,          /# rÄ   ©Ú	frozensetrB   )r:   s   "r0   r;   r;   ¢  s   € ÷ 	[ñ 	[œY¤s�^ñ 	[r<   c                 óº   € \         ;_uu_ 4        \        R \        \        P	                  4       ,           4       4      uuRRR4       #   + '       g   i     R# ; i)uè  Thread-safe snapshot of executing job IDs (dispatch until ``_process_job`` returns). Read by
the gateway shutdown drain, otherwise blind to cron work (runs outside ``_running_agents``).

_drain_active_agents``) reads this to treat in-flight cron work as active the same way it already treats
in-flight chat sessions via ``_running_agents`` â€” cron jobs run through their own thread pool here,
entirely outside that dict, so without this the drain is structurally blind to them (#60432).
c              3   ó2   "  € T F  q^,          x € K  	  R# 5i©rL  Nrù   ©rC   Úkeys   & r0   rE   Ú&get_running_job_ids.<locals>.<genexpr>«  s   é € ÐZÑ+Y C˜QŸšÓ+Yùó   ‚N)Ú_running_lockr†  Ú_running_job_idsÚ_running_fire_ownersÚkeysrù   r<   r0   Úget_running_job_idsr’  ¢  s3   € ÷ 
ŽÜÑZÔ+;Ô>R×>WÑ>WÓ>YÖ+YÓZÓZ÷ 
��‹ús   �/A	Á	A	c                ó:   € V ^8„  d   QhR\         \        ,          /# rÄ   )rO   r8   )r:   s   "r0   r;   r;   ®  s   € ÷ 
ñ 
¤¤d¥ñ 
r<   c                 ó¤  € \         P                   ! 4       p \        ;_uu_ 4        \        \        \        P                  4       ,          4       Uu. uFW  pRV^,          RV\        9   d   \        V \        V,          ,
          ^4      MRR\        P                  V4      RV\        9   /NKY  	  upuuRRR4       # u upi   + '       g   i     R# ; i)a  Per in-flight job: ``{"job_id", "elapsed_s", "worker_pid", "restart_safe"}`` (``worker_pid``
None for in-process runs; ``restart_safe`` True when the worker owns its own systemd scope). The
drain wait publishes this so ``hermes update`` can say WHICH job it is waiting on.r½   Ú	elapsed_sNÚ
worker_pidÚrestart_safe)ÚtimerŽ  r  r�  r�  r‘  Ú_running_sinceÚroundÚ_running_worker_pidsrA   Ú_scope_isolated_job_ids)r   r‹  s     r0   Úget_running_job_detailsr�  ®  s©   € ô �)Š)‹+€Cß	Žô Ô.Ô1E×1JÑ1JÓ1LÕLÔMó
ñ
 N�ð	 �s˜1•vØÀÌÔAVœ% ¤n°SÕ&9Õ 9¸1Ô=Ð\`ØÔ/×3Ñ3°CÓ8Ø˜SÔ$;Ñ;ó=ñ Nñ
÷ 
Šùò
÷ 
�ˆús   ¤+B>ÁAB9Â,B>Â9B>Â>C	c                ó:   € V ^8„  d   QhR\         \        ,          /# rÄ   r…  )r:   s   "r0   r;   r;   ½  s   € ÷ @ñ @œI¤c�Nñ @r<   c                 ó6   € \        R \        4        4       4      # )u¾  In-flight job IDs older than their stale-inflight allowance (``max(2 * interval,
cron.inflight_max_minutes)``) â€” the scheduler's own definition of a claim that can no longer be
making progress. ``sweep_stale_inflight`` cannot release these while the worker thread is still
alive (a delivery blocked on a dead transport, #115469), so the gateway restart drain reads this to
skip them the way it skips wedged chat turns; restart is their remedy.
c              3   ó2   "  € T F  q^,          x € K  	  R# 5ir‰  rù   rŠ  s   & r0   rE   Ú%get_wedged_job_ids.<locals>.<genexpr>Ä  s   é € Ð?Ñ'> ˜—V’VÓ'>ùr�  )r†  Ú_wedged_inflight_keysrù   r<   r0   Úget_wedged_job_idsr£  ½  s   € ô Ñ?Ô'<Ô'>Ó?Ó?Ð?r<   c                ó:   € V ^8„  d   QhR\         \        ,          /# rÄ   )r†  rn   )r:   s   "r0   r;   r;   Ç  s   € ÷ Xñ Xœy¬Õ/ñ Xr<   c            	     ó¨  aa€ \         P                   ! 4       p \        ;_uu_ 4        \        P                  4        UUu/ uF  w  rV\        9   g   K  WV,
          bK  	  pppV Uu/ uF  q\
        9   g   K  V\
        V,          bK  	  upoRRR4       X'       g   \        4       # \        4       R,          oV Uu. uF  qS9  g   K  VNK  	  ppV'       Ed   / p\        P                  ! \        4      ;_uu_ 4        ^ RIHp V! 4        Uu/ uF  qwP                  R4      VbK  	  ppRRR4       \        \        4       4      p\        ;_uu_ 4        V F  pSp	V^ ,          V8X  d   VP                  V^,          4      MRp
\!        T
;'       g    / 4      pV'       d   \#        V	RV,          R,          4      p	V	SV&   V\        9   g   Kv  V	\
        V&   K�  	  RRR4       \        VV3R lVP                  4        4       4      # u uppi u upi   + '       g   i     ELŒ; iu upi u upi   + '       g   i     EL; i  + '       g   i     Lq; i)zXIn-flight keys behind :func:`get_wedged_job_ids`, before the projection to bare job IDs.Nç      N@©Ú	load_jobsrW   ç       @c              3   ó`   <"  € T F#  w  rV\        SV,          S4      8¼  g   K  Vx € K%  	  R # 5ir?   )Úmax)rC   r‹  ÚageÚ
allowancesÚfloor_secondss   &  €€r0   rE   Ú(_wedged_inflight_keys.<locals>.<genexpr>å  s+   øé € ð XÙ(‘�¨C´3°zÀ#µÈÓ3VÑ,V�Š›Lùs   ƒ.¤
.)r˜  rŽ  r™  Úitemsr�  Ú_running_allowance_sr†  Ú_inflight_min_allowance_minutesÚ
contextlibÚsuppressrX   rË   r¨  rA   r   r£   Ú_job_interval_minutesr«  )r   r‹  ÚstartedÚagesÚ
unresolvedÚby_idr¨  ÚjÚ
local_homeÚ	allowanceÚ	local_jobÚinterval_minutesr­  r®  s               @@r0   r¢  r¢  Ç  sÕ  ù€ ä
�)Š)‹+€Cß	ŽÜ7E×7KÑ7KÔ7MÔiÑ7M¡| sÐQTÔXhÑQhÔ"�˜7•]Ò"Ñ7MˆÑiÙ@DÓdÁ¸ÔOcÑHcÔ4�cÔ/°Õ4Ò4ÁÑdˆ
÷ 
÷ Ü‹{ÐÜ3Ó5¸Õ<€MÙ!%Ó?¡˜#°JÑ)>—#�#¡€JÐ?ß€zð
 ˆÜ× Ò ¤×+Õ+Ý+Ù-6¬[Ó9©[¨—U‘U˜4“[ !’^©[ˆEÐ9÷ ,ô %Ô%5Ó%7Ó8ˆ
ßŽ]Û!�Ø)�	Ø14°Qµ¸:Ô1E˜EŸI™I c¨!¥fÔ-È4�	Ü#8¸¿¸ÀbÓ#IÐ ß#Ü # I¨sÐ5EÕ/EÈÕ/LÓ M�IØ"+�
˜3‘ØÔ*Ö*Ø09Ô(¨Ó-ñ "÷ ô õ XØ ŸJ™JœLóXó Xð Xùó5 jùÚd÷ 
�ˆüò @ùò :÷ ,×+Ð+ú÷ �]ús|   ¦H¾H
ÁH
ÁHÁ&H
Á7H
Â	HÂ;H#ÃH#Ã=H-ÄH(Ä'H-Å=IÆIÆ'IÇIÈHÈH 	È(H-È-H>	ÉI	c                ó$   € V ^8„  d   QhR\         /# rÄ   rï   )r:   s   "r0   r;   r;   é  s   € ÷ ñ ¤dñ r<   c                 óB  € \        4       p \        ;_uu_ 4        \        \        P	                  4       ,          p\
        V,          V ,
          pRRR4       V X,          p R\        W,
          X,
          4      R\        V 4      R\        V4      /#   + '       g   i     LI; i)a}  In-flight cron runs split for the gateway restart wait: ``awaitable``, ``wedged`` and
``restart_safe`` (scoped external worker, not wedged). The three are disjoint and sum to the
number of in-flight runs.

A ``scoped`` worker runs in a transient user scope outside the gateway cgroup, so a systemd
stop/restart cannot reach it: the shutdown drain deliberately leaves it unmarked
(``mark_running_jobs_interrupted``) and its final send rides the durable delivery queue, drained
by whichever gateway is live next. Holding the restart wait for it only keeps the gateway in
``draining`` (refusing new turns) for up to ``agent.restart_after_turn_timeout``. A ``degraded``
worker (external subprocess, no reachable user bus) stays in the gateway cgroup and dies with a
systemd stop, so it stays awaitable.

Counted per in-flight KEY, not per bare job ID: one multiplexed gateway can run the same job ID
in two profiles, and projecting to bare IDs first lets one profile's wedged or scoped run hide
the other profile's live run, which the restart would then kill (e.g. a scoped ``daily-brief``
in profile A next to a degraded ``daily-brief`` in profile B).
NÚ	awaitableÚwedgedr—  )r¢  rŽ  r�  r�  r‘  rœ  r»   )rÂ  Úinflightr—  s      r0   Úget_restart_wait_cron_countsrÄ  é  s|   € ô$ #Ó$€Fß	ŽÜ#Ô&:×&?Ñ&?Ó&AÕAˆÜ/°(Õ:¸fÕDˆ÷ 
ð �hÕ€Fà”S˜Õ*¨\Õ9Ó:Ø”#�f“+Øœ˜LÓ)ðð ÷	 
�ús   ™4BÂB	c                óh   € V ^8„  d   QhR\         R\        \        \         ,          ,          R\        /# rZ  )rB   r   r   r9   )r:   s   "r0   r;   r;     s/   € ÷ Fñ Fœ3ð F¤h¬t´c­zÕ&:ð FÄdñ Fr<   c                ó¦   € \        W4      p\        ;_uu_ 4        V\        9   ;'       g
    V\        9   uuRRR4       #   + '       g   i     R# ; i)aË  True when THIS process has an in-flight run of ``job_id`` FOR ``home`` (default: the active
cron scope's home).

The bare-id accessors above report the host-wide union so the shutdown drain and metrics see
every profile's work. Liveness consumers must not: one process ticks every profile, so a
``daily-brief`` running in profile A would otherwise report profile B's idle ``daily-brief``
as running and keep B's stale one-shot alive as a "possibly live run".
N)r\  rŽ  r�  r�  )r½   r¦   r‹  s   && r0   Úis_job_runningrÇ    s6   € ô ˜Ó
%€Cß	ŽØÔ&Ñ&×EÐE¨#Ô1EÑ*E÷ 
��‹ús	   š?¿A	c                ó@   € V ^8„  d   QhR\         R\        R\        RR/# )r4   r½   ÚpidÚscope_isolatedr6   N)rB   r   r9   )r:   s   "r0   r;   r;     s)   € ÷ -ñ -¬ð -´3ð -Ì4ð -ÐTXñ -r<   c          	     óV  € \        V 4      p\        ;_uu_ 4        \        P                  ! \        \
        4      ;_uu_ 4        \        V4      \        V&   RRR4       V'       d   \        P                  V4       RRR4       R#   + '       g   i     L7; i  + '       g   i     R# ; i)aC  Record the external worker holding *job_id* so a drain observer can name it, and whether
its scope isolates it from this process.

``scope_isolated`` is the strong form of restart-safety: only a ``scoped`` dispatch
(``GatewayChildDispatch``) puts the worker in its own transient systemd scope, outside the
gateway cgroup. A ``degraded`` worker is still external but shares the cgroup and dies with a
systemd stop, so it must NOT be listed as restart-safe. Called once per accepted handoff;
both maps are cleared by ``release_running_job`` and by the worker waiter's ``finally``.
N)
r\  rŽ  r³  r´  rÖ   r(   re   r›  rœ  Úadd)r½   rÉ  rÊ  r‹  s   &&$ r0   Ú_record_external_cron_workerrÍ    sc   € ô ˜Ó
€Cß	ŽÜ× Ò ¤¬J×7Õ7Ü(+¨C«Ô  Ñ%÷ 8çÜ#×'Ñ'¨Ô,÷	 
‰ß7×7ú÷ 
�ˆús)   š(BÁB	ÁBÁ%BÂBÂBÂB(	rS   Úfuturec                ó0   € V ^8„  d   QhR\         R\        /# )r4   r½   r6   rT  )r:   s   "r0   r;   r;   '  s   € ÷ ñ ¤Sð ÔTXñ r<   c          	     óò  € ^ RI Hp \        V \        \	        4       4      4      pVP                  4       ;_uu_ 4       p\        ;_uu_ 4        V'       d   V\        9   d    RRR4       RRR4       R# \        P                  V4       \        P                  ! 4       \        V&   V\        V&   V\        V&    RRR4       RRR4       R#   + '       g   i     M; iRRR4       R#   + '       g   i     R# ; i)aM  Atomically add ``job_id`` to the in-flight set; False (caller must skip) if already mid-run.
Single dedupe owner for ticker + manual runs (the fire claim's 300s TTL is outlived by real
jobs). Callers MUST pair success with ``release_running_job`` in a ``finally``.
Dispatchers pass a unique ``owner`` back on release. Direct workers register a running
``future`` atomically because no executor submission will replace the pending sentinel.

This is the single dedupe owner shared by the ticker's ``_submit_with_guard`` and manual runs
(``tools/cronjob_tools``): the fire claim alone cannot prevent a double-fire because its TTL (300s) is
routinely outlived by real jobs, after which a manual ``cronjob(action='run')`` would claim successfully
and run the same job concurrently (idea from #53395 by @izumi0uu).
Registration also makes the run visible to ``get_running_job_ids`` (the gateway shutdown drain, #60432)
and ``mark_running_jobs_interrupted``. Dedupe is per PROFILE: the key carries the active cron
scope's home, so one multiplexing process never treats two profiles' same-named jobs as one.
)Ú
retirementNFT)Úhermes_cli.backend_retirementrÑ  r\  r`  r£   ÚworkrŽ  r�  rÌ  r˜  r™  Ú_running_futuresÚ_running_registration_owners)r½   rS   rÎ  rÑ  r‹  Úadmitteds   &$$   r0   Útry_register_running_jobr×  '  s¡   € õ 9ä
˜Ô 7Ô8HÓ8JÓ KÓ
L€CØ	�‰×	Ô	˜h¯®ß˜3Ô"2Ô2Ø÷ )6×	Ñ	ô 	×Ñ˜SÔ!ô #Ÿiši›kŒ�sÑØ &Ô˜ÑØ,1Ô$ SÑ)Ø÷ )6×	Ñ	¯¯ú×	×	×	Ò	ús0   ¼C%ÁC	Á C%Á2AC	Â6C%ÃCÃC%Ã%C6	c                ó`   € V ^8„  d   QhR\         R\        \        \         ,          ,          RR/# )r4   r½   r¦   r6   N)rB   r   r   )r:   s   "r0   r;   r;   E  s-   € ÷ -ñ -Üð-Ü¤¤s¥
Õ+ð-à	ñ-r<   c               óò  € \        W4      p\        ;_uu_ 4        Ve%   \        P                  V4      VJd    RRR4       R# \        P	                  VR4       \
        P                  V4       \        P	                  VR4       \        P	                  VR4       \        P	                  VR4       \        P	                  VR4       \        P                  V4       RRR4       R#   + '       g   i     R# ; i)a«  Remove the registration unless an explicit ``owner`` has been replaced.

``home`` MUST be passed by any caller that does not run inside the same cron scope the claim
was registered under. The scope is a ContextVar the ticker binds per profile: a pool worker
releasing in a ``finally`` outside ``ctx.run`` resolves the default (launch) home instead, so
the discard misses the real key and every secondary profile's claim leaks.
N)r\  rŽ  rÕ  rA   Úpopr�  Údiscardr™  r±  rÔ  r›  rœ  )r½   r¦   rS   r‹  s   &&$ r0   Úrelease_running_jobrÜ  E  s°   € ô ˜Ó
%€Cß	ŽØÒÔ!=×!AÑ!AÀ#Ó!FÈeÓ!SØ÷ 
‰ô 	%×(Ñ(¨¨dÔ3Ü× Ñ  Ô%Ü×Ñ˜3 Ô%Ü× Ñ   dÔ+Ü×Ñ˜S $Ô'Ü× Ñ   dÔ+Ü×'Ñ'¨Ô,÷ 
��Šús   šC%ÁBC%Ã%C6	c                ó$   € V ^8„  d   QhR\         /# rÄ   rÅ   )r:   s   "r0   r;   r;   \  s   € ÷ +ñ +¬ñ +r<   c                 óP  € \         P                  ! \        4      ;_uu_ 4        \        4       ;'       g    / p \	        V \
        4      '       d   V P                  R/ 4      M/ P                  R4      pVe   \        V4      pV^ 8”  d   VuuRRR4       # RRR4       \        R4      P                  4       pV'       d    \        V4      pV^ 8”  d   V#  \        # \        #   + '       g   i     LS; i  \        \        3 d$    \        P                  RT\        4        \        # i ; i)zZStale allowance floor (min): ``cron.inflight_max_minutes``, else env escape hatch/default.r`   Úinflight_max_minutesNÚ HERMES_CRON_INFLIGHT_MAX_MINUTESz=Invalid HERMES_CRON_INFLIGHT_MAX_MINUTES=%r; using default %s)r³  r´  rX   r   r@   r8   rA   rÆ   r   r&   r(   rÖ   ræ   r&  Ú_INFLIGHT_MIN_ALLOWANCE_MINUTES)Ú_ucfgÚ_cfg_valÚvalÚraws       r0   r²  r²  \  sõ   € ä	×	Ò	œY×	'Õ	'Ü“×#Ð# ˆä%/°´t×%<Ò%<ˆE�I‰I�f˜bÔ!À"ß
‰#Ð$Ó
%ð 	ð ÒÜ˜“/ˆCØ�QŒwØ÷ 
(×	'Ò	'ô Ð=Ó
>×
DÑ
DÓ
F€Cß
ð	1Ü˜“*ˆCØ�QŒwØ�
ð ô +Ð*Ô*Ð*÷) 
(×	'ûô œIÐ&ô 	1Ü�N‰NØOØÜ/õ1ô +Ð*ð	1ús   £A%CÂ=C1 ÃC.	Ã1,D%Ä$D%c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r4   Úexprr6   ©rB   r   rÆ   )r:   s   "r0   r;   r;   y  s   € ÷ ñ ¤ð ¬´%­ñ r<   c                óì  € V \         9   d   \         V ,          # RpRp\        P                  ! \        4      ;_uu_ 4        ^ RIHp V! 4       pV'       dp   ^ RIHp ^ RIHp VP                  ! 4       pV! W4      pVP                  V4      pVP                  V4      p	W˜,
          P                  4       R,          p
V
^ 8”  d   T
MRpRRR4       Vf	   V'       d
   V\         V &   V#   + '       g   i     L'; i)zYCron expression cadence (gap between next two fires) in minutes; None -> floor allowance.NF)Ú_ensure_croniter)Úcroniter)r   r¦  )Ú_cron_interval_cacher³  r´  rX   rË   rê  rë  r   r   Úget_nextÚtotal_seconds)rç  r  Úokrê  Ú	_croniterr   ÚbaseÚitÚfirstÚsecondÚgaps   &          r0   Ú_cron_interval_minutesrö  y  sÀ   € àÔ#Ô#Ü# DÕ)Ð)Ø€FØ	€BÜ	×	Ò	œY×	'Õ	'Ý.áÓˆßÝ7Ý)à—<’<“>ˆDÙ˜4Ó&ˆBØ—K‘K Ó)ˆEØ—[‘[ Ó*ˆFØ•>×0Ñ0Ó2°TÕ9ˆCØ !œG‘S¨ˆF÷ 
(ð" ÒŸRØ%+Ô˜TÑ"Ø€M÷' 
(×	'ús   ¿BC#Ã#C3	c                óF   € V ^8„  d   QhR\         R\        \        ,          /# r3   )r8   r   rÆ   )r:   s   "r0   r;   r;   •  s   € ÷ ñ œtð ¬´­ñ r<   c           	     óf  € \         P                  ! \        4      ;_uu_ 4        V P                  R4      p\	        V\
        4      '       d/   VP                  4       '       d   ^ RIHp V! V4      ;'       g    / p\	        V\        4      '       d‡   VP                  R4      pVR8X  d1   VP                  R4      pV'       d   \        V4      MRuuRRR4       # VR8X  d8   \        \        VP                  R4      ;'       g    R	4      4      uuRRR4       # RRR4       R#   + '       g   i     R# ; i)
z³Best-effort job interval in minutes (None if unknown / one-shot -> floor). ``schedule`` is
persisted as a parsed dict; the string path is only a fallback for programmatic callers.r^   )Úparse_scheduler_   rd   ÚminutesNr`   rç  r$   )r³  r´  rX   rA   r@   rB   r&   rË   rù  r8   rÆ   rö  )r5   r^   rù  r_   rú  s   &    r0   rµ  rµ  •  sÚ   € ô 
×	Ò	œY×	'Õ	'Ø—7‘7˜:Ó&ˆÜ�h¤×$Ò$¨¯©×)9Ò)9Ý0á% hÓ/×5Ð5°2ˆHÜ�h¤×%Ò%Ø—<‘< Ó'ˆDØ�zÔ!Ø"Ÿ,™, yÓ1�ß)0”u˜W”~°d÷ 
(Ò	'ð �vŒ~Ü-¬c°(·,±,¸vÓ2F×2LÐ2LÈ"Ó.MÓN÷ 
(×	'Ò	'ñ ÷ 
(Ö	'ñ ús*   £=DÁ!DÁ6A	DÃ DÃ(DÄ 
DÄD0	c                ó$   € V ^8„  d   QhR\         /# rÄ   rï   )r:   s   "r0   r;   r;   ¨  s   € ÷ >ñ >¤$ñ >r<   c                 ól  € \         P                   ! 4       p \        ;_uu_ 4        R\        R \         4       4      R\        P                  4        UUu/ uF  w  rV^,          \        W,
          ^4      bK!  	  uppR\        R\        \        4      /uuRRR4       # u uppi   + '       g   i     R# ; i)zZProbe-visible snapshot; non-zero ``forced_releases`` means a job wedged and was recovered.Úrunningc              3   ó2   "  € T F  q^,          x € K  	  R# 5ir‰  rù   rŠ  s   & r0   rE   Ú+get_inflight_guard_stats.<locals>.<genexpr>­  s   é € ÐAÑ0@¨ !ŸfšfÓ0@ùr�  Úrunning_ages_secondsÚforced_releasesÚrecent_forced_releasesN)
r˜  rŽ  r  r�  r™  r°  rš  Ú_forced_release_countrO   Ú_forced_releases)r   r‹  r¶  s      r0   Úget_inflight_guard_statsr  ¨  sŒ   € ä
�)Š)‹+€Cß	Žà”vÑAÕ0@ÓAÓAØ"ä$2×$8Ñ$8Ô$:ô%á$:‘L�Cð �A•œ˜c�m¨QÓ/Ò/Ù$:ò%ð Ô4Ø$¤dÔ+;Ó&<ð>÷ 
Šùó%÷ 
�ˆús   ¤/B"Á%BÁ8B"ÂB"Â"B3	c          
      óL   € V ^8„  d   QhR\         R\         R\        R\        RR/# )r4   r½   rc   Úage_secondsÚallowance_secondsr6   N©rB   rÆ   )r:   s   "r0   r;   r;   ¶  s8   € ÷ Fñ F¤3ð F¬cð FÄð FÔZ_ð FÐdhñ Fr<   c                ó„  € RV RVR\        V^4      R\        V^4      R\        4       P                  4       /p\        ;_uu_ 4        \        P                  V4       \        R\        ) 1 RRR4        \        4       R,          R,          p\        VP                  4       \        VR	R
R7      ;_uu_ 4       pVP                  \        P                  ! V4      R,           4       RRR4       R#   + '       g   i     L‹; i  + '       g   i     R# ; i  \         d"   p\        P!                  RT4        Rp?R# Rp?ii ; i)z@Persist a countable signal for one forced release (best-effort).r½   rc   r  r  ÚatNr`   zinflight_forced_releases.jsonlÚaúutf-8©ÚencodingrK  z*Could not append forced-release record: %s)rš  r×   Ú	isoformatrŽ  r  r  Ú_FORCED_RELEASE_HISTORYr£   r)  ÚparentÚopenÚwriteÚjsonÚdumpsrX   ræ   rç   )r½   rc   r  r  ÚentryÚpathÚfhÚes   &&&&    r0   Ú_record_forced_releaser  ¶  sù   € ð 	�&Ø�Ø”u˜[¨!Ó,ØœUÐ#4°aÓ8ØŒk‹m×%Ñ%Ó'ð)€E÷ 
ŽÜ×Ñ Ô&ÜÐ6Ô6Ð6Ð6Ð7÷ 
ðFÜÓ! FÕ*Ð-MÕMˆÜ˜Ÿ™Ô%Ü�$˜ g×.Õ.°"Ø�H‰H”T—Z’Z Ó&¨Õ-Ô.÷ /Ñ.÷ 
�ú÷ /×.Ð.ûäô FÜ�‰ÐAÀ1×EÒEûðFúsC   Á$C,Á2AD Â5-C?Ã"D Ã,C<	Ã?D	Ä
D ÄD ÄD?ÄD:Ä:D?c                ó$   € V ^8„  d   QhR\         /# rÄ   rï   )r:   s   "r0   r;   r;   Ê  s   € ÷ ñ ´$ñ r<   c            	     óú  € \        \        4       4      p \        ;_uu_ 4        \         Uu/ uF/  q^ ,          V 8X  g   K  V^,          \        P                  V4      bK1  	  ppRRR4       XP                  4        UUu. uF-  w  r4Ve#   V\        J g   VP                  4       '       g   K+  VNK/  	  pppV'       g   / #  ^ RI	H
p V! V4      # u upi   + '       g   i     Lw; iu uppi   \         d    / u # i ; i)uR  Latest durable execution per releasable-looking claim (missing/pending/done future), one
indexed query so the healthy path pays no DB work. Snapshot under _running_lock â€” iterating
the set while try_register/release mutate it raises RuntimeError.

Scoped to the ACTIVE profile's claims: the executions ledger it queries is that home's.
N)Úlatest_executions)r   r£   rŽ  r�  rÔ  rA   r°  Ú_FUTURE_PENDINGÚdoneÚcron.executionsr  rX   )r»  r‹  Úclaim_futuresr½   ÚfutÚ
candidatesÚ_latest_execss          r0   Ú(_latest_executions_for_releasable_claimsr&  Ê  så   € ô !Ô!1Ó!3Ó4€Jß	Žõ (ó
á'�¨q­6°ZÑ+?ô .ˆC��FÔ$×(Ñ(¨Ó-Ò-Ù'ð 	ð 
÷ 
ð #0×"5Ñ"5Ô"7ôÙ"7‘;�6ØŠ;˜#¤Ó0°C·H±H·J÷ 	ˆÑ"7ð ñ ÷ Øˆ	ðÝFÙ˜ZÓ(Ð(ùò
÷ 
�üó
øô ô ØŠ	ðús?   ¢	C«C¿!CÁ CÁ=(C$Â*C$Â>C* ÃCÃC!	Ã*C:Ã9C:c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r4   ÚrowÚclaim_startedr6   )r8   rÆ   r9   )r:   s   "r0   r;   r;   ä  s!   € ÷ ñ œtð ´Eð ¼dñ r<   c                óÞ   € V P                  R4      pV'       g   R#  ^ RIHp V! \        P                  ! V4      4      pVP                  4       V8¬  #   \        \        \        3 d     R# i ; i)a	  True when the ledger row was claimed at/after this in-memory claim. An older terminal row is
the PREVIOUS run's (try_register->create_execution window); releasing on it would
double-dispatch. Unparseable timestamps fail closed (the age path still bounds the claim).Ú
claimed_atF)rÓ   )	rA   rË   rÓ   r   rÕ   Ú	timestampr(   rÖ   ÚOSError)r(  r)  r+  Ú_ensure_aware_tsÚrow_tss   &&   r0   Ú_row_belongs_to_claimr0  ä  sb   € ð —‘˜Ó&€JßÙðÝ?Ù!¤(×"8Ò"8¸Ó"DÓEˆØ×ÑÓ! ]Ñ2Ð2øÜœ	¤7Ð+ô Úðús   �4A ÁA,Á+A,c                óX   € V ^8„  d   QhR\         R\        R\        R\        R\        RR/# )r4   r5   r½   r¬  r¼  Úreasonr6   N)r8   rB   rÆ   )r:   s   "r0   r;   r;   ó  s@   € ÷  Tñ  Tœtð  T¬Sð  T´uð  TÌð  TÔ]`ð  TÐeiñ  Tr<   c           	     ó  € V P                  R4      ;'       g    TpV\        J d   RMVf   RMRp\        P                  RWVWW74       \	        WW#4       VR8X  d   R# V P                  R4      ;'       g    / p\        V\        4      '       d,   VP                  R	4      e   \        P                  R
Wa4       R#  \        VRRV^<,          R RV^<,          R R24       R#   \         d"   p	\        P                  RY4        Rp	?	R# Rp	?	ii ; i)z¤WARNING log + probe record for one forced release, then ``last_error`` unless the ledger
already holds the run's real outcome or the job has a finite repeat budget.rc   ÚpendingNÚmissingÚfinisheduÉ   cron.inflight.forced_release event=forced_release reason=%s job='%s' id=%s age=%.0fs allowance=%.0fs future=%s â€” stale in-flight claim released; the job was skipping every fire with 'already running'úledger-terminalÚrepeatÚtimesu²   cron.inflight.forced_release.job_untouched job='%s' id=%s â€” finite-repeat job released without mark_job_run (repeat budget preserved); row left in place so it re-fires normallyFz+Stale in-flight claim force-released after z.1fzm (allowance z=m); previous run never released the scheduler in-flight guardz.Could not record forced release for job %s: %s)	rA   r  ræ   r&  r  r@   r8   r2  rX   )
r5   r½   r¬  r¼  r#  r2  rc   Úfuture_stater8  r  s
   &&&&&&    r0   Ú_record_stale_releaser;  ó  s  € ð �7‰7�6‹?×$Ð$˜f€DØ #¤Ó 6‘9ÈÊ¹IÐZd€LÜ
‡N�Nð	Kð 	�f 9ô	<ô
 ˜6¨Ô8ð Ð"Ô"Ùð �W‰W�XÓ×$Ð$ "€FÜ�&œ$×Ò F§J¡J¨wÓ$7Ò$CÜ�‰ðDð ô		ñ
 	ðTÜØ�EØ9¸#À½(À3¸ð HØ# b�.¨Ð-ð .,ð-ö	.øô
 ô TÜ�‰ÐGÈ×SÒSûðTús   Â:$C  Ã DÃ+DÄDc                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r4   Údue_jobsr6   )r   rO   )r:   s   "r0   r;   r;     s"   € ÷ @!ñ @!¤8¬D¥>ð @!¼Tñ @!r<   c           
     óò  € T ;'       g    .  Uu/ uF-  p\        V\        4      '       g   K  VP                  R4      VbK/  	  pp\        4       R,          p\        P                  ! 4       p. p^ RIHp \        4       p\        \        4       4      pVP                  4        U	Uu/ uF  w  r‘V	\        V4      bK  	  p
p	p\        ;_uu_ 4        \         Uu. uF  q»^ ,          V8X  g   K  VNK  	  up EF…  pV^,          p\        P                  V4      pVf   V\        V&   K1  WN,
          pV
P                  V4      pTpV'       d   \        VRV,          R,          4      p\         P                  V4      pV\"        J d   MVe   VP%                  4       '       g   Kª  VP                  V4      pVe,   VP                  R4      V9   d   \'        VV4      '       d   RpMVV8¼  d   RpMKö  \(        P+                  VR4       \        P-                  V4       \        P+                  VR4       \.        P+                  VR4       \         P+                  VR4       \0        ^,          sVP3                  WßVVV34       EKˆ  	  RRR4       V F0  w  rßppp\5        VP                  V4      ;'       g    / WßVVV4       K2  	  V Uu. uF  pV^ ,          NK  	  up# u upi u upp	i u upi   + '       g   i     Lo; iu upi )	u¹  Force-release in-flight claims that can no longer be making progress; returns released ids.

Stale = older than ``max(2 * interval, floor)`` AND (no live future â€” submit path hung before
``pool.submit`` returned â€” or finished without discarding the id) â€” or the claim's OWN ledger
row is terminal regardless of age. Each release logs WARNING ``event=forced_release``, bumps
the probe counter, mirrors JSONL, and writes ``last_error``.
rW   r¦  )r:  Nr©  Ústatusr7  r¬  )r@   r8   rA   r²  r˜  r!  r:  r&  r   r£   r°  rµ  rŽ  r�  r™  r«  rÔ  r  r   r0  rÕ  rÚ  rÛ  r±  r  r  r;  )r=  rº  r¹  r®  r   ÚstaleÚ_terminal_statesÚ_latestÚ_local_homeÚjidÚ
_intervalsrD   r‹  r½   r¶  r¬  r¾  r¼  r#  Úlatestr2  Ú_reasonÚss   &                      r0   Úsweep_stale_inflightrI    s~  € ð '/§n n°" nÓM¡n ¼ÀAÄt×9LŒ^ˆQ�U‰U�4‹[˜!Š^¡n€EÐMÜ3Ó5¸Õ<€MÜ
�)Š)‹+€CØ€EÝDä6Ó8€GÜ!Ô"2Ó"4Ó5€Kà>C¿k¹k¼mÔL¹m±F°C�#Ô,¨QÓ/Ò/¹m€JÑLç	ŽÝ/ÓGÑ/˜!°Qµ4¸;Ñ3F—A�AÑ/ÕGˆCØ˜•VˆFÜ$×(Ñ(¨Ó-ˆGØŠà&)”˜sÑ#ÙØ•-ˆCØ)Ÿ~™~¨fÓ5ÐØ%ˆIßÜ 	¨3Ð1AÕ+AÀDÕ+HÓI�	Ü"×&Ñ& sÓ+ˆCØ”oÓ%àØ’¨¯©¯ªÙð —[‘[ Ó(ˆFàÒ"Ø—J‘J˜xÓ(Ð,<Ô<Ü)¨&°'×:Ò:à*‘Ø˜	Ô!Ø‘áÜ(×,Ñ,¨S°$Ô7Ü×$Ñ$ SÔ)Ü×Ñ˜s DÔ)Ü ×$Ñ$ S¨$Ô/Ü× Ñ   dÔ+Ü! QÕ&Ð!Ø�L‰L˜& y°#°vÐ>×?ñM H÷ 
óR 16Ñ,ˆ�Y  WÜ˜eŸi™i¨Ó/×5Ð5°2°vÀIÈsÐT[Ö\ñ 16áÓ ™%�QˆAˆa�DˆD™%Ñ Ð ùòm Nùó Mùò H÷ 
�üòV !sB   �K¬KÂ"KÃ
	K!ÃKÃ'KÃ-B*K!ÆC"K!Ê<K4ËK!Ë!K1	Úonly_ownersc                óR   € V ^8„  d   QhR\         R\        \        ,          R\        /# )r4   r2  rJ  r6   )rB   r   r  rO   )r:   s   "r0   r;   r;   Y  s(   € ÷ 7ñ 7Üð7Ü!)¬#¥ð7ä	ñ7r<   c               ó  € \         ;_uu_ 4        \        \        4      p\        P	                  4        UUUUUu. uF-  w  r4W29  g   K  VP	                  4        F  w  pw  rgWSWg3NK  	  K/  	  ppppppVe1   V U	u. uF$  q™^,          ^,          V	^,          3V9   g   K"  V	NK&  	  pp	V U
UUUu0 uF  w  r£r¼VkK
  	  pppp
pVf+   VP                  R \        V,
          V,
           4       4       \        P                  R V 4       4       RRR4       . pX F„  w  róppV^,          pV'       g*   \        P                  RV4       VP                  V4       KA   \        V4      ;_uu_ 4        \        VRV VR7      '       d   VP                  V4       RRR4       K†  	  V# u upppppi u up	i u upppp
i   + '       g   i     L´; i  + '       g   i     KÄ  ; i  \         d#   p\        P                  RTT4        Rp?Kï  Rp?ii ; i)a€  Best-effort: mark every in-flight cron job interrupted; returns the job IDs marked.

Called by gateway shutdown right after ``process_registry.kill_all()``: a job whose tool was
killed must never report success. ``only_owners`` (``(job_id, fire_owner)`` pairs) restricts
marking. Tokens go into ``_interrupted_job_ids`` BEFORE ``last_status`` is written so
``run_one_job`` sees them.
Nc              3   óN   "  € T F  pR VR \        V^ ,          4      3x € K  	  R # 5ir?   )rd  rŠ  s   & r0   rE   Ú0mark_running_jobs_interrupted.<locals>.<genexpr>r  s0   é € ð  ñ Nð ð �s˜DÔ"5°c¸!µfÓ"=Õ>ãMùs   ‚#%c              3   ó8   "  € T F  w  rr4Ve   TMTx € K  	  R # 5ir?   rù   )rC   Útokenr‹  Ú_ownerÚ_profile_homes   &    r0   rE   rN  x  s&   é € ð $
á5AÑ1�˜Fð Ò&‰E¨CÔ/Û5Aùs   ‚zdJob '%s' interrupted before its durable fire owner was registered; leaving persisted state untouchedF)Úexpected_fire_ownerz%Failed to mark job %s interrupted: %s)rŽ  r  Ú_restart_safe_waiter_job_idsr�  r°  Úextendr�  Ú_interrupted_job_idsÚupdateræ   r&  r  r6  r2  rX   )r2  rJ  Úrestart_safe_waitersr‹  Ú
executionsrP  rS   Úprofile_homeÚactive_firesÚfireÚ_tÚ_oÚ_pÚregistered_keysÚmarkedÚ_tokenÚ
fire_ownerr½   r  s   &$                 r0   Úmark_running_jobs_interruptedrd  Y  sì  € ÷ 
ŽÜ"Ô#?Ó@Ðô $8×#=Ñ#=Ô#?÷
á#?‘�ØÑ.ô .ð 1;×0@Ñ0@Ö0BÑ,�Ñ,˜ð ˜Ó-ñ 1Cñ .Ù#?ð 	ô 
ð Ò"Ù-9Ób©\ TÀ1½gÀa½jÈ$ÈqÍ'Ð=RÐVaÑ=aŸD˜D©\ˆLÐbÙ6BÖC±l¡? 2¨B›3±lˆÓCØÒð ×Ññ  ô % Õ6Ð9MÖMó ô ô 	×#Ñ#ñ $
á5Aó$
ô 	
÷+ 
ð2 €FÛ1=Ñ-ˆ�Z Ø�Q•ˆßÜ�N‰Nð4àôð �M‰M˜&Ô!Ùð	OÜ ×-Õ-ÜØ˜E 6¸z÷Kó Kà—M‘M &Ô)÷ .Ñ-ñ 2>ð& €MùöW
ùò cùÝC÷ 
�ú÷N .×-Ð-ûô ô 	OÜ�N‰NÐBÀFÈA×NÒNûð	Oúsw   �*F6¹
F Á$F Á,F6Á:F)ÂF)Â$	F6Â-F.Â;AF6ÅGÅ+'G	ÆGÆ F6Æ6G	Ç	GÇGÇGÇH
Ç(HÈH
c                óR   € V ^8„  d   QhR\         R\        \        ,          R\        /# ©r4   r½   rP  r6   ©rB   r   Úobjectr9   )r:   s   "r0   r;   r;   “  s&   € ÷ +ñ +œCð +¬´Õ(8ð +ÄDñ +r<   c                ó¸   € \        V 4      p\        ;_uu_ 4        Ve   V\        9   d    RRR4       R# V\        9   uuRRR4       #   + '       g   i     R# ; i)a  Non-destructive peek: has shutdown marked THIS execution interrupted? Used before deciding
what to deliver; does not clear the flag (the authoritative pre-``last_status`` check needs it).
``token`` scopes to one execution so a fresh run reusing the job ID isn't poisoned.NT)r\  rŽ  rV  )r½   rP  r‹  s   && r0   Ú_is_interruptedrj  “  sB   € ô ˜Ó
€Cß	ŽØÒ Ô*>Ô!>Ø÷ 
‰ð Ô*Ñ*÷ 
��‹ús   šAµAÁA	c                óR   € V ^8„  d   QhR\         R\        \        ,          R\        /# rf  rg  )r:   s   "r0   r;   r;   ž  s&   € ÷ ñ ¤cð ´(¼6Õ2Bð Ìdñ r<   c                ó
  € \        V 4      p\        ;_uu_ 4        RpVe#   V\        9   d   \        P                  V4       RpV\        9   d   \        P                  V4       RpVuuRRR4       #   + '       g   i     R# ; i)z°Return True and clear the flag if shutdown marked THIS execution interrupted. Called right
before ``last_status`` is written; consuming stops the flag leaking into a later run.FNT)r\  rŽ  rV  rÛ  )r½   rP  r‹  Úhits   &&  r0   Ú_consume_interrupted_flagrn  ž  sd   € ô ˜Ó
€Cß	ŽØˆØÒ Ô*>Ô!>Ü ×(Ñ(¨Ô/ØˆCØÔ&Ô&Ü ×(Ñ(¨Ô-ØˆCØ÷ 
��‹ús   šAA1Á1B	c                ó$   € V ^8„  d   QhR\         /# rÄ   rÅ   )r:   s   "r0   r;   r;   ­  s   € ÷ ñ ¤%ñ r<   c                 ó¼   € \        R4      P                  4       p V '       g   R#  \        V 4      #   \        \        3 d    \
        P                  RT 4        R# i ; i)zïParse HERMES_CRON_TIMEOUT (seconds). 0 = unlimited; bad input = 600. Shared by the
inactivity monitor and the cwd-lock bound so they can't drift: the lock bound must stay >= the
inactivity limit or waiters fail while a healthy holder runs.ÚHERMES_CRON_TIMEOUTg     À‚@z2Invalid HERMES_CRON_TIMEOUT=%r; using default 600s)r   r&   rÆ   r(   rÖ   ræ   r&  )rå  s    r0   Ú_cron_inactivity_secondsrr  ­  sS   € ô Ð0Ó
1×
7Ñ
7Ó
9€CßÙðÜ�S‹zÐøÜœ	Ð"ô Ü�‰ÐKÈSÔQÚðús   ¥
0 °'AÁAc                ón   € V ^8„  d   QhR\         \        ,          R\        P                  P                  /# )r4   Úmax_workersr6   )r   re   Ú
concurrentÚfuturesÚThreadPoolExecutor)r:   s   "r0   r;   r;   »  s*   € ÷ ñ ¤H¬S¥Mð ´j×6HÑ6H×6[Ñ6[ñ r<   c                ó8  € \        \        \        4       4      4      p\        P	                  V4      pVe   \
        P	                  V4      V 8w  dK   Ve   VP                  RRR7       \        P                  P                  V RR7      pV\        V&   V \
        V&   V# )aM  Return (or create) the persistent parallel pool for the ACTIVE profile.

Pools are per profile home because ``cron.max_parallel_jobs`` is a per-profile config key:
a single process-global pool is created by whichever profile the multiplexing gateway ticks
first and then silently imposes that profile's limit on every other profile.
F©ÚwaitÚcancel_futureszcron-parallel)rt  Úthread_name_prefix)
r   r`  r£   Ú_parallel_poolsrA   Ú_parallel_pool_max_workersÚshutdownru  rv  rw  )rt  r¦   Úpools   &  r0   Ú_get_parallel_poolr�  »  s‘   € ô Ô2Ô3CÓ3EÓFÓG€DÜ×Ñ˜tÓ$€DØ‚|Ô1×5Ñ5°dÓ;¸{ÔJØÒØ�M‰M˜u°UˆMÔ;Ü×!Ñ!×4Ñ4Ø#¸ð 5ó Iˆà $Œ˜ÑØ+6Ô" 4Ñ(Ø€Kr<   c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   r;   Î  s   € ÷ <ñ <¨ñ <r<   c                ó´   € \        V 4       FH  p\        P                  VR4      p\        P                  VR4       Vf   K5  VP	                  RRR7       KJ  	  R# )u¢  Drop the parallel pools of homes this process no longer ticks.

Pools are per home and used to live until ``atexit``: a host that serves many profiles â€” or
churns them â€” accumulated one ThreadPoolExecutor and its live ``cron-parallel`` threads per
home ever ticked, and a deleted profile's pool was never reclaimed. ``wait=False`` so the
ticker is never blocked; queued work still drains before the executor dies.
NFry  )rO   r}  rÚ  r~  r  )Ú	home_keysr‹  r€  s   &  r0   Údiscard_parallel_poolsr…  Î  sJ   € ô �IŽˆÜ×"Ñ" 3¨Ó-ˆÜ"×&Ñ& s¨DÔ1ØÔØ�M‰M˜u°UˆMÖ;ó	 r<   c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   r;   Ý  s   € ÷ 'ñ ' ñ 'r<   c                 óÄ   € \        \        P                  4       4       F  p V P                  RRR7       K  	  \        P	                  4        \
        P	                  4        R# )z:Shut down every profile's persistent pool on process exit.TFry  N)rO   r}  Úvaluesr  Úclearr~  )r€  s    r0   Ú_shutdown_parallel_poolrŠ  Ý  sB   € ä”_×+Ñ+Ó-Ö.ˆØ�‰˜4°ˆÖ6ñ /ä×ÑÔÜ×$Ñ$Ö&r<   c                ó$   € V ^8„  d   QhR\         /# rÄ   r   )r:   s   "r0   r;   r;   ç  s   € ÷ =ñ =œ4ñ =r<   c                  ó2   € \        4       R ,          R,          # )r`   zusage_audit.jsonl©r£   rù   r<   r0   Ú_usage_audit_pathrŽ  ç  s   € ÜÓ Õ&Ð)<Õ<Ð<r<   c                ó$   € V ^8„  d   QhR\         /# rÄ   rv   )r:   s   "r0   r;   r;   ë  s   € ÷ Rñ Rœñ Rr<   c                 ó�   € \         P                  ! \        4      p V P                  R4      V P                  R,          R R2,           # )z@RFC3339 UTC timestamp with millisecond precision and 'Z' suffix.z%Y-%m-%dT%H:%M:%S.éè  Ú03dÚZ)r   r   r   ÚstrftimeÚmicrosecond)r   s    r0   Ú_utcnow_iso_msr–  ë  s8   € ä
�,Š,”sÓ
€CØ�<‰<Ð,Ó-°3·?±?ÀdÕ3JÈ3Ð2OÈqÐ0QÕQÐQr<   c                ó(   € V ^8„  d   QhR\         RR/# )r4   Úrecordr6   Nrï   )r:   s   "r0   r;   r;   ñ  s   € ÷ 
:ñ 
:œtð 
:¨ñ 
:r<   c                ój  €  \        4       p\        VP                  4       \        P                  ! V RR7      p\        VRRR7      ;_uu_ 4       pVP                  VR,           4       RRR4       R#   + '       g   i     R# ; i  \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)	uŒ   Append one JSONL line to cron/usage_audit.jsonl. NEVER raises â€” a logger bug must not
break cron jobs (the whole write is inside one try).F)Úensure_asciir  r  r  rK  Nzusage_audit write failed: %s)
rŽ  r)  r  r  r  r  r  rX   ræ   r&  )r˜  r  ÚlineÚfr  s   &    r0   Ú_write_usage_auditr�  ñ  s|   € ð:Ü Ó"ˆÜ˜Ÿ™Ô%Ü�zŠz˜&¨uÔ5ˆÜ�$˜ g×.Õ.°!Ø�G‰G�D˜4•KÔ ÷ /×.×.Ò.ûäô :Ü�‰Ð5°q×9Ò9ûð:ús6   ‚AB ÁA2Á(B Á2B	Á=B ÂB ÂB2ÂB-Â-B2c                óF   € V ^8„  d   QhR\         \        ,          R\        /# ©r4   rë   r6   )r   ÚBaseExceptionr9   )r:   s   "r0   r;   r;   þ  s   € ÷ *ñ *¤H¬]Õ$;ð *Ätñ *r<   c                ó   € ^ RI Hp V! V 4      # )u  True when the interpreter is finalizing (tick fired during gateway teardown): concurrent.
futures/asyncio refuse new work, so delivery attempts only pollute errors.log â€” callers skip
with a warning. ``exc`` lets an already-raised scheduling error count as a shutdown signal.

A cron tick can fire while the gateway is tearing down â€” SIGTERM from ``hermes update`` / ``hermes
gateway stop`` / systemd restart, or an OOM-kill. Once finalization starts, ``concurrent.futures``
refuses new work with ``RuntimeError: cannot schedule new futures after interpreter shutdown`` and
asyncio's default executor is gone, so *any* attempt to schedule delivery (live-adapter,
``asyncio.run``, or a fresh pool) is doomed and only pollutes ``errors.log`` with a traceback. See
#55924, #58720.
)Úinterpreter_shutting_down)Útools.interpreter_shutdownr¢  )rë   r¢  s   & r0   Ú_interpreter_shutting_downr¤  þ  s   € õ Eá$ SÓ)Ð)r<   c                ó$   € V ^8„  d   QhR\         /# rÄ   r   )r:   s   "r0   r;   r;     s   € ÷ -ñ -œ$ñ -r<   c                 ó2   € \         ;'       g    \        4       # )u¾  Hermes home at call time (honouring the test override). Cron is per-profile: never freeze
this at import or anchor it at the shared default root â€” either breaks profile isolation.

Cron is per-profile by design (#4707): the in-process ticker runs inside a profile-scoped gateway, so
resolving the active HERMES_HOME at call time means a profile's jobs are stored AND executed under that
profile's home (its .env, config.yaml, scripts, skills).
)Ú_hermes_homer   rù   r<   r0   r£   r£     s   € ô ×,Ð,œ?Ó,Ð,r<   c                óF   € V ^8„  d   QhR\         \        \        3,          /# rÄ   )rn   r   )r:   s   "r0   r;   r;     s   € ÷ -ñ -œœt¤T˜zÕ*ñ -r<   c                 ó<   € \        4       p V R,          pWR,          3# )zHResolve cron lock paths at call time so profile/env changes are honored.r`   z
.tick.lockr�  )Úhermes_homeÚlock_dirs     r0   Ú_get_lock_pathsr¬    s"   € ä"Ó$€KØ˜VÕ#€HØ Õ,Ð,Ð,r<   c                ó0   € V ^8„  d   QhR\         R\        /# )r4   Úerrr6   )r-  r9   )r:   s   "r0   r;   r;   (  s   € ÷ 
ñ 
¤7ð 
¬tñ 
r<   c                ó  € V P                   f   R# \        e=   V P                   \         P                  \         P                  \         P                  39   # \
        e.   V P                   \         P                  \         P                  39   # R# )u  True when *err* from the lock syscall means another ticker holds the lock (POSIX flock:
EWOULDBLOCK/EAGAIN, EACCES on some NFS; msvcrt.locking: EACCES/EDEADLK). Everything else â€”
notably EMFILE/ENFILE and EACCES on open() â€” must be surfaced, never swallowed as contention.F)ÚerrnoÚfcntlÚEWOULDBLOCKÚEAGAINÚEACCESÚmsvcrtÚEDEADLK)r®  s   &r0   Ú_is_lock_contention_errnor·  (  s`   € ð ‡y�yÒÙÜÒØ�y‰yœU×.Ñ.´·±¼e¿l¹lÐKÑKÐKÜÒØ�y‰yœUŸ\™\¬5¯=©=Ð9Ñ9Ð9Ùr<   c                ó0   € V ^8„  d   QhR\         R\        /# rH  rT  )r:   s   "r0   r;   r;   5  s   € ÷ Cñ C¤ð C¬ñ Cr<   c                óF   € V P                  4       pRV9   ;'       g    RV9   # )z:Text half of _is_fd_exhaustion (shared with the CLI hint).ztoo many open filesÚemfile)r·   )r¾   Úlowereds   & r0   Ú_is_fd_exhaustion_textr¼  5  s%   € à�j‰j‹l€GØ  GÑ+×BÐB¨x¸7Ñ/BÐBr<   c                ó0   € V ^8„  d   QhR\         R\        /# rŸ  )r   r9   )r:   s   "r0   r;   r;   ;  s   € ÷ ,ñ ,œ=ð ,¬Tñ ,r<   c                ó¸   € \        V \        4      '       d2   V P                  \        P                  \        P                  39   d   R# \        \        V 4      4      # )z¸True when *exc* indicates fd exhaustion: EMFILE/ENFILE errno, or the "Too many open files"
wording for wrapped exceptions (load_jobs wraps the OSError in a RuntimeError).

See #87644.
T)r@   r-  r°  ÚEMFILEÚENFILEr¼  rB   )rë   s   &r0   Ú_is_fd_exhaustionrÁ  ;  s;   € ô �#”w×Ò C§I¡I´%·,±,ÄÇÁÐ1MÔ$MÙÜ!¤# c£(Ó+Ð+r<   c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   r;   F  s   € ÷ &ñ & $ñ &r<   c                 óD  € \         P                  ! \        4      ;_uu_ 4        ^ RIp V P	                  4        RRR4       \         P                  ! \        4      ;_uu_ 4        ^ RIHp V! R4       RRR4       R#   + '       g   i     LK; i  + '       g   i     R# ; i)a4  Best-effort fd reclamation: gc.collect() closes file objects stuck in reference cycles;
apply_nofile_soft_limit() raises the RLIMIT_NOFILE soft limit for headroom. Never raises.

The cron FD-leak family (#60859, #79742, #80792) leaks descriptors from abandoned workers/sessions. Two
safe, idempotent levers:
N)Úapply_nofile_soft_limit)r³  r´  rX   ÚgcÚcollectÚhermes_cli.resource_limitsrÄ  )rÅ  rÄ  s     r0   Ú_reclaim_fds_best_effortrÈ  F  sa   € ô 
×	Ò	œY×	'Õ	'Ûà
�
‰
Œ÷ 
(ô 
×	Ò	œY×	'Õ	'ÝFá Ô%÷ 
(Ñ	'÷	 
(×	'ú÷ 
(×	'Ð	'ús   £A;Á"BÁ;B	ÂB	c                ó$   € V ^8„  d   QhR\         /# rÄ   )re   )r:   s   "r0   r;   r;   W  s   € ÷ ñ ¬Cñ r<   c                ón   a a€ ^ RI HpHp V! 4       P                  4       '       g   ^ # V V3R lpV! V4      # )z@Send queued worker results through this gateway's live adapters.)Ú_pathÚdrainc                 ó¨   <€ \        WSSVR 7      pV'       g:   V'       d2   V P                  R4      '       g   \        V P                  R4      4       V# )©ÚadaptersÚloopÚfor_failureÚ$_notification_all_targets_suppressedÚ_failure_incident_id)Ú_deliver_resultrA   rö   )Ú
queued_jobÚqueued_contentÚqueued_for_failurerª   rÏ  rÐ  s   &&& €€r0   ÚsendÚ"drain_delivery_queue.<locals>.send`  sF   ø€ ÜØ°ÀØ*ô
ˆ÷ ×,Ø"Ÿ™Ð'M×NÒNÜ" :§>¡>Ð2HÓ#IÔJØˆr<   )Úcron.delivery_queuerË  rÌ  Úexists)rÏ  rÐ  rË  rÌ  rØ  s   ff   r0   Údrain_delivery_queuerÜ  W  s+   ù€ ç0ñ
 ‹7�>‰>×ÒÙö
ñ �‹;Ðr<   rÔ   r¦  ç      ð?c                ó$   € V ^8„  d   QhR\         /# rÄ   rÅ   )r:   s   "r0   r;   r;   x  s   € ÷ ñ ¤uñ r<   c                 ó>  € Rp  ^ RI Hp V! 4       ;'       g    / p\        V\        4      '       d   VP	                  R/ 4      M/ pVP	                  R4      pVe   \        V4      pV^ 8¼  d   V# V #   \         d"   p\        P                  RT4        Rp?T # Rp?ii ; i)z6Return the wall-clock bound for cron post-run cleanup.g      $@)r   r`   Úcleanup_timeout_secondsNz3Failed to load cron cleanup timeout from config: %s)	Úhermes_cli.configr   r@   r8   rA   rÆ   rX   ræ   rç   )Údefaultr   rN   r  Ú
configuredÚtimeoutrë   s          r0   Ú_cron_cleanup_timeout_secondsrå  x  sš   € à€GðQÝ1á‹m×!Ð!˜rˆÜ*4°S¼$×*?Ò*?�3—7‘7˜6 2Ô&ÀRˆØ—\‘\Ð";Ó<ˆ
ØÒ!Ü˜JÓ'ˆGØ˜!Œ|Ø�ð €Nøô ô QÜ�‰ÐJÈC×PÐPØ€NûðQús   „A0 ˜AA0 Á0BÁ;BÂBÚtimeout_secondsc                ó^   € V ^8„  d   QhR\         R\         R\        \        ,          R\        /# )r4   r½   Úlabelræ  r6   )rB   r   rÆ   r9   )r:   s   "r0   r;   r;   Š  s0   € ÷ 'ñ 'Üð'Ü$'ð'Ü:BÄ5½/ð'ä	ñ'r<   c               ó,  a aa	€ Vf   \        4       M
\        V4      pV^ 8:  d    S ! 4        R# \        P                  ! 4       o. o	R V VV	3R llp\        P                  ! \        V4      RV 2RR7      pVP                  4        SP                  V4      '       g   \        P                  R	VVV4       R# S	'       d!   \        P                  RWS	^ ,          4       R# R#   \        \        3 d#   p\        P                  RYT4        Rp?R# Rp?ii ; i)
zDRun fallible post-run cleanup without permanently wedging a cron ID.NTzJob '%s': %s failed: %sFc                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   Ú4_run_cron_cleanup_with_timeout.<locals>.__annotate__š  s   € ÷ ñ �Tñ r<   c                  ó´   <€  S! 4        SP                  4        R #   \          d   p SP                  T 4        R p ? L3R p ? ii ; i  SP                  4        i ; ir?   )r   r  r  )rë   Úcleanupr   rª   s    €€€r0   Ú_runnerÚ/_run_cron_cleanup_with_timeout.<locals>._runnerš  sE   ø€ ð	ÙŒIð �H‰HŽJøô ô 	Ø�L‰L˜×Ñûð	ûð �H‰H�Jús#   ƒ œA§=¸A ½AÁA ÁAzcron-cleanup-©Útargetrc   ÚdaemonzRJob '%s': %s exceeded %.1fs; abandoning cleanup so future runs remain dispatchable)rå  rÆ   rX   ÚKeyboardInterruptræ   rç   Ú	threadingÚEventÚThreadr    Ústartrz  rª   )
rí  r½   rè  ræ  rä  rë   rî  Úworkerr   rª   s
   f$$$    @@r0   Ú_run_cron_cleanup_with_timeoutrù  Š  sò   ú€ ð 3BÒ2IÔ,Ô.ÌuÐUdÓOe€GØ�!„|ð	ÙŒIÙô
 �?Š?Ó€DØ!#€E÷ò ô ×ÒÜ˜Ó!¨-¸°xÐ(@ÈôO€Fà
‡L�L„NØ�9‰9�W×ÒÜ�‰Ø`ØØØô		ñ
 ßÜ�‰Ð.°¸uÀQ½xÔHÙÙøô= Ô,Ð-ô 	Ü�L‰LÐ2°FÀ3ÔGÝûð	ús   ¥C  Ã DÃ1DÄDc                   ó<   a € ] tR tRt o RtV 3R lR ltR tRtV tR# )Ú_BoundedCronSessionDBi´  z´Proxy SessionDB cleanup calls through the cron cleanup timeout; after the first failure or
timeout all later calls fail immediately (a damaged connection leaks at most one worker).c                ó    <€ V ^8„  d   QhRS[ /# )r4   r½   rv   )r:   r€   s   "€r0   r;   Ú"_BoundedCronSessionDB.__annotate__¸  s   ø€ ÷ ñ ©3ñ r<   c                ó,   € Wn         W n        R V n        R# rä   )Ú_session_dbÚ_job_idÚ	_disabled)r‡   r*   r½   s   &&&r0   r†   Ú_BoundedCronSessionDB.__init__¸  s   € Ø%ÔØŒØˆŽr<   c                ón   a aa€ \        S P                  S4      o\        S4      '       g   S# VV V3R  lpV# )c                  ó  <a aa€ SP                   '       d   \        R 4      h/ oV VVV3R lp\        VSP                  RS R2R7      pV'       g.   SP	                  R4      pVe   VhRSn         \        RS R24      hSP	                  R	4      # )
z9session finalization disabled after prior cleanup failurec                  óR   <€  S! S/ SB SR &   R#   \          d   p T SR&   h Rp ? ii ; i)Úvaluerª   N)r   )rë   ÚargsÚkwargsr  rñ  s    €€€€r0   Ú_callÚB_BoundedCronSessionDB.__getattr__.<locals>._bounded.<locals>._callÈ  s7   ø€ ðÙ&,¨dÐ&=°fÑ&=�F˜7“OøÜ$ô Ø&)�F˜7‘OØûðús   ƒ �&›!¡&zsession finalization (r„   )r½   rè  rª   Tzsession finalization method z
 timed outr  )r  r  rù  r   rA   ÚTimeoutError)	r  r  r	  rï  rª   r  rc   r‡   rñ  s	   jl   @€€€r0   Ú_boundedÚ3_BoundedCronSessionDB.__getattr__.<locals>._boundedÂ  s‘   û€ Ø�~�~ˆ~Ü"Ð#^Ó_Ð_àˆF÷ð ô 0Ø˜dŸl™lÐ4JÈ4È&ÐPQÐ2RôTˆBçØŸ
™
 7Ó+�ØÒ$Ø�Kà!%�”Ü"Ð%AÀ$ÀÀzÐ#RÓSÐSØ—:‘:˜gÓ&Ð&r<   )r)   rÿ  Úcallable)r‡   rc   r  rñ  s   ff @r0   Ú__getattr__Ú!_BoundedCronSessionDB.__getattr__½  s1   ú€ Ü˜×)Ñ)¨4Ó0ˆÜ˜×ÒØˆM÷	'ð0 ˆr<   )r  r   rÿ  N)	rŠ   r‹   rŒ   r�   rŽ   r†   r  r�   r�   rq  s   @r0   rû  rû  ´  s   ø‡ € ña÷ð ÷
ð r<   rû  c          
      óT   € V ^8„  d   QhR\         R\         R\         R\         R\         /# )r4   r¼   r½   Únow_isoÚmoder6   rv   )r:   s   "r0   r;   r;   Ý  s/   € ÷ ñ œcð ¬3ð ¼ð ÄCð ÌCñ r<   c           	     ó    € RV  RV RV RV R2	# )zKCommon markdown header for the short-circuit run docs (no_agent / monitor).ú# Cron Job: ú

**Job ID:** ú
**Run Time:** z
**Mode:** rK  rù   )r¼   r½   r  r  s   &&&&r0   Ú_job_doc_headerr  Ý  s5   € ð �x�jð !Ø�hð Ø ˜	ð "Ø�F˜"ð	ðr<   c                óR   € V ^8„  d   QhR\         R\        R\        \        ,          /# )r4   r5   r½   r6   ©r8   rB   r   )r:   s   "r0   r;   r;   ç  s%   € ÷ ñ œdð ¬Cð ´H¼SµMñ r<   c                óê   € V P                  R4      ;'       g    RP                  4       ;'       g    RpV'       d8   \        V4      P                  4       '       g   \        P                  RW4       R# V# )zLConfigured job workdir, or None when unset / no longer a directory (logged).Úworkdirr$   NuG   Job '%s': configured workdir %r no longer exists â€” running without it)rA   r&   r   Úis_dirræ   r&  )r5   r½   r  s   && r0   Ú_resolve_job_workdirr  ç  sZ   € à�w‰w�yÓ!×'Ð' R×.Ñ.Ó0×8Ð8°D€Gß”t˜G“}×+Ñ+×-Ò-Ü�‰ØUØô	ñ Ø€Nr<   c                ó”   € V ^8„  d   QhR\         R\        R\        R\        \        \        \        \        \        ,          3,          /# ©r4   r5   r½   r¼   r6   )r8   rB   rn   r9   r   )r:   s   "r0   r;   r;   ò  s>   € ÷ 4>ñ 4>Ü	ð4>Üð4>Ü&)ð4>ä
Œ4””cœ8¤C�=Ð(Õ)ñ4>r<   c                ó8  €  ^ RI Hp V! \        4       R7       V P                  R4      p\        T;'       g    R4      P                  4       '       g   ^ RI	H
p \        WV4      # \        W4      p \        WWsR	7      w  r‰\        4       P!                  R4      p\#        W!VR4      pV'       g   RV RV	 RV 2pRV RV	 R2WÙ3# \%        V	4      '       g$   \        P'                  RV4       RV R2\(        R3# V	P                  4       '       g$   \        P'                  RV4       RV R2\(        R3# RV RV	 R2V	R3#   \         d    \        P                  RTRR7        ELJi ; i  \         d(   p
\        P                  R
T4       RRT
 2r˜ Rp
?
ELRp
?
ii ; i)uÄ   no_agent short-circuit â€” the script IS the job (no AIAgent, no tokens). stdout â†’ delivered
verbatim; empty stdout or wakeAgent=false â†’ silent success; non-zero exit/timeout â†’ error alert.
)Úload_hermes_dotenv©rª  z%Job '%s': no_agent .env reload failedT©Úexc_infoÚscriptr$   )ÚNO_AGENT_WITHOUT_SCRIPT_ERROR©r  Úcancel_eventz.Job '%s': script execution raised unexpectedlyFzScript execution failed: Nú%Y-%m-%d %H:%M:%Szno_agent (script)u   âš  Cron watchdog 'z' script failed

ú

Time: z**Status:** script failed

rK  u8   Job '%s' (no_agent): wakeAgent=false gate â€” silent runz%**Status:** silent (wakeAgent=false)
u0   Job '%s' (no_agent): empty stdout â€” silent runz"**Status:** silent (empty output)
z
---

)Úhermes_cli.env_loaderr"  r£   rX   ræ   rç   rA   rB   r&   Úcron.jobs_invariantsr'  Ú_block_and_pause_jobr  Ú$_run_job_script_with_claim_heartbeatÚ	exceptionr×   r”  r  Ú_parse_wake_gater%  ÚSILENT_MARKER)r5   r½   r¼   r)  r"  Úscript_pathr'  Ú_job_workdirrï  Úoutputrë   r  ÚheaderÚalerts   &&&&          r0   Ú_run_no_agent_jobr8  ò  s»  € ðUÝ<áÔ'7Ó'9Õ:ð —'‘'˜(Ó#€Käˆ{× Ð ˜bÓ!×'Ñ'×)Ò)ÝFä# FÐ6SÓTÐTô (¨Ó4€Lð>Ü9Ø lôO‰
ˆô ‹m×$Ñ$Ð%8Ó9€GÜ˜X¨wÐ8KÓL€Fçð " ( Ð+>Øˆhð Ø�Iðð 	ð
 ˜˜Ð =¸f¸XÀRÐHÈ%ÐWÐWô ˜F×#Ò#Ü�‰ÐNÐPVÔWØ˜�xÐEÐFÌÐW[Ð[Ð[à�<‰<�>Š>Ü�‰ÐFÈÔOØ˜�xÐBÐCÄ]ÐTXÐXÐXà�F�8˜9 V H¨BÐ/°¸Ð=Ð=øôQ ô UÜ�‰Ð<¸fÈtˆ×TðUûô ô >Ü×ÑÐIÈ6ÔRØÐ7¸°uÐ=ŽFûð>ús)   ‚D= Á1E' Ä=#E$Å#E$Å'FÅ2FÆFc                óØ   € V ^8„  d   QhR\         R\        R\        R\        \        ,          R\        \        \        ,          \        \        ,          \        \        ,          3,          /# ©r4   r5   r½   r¼   Úextra_promptr6   ©r8   rB   r   rn   )r:   s   "r0   r;   r;   )  sP   € ÷ #2ñ #2Ü	ð#2Üð#2Ü&)ð#2Ü9AÄ#½ð#2ä
Œ8”E�?œH¤S�M¬8´C­=Ð8Õ9ñ#2r<   c                óò  € ^ RI HpHp V! V 4      '       g   RVR3# V! V 4      p\        4       P	                  R4      p\        W!VR4      pVP                  '       gX   \        P                  RWP                  4       RV RVP                   RV 2p	R	V R
VP                   R2W–P                  3VR3# VP                  '       g'   \        P                  RV4       RV R2\        R3VR3# RW6P                  3# )a^  Monitor gate (hash-suppressed change detection). Must run BEFORE any agent machinery so an
unchanged tick costs no LLM/delivery. Returns ``(early_result | None, extra_prompt,
monitor_context)``. Monitor context is runtime data and must remain distinct from a
user-authored ``extra_prompt`` so the prompt scanner keeps its strict user-input boundary.
)Úcheck_monitorÚjob_has_monitorNr*  Úmonitorz#Job '%s': monitor source failed: %su   âš  Cron monitor 'z' source failed

r+  Fz#**Status:** monitor source failed

rK  u<   Job '%s': monitor output unchanged â€” suppressing agent runTz-**Status:** no_change (agent run suppressed)
)Úcron.monitorr>  r?  r×   r”  r  rï  ræ   rª   Úchangedr%  r2  Úcontext_block)
r5   r½   r¼   r;  r>  r?  Ú_monÚ_mon_nowr6  Ú
_mon_alerts
   &&&&      r0   Ú_apply_monitor_gaterG  )  s  € ÷ <á˜3×ÒØ�\ 4Ð'Ð'Ù˜Ó€DÜ‹}×%Ñ%Ð&9Ó:€HÜ˜X¨x¸ÓC€FØ�7�7ˆ7ô 	�‰Ð:¸FÇJÁJÔOà   
Ð*=Ø�z‰zˆlð Ø�Jð ð 	ð �f�XÐBÀ4Ç:Á:À,ÈbÐQÐS]×_iÑ_ið
à˜ðð 	ð �<�<ˆ<ä�‰ÐRÐTZÔ[à�V�HÐJÐKÌ]Ð\`ð
à˜ðð 	ð
 �×1Ñ1Ð1Ð1r<   c                   ó0   a € ] tR tRt o RtV 3R ltRtV tR# )Ú_CronJobConfigiO  z4Config-derived inputs for one agent-backed cron run.c                óJ   <€ V ^8„  d   Qh/ S[ ;R&   S[;R&   S[;R&   S[;R&   # )r4   rN   rH   Ú	model_cfgÚcron_default_provider)r8   rB   r   )r:   r€   s   "€r0   r;   Ú_CronJobConfig.__annotate__O  s6   ø‡ ‚ ñ 
�Iñ	 ñ
 �Jñ ñ �Nñ ñ Ñò r<   rù   N)rŠ   r‹   rŒ   r�   rŽ   Ú__annotate_func__r�   r�   rq  s   @r0   rI  rI  O  s   ø‡ € á>÷ ƒ r<   rI  c                óH   € V ^8„  d   QhR\         R\        R\        R\        /# r   )r8   rB   rI  )r:   s   "r0   r;   r;   Y  s.   € ÷ 2Kñ 2Kœtð 2K¬Sð 2K¼Cð 2KÄNñ 2Kr<   c                ó~  € ^ RI Hp V P                  R4      ;'       g    \        R4      ;'       g    RpRp/ p/ p ^ RIHp \        \        4       R,          4      p	\        P                  P                  V	4      '       Ed†   V! \        V	4      4      pVP                  R4      ;'       g    / pVP                  R4      ;'       g    / p
Rp\        V
\        4      '       de   \        V
P                  R4      ;'       g    R4      P                  4       p\        V
P                  R4      ;'       g    R4      P                  4       pV P                  R4      '       g¬   V'       d   TpM \        V\        4      '       d   TMZ\        V\        4      '       dD   VP                  R	4      ;'       g+    VP                  R4      ;'       g    VP                  R
4      MRp\        T;'       g    R4      P                  4       ;'       g    Tp\        V\        4      '       d   TMRP                  4       ;'       g    V! 4       pV'       g3   \%        RV RV P                  R4      : R\        R4      : RV R2	4      h\&        P(                  ! \        4      ;_uu_ 4        ^ RIHp VP                  R/ 4      p\        V\        4      '       d!   VP                  R4      '       d
   V! RR7       RRR4       \/        WdWu4      #   \         d"   p\         P#                  RY4        Rp?ELRp?ii ; i  + '       g   i     LK; i)a  Load config.yaml and resolve the run's model: per-job pin > cron.model (fleet default) >
the main agent model (config ``model:``, then HERMES_MODEL) > the claimed welcome trial's. Re-read
every tick (no cache) so ``hermes cron edit --model`` and ``hermes model`` both apply next tick.)Útrial_modelrH   ÚHERMES_MODELr$   )Úload_user_config_effectivezconfig.yamlr`   Úmodel_providerrâ  rc   z8Job '%s': failed to load config.yaml, using defaults: %sNú
Cron job 'z%' has no model configured (job.model=z, HERMES_MODEL=zY, config.yaml model.default missing or empty). Set a per-job model via `hermes cron edit z= --model <name>` or set a default with `hermes model <name>`.)Úapply_ipv4_preferenceÚnetworkÚ
force_ipv4T)Úforce)Úhermes_cli.anon_authrQ  rA   r   Úhermes_cli.config_effectiverS  rB   r£   Úosr  rÛ  r   r@   r8   r&   rX   ræ   r&  r  r³  r´  r$  rV  rI  )r5   r½   r¼   rQ  rH   Ú_cron_default_providerÚ_cfgÚ
_model_cfgrS  Ú	_cfg_pathÚ_cron_cfg_for_modelÚ_cron_default_modelÚ_mainr  rV  Ú_net_cfgs   &&&             r0   Ú_load_cron_job_configre  Y  s§  € õ 1Ø�G‰G�GÓ×FÐFÔ 0°Ó @×FÐFÀB€EØÐØ€DØ€Jð^ÝJÜÔ(Ó*¨]Õ:Ó;ˆ	Ü�7‰7�>‰>˜)×$Ó$Ù-¬d°9«oÓ>ˆDàŸ™ 'Ó*×0Ð0¨bˆJØ"&§(¡(¨6Ó"2×"8Ð"8°bÐØ"$ÐÜÐ-¬t×4Ò4Ü&)Ð*=×*AÑ*AÀ'Ó*J×*PÐ*PÈbÓ&Q×&WÑ&WÓ&YÐ#Ü),Ð-@×-DÑ-DÐEUÓ-V×-\Ð-\ÐZ\Ó)]×)cÑ)cÓ)eÐ&Ø—7‘7˜7×#Ò#ß&Ø/‘Eô +5°ZÄ×*EÒ*E™Jä% j´$×7Ò7ð #Ÿ™ yÓ1×fÐf°Z·^±^ÀGÓ5L×fÐfÐPZ×P^ÑP^Ð_eÓPføØ=?ð ô   § ¨Ó,×2Ñ2Ó4×=Ð=¸�Eô ! ¬×,Ò,‰U°"×;Ñ;Ó=×NÐNÁÃ€EçÜØ˜˜
ð #ØŸ'™' 'Ó*Ñ-ð .Ü,¨^Ó<Ñ?ð @!ð "( ð )2ð2ó
ð 	
ô 
×	Ò	œY×	'Õ	'Ý:Ø—8‘8˜I rÓ*ˆÜ�h¤×%Ò%¨(¯,©,°|×*DÒ*DÙ!¨Õ-÷	 
(ô
 ˜$ zÓJÐJøô) ô ^Ü�‰ÐQÐSY×]Ò]ûð^ú÷ 
(×	'úsn   ¼A.K= Â+K= Ã7K= Ã>1K= Ä0+K= ÅK= Å$K= Å'AK= Æ-K= Ç!K= Ç(K= ÈK= ÊAL,Ë 	L,Ë=L)ÌL$Ì$L)Ì,L<	c                óR   € V ^8„  d   QhR\         R\        R\        \        ,          /# )r4   rN   r½   r6   )r8   rB   r   rO   )r:   s   "r0   r;   r;   Ž  s%   € ÷ ñ ¤ð ¬cð ´h¼tµnñ r<   c                óÞ  € \        V P                  R/ 4      \        4      '       d   V P                  R/ 4      M/ p\        R4      ;'       g-    V P                  RR4      ;'       g    VP                  RR4      pV'       g   R# \	        V4      P                  4       pVP                  4       '       g   \        4       V,          pVP                  4       '       g   R#  \        VRRR7      ;_uu_ 4       p\        P                  ! V4      pRRR4       \        X\        4      '       d   V# R#   + '       g   i     L*; i  \         d#   p\        P                  R	YT4        Rp?R# Rp?ii ; i)
zVPrefill messages from env or config.yaml (top-level key canonical; agent.* is legacy).r  ÚHERMES_PREFILL_MESSAGES_FILEÚprefill_messages_filer$   NÚrú	utf-8-sigr  z8Job '%s': failed to parse prefill messages file '%s': %s)r@   rA   r8   r   r   Ú
expanduserÚis_absoluter£   rÛ  r  r  ÚloadrO   rX   ræ   r&  )rN   r½   r	  Úprefill_fileÚpfpathÚ_pfÚprefill_messagesr  s   &&      r0   Ú_load_prefill_messagesrs  Ž  s#  € ä(2°3·7±7¸7ÀBÓ3GÌ×(NÒ(N�—‘˜ Ô$ÐTV€IäÐ7Ó8÷ 	6ð 	6Ø�7‰7Ð*¨BÓ/÷	6ð 	6à�=‰=Ð0°"Ó5ð ÷
 ÙÜ�,Ó×*Ñ*Ó,€FØ×Ñ×ÒÜ!Ó# fÕ,ˆØ�=‰=�?Š?ÙðÜ�&˜#¨×4Õ4¸Ü#Ÿyšy¨›~Ð÷ 5ä#-Ð.>Ä×#EÒ#EÐÐOÈ4ÐO÷ 5×4ûô ô Ü�‰ÐQÐSYÐcdÔeÝûðús6   ÃD? Ã3D,Ä
D? Ä*D? Ä,D<	Ä7D? Ä?E,Å
E'Å'E,c                ój   € V ^8„  d   QhR\         R\        R\        R\         R\        \        ,          /# )r4   r5   r½   r¼   rN   r6   r<  )r:   s   "r0   r;   r;   ¦  s;   € ÷ @ñ @œTð @¬3ð @¼#ð @ÄDð @ÌXÔV[Í_ñ @r<   c                ó˜  € Rp \        V4      '       dd   \        W4      pV'       gQ   V P                  R4      '       d:   \        P                  ! \
        4      ;_uu_ 4        ^ RIHp V! V4       RRR4       T'       g   R# \        YT4      #   + '       g   i     L&; i  \
         d    \        P                  RTRR7       Rp LPi ; i)am  Pre-dispatch config validation: refuse unrunnable jobs (missing key, unready skill,
unconfigured delivery) BEFORE AIAgent is built. run_one_job keys off BLOCKED_CONFIG_MARKER to
record blocked_config and alert once (`preflight_alerted` bit). Must run after the wake gate so
silent ticks stay silent. Opt-out: `cron.preflight: false`. Returns failure tuple or None.
NÚpreflight_alerted)Úclear_preflight_alertedu7   Job '%s': preflight validation errored â€” failing openTr$  )Ú_cron_preflight_enabledÚ_preflight_job_configrA   r³  r´  rX   rË   rw  ræ   rç   Ú_blocked_config_result)r5   r½   r¼   rN   Ú
_pf_reasonrw  s   &&&&  r0   Ú_preflight_or_blockr|  ¦  sž   € ð €JðÜ" 3×'Ò'Ü.¨sÓ8ˆJß #§'¡'Ð*=×">Ò">ä×(Ò(¬×3Õ3ÝAÙ+¨FÔ3÷ 4÷ ÙÜ! &°JÓ?Ð?÷ 4×3ûô ô ä�‰ÐNÐPVÐaeˆÔfØŠ
ðús4   „:B! ¿"B! Á!BÁ0B! ÂB	ÂB! ÂB! Â!%C	ÃC	c                óH   € V ^8„  d   QhR\         R\         R\         R\        /# )r4   r½   r¼   r{  r6   r•   )r:   s   "r0   r;   r;   Å  s(   € ÷ <ñ <¤3ð <´#ð <Ä3ð <Ì5ñ <r<   c           	     ó.  € \         P                  RWV4       Rp ^ RIHp V! V 4      pV'       d   \        M\        pRV RV  R	\        4       P                  R
4       RV R2	pRVRV RV 23#   \         d    \         P                  RT RR7        Lji ; i)zMThe ``blocked_config`` failure tuple for *_pf_reason*, alerting once per job.uZ   Job '%s' (ID: %s): BLOCKED by pre-dispatch config validation â€” %s (no LLM call was made)F)Úmark_preflight_alertedz2Job '%s': could not persist preflight alert markerTr$  r  r  r  r*  z”
**Status:** BLOCKED (configuration)

The pre-run configuration check found a problem, so the agent did not run (nothing was charged).

**Reason:** zÞ

Hermes tries again at the next scheduled time and clears this state on the first healthy run; this alert is not repeated. Check with `hermes cron doctor`. Set `cron.preflight: false` in config.yaml to disable this check.r$   r³   )
ræ   r&  rË   r  rX   rç   ÚBLOCKED_CONFIG_SILENT_MARKERÚBLOCKED_CONFIG_MARKERr×   r”  )r½   r¼   r{  Úalready_alertedr  ÚmarkerÚblocked_docs   &&&    r0   rz  rz  Å  sÆ   € ä
‡N�NØdØ˜*ô&ð €OðbÝ4Ù0°Ó8ˆ÷ .=Õ)ÔBW€Fà
�x�jð !Ø�hð Ü$›×/Ñ/Ð0CÓDÐEð Fð "�lð #7ð		7ð ð �+˜r f X¨Q¨z¨lÐ#;Ð;Ð;øô ô bÜ�‰ÐIÈ6Ð\`ˆÖaðbús   ›A. Á.#BÂBc          
      ój   € V ^8„  d   QhR\         R\        R\        R\        \         \        3,          /# )r4   r5   r½   Újcr6   )r8   rB   rI  rn   )r:   s   "r0   r;   r;   à  s>   € ÷ EXñ EXœdð EX¬Cð EX´^ð EXÌÌdÔTWÈiÕHXñ EXr<   c           
     óü  € ^ RI HpHp ^ RIHp VP
                  pV P                  R4      ;'       g    VP                  ;'       g    Rp RVRV/pV P                  R4      '       d   V P                  R4      VR&   V! R/ VB V3#   \         Edj   p	\        Y•4      p
\        T	4      pT
'       g   T'       g   \        T! T	4      4      T	h\        YP                  4      ;'       g    . p\        P                  R	Y'       d   R
MRT	T'       d   RM\!        T 4      '       d   RMR4       T EFµ  p\        T\"        4      '       g   K  \%        TP                  R4      ;'       g    R4      P'                  4       p\%        TP                  R4      ;'       g    R4      P'                  4       pT'       d	   T'       g   K’   ^ RIHpHp RTRT/pTP                  R4      '       d   TR,          TR&   T! T4      pT'       d   TTR&   T! R/ TB pT! TT4      TR&   \        P/                  RTTP                  R4      T4       ^ RIHp T! T;'       g>    \        TP2                  \"        4      '       d   TP2                  P                  R4      MRTTP                  R4      T4      TR&   TT3u u Rp	?	#   \         d$   p\        P5                  RYT4        Rp?EK°  Rp?ii ; i	  \        T! T	4      4      T	hRp	?	ii ; i)a´  Resolve the runtime, walking the fallback chain on auth/transient-network errors. Returns
``(runtime, model)``; provider+model swap atomically (never swap only the provider while keeping
a paid primary model). Provider precedence: per-job pin > cron.model_provider > persisted
global config (None lets resolve_runtime_provider read it). A pinned job has no chain here
(``_job_fallback_chain``): its resolve failure is the job's failure.)Úresolve_runtime_providerÚformat_runtime_provider_error)Ú	AuthErrorrG   NÚ	requestedÚtarget_modelrI   Úexplicit_base_urlz6Job '%s': primary provider resolve failed (%s: %s), %sÚauthztransient networkztrying fallbackz#not falling back: the job is pinnedzno fallback configuredr$   rH   )Úeffective_runtime_providerÚresolve_entry_api_keyÚexplicit_api_keyz*Job '%s': fallback resolved to %s model %s)Úpre_agent_fallback_noticeÚ_fallback_noticez Job '%s': fallback %s failed: %srù   )Úhermes_cli.runtime_providerrˆ  r‰  Úhermes_cli.authrŠ  rH   rA   rL  rX   r@   Ú$_is_transient_provider_resolve_errorr  rT   rN   ræ   r&  rK   r8   rB   r&   Úhermes_cli.fallback_configr�  r�  r%  r’  rK  rç   )r5   r½   r†  rˆ  r‰  rŠ  rH   r‹  Úruntime_kwargsÚresolve_excÚis_authÚis_transient_netrY   r  Úfb_providerÚfb_modelr�  r�  Ú	fb_kwargsÚ
fb_api_keyÚruntimer’  Úfb_excs   &&&                    r0   Ú_resolve_job_runtimer¢  à  s®  € ÷Aå)à�H‰H€EØ—‘˜
Ó#×GÐG r×'?Ñ'?×GÐGÀ4€Ið9Xð ˜à˜Eð
ˆð
 �7‰7�:×ÒØ25·'±'¸*Ó2EˆNÐ.Ñ/Ù'Ñ9¨.Ñ9¸5Ð@Ð@øÜõ .Xô ˜[Ó4ˆÜ?ÀÓLÐß×+ÜÑ<¸[ÓIÓJÐP[Ð[ä# C¯©Ó0×6Ð6°BˆÜ�‰ØDØžg‘FÐ+>Àß!&ÑÜ9JÈ3×9OÒ9OÑ5ÐUmô		pô
 ˆEÜ˜e¤T×*Ò*ÙÜ˜eŸi™i¨
Ó3×9Ð9°rÓ:×@Ñ@ÓBˆKÜ˜5Ÿ9™9 WÓ-×3Ð3°Ó4×:Ñ:Ó<ˆHß§hÙð^ßhà(¨+°~ÀxÐP�	Ø—9‘9˜Z×(Ò(Ø5:¸:Õ5F�IÐ1Ñ2Ù2°5Ó9�
ßØ4>�IÐ0Ñ1Ù2Ñ?°YÑ?�ñ 'AÀÈÓ&P�˜
Ñ#Ü—‘Ø@Ø˜GŸK™K¨
Ó3°Xô?õ
 QÙ.GØ×iÐiÄ*ÈRÏ\É\Ô[_×B`ÒB` "§,¡,×"2Ñ"2°:Ô">ÐfhØ˜7Ÿ;™; zÓ2°Hó/>�Ð*Ñ+ð  Ð(×(øÜô ^Ü—‘Ð?ÀÐV\×]Ó]ûð^úñ= ô@ Ñ8¸ÓEÓFÈKÐWûð].Xús�   ÁB Á(B ÂK;Â%K6Â8-K6Ã&&K6ÄAK6Å#1K6ÆK6Æ2K6Æ:K6Æ=$J1Ç"J1Ç>AJ1ÉAJ1Ê)K6Ê+K;Ê1KÊ<KËK6ËKËK6Ë6K;c                ó0   € V ^8„  d   QhR\         R\        /# )r4   r   r½   r\   )r:   s   "r0   r;   r;   (  s   € ÷ ñ ¤4ð ´ñ r<   c           	      ó¦  € \        V P                  R 4      ;'       g    R4      P                  4       P                  4       pV'       g   R#  ^ RIHp V! V4      pVP                  4       '       d1   \        P                  RW\        VP                  4       4      4       V#  R#   \         d#   p\        P                  RYT4        Rp?R# Rp?ii ; i)rG   r$   N)Ú	load_poolz@Job '%s': loaded credential pool for provider %s with %d entriesz3Job '%s': failed to load credential pool for %s: %s)rB   rA   r&   r·   Úagent.credential_poolr¥  Úhas_credentialsræ   r%  r»   ÚentriesrX   rç   )r   r½   Úruntime_providerr¥  r€  r  s   &&    r0   Ú_load_credential_poolrª  (  sµ   € Ü˜7Ÿ;™; zÓ2×8Ð8°bÓ9×?Ñ?ÓA×GÑGÓIÐßÙð	iÝ3ÙÐ)Ó*ˆØ×Ñ×!Ò!Ü�K‰KØRØ¬#¨d¯l©l«nÓ*=ô?ð ˆKð	 "ñ øô ô iÜ�‰ÐJÈFÐfg×hÐhÙûðiús   Á#B# Á0/B# Â#CÂ.CÃCc                ó(   € V ^8„  d   QhR\         RR/# )r4   r½   r6   Nrv   )r:   s   "r0   r;   r;   9  s   € ÷ `ñ `¤ð `¨ñ `r<   c                óÔ   €  ^ RI Hp V! 4       pV'       d#   \        P                  RV \	        V4      4       R# R#   \
         d"   p\        P                  RY4        Rp?R# Rp?ii ; i)zˆRegister MCP servers for the agent's tool registry. Idempotent across ticks; non-fatal so a
broken MCP server never kills a working job.)Údiscover_mcp_toolsz"Job '%s': %d MCP tool(s) availablez3Job '%s': MCP initialization failed (non-fatal): %sN)Útools.mcp_tool_discoveryr­  ræ   r%  r»   rX   r&  )r½   r­  Ú
_mcp_toolsÚ_mcp_excs   &   r0   Ú_init_cron_mcp_toolsr±  9  sW   € ð`õ 	@Ù'Ó)ˆ
ßÜ�K‰KÐ<¸fÄcÈ*ÃoÖVñ øäô `Ü�‰ÐLÈf×_Ò_ûð`ús   ‚; — ; »A'ÁA"Á"A'c                ó$   € V ^8„  d   QhR\         /# )r4   r5   rï   )r:   s   "r0   r;   r;   J  s   € ÷ Cñ Cœtñ Cr<   c                óv  aa€ ^ RI Hp V! 4       o^ RIHpHp Sf   V! 4       '       d	   V! R4      h\        4       p ^ RIHo VV3R lpV^ 8:  d   V! 4       # \        P                  P                  ^R7      p\        P                  ! 4       pVP                  VP                  V4      p VP                  VR7      VP!                  R	R
7       #   \        P                  P"                   d    ^ RIHp	 TP)                  T	4       h i ; i  TP!                  R	R
7       i ; i  \        P                  P"                   d;    Se   \#        R4      h\*        P-                  RT P/                  RR4      T4        R# \0         d8   p
Se   h \*        P3                  RT P/                  RR4      T
4        Rp
?
R# Rp
?
ii ; i)zÜBound store acquisition separately from the conversation watchdog.

Canonical runs borrow the owner's exact store and fail closed on acquisition
errors. Only the legacy non-owner helper path may return no session store.
©Úcurrent_execution)ÚWorkerPersistenceErrorÚis_worker_processNÚ!worker_cron_registration_required)Úacquirec                  óÖ   <€ Sf   S! 4       # S! \        S^ ,          P                  P                  4      4      p V S^ ,          P                  Jd   ^ RIHp V! V 4       \        R4      hV # )N©Úrelease_or_closez'cron requires the canonical owner store)r   ÚdbÚdb_pathÚhermes_state_registryr¼  r  )r½  r¼  r¹  rS   s     €€r0   Úacquire_storeÚ,_open_cron_session_db.<locals>.acquire_storec  sY   ø€ ØŠ}Ù“yÐ Ùœ˜e A�hŸk™k×1Ñ1Ó2Ó3ˆBØ˜˜q�Ÿ™Ó$ÝBÙ  Ô$Ü"Ð#LÓMÐMØˆIr<   ©rt  ©rä  F)rz  )Ú_close_late_session_db_resultz2Canonical cron session store acquisition timed outu‡   Job '%s': SessionDB init did not return within %.0fs â€” proceeding without a session store for this run instead of blocking it foreverrW   r#  z0Job '%s': SQLite session store not available: %s)Úgateway.session_cronrµ  Úagent.runtime_session_storer¶  r·  Ú_get_session_db_timeoutr¿  r¹  ru  rv  rw  ÚcontextvarsÚcopy_contextÚsubmitÚrunr  r  r  Úcron.scheduler_detached_workerrÄ  Úadd_done_callbackræ   rª   rA   rX   rç   )r5   rµ  r¶  r·  Ú_session_db_timeoutrÀ  Ú_session_db_poolÚ_session_db_contextÚ_session_db_futurerÄ  r  r¹  rS   s   &          @@r0   Ú_open_cron_session_dbrÒ  J  sŸ  ù€ õ 7ÙÓ€EßUØ‚}Ñ*×,Ò,ñ %Ð%HÓIÐIÜ1Ó3Ðð,`Ý1ö	ð  !Ô#Ù “?Ð"Ü%×-Ñ-×@Ñ@ÈQÐ@ÓOÐô *×6Ò6Ó8ÐØ-×4Ñ4Ð5H×5LÑ5LÈmÓ\Ðð	2Ø%×,Ñ,Ð5HÐ,ÓIð ×%Ñ%¨5Ð%Õ1øô ×!Ñ!×.Ñ.ô 	õ UØ×0Ñ0Ð1NÔOØð	ûð ×%Ñ%¨5Ð%Õ1ûÜ×Ñ×*Ñ*ô 5ØÒÜÐSÓTÐTÜ�‰ðRà�G‰G�D˜#ÓÐ 3õ	5ñ ô	 ô `ØÒØÜ�‰ÐGÈÏÉÐQUÐWZÓI[Ð]^×_Ð_Ùûð	`úsO   ¼D ÁAD Â)C Â:D Ã8DÄD ÄDÄD ÄAF8Å7F8Æ F8Æ,F3Æ3F8c                ó4   € V ^8„  d   QhR\         R\        RR/# )r4   r¼   Úlimit_sr6   Nr	  )r:   s   "r0   r;   r;   �  s!   € ÷ ,ñ ,¬sð ,¼Uð ,Àtñ ,r<   c                ó"  € / p\        V R4      '       d<   \        P                  ! \        4      ;_uu_ 4        V P	                  4       pRRR4       VP                  RR4      pVP                  R^ 4      p\        P                  RYTYCP                  R^ 4      VP                  R^ 4      VP                  R	4      ;'       g    R
4       \        V RRR7       \        RV R\        V4       R\        V4       RV 24      h  + '       g   i     L¾; i)zHLog the agent's last activity, hard-interrupt it and raise TimeoutError.Úget_activity_summaryNÚlast_activity_descÚunknownÚseconds_since_activityz_Job '%s' idle for %.0fs (inactivity limit %.0fs) | last_activity=%s | iteration=%s/%s | tool=%sÚapi_call_countÚmax_iterationsÚcurrent_toolÚnonezCron job timed out (inactivity)zcron inactivity watchdog)Útool_reasonrU  z' idle for z	s (limit u   s) â€” last activity: )Úhasattrr³  r´  rX   rÖ  rA   ræ   rª   r   r  re   )r  r¼   rÔ  Ú	_activityÚ
_last_descÚ	_secs_agos   &&&   r0   Ú_raise_inactivity_timeoutrã  �  sõ   € à€IÜˆuÐ,×-Ò-Ü× Ò ¤×+Õ+Ø×2Ñ2Ó4ˆI÷ ,à—‘Ð3°YÓ?€JØ—‘Ð6¸Ó:€IÜ
‡L�Lð	9à˜WØ—M‘MÐ"2°AÓ6¸	¿¹ÐFVÐXYÓ8ZØ�‰�nÓ%×/Ð/¨ô1ô ˜5Ð"CÐQkÕlÜ
Ø
�X�J˜kÜˆy‹>Ð
˜)¤C¨£L >ð 2Ø(˜\ð	+ó,ð ,÷ ,×+ús   ·C>Ã>D	c                ó‚   € V ^8„  d   QhR\         R\        R\         R\         R\         R\        \        ,          R\        /# )r4   Úpromptr5   r½   r¼   Útask_idÚworker_stater6   )rB   r8   r   )r:   s   "r0   r;   r;   ¥  sS   € ÷ rñ rÜðrÜ!ðrÜ+.ðrÜ:=ðrÜHKðräœ4•.ðrô 
ñrr<   c                ó‚  a aaaaaaaaaaaaa€ \        4       pV^ 8”  d   TMRoRoVP                  R4      p	\        V	\        4      ;'       d    V	P                  R4      R8H  oVP                  R4      p
\        V
\        4      '       d%   \	        V
P                  R4      ;'       g    R4      MRo\
        P                  ! 4       oR	 V VV3R
 llpVVVVV3R lp\        4       o\        P                  P                  ^R7      p\        P                  ! 4       pVP                  VP                  S P                  WR7      oVe   SVR&   Ro\         P"                  ! 4       oR V 3R lloR VVVVVVV3R llp\         P$                  ! VR\	        S4      R,           2RR7      p\'        \	        VP                  R4      ;'       g    R4      SS\(        R7      p Se   VP+                  4        Sf   S'       g   Sf   SP-                  4       pMqRp \        P                  P/                  S0SR7      w  ppV'       d   V! 4        SP-                  4       pM)S'       d   M V! 4        V! 4        VP1                  4        Ko  SP7                  4        VP5                  RRR7       S'       d   \9        S SS4       \        V\        4      '       g&   \;        R\=        V4      P>                   RV: 24      hV#   \2         d    TP5                  RRR7       h i ; i  SP7                  4        TP5                  RRR7       i ; i)zœRun ``agent.run_conversation`` on a worker thread under the inactivity (not wall-clock)
watchdog: default 600s, override HERMES_CRON_TIMEOUT, 0 = unlimited.Ng      @r^   r_   ÚonceÚ	run_claimÚbyr$   c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   Ú._run_agent_with_watchdog.<locals>.__annotate__»  s   € ÷ [ñ [ tñ [r<   c                  ó¨   <€ Se   SP                  4       '       g   R # S e$   \        S R4      '       d   S P                  R4       \        RS R24      h)NÚ	interruptz"Cron fire claim ownership was lostrU  z'' lost its durable fire claim ownership)rl  rß  rï  r  )r  r)  r¼   s   €€€r0   Ú_abort_if_fire_claim_lostÚ;_run_agent_with_watchdog.<locals>._abort_if_fire_claim_lost»  sN   ø€ ØÒ |×':Ñ':×'<Ò'<ÙØÒ¤¨°×!<Ò!<Ø�O‰OÐ@ÔAÜ˜Z¨ zÐ1XÐYÓZÐZr<   c                  óò   <€ S'       d	   S'       g   R # \         P                  ! 4       p V S,
          \        8  d   R # V o \        SSR7       R #   \         d    \
        P                  RSRR7        R # i ; i)N©Úexpected_ownerz$Job '%s': run_claim heartbeat failedTr$  )r˜  Ú	monotonicÚ_RUN_CLAIM_HEARTBEAT_SECONDSr1  rX   ræ   rç   )Ú_monoÚ_is_oneshotÚ_last_claim_heartbeatÚ_run_claim_ownerr½   r¼   s    €€€€€r0   Ú_heartbeat_run_claim_if_dueÚ=_run_agent_with_watchdog.<locals>._heartbeat_run_claim_if_dueÂ  sf   ø€ ç×"2ÙÜ—’Ó ˆØÐ(Õ(Ô+GÔGÙØ %Ðð	ZÜ Ð7G×HøÜô 	ZÜ�L‰LÐ?ÀÐTXˆL×Yð	Zús   Á A Á#A6Á5A6rÂ  )ræ  rÎ  Fc                ó$   € V ^8„  d   QhR\         /# rÄ   rÅ   )r:   s   "r0   r;   rí  Û  s   € ÷ ñ œ5ñ r<   c                  ó¼   <€ \        SR 4      '       g   R#  SP                  4       p \        V P                  RR4      ;'       g    R4      #   \         d     R# i ; i)rÖ  g        rÙ  )rß  rÖ  rÆ   rA   rX   )Ú_actr  s    €r0   Ú_idle_secondsÚ/_run_agent_with_watchdog.<locals>._idle_secondsÛ  sX   ø€ Ü�uÐ4×5Ò5Ùð	Ø×-Ñ-Ó/ˆDÜ˜Ÿ™Ð":¸CÓ@×GÐGÀCÓHÐHøÜô 	Úð	ús   —-A ÁA ÁAÁAc                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   rí  ä  s   € ÷ 'ñ '˜tñ 'r<   c            	      ó^   <€ Sf   R # \        SSS SSP                  SR7      '       d   RoR # R # )N)Úget_idle_secondsrÔ  Úpoll_sÚstopÚfuture_doneÚmeterT)rE  r   )Ú_POLL_INTERVALÚ_awake_idleÚ_cron_futureÚ_cron_inactivity_limitr   Ú_inactivity_timeoutÚ_watch_stops   €€€€€€€r0   Ú_watch_inactivityÚ3_run_agent_with_watchdog.<locals>._watch_inactivityä  s?   ø€ à!Ò)ÙÜ$Ø*Ð4JÐSaØ¨,×*;Ñ*;À;÷Pó Pð #'ÒñPr<   zcron-inactivity-:Né   NTrð  Úexecution_id)Úidle_secondsÚevery_secondsrÃ  ry  z agent.run_conversation returned z instead of dict: ) rr  rA   r@   r8   rB   r˜  rõ  r!   ru  rv  rw  rÈ  rÉ  rÊ  rË  Úrun_conversationrô  rõ  rö  rD  rö  r÷  r  rz  ÚtickrX   r  r  rã  r  ÚtyperŠ   )r  rå  r5   r½   r¼   ræ  r)  rç  Ú_cron_timeoutÚ_job_scheduleÚ
_run_claimrð  rû  Ú
_cron_poolÚ_cron_contextr  Ú_watch_threadÚ	_progressr  r   Ú_r	  r
  r  r  r   r  rø  rù  rú  r  s   f&&ff&f&             @@@@@@@@@@r0   Ú_run_agent_with_watchdogr   ¥  sæ  ÿý€ ô -Ó.€MØ.;¸aÔ.?™]ÀTÐØ€Nð —G‘G˜JÓ'€MÜ˜]¬DÓ1×YÐY°m×6GÑ6GÈÓ6OÐSYÑ6Y€KØ—‘˜Ó%€JÜ:DÀZÔQU×:VÒ:V”s˜:Ÿ>™>¨$Ó/×5Ð5°2Ô6Ð\^ÐÜ ŸNšNÓ,Ð÷[ò [÷Zñ Zô !Ó"€KÜ×#Ñ#×6Ñ6À1Ð6ÓE€Jä×,Ò,Ó.€MØ×$Ñ$Ø×Ñ˜5×1Ñ1°6ð %ó L€LàÒØ!-ˆ�XÑØÐÜ—/’/Ó#€K÷ð ÷'ö 'ô ×$Ò$Ø Ð)9¼#¸f»+Àb½/Ð9JÐ'KÐTXôZ€Mô )ÜˆC�G‰G�NÓ#×)Ð) rÓ*¨HÀ=Ü2ô4€Ið=Ø!Ò-ð
 ×ÑÔ!Ø!Ò)·+À,ÒBVØ!×(Ñ(Ó*‰FàˆFØÜ$×,Ñ,×1Ñ1°<°.È.Ð1ÓY‘��aßÙ-Ô/Ø)×0Ñ0Ó2�FØß&ØÙ)Ô+Ù+Ô-Ø—‘Ö ð
 	�‰ÔØ×Ñ °tÐÔ<çÜ! %¨Ð3IÔJä�fœd×#Ò#ÜØ.¬t°F«|×/DÑ/DÐ.EÐEWÐX^ÑWaÐbó
ð 	
ð €Møô ô Ø×Ñ °tÐÔ<Øðûð 	�‰ÔØ×Ñ °tÐÕ<úsH   ÇK6 Ç;K6 ÈL È/K6 É K6 ÉL ÉK6 É L É! K6 Ë6 LÌL Ì%L>c                óH   € V ^8„  d   QhR\         R\        R\        R\        /# )r4   r  r½   r¼   r6   r\   )r:   s   "r0   r;   r;     s)   € ÷ ;ñ ;¬ð ;´cð ;ÄSð ;ÔVYñ ;r<   c                ó°  € \        V P                  R4      ;'       g    R4      pV P                  R4      ;'       g    RP                  4       p\        V 4      pV P                  R4      RJ g   V P                  R4      RJ d7   V'       g/   \	        V P                  R4      ;'       g    T;'       g    R	4      hV'       d   \
        P                  R
V4       V P                  RR4      ;'       g    RpV'       d   ^ RIHp V! WpP                  R. 4      4      pVP                  4       R8X  d   RpVP                  4       '       d¹   V'       d±   . p	 ^ RI	H
p
 \        V P                  R4      ;'       g    R4      pR.V
O FM  pRV// 3 F@  p VP                  ! WL3/ VB pT'       g   K!  T	P                  TP                  4       4       KB  	  KO  	  VP                  4       V	9   d   \
        P                  RW4       RpV#   \         d    Rp
 L¸i ; i  \         d*     TP                  T4      p L’  \         d    Rp  L¢i ; i\         d    Rp L´i ; i)zçDeliverable final response from a ``run_conversation`` result. Raises RuntimeError on
`failed=True`/`completed=False`: the error text may sit in `final_response` and would otherwise
be delivered as the reply with the job marked ok.Úturn_exit_reasonr$   Úfinal_responseÚfailedTÚ	completedFrª   zagent reported failurez„Job '%s' reached the iteration limit but produced a final fallback response; delivering the response instead of failing the cron run)Ú(repair_explicit_computer_use_media_pathsÚmessagesú(No response generated))ÚPERSISTENCE_ERROR_CAUSESrH   NuN   Job '%s': abnormal empty turn (%s) â€” suppressing explainer for cron delivery)ÚlockedÚdiskrØ  )rB   rA   r&   r"   r  ræ   r&  Úgateway.media_repairr'  Úhermes_state_errorsr*  rX   Ú#_format_turn_completion_explanationrÖ   r  r%  )r  r½   r¼   ÚAIAgentr#  Úfinal_response_textÚmax_iteration_summaryr$  r'  Ú_explainer_variantsÚ_causesÚ_modelÚ_causeÚ_kwargsÚ_variants   &&&&           r0   Ú_final_response_from_resultr9    s,  € ô ˜6Ÿ:™:Ð&8Ó9×?Ð?¸RÓ@ÐØ!Ÿ:™:Ð&6Ó7×=Ð=¸2×DÑDÓFÐÜ4°VÓ<ÐØ‡z�z�(Ó˜tÓ#¨¯
©
°;Ó(?À5Ó(H×QfÜ˜6Ÿ:™: gÓ.×aÐaÐ2E×aÐaÐIaÓbÐbßÜ�‰ðFàô	ð
 —Z‘ZÐ 0°"Ó5×;Ð;¸€NçÝQáAØŸJ™J z°2Ó6ó8ˆà×ÑÓÐ!:Ô:Øˆð ×Ñ×Ò×"2à Ðð	4ÝOô
 �V—Z‘Z Ó(×.Ð.¨BÓ/ˆØÐ&˜gÓ&ˆFØ$ fÐ-¨rÓ2�ð"Ø&×JÒJÐK[ÑoÐgnÑo�H÷ ‘8Ø'×.Ñ.¨x¯~©~Ó/?Ö@ó 3ñ 'ð ×ÑÓ!Ð%8Ô8Ü�K‰KØ`Øô*ð  ˆNØÐøô/ ô 	4Ø3ŠGð	4ûô !ô &ð&Ø#*×#NÑ#NÐO_Ó#`šøÜ$ô &Ø#%›ð&úä ô "Ø!’Hð"úsH   ÅH  ÆHÈ HÈHÈIÈH2È2I	È?IÉI	ÉIÉIÉIc          
      ób   € V ^8„  d   QhR\         R\         R\         R\        \         ,          RR/# )r4   r½   r¼   Úcron_session_idr  r6   NrI  )r:   s   "r0   r;   r;   X  sD   € ÷ ^Vñ ^V´cð ^VÄSð ^VÔ[^ð ^VÜ$,¬S¥Mð^VØ=Añ^Vr<   c                óZ  € \        W4      pTp VP                  V4      pV'       d   Tp RP                  TP                  4       4      R,          P                  4       ;'       g    RT 2pT R\        \        4       R4       2p\        YgT4      '       g   \        YgRT 24       Rp TP                  T.4      pTP!                  T4      pTR9   d   Rp\        P#                  RTTT4       T'       d    TP%                  Yu4        TP'                  Y~4       Te   RTn         ^ RIHp T! T4       R#   \        \        3 d~   p	\        P
                  ! \        \        34      ;_uu_ 4        \        TRR4      p
T
'       d   T
pRRR4       M  + '       g   i     M; i\        P                  RY)4        Rp	?	EL”Rp	?	ii ; i  \        \        3 d~   p	\        P                  R	Y)4       \        TR
R 4      ! RT 24      RT RTRR  23 F6  p \        YgT4      '       d	     Rp	?	EK‡  K     \        \        3 d     K4  i ; i	   Rp	?	EL©Rp	?	ii ; i  \        \        3 d"   p	\        P                  RY)4        Rp	?	EL—Rp	?	ii ; i  \        \        3 d$   p	\        P                  RY)RR7        Rp	?	EL´Rp	?	ii ; i  \        \        3 d"   p	\        P                  RY)4        Rp	?	ELÌRp	?	ii ; i  \        \        3 d"   p	\        P                  RY)4        Rp	?	R# Rp	?	ii ; i)zTTitle, classify, end and release the cron session after the agent turn has returned.r+   Nz4Job '%s': failed to resolve cron compression tip: %sr³   :Né<   Nzcron u    Â· z%b %d %H:%Mz.Job '%s': failed to set cron session title: %sr%   c                 ó   € V # r?   rù   )Úbs   &r0   Ú<lambda>Ú(_finalize_cron_session.<locals>.<lambda>  s   € Ér<   Úcron_completeÚcron_incomplete_no_outputu^   Job '%s': session ended without a final assistant message (lifecycle=%s) â€” booking run as %sz5Job '%s': session lifecycle classification failed: %sz4Job '%s': failed to stamp workdir on session row: %sTr$  Fz#Job '%s': failed to end session: %sr»  z2Job '%s': failed to close SQLite session store: %siúÿÿÿ)Úinterruptedrª   Úempty)rû  Úget_compression_tiprX   ró  r³  r´  r)   ræ   rç   rO  Úsplitr&   r   r×   r1   Úsession_lifecycle_statusesrA   r&  Úupdate_session_cwdÚend_sessionÚ_end_session_on_closer¿  r¼  )r*   r  r½   r¼   r;  r  rÿ  Ú_final_cron_session_idÚ_compression_tipr  Ú_agent_session_idÚ_title_baseÚ_cron_titleÚ	_fallbackÚ_end_reasonÚ	_statusesÚ
_lifecycler¼  s   &&&&&&            r0   Ú_finalize_cron_sessionrU  X  s  € ô (¨
Ó;€Kð -ÐðXØ&×:Ñ:¸?ÓKÐßØ%5Ð"ð ð —h‘h˜xŸ~™~Ó/Ó0°Õ5×;Ñ;Ó=×QÐQÀ5ÈÈÐAQˆØ$˜ T¬-¼»À}Ó*UÐ)VÐWˆÜ& {ÈK×XÒXÜ# KÈ5ÐQWÐPXÐIYÔZð4 "€Kð
YØ×:Ñ:Ð<RÐ;SÓTˆ	Ø—]‘]Ð#9Ó:ˆ
ØÐ:Ô:Ø5ˆKÜ�N‰Nð?à˜
 Kô1÷ ð	kØ×*Ñ*Ð+AÔKðGØ×ÑÐ 6ÔDð ÒØ*/ˆEÔ'ðVÝ:Ù˜Ö%øôa Ô(Ð)ô XÜ× Ò ¤)Ô->Ð!?×@Õ@Ü '¨¨|¸TÓ BÐ÷ !Ø):Ð&÷ A×@×@Ð@úô 	�‰ÐKÈV×WÒWûðXûô, Ô(Ð)ô Ü�‰ÐEÀvÔQô �KÐ!<¹kÔJÈUÐSYÐRZÐK[Ó\Ø�F�8˜1Ð3°B°CÐ8Ð9Ð:ó<ˆIðÜ*¨;ÐPY×ZÒZßñ [øäÔ0Ð1ô Úðú÷<ûð	ûôF Ô(Ð)ô YÜ�‰ÐLÈf×XÒXûðYûô Ô,Ð-ô 	kÜ�L‰LÐOÐQWÐeiˆL×jÒjûð	kûô Ô(Ð)ô GÜ�‰Ð:¸F×FÒFûðGûô
 Ô(Ð)ô VÜ�‰ÐIÈ6×UÒUûðVúsØ   �D5 «:G Á&A G Â)AI Ã6J ÄK Ä%K8 Ä5GÅ(F>Å.FÆ	F>ÆFÆF>Æ>GÇIÇ;IÈH/È%IÈ-IÈ/IÉ IÉIÉIÉIÉJ	É(JÊJ	ÊK ÊJ;Ê;K ËK5ËK0Ë0K5Ë8L*Ì	L%Ì%L*c                ó0   € V ^8„  d   QhR\         R\         /# rH  rv   )r:   s   "r0   r;   r;   ¹  s   € ÷ :ñ :œcð :¤cñ :r<   c                óF   € V P                  RR4      P                  RR4      # )zCCRLF/CR -> LF, matching what text-mode reads of the archive return.z
rK  Ú)Úreplace)r¾   s   &r0   Ú_normalize_newlinesrZ  ¹  s    € à�<‰<˜ Ó%×-Ñ-¨d°DÓ9Ð9r<   Úprompt_stampr$   c                ó`   € V ^8„  d   QhR\         R\        R\        R\        R\        R\        /# )r4   r5   r-   r½   rå  r[  r6   r\   )r:   s   "r0   r;   r;   ¾  s8   € ÷ ñ œð ¤cð ´3ð Äð ÔVYð Ôcfñ r<   c               óŽ   € RV RV R\        4       P                  R4       RV P                  RR4       RV \         V \         2# )	zDHeader of the persisted run document (title, ids, schedule, prompt).r  r  r  r*  z
**Schedule:** Úschedule_displayzN/Aú

)r×   r”  rA   Ú_PROMPT_HEADINGÚ_PROMPT_SEPARATOR)r5   r-   r½   rå  r[  s   &&&&$r0   Ú_run_doc_headerrb  ¾  sg   € ð �u�gð Ø�hð Ü$›×/Ñ/Ð0CÓDÐEð FØŸ™Ð!3°UÓ;Ð<¸DØˆ.œÐ)¨&¨Ô2CÐ1Dð		Fðr<   c                ó¸   € V ^8„  d   QhR\         R\        R\        R\        \        ,          R\        \        \        ,          \        \        ,          3,          /# r:  )r8   rB   r   rn   Ú
_RunResult)r:   s   "r0   r;   r;   Ì  sR   € ÷ Wñ WÜ	ðWÜðWÜ&)ðWÜ9AÄ#½ðWä
Œ8”JÕ¤¬#¥Ð.Õ/ñWr<   c           
     ó(  € V P                  R4      '       g   ^ RIHpHp  V! 4        V P                  R4      '       d   \        WW$4      R	3# ^ R
IH	pH
p	 V	! V 4      '       d   \        WV4      R	3# \        WW#4      w  r£pV
e   V
R	3# R	pV P                  R4      pV'       d†   \        V V\        W4      VR7      pVw  rïV'       db   \        V4      '       gQ   \        P!                  RW!4       \#        V 4       RV RV R\%        4       P'                  R4       R2pRV\(        R	3R	3#  \+        WVVR7      pTf.   \        P!                  RT4       \#        T 4       RR\(        R	3R	3# R	T3#   T d9   p\        P                  RY4       RRT RT R2R\        T4      3R	3u R	p?# R	p?ii ; i  \,         dY   p\        P/                  RY!T4       RT RT R\%        4       P'                  R4       RT R2	pRTR\        T4      3R	3u R	p?# R	p?ii ; i)zñRun every pre-agent gate and build the prompt. Returns ``(early_result, prompt)``: an early
result short-circuits ``run_job`` (no_agent job, empty payload, monitor gate, wake gate,
injection block, empty prompt); otherwise ``prompt`` is set.r±   )ÚInvalidUserConfigErrorÚrequire_parseable_user_configu    Job '%s': refusing to run â€” %sFr  z	

Error: rK  r$   N)ÚEMPTY_PAYLOAD_ERRORÚjob_payload_is_emptyr&  r(  z6Job '%s' (ID: %s): wakeAgent=false, skipping agent runr  r  r*  u<   

Script gate returned `wakeAgent=false` â€” agent skipped.
T)Úprerun_scriptr;  Úruntime_data_promptu=   Job '%s' (ID: %s): blocked by prompt-injection scanner â€” %sz£
**Status:** BLOCKED

The assembled prompt (user prompt + loaded skill content) tripped the cron injection scanner and the agent was NOT run.

**Scanner result:** a  

Audit the skill(s) attached to this job for prompt-injection payloads or invisible-unicode markers. If the skill is legitimate and the match is a false positive, rephrase the content to avoid the threat pattern (`tools/cronjob_tools.py::_CRON_THREAT_PATTERNS`).z6Job '%s': script produced no output, skipping AI call.)rA   rá  rf  rg  ræ   rª   rB   r8  rË   rh  ri  r.  rG  r/  r  r1  r%  r   r×   r”  r2  Ú_build_job_promptrø   r&  )r5   r½   r¼   r;  r)  rf  rg  rë   rh  ri  Ú_earlyÚmonitor_contextrj  r3  Ú_ran_okÚ_script_outputÚ
silent_docrå  Ú	block_excr„  s   &&&&&               r0   Ú_prepare_job_promptrs  Ì  si  € ð �7‰7�:×Òß[ð	\Ù)Ô+ð ‡w�wˆz×ÒÜ  ¨hÓEÀtÐKÐK÷ Dá˜C× Ò Ü# FÐ6IÓJÈDÐPÐPä,?ÀÈXÓ,dÑ)€F˜/ØÒØ�tˆ|Ðð €MØ—'‘'˜(Ó#€KßÜ<ØØÜ(¨Ó5Ø%ô	
ˆð #0ÑˆßÔ+¨N×;Ò;Ü�K‰KÐPÐRZÔcÜ˜cÔ"à˜x˜jð )Ø%˜hð '!Ü!,£×!7Ñ!7Ð8KÓ!LÐ Mð NNðNð ð ˜*¤m°TÐ:¸DÐ@Ð@ð>Ü"Ø¸<Ø /ô
ˆð. ‚~Ü�‰ÐLÈhÔWÜ˜#ÔØ�bœ-¨Ð.°Ð4Ð4Ø�ˆ<ÐøðU &ô 	\Ü�L‰LÐ;¸VÔIØ˜\¨(¨°;¸s¸eÀ2ÐFÈÌCÐPSËHÐUÐW[Ð[Õ[ûð	\ûôf &ô >ä�‰ØKÈXÐ_hô	
ð ˜8˜*ð %Ø!˜(ð #Ü(›]×3Ñ3Ð4GÓHÐIð J#ð $- +ð .Tð
Tð 	ð �{ B¬¨I«Ð7¸Ð=Õ=ûð%>ús<   ¡E, Ä)F. Å,F+Å3-F&Æ F+Æ&F+Æ.HÆ9AHÈHÈHc                   óZ   a € ] tR tRt o RtV 3R lR ltV 3R lR ltV 3R lR ltR	tV t	R
# )Ú_CronRunScopei,	  u  Per-run ContextVar / tool-cwd scope for ``run_job`` (ContextVars, not os.environ, so
parallel jobs don't clobber each other). Construct before the try, ``enter()`` as its first
statement, ``exit()`` in the finally â€” every setter here has a matching reset there.

HERMES_SESSION_* are deliberately NOT seeded from job["origin"]: it is delivery metadata, not
a sender, and terminal/tts/skills/send_message tools would act as if the origin user were
driving the agent. Delivery reads job["origin"] / HERMES_CRON_AUTO_DELIVER_* directly.
c                ó<   <€ V ^8„  d   QhRS[ RS[RS[S[,          /# )r4   r5   r½   r  r  )r:   r€   s   "€r0   r;   Ú_CronRunScope.__annotate__6	  s&   ø€ ÷ #!ñ #!™Dð #!©#ð #!¹XÁc½]ñ #!r<   c                ó   € ^ RI HpHp ^ RIHp WPn        \        W4      V n        T! RRRRV P                  ;'       g    RR7      V n        \         F  pWW,          P                  R4       K  	  RT RT;'       g9    VP                  R4      ;'       g     \        P                  ! 4       P                   2V n        V P                  '       d   V! V P                  V P                  4       VR	,          V n        R
V n        R
V n        R
V n        R
# )é    )Úset_session_varsÚ_VAR_MAP)Úrecord_session_cwdr$   F)ÚplatformÚchat_idÚ	chat_nameÚasync_deliveryÚcwdzcron:Ú:r  ÚHERMES_CRON_SESSIONN)Úgateway.session_contextrz  r{  Útools.terminal_toolr|  Ú_var_mapr  r  Ú_ctx_tokensÚ_CRON_DELIVERY_VARSr  rA   ÚuuidÚuuid4Úhexræ  Ú_cron_session_varÚ_cron_session_tokenÚ_non_dispatcher_tokenÚ_spend_token)r‡   r5   r½   r  rz  r{  r|  rc   s   &&&&    r0   r†   Ú_CronRunScope.__init__6	  sà   € ßFÝ:à Œä+¨CÓ8ˆŒÙ+ØØØð !Ø—‘×"Ð" ô!
ˆÔ÷$ (ˆDØ�N×Ñ˜rÖ"ñ (ð ˜v˜h a¨×(cÐ(c¸¿¹ÀÓ8O×(cÐ(cÔSW×S]ÒS]ÓS_×ScÑScÐ'dÐeˆŒØ�<�<ˆ<Ù˜tŸ|™|¨T¯\©\Ô:Ø!)Ð*?Õ!@ˆÔØ#'ˆÔ Ø%)ˆÔ"Ø ˆÖr<   c                ó   <€ V ^8„  d   QhRR/# rl   rù   )r:   r€   s   "€r0   r;   rw  [	  s   ø€ ÷ 3ñ 3�tñ 3r<   c                óž   € V P                   P                  R 4      V n        \        4       V n        ^ RIHp V! V P                  4      V n        R# )Ú1)Úbind_runN)	rŒ  r  r�  r   rŽ  Útools.mcp_tool_costsr”  ræ  r�  )r‡   r”  s   & r0   ÚenterÚ_CronRunScope.enter[	  s?   € ð $(×#9Ñ#9×#=Ñ#=¸cÓ#BˆÔ ô
 &HÓ%IˆÔ"å1Ù$ T§\¡\Ó2ˆÖr<   c                ó   <€ V ^8„  d   QhRR/# rl   rù   )r:   r€   s   "€r0   r;   rw  h	  s   ø€ ÷ (ñ (�dñ (r<   c                ó¼  € ^ RI Hp ^ RIHp V! V P                  4       V! V P
                  4       V P                  e&   V P                  P                  V P                  4       V P                  e   \        V P                  4       V P                  e   ^ RIHp V! V P                  4       \         F%  pV P                  V,          P!                  R4       K'  	  R# )ry  )Úclear_session_vars)Úclear_session_cwdN)Ú
unbind_runr$   )r„  rš  r…  r›  ræ  r‡  r�  rŒ  ÚresetrŽ  r   r�  r•  rœ  rˆ  r†  r  )r‡   rš  r›  rœ  rc   s   &    r0   ÚexitÚ_CronRunScope.exith	  s    € Ý>Ý9á˜$Ÿ,™,Ô'Ù˜4×+Ñ+Ô,Ø×#Ñ#Ò/Ø×"Ñ"×(Ñ(¨×)AÑ)AÔBØ×%Ñ%Ò1Ü-¨d×.HÑ.HÔIØ×ÑÒ(Ý7Ù�t×(Ñ(Ô)ß'ˆDØ�M‰M˜$Õ×#Ñ# BÖ'ó (r<   )r�  rŒ  r‡  rŽ  r�  r†  ræ  r  N)
rŠ   r‹   rŒ   r�   rŽ   r†   r–  rž  r�   r�   rq  s   @r0   ru  ru  ,	  s)   ø‡ € ñ÷#!ð #!÷J3ð 3÷(ö (r<   ru  c                ó(   € V ^8„  d   QhR\         RR/# rî   rï   )r:   s   "r0   r;   r;   y	  s   € ÷ 
ñ 
´Dð 
¸Tñ 
r<   c                ó–  € ^ RI HpHp ^ RIHp V! \        4       4       V! \        4       R7       \        V 4      pV'       d‡   VR,          P                  VR,          4       VR,          P                  \        VR,          4      4       VR,          P                  VP                  R	4      f   RM\        VR	,          4      4       R
# R
# )z[Re-read .env for this run and publish the auto-deliver target into the session ContextVars.)r"  Úreset_secret_source_cache)r{  r#  Ú!HERMES_CRON_AUTO_DELIVER_PLATFORMr}  Ú HERMES_CRON_AUTO_DELIVER_CHAT_IDr~  Ú"HERMES_CRON_AUTO_DELIVER_THREAD_IDÚ	thread_idNr$   )
r,  r"  r¢  r„  r{  r£   Ú_resolve_delivery_targetr  rB   rA   )r5   r"  r¢  r{  Údelivery_targets   &    r0   Ú*_reload_dotenv_and_publish_delivery_targetr©  y	  s    € ÷ TÝ0áÔ.Ó0Ô1ÙÔ#3Ó#5Õ6ä.¨sÓ3€OßØÐ4Õ5×9Ñ9¸/È*Õ:UÔVØÐ3Õ4×8Ñ8¼¸_ÈYÕ=WÓ9XÔYØÐ5Õ6×:Ñ:Ø!×%Ñ% kÓ2Ò:‰BÄÀOÐT_ÕD`Ó@aö	
ñ r<   c                   óT   a € ] tR tRt o RtRtRtRtRtRt	Rt
RtRtRtV 3R ltRtV tR# )Ú_CronAgentSetupiŒ	  z\Everything ``AIAgent(...)`` needs that is resolved from job + config (or a preflight block).Nr$   c                ó¦   <€ V ^8„  d   Qh/ S[ S[,          ;R&   S[;R&   S[;R&   S[;R&   S[;R&   S[;R&   S[;R&   S[;R&   S[ S[,          ;R	&   # )
r4   ÚblockedrH   r   rr  rÛ  Úreasoning_configÚfallback_modelÚcredential_poolÚfallback_notice)r   rd  rB   r8   r   )r:   r€   s   "€r0   r;   Ú_CronAgentSetup.__annotate__Œ	  s‚   ø‡ ‚ ñ ‘jÕ!Ñ(ñ ñ �Oñ	 ñ
 Ññ ñ Ñ ñ ñ Ññ ñ Ñ ñ ñ Ññ ñ Ññ ñ ™c•]Ñ)ò r<   rù   )rŠ   r‹   rŒ   r�   rŽ   r­  rH   r   rr  rÛ  r®  r¯  r°  r±  rN  r�   r�   rq  s   @r0   r«  r«  Œ	  s>   ø‡ € áfØ$(€GØ€EØ€GØ ÐØ€NØ ÐØ€NØ€OØ%)€O÷ ƒ r<   r«  c                óH   € V ^8„  d   QhR\         R\        R\        R\        /# r   )r8   rB   r«  )r:   s   "r0   r;   r;   š	  s(   € ÷ 'ñ '¤4ð '´ð 'Äð 'ÌOñ 'r<   c                ó  € VP                   p\        VP                  R7      p\        WA4      Vn        ^ RIHp VP                  R/ 4      P                  R4      pVf   VP                  R4      pV! V4      Vn        \        V 4       \        WW$4      Vn        VP                  e   V# \        WV4      w  Vn        Vn        VP                  P                  RR4      Vn        \!        T \#        V\$        4      '       d   TM/ \'        VP                  4      4      Vn        \+        W4      Vn        \/        VP                  V4      Vn        \3        V4       \5        V4      '       d%   \7        W4      pV'       d   \9        WV4      Vn        V# )z«Resolve model/runtime/reasoning/pool for the run, in the original gate order: exfil guard ->
preflight (may block) -> runtime (+ fallback chain) -> credential pool -> MCP.)rH   )Úresolve_turn_limitr  Ú	max_turnsNr“  )rN   r«  rH   rs  rr  rá  rµ  rA   rÛ  Ú_guard_job_credential_exfilr|  r­  r¢  r   rÚ  r±  r(  r@   r8   rB   r®  rT   r¯  rª  r°  r±  rx  Ú_empty_requested_mcp_toolsetsrz  )	r5   r½   r¼   r†  r^  ÚsetupÚ_resolve_turn_limitÚ_mtÚ_mcp_reasons	   &&&&     r0   Ú_resolve_cron_agent_setupr½  š	  sA  € ð �6‰6€DÜ "§(¡(Ô+€EÜ3°DÓA€EÔõ LØ
�(‰(�7˜BÓ
×
#Ñ
# KÓ
0€CØ
‚{Ø�h‰h�{Ó#ˆÙ.¨sÓ3€EÔô   Ô$ä'¨°XÓD€E„MØ‡}�}Ò Øˆä!5°cÀ2Ó!FÑ€E„M�5”;Ø!ŸM™M×-Ñ-Ð.@À$ÓG€EÔÜ:Ø”Z ¤d×+Ò+‰T°´S¸¿¹Ó5Eó€EÔô
 /¨sÓ9€EÔÜ1°%·-±-ÀÓH€EÔä˜Ô ô ˜t×$Ò$Ü3°CÓ>ˆßÜ2°6À[ÓQˆEŒMØ€Lr<   c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r4   r5   r^  r¹  )r8   r«  )r:   s   "r0   r;   r;   Ä	  s!   € ÷ "ñ "¬ð "´Dð "Äñ "r<   c          	      óz  € VP                   pVP                  R 4      ;'       g    / pT ! R)/ RVP                  bRVP                  R4      bRVP                  R4      bRVP                  R4      bRVP                  R4      bRVP                  R4      bRVP                  R4      bRVP                  R	4      bR
VP                  R4      bRVP                  bRVP                  bRVP
                  bRVP                  bRVP                  bRVP                  R4      bRVP                  R4      bRVP                  R4      bRVP                  R4      bRVP                  R4      ;'       g    / P                  R4      bR\        W4      bR\        V4      bRRbR \        V4      '       * bR!RbR"R#bR$RbR%R&bR'VbR(Vb # )*Úprovider_routingrH   Úapi_keyrI   rG   Úrequested_providerÚapi_modeÚrequest_overridesÚacp_commandÚcommandÚacp_argsr  rÛ  r®  rr  r¯  r°  Úproviders_allowedÚonlyÚproviders_ignoredÚignoreÚproviders_orderÚorderÚprovider_sortÚsortÚopenrouter_min_coding_scoreÚ
openrouterÚmin_coding_scorer  r  Ú
quiet_modeTÚskip_context_filesÚload_soul_identityÚskip_memoryFÚskip_background_reviewr}  r`   r+   r*   rù   )r   rA   rH   rÛ  r®  rr  r¯  r°  r  r  r9   )	r0  r5   r^  r¹  r  r+   r*   r   Úprs	   &&&&$$$  r0   Ú_construct_cron_agentrÙ  Ä	  s  € Ø�m‰m€GØ	�‰Ð$Ó	%×	+Ð	+¨€BÙò Ø�kŠkðà—‘˜IÔ&ðð —‘˜ZÔ(ðð —‘˜ZÔ(ð	ð
 #Ÿ;™;Ð';Ô<ðð —‘˜ZÔ(ðð "Ÿ+™+Ð&9Ô:ðð —K‘K 	Ô*ðð —‘˜VÔ$ðð ×+Ò+ðð ×/Ò/ðð ×/Ò/ðð ×+Ò+ðð ×-Ò-ðð Ÿ&™& œ.ðð  Ÿ&™& Ô*ð!ð" Ÿ™˜wœð#ð$ —f‘f˜V”nð%ð& &*§X¡X¨lÓ%;×%AÐ%A¸r×$FÑ$FÐGYÔ$Zð'ô( 8¸ÔBð)ô* :¸$Ô?ð+ñ, ð-ô0  $ G›}Õ,ð1ñ2  ð3ñ4 ð5ñ6  $ð7ñ8 ð9ñ: ð;ñ< ð=ð r<   c                   óH   a € ] tR tRt o RtV 3R lR ltV 3R lR ltRtV tR# )	Ú
_FireAuditié	  z[One usage_audit.jsonl line per fire (created once the agent exists; fire id + start clock).c                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )r4   r5   r½   rH   r\   )r:   r€   s   "€r0   r;   Ú_FireAudit.__annotate__ì	  s"   ø€ ÷ (ñ (™Dð (©#ð (±cñ (r<   c                ó¬   € WVuV n         V n        V n        \        P                  ! 4       P
                  V n        \        P                  ! 4       V n	        R # r?   )
r5   r½   rH   r‰  rŠ  r‹  Úfire_idr˜  rõ  Út_start)r‡   r5   r½   rH   s   &&&&r0   r†   Ú_FireAudit.__init__ì	  s7   € Ø,/¸Ð)ˆŒ�$”+˜tœzÜ—z’z“|×'Ñ'ˆŒÜ—~’~Ó'ˆŽr<   c                ó:   <€ V ^8„  d   QhRS[ RS[S[,          RR/# )r4   r  rª   r6   N©r8   r   rB   )r:   r€   s   "€r0   r;   rÝ  ñ	  s&   ø€ ÷ ñ ™Dð ©±#­ð ¸4ñ r<   c                óÌ  € \        R \        4       RV P                  RV P                  RVP	                  R4      RVP	                  R4      RVP	                  R4      R\        VP	                  R4      4      RV P                  P	                  R4      R	V P                  ;'       g    R
R\        \        P                  ! 4       V P                  ,
          R,          4      RV/4       R
# )Útsr½   rß  Úprompt_tokensÚcompletion_tokensÚtotal_tokensÚresponse_silentÚdeliver_targetÚdeliverrH   NÚduration_msr‘  rª   )r�  r–  r½   rß  rA   r9   r5   rH   re   r˜  rõ  rà  )r‡   r  rª   s   &&&r0   r  Ú_FireAudit.writeñ	  s¯   € ÜØ”.Ó"Ø�d—k‘kØ�t—|‘|Ø˜VŸZ™Z¨Ó8Ø §¡Ð,?Ó!@Ø˜FŸJ™J ~Ó6Øœt F§J¡JÐ/@Ó$AÓBØ˜dŸh™hŸl™l¨9Ó5Ø�T—Z‘Z×'Ð' 4Øœ3¤§¢Ó 0°4·<±<Õ ?À4ÕGÓHØ�Uðö 	r<   )rß  r5   r½   rH   rà  N)	rŠ   r‹   rŒ   r�   rŽ   r†   r  r�   r�   rq  s   @r0   rÛ  rÛ  é	  s   ø‡ € Ùe÷(ð (÷
ö r<   rÛ  Údefer_agent_teardownr;  r)  r  c                ó  € V ^8„  d   QhR\         R\        \        ,          R\        \        ,          R\        \        ,          R\        \        ,          R\
        \        \        \        \        \        ,          3,          /# )r4   r5   rî  r;  r)  r  r6   )r8   r   rO   rB   rf  rn   r9   )r:   s   "r0   r;   r;   
  sk   € ÷ L4ñ L4Ü	ðL4Ü(0´­ðL4ÜMUÔVYÍ]ðL4äÔ+Õ,ðL4äCKÌCÅ=ðL4ô Œ4””cœ8¤C�=Ð(Õ)ñL4r<   c               ó   € ^ RI Hp V! 4       pVe   VR,          V R,          V38w  d   RpV P                  R4      '       g   Vf   ^ RIHp V! WVVR7      # V R,          p\        V P                  R4      ;'       g&    V P                  R	4      ;'       g    T;'       g    R
4      p	\        WW’V4      w  r«V
e   V
# ^ RIHp Ve
   V^,          MRV R\        4       P                  R4       2p\        P                  RW˜4       \        P                  RVR,          4       RpRpRpRp/ p\        WV4      p VP                  4        VP                  '       d"   \        P                  RVVP                  4       \!        V 4       \#        WV	4      pVP$                  pVP&                  p\)        WV	V4      pVP*                  e¡   TP*                  ^ RIHp V! VP                  R4      VWèW�VP                  R7      pVP1                  4        V'       d"   V'       g   \3        VWèW�VP                  R7       V'       g(   Ve   Ve   VP5                  V4       # # \7        Wè4       # # VP&                  p\9        V 4      p\;        WÀVVVP                  VVR7      p\=        WV4      p\?        WëWV	VP@                  VVR7      p\C        VW‰V4      pVPD                  '       dF   VPG                  4       '       d0   \I        V4      '       g   \K        V4      f   VPD                   RV 2pV'       d   TMRp\M        V4      p\M        V4      p\O        W	VV\P         \S        V4       R2R7      \T         \S        V4       R\V         V \X         2,           p\        P                  RV	4       TP[                  \]        T\I        T;'       g    R4      R7      R4       RVVR3^ RIHp V! VP                  R4      VWèW�VP                  R7      pVP1                  4        V'       d"   V'       g   \3        VWèW�VP                  R7       V'       g(   Ve   Ve   VP5                  V4       # # \7        Wè4       # #   \^         Edm   p\a        T4      Pb                   R T: 2p\        Pe                  R!T	T4        ^ R"I3H4p  T ! TT4      '       d   RT R#&   ^ R$I5H6p! T!! T4      p"T"'       d   T"T R%&   M'  \^         d    \        Po                  R&T4        Mi ; iTe   TP[                  / T4       ^ R'I8H9p# \O        Y	 R(2Y‹4      T#! T4      ,           pR)TRT3u Rp?^ RIHp T! TP                  R4      TYèY�TP                  R7      pTP1                  4        T'       d"   T'       g   \3        TYèY�TP                  R7       T'       g(   Te   Te   TP5                  T4       # # \7        Yè4       # # Rp?ii ; i  ^ RIHp T! TP                  R4      TYèY�TP                  R7      pTP1                  4        T'       d"   T'       g   \3        TYèY�TP                  R7       T'       g(   Te   Te   TP5                  T4       i i \7        Yè4       i i ; i)*uj  Execute a single cron job. Returns (success, full_output_doc, final_response, error).
``defer_agent_teardown``: if a list, the live agent is appended instead of torn down; the caller
MUST call ``_teardown_cron_agent(agent)`` AFTER delivery (a torn-down async client can't
deliver). ``extra_prompt``: per-fire context, never persisted.

``defer_agent_teardown``: when a caller passes a list, ``run_job`` skips the agent's async-resource
teardown (``agent.close()`` + ``cleanup_stale_async_clients()``) in its ``finally`` block and instead
appends the live agent to that list. The caller is then responsible for calling
``_teardown_cron_agent(agent)`` AFTER it has delivered the result. This closes the ordering window in
#58720 where delivery ran against a torn-down async client (defense-in-depth alongside the
interpreter-shutdown guard). When ``None`` (the default) teardown happens inline as before, so every
existing caller is unchanged.
``extra_prompt``: optional per-run context from ``cronjob(action='run', prompt=...)`` (#57331). Appended
to the stored prompt for this fire only â€” never persisted to the job definition.
r´  N:r4   NNrW   r±   )Úrun_canonical_job)r;  r)  r  rc   rå  rQ   )r0  Úcron_r  z%Y%m%d_%H%M%SzRunning job '%s' (ID: %s)z
Prompt: %s:Néd   Nr$   z&Job '%s': using task-scoped workdir %s)Ú defer_teardown_to_running_workerrÎ  )r  )r  r+   r*   )rç  r_  r)  rK  )r[  zJob '%s' completed successfully)ré  Tú: zJob '%s' failed: %s)Úis_model_unreachable_failureÚ_model_unreachable)Úhold_seconds_from_failureÚ_quota_hold_secondsz3Job '%s': unreachable-failure classification failed)Úformat_run_errorz	 (FAILED)F):rÅ  rµ  rA   Úcron.scheduler_authorityrñ  rB   rs  Ú	run_agentr0  r×   r”  ræ   r%  ru  r–  r  r©  re  rN   rH   r½  r­  rÌ  rô  rž  rU  r  Ú_teardown_cron_agentrÒ  rÙ  rÛ  r   ræ  r9  r±  r&   rX  rR  rZ  rb  Ú_PROMPT_FRAMEr»   Ú_RESPONSE_FRAMEÚ_RESPONSE_HEADINGÚ_RESPONSE_TERMINATORr  r8   rX   r  rŠ   r0  Úcron.unreachable_retryrö  Úcron.quota_holdrø  rç   Úcron.scheduler_diagnosticsrú  )$r5   rî  r;  r)  r  rµ  Úowner_executionrñ  r½   r¼   Úearlyrå  r0  Ú_cron_session_idr  rH   rÿ  Ú_auditÚ_worker_stateÚscoper†  r^  r¹  rô  Ú_worker_teardown_deferredr  r$  Úlogged_responseÚframed_promptr5  r  Ú	error_msgrö  rø  Ú_hold_srú  s$   &$$$$                               r0   Úrun_jobr  
  s  € õ& 7Ù'Ó)€OØÒ" °rÕ':¸sÀ4½yÈ,Ð>WÔ'WØˆØ�7‰7�:×Ò ?Ò#:Ý>Ù  ÈlØ.:ô<ð 	<à��Y€FÜ�3—7‘7˜6“?×OÐO c§g¡g¨hÓ&7×OÐO¸6×OÐOÀZÓP€Hä'¨°XÈ\ÓZ�M€EØÒØˆÝ!à.=Ò.I˜¨Ö*Ø ˜x q¬«×)?Ñ)?ÀÓ)PÐ(QÐRð ä
‡K�KÐ+¨XÔ>Ü
‡K�K�˜f T�lÔ+à€EØ€EØ€KØ#'€FØ€MÜ˜# |Ó4€Eð^4Ø�‰ŒØ�=�=ˆ=Ü�K‰KÐ@À&È%Ï-É-ÔXÜ2°3Ô7ä" 3°Ó9ˆØ�v‰vˆØ—‘ˆÜ)¨#°xÀÓDˆØ�=‰=Ò$Ø—=‘=õ~ 	TÙ$DØ×Ñ˜hÓ'¨°eÀXØ—M‘Mô%#Ð!ð 	�
‰
Œß×8Ü" ;°¸xØ+0¯=©=õ:÷ )Ø#Ò/ØÒ$Ø(×/Ñ/°Õ6ð %ô % UÕ3ð )ð[ —‘ˆô ,¨CÓ0ˆÜ%Ø˜$ ¨u¯}©}ÐIYØ"ô$ˆô ˜C¨Ó/ˆä)Ø˜3¨°%·-±-ÀØ&ô(ˆô 5°V¸VÈwÓWˆØ×!×!Ð! n×&:Ñ&:×&<Ò&<ÔE^Ð_m×EnÒEnÜ.¨~Ó>ÒFð !&× 5Ñ 5Ð6°d¸>Ð:JÐKˆNç,:™.Ð@Yˆô ,¨FÓ3ˆÜ-¨oÓ>ˆä˜C¨6°=Ü,9¨?¼3¸}Ó;MÐ:NÈbÐ)QôSä Ð!¤# oÓ"6Ð!7°rÔ:KÐ9LÈ_ÐL]Ô^rÐ]sÐtõuð 	ô
 	�‰Ð5°xÔ@Ø�‰”T˜&Ô2KÈN×L`ÐL`Ð^`Ó2aÔbÐdhÔiØ�V˜^¨TÐ1õ> 	TÙ$DØ×Ñ˜hÓ'¨°eÀXØ—M‘Mô%#Ð!ð 	�
‰
Œß×8Ü" ;°¸xØ+0¯=©=õ:÷ )Ø#Ò/ØÒ$Ø(×/Ñ/°Õ6ð %ô % UÕ3ð )øôY õ ,Ü˜A“w×'Ñ'Ð(¨¨1©%Ð0ˆ	Ü×ÑÐ.°¸)ÔDð	XÝKÙ+¨A¨u×5Ò5Ø,0�Ð(Ñ)õ BÙ/°Ó2ˆGßØ-4�Ð)Ñ*ùÜô 	XÜ�L‰LÐNÐPVÖWð	Xúð ÒØ�L‰L˜˜YÔ'Ý?ä˜C :¨YÐ!7¸ÓHÙ˜qÓ!õ"ð 	ð �f˜b )Ð+Ô+õ 	TÙ$DØ×Ñ˜hÓ'¨°eÀXØ—M‘Mô%#Ð!ð 	�
‰
Œß×8Ü" ;°¸xØ+0¯=©=õ:÷ )Ø#Ò/ØÒ$Ø(×/Ñ/°Õ6ð %ô % UÕ3ð )ûðY,ûõ: 	TÙ$DØ×Ñ˜hÓ'¨°eÀXØ—M‘Mô%#Ð!ð 	�
‰
Œß×8Ü" ;°¸xØ+0¯=©=õ:÷ )Ø#Ò/ØÒ$Ø(×/Ñ/°Õ6ð %ô % UÕ3ð )ús}   Ä8BQ, É%BQ, Ë36Q, Ì*B-Q, Ñ,W$Ñ82WÒ+/S!ÓS!Ó WÓ!!TÔWÔTÔA WÕW$ÕW' ×W$×$W' ×'AY=Ø4 Y=Ù(Y=c                óJ   € V ^8„  d   QhR\         R\        \        ,          RR/# )r4   r½   ræ  r6   Nrè  )r:   s   "r0   r;   r;   �
  s(   € ÷ )ñ )Üð)Ü,4´U­Oð)à	ñ)r<   c               ó<   a a€ R V V3R llp\        VSRVR7       R# )uÊ  Release an ephemeral cron agent's async resources within a hard bound (this runs outside the
inactivity watchdog). Shared by ``run_job``'s finally and deferred post-delivery teardown.

Split out of ``run_job``'s ``finally`` so a caller that defers teardown (to deliver first â€” #58720) can
invoke the identical cleanup AFTER delivery. The timeout matters because this executes after
``run_conversation`` has returned, outside the agent inactivity watchdog.
c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   Ú*_teardown_cron_agent.<locals>.__annotate__š
  s   € ÷ \ñ \˜Dñ \r<   c                  ó  <€  Se   SP                  4         ^ RIHp T! 4        R #   \        \        3 d"   p \        P	                  RST 4        R p ? L=R p ? ii ; i  \         d#   p \        P	                  RST 4        R p ? R # R p ? ii ; i)Nz-Job '%s': failed to close agent resources: %s)Úcleanup_stale_async_clientsz4Job '%s': failed to reap stale auxiliary clients: %s)ÚcloserX   ró  ræ   rç   Úagent.auxiliary_clientr  )r  r  r  r½   s     €€r0   Ú_cleanup_agentÚ,_teardown_cron_agent.<locals>._cleanup_agentš
  s   ø€ ð	UØÒ Ø—‘”ð	\ÝJÙ'Ö)øô Ô,Ð-ô 	UÜ�L‰LÐHÈ&ÐRS×TÑTûð	Uûô ô 	\Ü�L‰LÐOÐQWÐYZ×[Ò[ûð	\ús+   ƒ' ˜A §A¸AÁAÁB	Á'BÂB	zagent resource teardown)r½   rè  ræ  N)rù  )r  r½   ræ  r  s   ff$ r0   rý  rý  �
  s$   ù€ ÷\ñ \ô #Ø˜vÐ-FØ'÷)r<   c                ó0   € V ^8„  d   QhR\         R\        /# r3   r7   )r:   s   "r0   r;   r;   ¬
  s   € ÷ Q+ñ Q+¬ð Q+´dñ Q+r<   c                ó<  a aaa	a
€ S P                  R4      p\        V\        4      '       d%   \        VP                  R4      ;'       g    R4      MRo	S	'       g	   V! R4      # \        S P                  R4      ;'       g    R4      o\        P
                  ! 4       o
\        P
                  ! 4       oR V V3R llp \        SS	R7      pTRJ d!   \        P                  RS4       T! R4       R
# R TTT	T
3R llp\        TRT3R l4      pTf   T! R4       R
#  T! S4      S
P                  4        TP                  RR7       #   \         d%    \        P                  R	SR
R7       T! R4        R
# i ; i  S
P                  4        TP                  RR7       i ; i)zDRun ``run`` while keeping this job's owned durable fire claim fresh.Ú
fire_claimrë  r$   NrW   c                ó(   € V ^8„  d   QhR\         RR/# )r4   rª   r6   Nrv   )r:   s   "r0   r;   Ú4_run_with_fire_claim_heartbeat.<locals>.__annotate__·
  s   € ÷ 
ñ 
¤ð 
¨ñ 
r<   c                 ó°   <€ SP                  R 4      pV'       g   R#  \        VRV R7       R#   \         d    \        P	                  RSRR7        R# i ; i)r  NF©Úsuccessrª   z8Job '%s': failed to close unstarted execution ledger rowTr$  )rA   r=  rX   ræ   r&  )rª   r  r5   r½   s   & €€r0   Ú_finish_unstartedÚ9_run_with_fire_claim_heartbeat.<locals>._finish_unstarted·
  sQ   ø€ Ø—w‘w˜~Ó.ˆßÙð	Ü˜\°5À×FøÜô 	Ü�N‰NØJØØð ÷ ð	ús   ž. ®#AÁAró  z.Job '%s': initial fire_claim validation failedTr$  zEFire claim ownership could not be validated before execution started.Fz@Job '%s': fire claim ownership was already lost before executionz3Fire claim ownership lost before execution started.c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   r  Ï
  s   € ÷  ñ  ˜Tñ  r<   c                  óº  <€ \         P                  ! 4       p SP                  \        4      '       g¬    \	        SSR 7      '       g�   \        S4      '       d   KB  SP                  \        4      '       g   \	        SSR 7      '       d   \         P                  ! 4       p K‡  SP                  4        \        P                  RS4       R# \         P                  ! 4       p KÆ  R#   \         dq    \        P                  RSRR7       \         P                  ! 4       T ,
          \        8¼  d/   SP                  4        \        P                  RS\        4        R#  EKB  i ; i)ró  z;Job '%s': fire claim ownership lost; interrupting stale runNz%Job '%s': fire_claim heartbeat failedTr$  zRJob '%s': fire_claim could not be renewed within %.1fs; interrupting uncertain run)r˜  rõ  rz  rö  r0  r4  Ú _FIRE_CLAIM_MISS_CONFIRM_SECONDSr  ræ   r&  rX   rç   Ú#_FIRE_CLAIM_HEARTBEAT_GRACE_SECONDS)Úlast_confirmedr½   Úlost_ownershiprS   r  s    €€€€r0   Ú_heartbeat_loopÚ7_run_with_fire_claim_heartbeat.<locals>._heartbeat_loopÏ
  s  ø€ ÜŸšÓ)ˆØ—)‘)Ô8×9Ò9ðÜ+¨FÀ5×IÓIÜ4°V×<Ò<á ð —y‘yÔ!A×BÒBÔFZØ"°5÷G:ó G:ä)-¯ªÓ)9˜Ù Ø"×&Ñ&Ô(Ü—N‘NØUØô ñ Ü!%§¢Ó!1’ñ# :øô$ ô Ü—‘ÐDÀfÐW[�Ô\ä—N’NÓ$ ~Õ5Ü:ô;ð #×&Ñ&Ô(Ü—N‘Nð5àÜ;ô	=ò
 ó;ðús*   ³$C ÁC Á4(C Â&C ÃC ÃA3EÅEzcron-fire-claim-heartbeatc                  ó4   <€ \         P                  R S RR7      # )z.Job '%s': could not start fire_claim heartbeatTr$  ©ræ   r&  )r½   s   €r0   r@  Ú0_run_with_fire_claim_heartbeat.<locals>.<lambda>ó
  s   ø€ ”—‘Ø<¸fÈtð ô Ur<   zAFire claim heartbeat could not be started; execution was not run.rÝ  rÃ  )rA   r@   r8   rB   rô  rõ  r0  rX   ræ   r&  Ú_start_heartbeat_threadr  rO  )r5   rË  Úclaimr#  Úowns_fire_claimr+  Úheartbeat_threadr½   r*  rS   r  s   f&     @@@@r0   Ú_run_with_fire_claim_heartbeatr4  ¬
  si  ü€ à�G‰G�LÓ!€EÜ*4°U¼D×*AÒ*AŒC�—	‘	˜$“×%Ð% 2Ô&Àr€EßÙ�4‹yÐä�—‘˜“×$Ð$ "Ó%€FÜ�?Š?Ó€DÜ—_’_Ó&€N÷
ñ 
ðÜ.¨vÀeÔLˆð ˜%ÓÜ�‰ÐYÐ[aÔbÙÐOÔPÙ÷ ó  ôD /ØÐ4ô	UóVÐð ÒÙÐ]Ô^Ùð+Ù�>Ó"à�‰Œ
Ø×Ñ cÐÕ*øôq ô Ü�‰ÐGÈÐZ^ˆÔ_ÙÐaÔbÚðûðn 	�‰Œ
Ø×Ñ cÐÕ*ús   Â<E ÄE7 Å+E4Å3E4Å7$FrÏ  rÐ  ÚverboseFc          
      ó€   € V ^8„  d   QhR\         R\        R\        \        ,          R\        \        ,          R\        /# )r4   r5   r5  r;  r)  r6   )r8   r9   r   rB   rf  )r:   s   "r0   r;   r;      sG   € ÷ f>ñ f>Ü	ðf>Ü59ðf>äœ3•-ðf>ä6>Ô?OÕ6Pðf>ô 
ñf>r<   c               ó

  a aaaaaa€ S P                  R4      '       g1   \        S R,          RS P                  R4      R7      pVR,          S R&   \        S R,          4      p\        S 4       \        P
                  P                  R4      V8H  pV'       g(    \        S 4      p	T	'       d   ^ RI
Hp T! S SSR7       R# Sf<   S P                  R4      pV'       d#   S P                  R4      '       d   \        V4      oS P                  R4      p\        V\        4      '       d%   \        VP                  R4      ;'       g    R4      MRp\+        4       o\-        4       P/                  4       p\1        S R,          4      p\2        ;_uu_ 4        T;'       g    RV3\4        P7                  V/ 4      S&   RRR4        \9        S R,          4      ;_uu_ 4        \;        S VVVVV VV3R l4      uuRRR4       \2        ;_uu_ 4        \4        P                  V4      pVe1   VP=                  SR4       V'       g   \4        P=                  VR4       RRR4       #   \         Edy   p
\        T
\        4      pT'       d   RMRpR	T R
T
 2pT'       d(   ^ RI
Hp T! S \        T
4      SSR7      '       d    Rp
?
R# \        P                  RS R,          T4       S P                  R4      p\        T\        4      '       d%   \        TP                  R4      ;'       g    R4      MRpR;pp T'       gB   \        4       ;_uu_ 4        \!        S TSSR7      w  ppRRR4       M  + '       g   i     M; i^ RIHp \'        S R,          RT3RT/T'       d   RT/M/ BT! S 4      '       d   RR/M/ B  \)        TRTTR7       M  \)        TRTTR7       i ; i Rp
?
R# Rp
?
ii ; i  + '       g   i     EL4; i  + '       g   i     # ; i  + '       g   i     M; i \2        ;_uu_ 4        \4        P                  T4      pTe1   TP=                  SR4       T'       g   \4        P=                  TR4       RRR4       R#   + '       g   i     R# ; i  \2        ;_uu_ 4        \4        P                  T4      pTe1   TP=                  SR4       T'       g   \4        P=                  TR4       RRR4       i   + '       g   i     i ; i; i)u�  Run ONE due job end-to-end: execute â†’ save output â†’ deliver â†’ mark. Shared by the built-in
ticker and external providers' ``fire_due``; does NOT decide due-ness or acquire the initial
claim (callers use the store CAS) but keeps it alive. True if processed (a job failure is
recorded via ``mark_job_run``), False only if processing raised. ``cancel_event``: optional
transport-level cancel (dashboard drain).r  rW   ÚdirectÚ_scheduled_instant©ÚsourceÚscheduled_instantÚ_HERMES_CRON_EXTERNAL_WORKERzfailed after handoffzdispatch failedzRestart-safe cron worker rõ  )Úrecord_unknown_worker_outcome)rª   rÏ  rÐ  NTzJob '%s': %sr  rë  r$   ©rÏ  rÐ  ©Úis_retry_runFÚdelivery_errorrS  Úladder_rung©r"  rª   Údelivery_outcomeÚmanual_run_promptÚmanual_run_atc                 ó*   <€ \        SSSSSV SSR 7      # ))rÏ  rÐ  r5  r;  Ú
claim_lostÚtransport_cancelÚexecution_token)Ú_run_one_job_body)r*  rÏ  r)  rK  r;  r5   rÐ  r5  s   &€€€€€€€r0   r@  Úrun_one_job.<locals>.<lambda>W  s#   ø€ Ô'8ØØ%ØØ#Ø!-Ø-Ø%1Ø$3õ(5r<   )rA   r<  rB   r   r\  ÚenvironÚ_launch_external_cron_workerrX   r@   Ú_ExternalWorkerPostHandoffErrorÚcron.scheduler_worker_failurer>  ræ   rª   r8   Ú_fire_secret_scopeÚ_deliver_crash_failurer  rA  r2  r=  rh  r£   Úresolver\  rŽ  r�  Ú
setdefaultr5  r4  rÚ  )r5   rÏ  rÐ  r5  r;  r)  Ú	executionr  Úexternal_ownerÚ
handed_offÚhandoff_errorÚpost_handoffÚstagerª   r>  r1  rS   rB  rE  rA  Ú_stampedrc  rZ  Ú	_fire_keyrY  rK  s   fddddd                   @r0   Úrun_one_jobr^     só  þ€ ð �7‰7�>×"Ò"Ü$Ø��I˜h¸#¿'¹'ÐBVÓ:WôYˆ	à'¨�oˆˆNÑä�s˜>Õ*Ó+€LÜ˜ÔÜ—Z‘Z—^‘^Ð$BÓCÀ|ÑS€Nßð*	Ü5°cÓ:ˆJ÷T ÝSá)¨#¸ÀtÕLÙØÒð —7‘7Ð.Ó/ˆß˜Ÿ™ ×0Ò0Ü˜x›=ˆLØ�G‰G�LÓ!€EÜ/9¸%Ä×/FÒ/F”�U—Y‘Y˜t“_×*Ð*¨Ô+ÈB€JÜ“h€OÜ#Ó%×-Ñ-Ó/€LÜ˜c $�iÓ(€Iß	Žà×Ð˜$ ðK.Ô×'Ñ'¨	°2Ó6°ÑG÷ 
ð>Ü(¨¨T­×3Õ3Ü1Ø÷5ò 5ó
6÷ 4Ñ3÷ Ž]Ü-×1Ñ1°)Ó<ˆJØÒ%Ø—‘˜°Ô5ß!Ü(×,Ñ,¨Y¸Ô=÷ ˆ]øôU õ (	ô & mÔ5TÓUˆLß.:Ñ*Ð@QˆEØ/°¨w°b¸¸ÐHˆEßÝWá0°¼CÀÓ<NÐYaÐhl×mÓmÝÜ�L‰L˜¨¨T­°EÔ:Ø—G‘G˜LÓ)ˆEÜ2<¸UÄD×2IÒ2I”C˜Ÿ	™	 $›×-Ð-¨2Ô.ÈrˆEØ04Ð4ˆNÐ-ð7÷
 $ä+×-Õ-Ü;QØ °Àô<FÑ8˜Ð(8÷ .×-×-Ð-úõ @ÜØ˜•IØØñð $2ð	÷
 :?Ð-¨uÑ5ÀBðñ 1=¸S×0AÒ0A˜ tÑ,Àròô !Ø ¨%°uØ%5ö7øÔ Ø ¨%°uØ%5ö7úõ ûðQ(	ú÷r 
�ˆú÷" �]ú÷ 4×3úÐ3÷ Ž]Ü-×1Ñ1°)Ó<ˆJØÒ%Ø—‘˜°Ô5ß!Ü(×,Ñ,¨Y¸Ô=÷ �]�]Š]û�]Ž]Ü-×1Ñ1°)Ó<ˆJØÒ%Ø—‘˜°Ô5ß!Ü(×,Ñ,¨Y¸Ô=÷ �]�]ˆ]ýsÙ   ÂI Æ&OÆ:R ÇPÇ*
R È3O0È6O0ÉOÉ!+OÊ!OÊ4A!OÌOÌ$N:Ì,N:Ì>MÍ	N:ÍM*Í%<N:Î"N:Î*OÎ:OÏOÏOÏO-	Ï0P ÐP	ÐR Ð%3Q9ÑQ9Ñ9R
	ÒTÒ3S/	ÓS/	Ó&	TÓ/S?Ó:Tz3Interrupted by shutdown before terminal completion.c                óV   € V ^8„  d   QhR\         R\        \        ,          R\        RR/# )r4   r5   rc  r  r6   Nrã  )r:   s   "r0   r;   r;   l  s6   € ÷ Lñ LÜ	ðLÜ#¤C�=ðLÜ8;ðLà	ñLr<   c                óà   € ^ RI Hp V R,          pVeM   \        WAR7      '       d;   \        VR\        3RV/V! V 4      '       d   RR/M/ B  \        VR\        R	7       R# \        VRR
R	7       R# )u¯  Bookkeeping after fire-claim ownership loss. A transport-level cancel (dashboard drain) is
not a real loss â€” we still own the claim, so record the interruption via the owner-fenced
terminal write instead of leaving fire_claim/last_status stale; otherwise discard.
An interrupted ladder re-run re-ran an occurrence that already counted, so its terminal
write must not spend another repeat slot (same as every other terminal path).r@  rW   Nró  FrS  rC  Tr!  z6Fire claim ownership lost; stale result was discarded.)r  rA  r0  r2  Ú_OWNERSHIP_LOST_INTERRUPTEDr=  )r5   rc  r  rA  r½   s   &&&  r0   Ú_record_fire_ownership_lostrb  l  sr   € õ 4Ø��Y€FØÒÔ"6°v×"YÓ"YÜØ�EÔ6ñ	
ØLVð	
á(4°S×(9Ò(9�˜tÑ$¸rò	
ô 	˜¨uÔ<W×XäØ %ØJ÷	Lr<   Úagent_declaredc                óª   € V ^8„  d   QhR\         R\        R\        R\        R\        \        \        \        \        \        \        ,          3,          /# )r4   r5   r"  r$  rc  r6   )r8   r9   rB   rn   r   )r:   s   "r0   r;   r;   ‚  sQ   € ÷ .gñ .gÜ	ð.gÜð.gÜ8;ð.gäð.gô Œ3””dœD¤(¬3¥-Ð/Õ0ñ.gr<   c               ó
  € V'       d   \        V4      MRp\        V9   pT;'       g
    \        V9   pRp	Rp
V'       d_   V'       gW   \        P                  ! RRV4      P                  4       p^ RIHp T! V P                  R4      ;'       g
    V R,          V4      pMäV'       d   Tp\        V 4       MÎ\        Y;'       g    RVR7      w  ršV	'       d   RpMªV'       df   ^ R	IHp T! V P                  R4      ;'       g
    V R,          V R,          VP                  4       P                  R
4      4      \        V 4      ,           pM=^ RIHp \!        W4      \        V 4      ,           V! W P                  R4      4      ,           pWØWyV
3# )aA  Text to deliver for a finished run. Returns ``(deliver_content, blocked_config,
silent_alert, incident_acked, failure_incident_id)``; ``silent_alert``: an alert-once marker
says the operator was already told, deliver nothing. ``agent_declared``: *error* is the
agent's own ``[CRON_FAILURE]`` evidence, delivered verbatim.r$   FNz\[blocked_config[^\]]*\]\s*)Úblocked_config_noticerc   rW   )rÛ   )r­   r´   )Úhold_noticerù  )rB   r€  r�  r¸   r¹   r&   r¶   rf  rA   rò   rì   r­   rº   rj   r  rg  rÂ   )r5   r"  rª   r$  rÛ   rc  r®  Úblocked_config_silentÚblocked_configÚincident_ackedÚfailure_incident_idÚ_pf_textrf  Údeliver_contentr­   rg  s   &$$$$$          r0   Ú_compose_run_deliveryrn  ‚  sJ  € ÷ Œ#ˆeŒ* 2€Cä8¸CÑ?ÐØ*×JÐJÔ.CÀsÑ.J€NØ€NØÐßŸgä—6’6Ð8¸"¸cÓB×HÑHÓJˆÝEÙ/°·±¸³×0LÐ0LÀ3ÀtÅ9ÈhÓW‰ß	Ø(ˆÜ,¨SÕ1ô
 /KØ—�˜"¨+ô/
Ñ+ˆ÷ Ø ‰Oßõ KÙ4Ø—‘˜“×,Ð, 3 t¥9¨c°$­i¸¿¹»×9KÑ9KÈCÓ9Póä% cÓ*õ+‰Oõ 4ä4°SÓ@ÔCXÐY\ÓC]Õ]á˜c§7¡7Ð+@Ó#AÓBõCð ð
 Ð,AÐSfÐfÐfr<   c                   ó   € ] tR tRtRtRtR# )Ú_FireClaimLostDuringSideEffecti³  zPRaised inside a side-effect fence when the durable fire claim is no longer ours.rù   Nrú   rù   r<   r0   rp  rp  ³  s   † ÝZr<   rp  c                   ód   a € ] tR tRt o RtRV 3R lR lltV 3R lR ltR tV 3R	 lR
 ltRt	V t
R# )Ú_FireOwnershipi·  zZFire-claim ownership checks for one run (``owner`` is None when the job carries no claim).Nc                óL   <€ V ^8„  d   QhRS[ RS[S[,          RS[S[,          /# )r4   r5   rI  rJ  )r8   r   rf  )r:   r€   s   "€r0   r;   Ú_FireOwnership.__annotate__º  s6   ø€ ÷ Uñ UÙðUÙ%-Ñ.>Õ%?ðUá"Ñ#3Õ4ñUr<   c                ó  € Wn         W n        W0n        Vf   Ve   \        W#4      MR V n        VP                  R4      p\        V\        4      '       d,   \        VP                  R4      ;'       g    R4      V n	        R # R V n	        R # )Nr  rë  r$   )
r5   rI  rJ  rs  r)  rA   r@   r8   rB   rS   )r‡   r5   rI  rJ  r1  s   &&&& r0   r†   Ú_FireOwnership.__init__º  sx   € ð Œð %ŒØ 0Ôð Ò%Ð)9Ò)Eô ! Ô>àð 	Ôð —‘˜Ó%ˆÜ3=¸eÄT×3JÒ3J”S˜Ÿ™ 4›×.Ð.¨BÓ/ˆŽ
ÐPTˆŽ
r<   c                ó    <€ V ^8„  d   QhRS[ /# rÄ   rh  )r:   r€   s   "€r0   r;   rt  Ì  s   ø€ ÷ Tñ T¡Tñ Tr<   c                ób   € V P                   R J;'       d    V P                   P                  4       # r?   )rJ  rl  rk  s   &r0   Útransport_cancelledÚ"_FireOwnership.transport_cancelledÌ  s*   € Ø×$Ñ$¨DÐ0×SÐS°T×5JÑ5J×5QÑ5QÓ5SÐSr<   c                óš   € V P                   f   \        P                  ! R4      # \        V P                  R,          V P                   R7      # )NTrW   ró  )rS   r³  Únullcontextr-  r5   rk  s   &r0   Úside_effect_fenceÚ _FireOwnership.side_effect_fenceÏ  s6   € Ø�:‰:ÒÜ×)Ò)¨$Ó/Ð/Ü §¡¨¥¸t¿z¹zÔJÐJr<   c                ó    <€ V ^8„  d   QhRS[ /# rÄ   rh  )r:   r€   s   "€r0   r;   rt  Ô  s   ø€ ÷ ñ ‘dñ r<   c                ó*  € V P                  4       '       d   R # V P                  f   R# \        V P                  R,          4      '       d   R# V P                  RJ;'       d    V P                  P                  4       p \        V P                  R,          V P                  R7      '       d   R#  T P                  e   T P                  P                  4        R #   \         d/    \        P                  RT P                  R,          R R7       Tu # i ; i)TNFrW   ró  z0Job '%s': fire_claim ownership validation failedr$  )ry  rS   r4  r5   rI  rl  r0  rX   ræ   rç   r  )r‡   Úlatcheds   & r0   ÚlostÚ_FireOwnership.lostÔ  sÜ   € Ø×#Ñ#×%Ò%ÙØ�:‰:ÒÙÜ(¨¯©°$­×8Ò8áð —/‘/¨Ð-×JÐJ°$·/±/×2HÑ2HÓ2Jˆð	Ü# D§H¡H¨T¥NÀ4Ç:Á:×NÓNÙð Oð �?‰?Ò&Ø�O‰O×ÑÔ!Ùøô ô 	Ü�L‰LØBÀDÇHÁHÈTÅNÐ]að ô cð ŠNð		ús   Á>.C Ã6DÄD)r)  rI  r5   rS   rJ  )NN)rŠ   r‹   rŒ   r�   rŽ   r†   ry  r}  r‚  r�   r�   rq  s   @r0   rr  rr  ·  s0   ø‡ € Ùd÷Uò U÷$Tð TòK÷
ö r<   rr  c                   óT   a € ] tR tRt o RtRtRtRtRtRt	Rt
RtRtRtV 3R ltRtV tR# )Ú_RunDeliveryií  zUMutable outcome of the save/compose/deliver phase, read back by the bookkeeping tail.FNc                óÚ   <€ V ^8„  d   Qh/ S[ ;R&   S[;R&   S[S[,          ;R&   S[;R&   S[S[,          ;R&   S[;R&   S[;R&   S[;R&   S[;R	&   S[;R
&   S[S[,          ;R&   S[;R&   # )r4   r5   r"  rª   Údelivery_attemptedrB  Úshould_deliverÚunresolved_originri  rc  rj  rk  Úside_effect_ownership_lost)r8   r9   r   rB   )r:   r€   s   "€r0   r;   Ú_RunDelivery.__annotate__í  s«   ø‡ ‚ ñ 
�Iñ ñ �Mñ	 ñ
 ‘C�=Ññ ñ Ñ$ñ ñ ™S•MÑ(ñ ñ Ñ ñ ñ Ñ#ñ ñ Ñ ñ ñ Ñ ñ ñ Ñ ñ ñ "¡#�Ñ-ñ ñ  !%Ñ,ò! r<   rù   )rŠ   r‹   rŒ   r�   rŽ   r‡  rB  rˆ  r‰  ri  rc  rj  rk  rŠ  rN  r�   r�   rq  s   @r0   r…  r…  í  sD   ø‡ € á_ð  %ÐØ$(€NØ €NØ#ÐØ €Nð !€NØ €NØ)-ÐØ',Ð÷! ƒ r<   r…  c                óX   € V ^8„  d   QhR\         R\        R\        R\        R\        RR/# )r4   ÚdÚfencer$  r5  r5  r6   N)r…  rr  rB   r9   )r:   s   "r0   r;   r;      sN   € ÷ dFñ dFÜðdFÜ*ðdFÜ<?ðdFÜILðdFä!ðdFð 
ñdFr<   c          
     ó`	  € V P                   pVP                  4       ;_uu_ 4       p	V	'       g   \        h\        VR,          4      '       d   RM\	        VR,          V4      p
RRR4       V'       d   X
e   \
        P                  RV
4       V P                  '       d(   \        VR,          V4      '       d   RV n        RV n	        \        W€P                  V P                  VX
V P                  R7      w  q°n        qÀn        V n        \        VP!                  4       4      ;'       d    V'       * V n        V P"                  '       db   V P                  '       gP   VP%                  R4      '       d9   ^ RIHp V! V4      '       d%   RV n        \
        P                  R	VR,          4       V P"                  '       dM   V P                  '       d;   \+        V4      '       d*   \
        P                  R
VR,          \,        4       RV n        V P"                  '       d;   VP/                  4       '       d%   RV n        \
        P1                  RVR,          4       V P"                  '       g   R# \3        \5        W€P                  '       * R7      4      R8H  ;'       d!    \7        W€P                  '       * R7      '       * V n        VP%                  R4      pV'       dë   VP%                  R4      '       gÔ   ^ RIHp V P8                  '       g*   \3        \5        W€P                  '       * R7      4      R8X  d   R# \?        V4      pV P                  '       d   V P                  VR&   VP                  4       ;_uu_ 4       pV'       g   \        hV! VVW°P                  '       * R7      pRV n         RRR4       RRXR,          RV//VR&   R#  VP                  4       ;_uu_ 4       pV'       g   \        hRV n         \C        VVVVV P                  '       * R7      V n"        RRR4       R#   + '       g   i     EL¿; i  + '       g   i     L•; i  + '       g   i     R# ; i  \F         dQ   p\I        T\        4      '       d   h \K        T4      T n"        \
        P                  RTR,          T4        Rp?R# Rp?ii ; i)z©Save output, compose the notice and deliver it (both side effects run under the fire-claim
fence; a lost claim raises ``_FireClaimLostDuringSideEffect`` for the caller).rW   NzOutput saved to: %sFz`Interrupted by gateway shutdown before the run finished (tool subprocess was killed mid-flight).)r"  rª   r$  rÛ   rc  r÷  )Ú
will_retryuA   Job '%s': suppressing failure notice â€” automatic re-run pendingu1   Job '%s': agent returned %s â€” skipping deliveryz;Job '%s': skipping delivery after fire claim ownership loss©rÑ  Úoriginr  r±   )ÚenqueueÚlocalrÓ  TÚ	canonicalr?  Úlast_delivery_queuedrÎ  úDelivery failed for job %s: %s)&r5   r}  rp  r4  r3  ræ   r%  r"  rj  rª   rn  rc  ri  rj  rk  r9   r&   rˆ  rA   r  r�  rX  r2  r‚  r&  Ú_normalize_deliver_valueÚ_delivery_lane_valueÚ_resolve_delivery_targetsr‰  rÚ  r“  r8   r‡  rÔ  rB  rX   r@   rB   )r�  rŽ  r$  r5  rÏ  rÐ  r5  rK  r5   Úowns_outputrÛ   rm  Ú_silent_alertr�  r  r“  rÕ  Úowns_deliveryÚqueuedÚdes   &&&&$$$$            r0   Ú_save_compose_deliverr      s¨  € ð �%‰%€CØ	×	 Ñ	 ×	"Ô	" kßÜ0Ð0ô 2°#°dµ)×<Ò<‰DÜ   T¥¨FÓ3ð 	÷	 
#÷ �;Ò*Ü�‰Ð)¨;Ô7ð 	‡y‡y€y”_ S¨¥Y°×@Ò@ØˆŒ	ð7ð 	
Œô 	Ø—Y‘Y a§g¡g¸nØ°×0@Ñ0@ô	BñØÔ)¨=Ô:JÈAÔLaô
 ˜O×1Ñ1Ó3Ó4×JÐJ¸]Ô9J€AÔØ××Ð §	§	 	¨c¯g©gÐ6J×.KÒ.Kõ
 	6Ù�c�?Š?Ø$ˆAÔÜ�K‰KØSÐUXÐY]ÕU^ô`ð 	××Ð˜AŸIŸI˜IÔ*CÀO×*TÒ*Tô 	�‰ÐGÈÈTÍÔTaÔbØ ˆÔà××Ð˜EŸJ™JŸLšLØ ˆÔÜ�‰ÐTÐVYÐZ^ÕV_Ô`à××ÐÙä Ô!5°cÏ9É9Ä}Ô!UÓVÐZbÑb÷ 	Jð 	JÜ)¨#¿y¹y¼=ÔIÔIð Ôð —7‘7˜>Ó*€Lß˜CŸG™G J×/Ò/Ý/à××ÐÔ":Ü$ S¿)¹)´mÔDó#FØIPô#QáÜ˜#“Yˆ
Ø× × Ð Ø12×1FÑ1FˆJÐ-Ñ.ð ×$Ñ$×&Ô&¨-ß Ü4Ð4Ù˜\¨:°×XaÑXaÔTaÔbˆFà#'ˆAÔ ÷ 'ð (3°X¸vÀhÕ?OÐQ_ÐamÐ4nÐ&oˆÐ"Ñ#ÙðFØ×$Ñ$×&Ô&¨-ß Ü4Ð4Ø#'ˆAÔ Ü.ØØØ!Øð !"§	¡	œMô ˆAÔ÷	 'Ñ&÷Y 
#×	"Ð	"ú÷F '×&ú÷ '×&Ð&ûô ô FÜ�bÔ8×9Ò9ØÜ˜r›7ˆÔÜ�‰Ð5°s¸4µyÀ"×EÒEûð	FúsN   ¥<PÍ.0P+Î;Q Ï:P>ÐQ ÐP(	Ð+P;	Ð>Q	Ñ	Q ÑQ ÑR-ÑAR(Ò(R-c                ót   € V ^8„  d   QhR\         R\        R\        \        \        ,          \        3,          /# )r4   r5   Úerr_textr6   )r8   rB   rn   r   )r:   s   "r0   r;   r;   g  s2   € ÷ #,ñ #,Ü	ð#,Üð#,ä
Œ8”C�=œ#ÐÕñ#,r<   c               óB  € \        \        V RR7      4      p\        W4      w  rVV'       d   R# Rp \        V \	        W4      \        V 4      ,           VVRR7      p\        V'       * ;'       d     VR8H  ;'       d    \        V RR7      '       * 4      p	\        VRV	VRRV P                  R	4      \        V P                  R
4      4      R7      p
V
R9   d   \        V4       Wz3#   \         d4   p\        T4      p\        P                  RT R,          T4        Rp?L¿Rp?ii ; i)zWFailure notice for a run that raised out of run_job. Returns (delivery_error, outcome).Tr‘  NrÎ  r—  rW   r’  Fr–  rÒ  )rB  rˆ  r‰  Únormalized_deliverrj  r"  Údelivery_queuedÚnotification_suppressed)NÚsuppressed_acked)Ú	deliveredÚnot_configured)r˜  r™  rì   rÔ  rÂ   rj   rX   rB   ræ   rª   r9   rš  rF  rA   rö   )r5   r¢  rÏ  rÐ  r¤  rj  rk  rB  Údelivery_excr‰  rE  s   &&$$       r0   rS  rS  g  s4  € ô 2Ô2FÀsÐX\Ô2]Ó^Ðä*FÀsÓ*UÑ'€NßØ'Ð'Ø€NðPÜ(Øô 1°Ó?ÔBWÐX[ÓB\Õ\ØØØô
ˆô ØÔ÷ 	Að 	AØ (Ñ*÷	Að 	Aä)¨#¸4Ô@Ô@óÐô
 2Ø%°dÐN_Ø-¸eÈUØŸ™Ð 6Ó7Ü $ S§W¡WÐ-SÓ%TÓ Uô	WÐð
 Ð:Ô:ÜÐ2Ô3ØÐ+Ð+øô ô PÜ˜\Ó*ˆÜ�‰Ð5°s¸4µyÀ,×OÑOûðPús   ±)C  Ã DÃ+)DÄDc                ó„   € V ^8„  d   QhR\         \        P                  \        \        P                  ,          3,          /# rÄ   ©rn   rÈ  ÚTokenr   )r:   s   "r0   r;   r;   Ž  s.   € ÷ &ñ &¤E¬+×*;Ñ*;¼XÄk×FWÑFWÕ=XÐ*XÕ$Yñ &r<   c                 óÒ   € ^ RI Hp Hp ^ RIHp ^ RIHp ^ RIHp \        \        4       4      pV! V4       V! V! V4      \        V4      R7      pV! 4       '       d	   V ! R4      MRpWg3# )uñ  Install the firing profile's secret scope for the span ``_run_one_job_body`` runs, delivery
included, and return the tokens ``_reset_fire_secret_scope`` needs.

Hydrate the profile's external secret sources BEFORE freezing the scope â€” the order
gateway/run.py and the external cron worker already use: ``build_profile_secret_scope`` only
READS the per-home source map, so a scope frozen first would carry no vault-backed value.

For a fire routed to a profile other than the process's own (``routed_profile_fire`` on the
fire's home â€” every entry point: ticker, dashboard Run now, CLI) also run under multiplex semantics â€” for
exactly this span and no wider. The desktop backend ticks every local profile from a process
that is not a multiplexer, so nothing else isolates that fire; and switching the context on
here rather than at the tick means no read is ever fail-closed without a scope to read â€” the
restart-safe handoff in ``run_one_job`` runs before this and keeps today's semantics (#107692).
)Úset_multiplex_contextÚset_secret_scope©Úrouted_profile_fire©Úhydrate_profile_secret_sources)Úowner_secret_scope©rZ  TN)Úagent.secret_scoper¯  r°  Úcron.scheduler_providerr²  r,  r´  Ú!tui_gateway.launch_profile_policyrµ  r   r£   rB   )r¯  r°  r²  r´  rµ  r¦   Úscope_tokenÚcontext_tokens           r0   Ú_install_fire_secret_scoper¼  Ž  s[   € ÷ KÝ;ÝDÝDäÔ Ó"Ó#€DÙ" 4Ô(Ù"Ñ#5°dÓ#;Ì#ÈdË)ÔT€KÙ3F×3HÒ3HÑ)¨$Ô/Èd€MØÐ%Ð%r<   c                óˆ   € V ^8„  d   QhR\         \        P                  \        \        P                  ,          3,          RR/# )r4   Útokensr6   Nr¬  )r:   s   "r0   r;   r;   ©  s6   € ÷ $ñ $¤U¬;×+<Ñ+<¼hÄ{×GXÑGXÕ>YÐ+YÕ%Zð $Ð_cñ $r<   c                óF   € ^ RI HpHp V w  r4Ve	   V! V4       V! V4       R# )uy   Undo ``_install_fire_secret_scope`` â€” the context first, so multiplex semantics never
outlive the scope they depend on.)Úreset_multiplex_contextÚreset_secret_scopeN)r·  rÀ  rÁ  )r¾  rÀ  rÁ  rº  r»  s   &    r0   Ú_reset_fire_secret_scoperÂ  ©  s&   € ÷ Oà!'Ñ€KØÒ Ù Ô.Ù�{Ö#r<   c               #  ób   "  € \        4       p  Rx € \        V 4       R#   \        T 4       i ; i5i)zL``_install_fire_secret_scope`` for the ``with`` block, reset on the way out.N)r¼  rÂ  )r¾  s    r0   rR  rR  ´  s(   é € ô (Ó)€Fð)Ûä  Ö(øÔ  Õ(üs   ‚/Ž ’/Ÿ,¬/c                óf   € V ^8„  d   QhR\         R\        R\        \        P                  ,          /# )r4   r5   r  r6   )r8   rB   r   rÈ  r­  )r:   s   "r0   r;   r;   ¾  s1   € ÷ Añ Aœ$ð A¬cð A´h¼{×?PÑ?PÕ6Qñ Ar<   c                ó°   € \         P                  P                  R4      V8X  d   \        V4      pM\	        V4      ;pf   R# \        YT;'       g    / 4      # )u¯   Win the run's ``claimed`` â†’ ``running`` CAS and bind its cron identity; ``None`` when the run
lost ownership first. A restart-safe worker already won it by adopting the row.r=  N)r\  rN  rA   r>  r@  r8  )r5   r  r˜  s   && r0   Ú_start_owned_runrÆ  ¾  sJ   € ô 
‡z�z‡~�~Ð4Ó5¸ÔEÜ˜|Ó,‰Ü*¨<Ó8Ð
8ˆ&Ò	AÙÜ °6·<°<¸RÓ@Ð@r<   c                ó0   € V ^8„  d   QhR\         R\        /# )r4   r5   r"  r7   )r:   s   "r0   r;   r;   È  s   € ÷ 
!ñ 
!¤Tð 
!´Dñ 
!r<   c                óp   € V'       d,   V P                  R4      '       g   \        V4      pVe   RVR3# WR3# )a'  An agent can finish its own turn after a delegated child has failed. Let it explicitly
declare that semantic failure so the existing failure path updates status, streaks, ledger,
and notification routing instead of recording a false healthy result.

Returns ``(success, error, agent_declared)``.r±   FT)rA   rR  )r5   r"  rª   r$  Úmarker_errors   &&&& r0   Ú_apply_agent_failure_markerrÊ  È  s=   € ÷ �s—w‘w˜z×*Ò*Ü1°.ÓAˆØÒ#Ø˜,¨Ð,Ð,Ø˜5Ð Ð r<   rI  rJ  rK  c                óÄ   € V ^8„  d   QhR\         R\        R\        \        ,          R\        \        ,          R\        \        ,          R\        \
        ,          R\        /# )r4   r5   r5  r;  rI  rJ  rK  r6   )r8   r9   r   rB   rf  rh  )r:   s   "r0   r;   r;   Õ  sh   € ÷ W8ñ W8Ü	ðW8Ü59ðW8äœ3•-ðW8ä4<Ô=MÕ4NðW8ô Ô/Õ0ðW8ô œfÕ%ð	W8ô
 
ñW8r<   c                óà  a a)€ \        S WV4      pVP                  p	VP                  p
VP                  pS P	                  R 4      pV'       g,   \        S R,          RS P	                  R4      R7      R,          p\        S VR7      o RpRpRpRpRp \        4       p\        S R,          4      '       gm   \        P                  RS P	                  R	S R,          4      4       \        VRR
R7        \        V4       Ve   \        V4       Ve   ^ RIHp V! V4       R# R# \!        S V4      pVfO   \        P#                  RS R,          4        \        V4       Ve   \        V4       Ve   ^ RIHp V! V4       R# R# ^ RIHp V! \'        4       4      p. o)R V)V 3R llpRS)RVR V/pVP(                  e   VP(                  VR&    \+        S 3/ VB w  ppppT! 4       '       dE   T! 4        \/        S Yœ4        \        T4       Te   \        T4       Te   ^ RIHp T! T4       R# R# \1        S TTT4      w  ppp\3        S TTTR7      p \5        TTTTYTTR7       TP:                  TP<                  ríT! 4        TP8                  '       d>   \/        S Yœ4        \        T4       Te   \        T4       Te   ^ RIHp T! T4       R# R# ^ RIH p T! TT4       T! 4       '       d½   TPC                  4       pTP:                  '       d9   TP<                  '       g'   T'       g   \        P#                  RS R,          4       MbT'       d   \        P#                  RS R,          4       \/        S Yœ4        \        T4       Te   \        T4       Te   ^ RIHp T! T4       R# R# \E        S R,          T4      '       dA   ^ RIH#p T! S YÎ4        \        T4       Te   \        T4       Te   ^ RIHp T! T4       R# R# ^ RIH$p T! TYœ4      \        T4       Te   \        T4       Te   ^ RIHp T! T4       # #   \,         d
    T! 4        h i ; i  \6         d    RTn         ELi ; i  TP:                  TP<                  ríT! 4        i ; i  \,         Edª   p ^ RI%H&p! \O        T T!4      '       dŒ   ^ RI(H)p" ^ RI%H*p# T#! S R,          T\W        T 4      4       T"! T\W        T 4      R7       \        PY                  R S R,          T 4        Rp ? \        T4       Te   \        T4       Te   ^ RIHp T! T4       R# R# \W        T 4      ;'       g    \[        T 4      P\                  p$\        PY                  R!S R,          T$\[        T 4      T T P^                  3R"7       R#p%\O        T \`        4      '       d=   T'       g5   \O        T \6        4      '       g   T! 4       '       g   \c        S T$YR$7      w  pp% \E        S R,          T4      '       gm   \e        S R,          4      '       gU   / p&T	e   T	T&R%&   \O        T \`        4      '       d   TT&R&&   ^ R'I3H4p' T'! S 4      '       d   RT&R(&   \k        S R,          RT$3/ T&B  M6  \`         d)   p(\        PY                  R)S R,          T(4        Rp(?(MRp(?(ii ; i \        TRT$T%R*7       M6  \`         d)   p(\        PY                  R+S R,          T(4        Rp(?(MRp(?(ii ; i\O        T \`        4      '       g   h  Rp ? \        T4       Te   \        T4       Te   ^ RIHp T! T4       R# R# Rp ? ii ; i  \        T4       Te   \        T4       Te   ^ RIHp T! T4       i i ; i),r  rW   r8  r9  r:  ©r  FNu6   Job '%s': one-shot dispatch limit reached â€” skippingrc   z3Dispatch claim rejected; execution was not started.r!  )Úreset_terminal_scopeTz;Cron job %s lost execution ownership before start; skipping)Úinstall_profile_terminal_scopec                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   Ú'_run_one_job_body.<locals>.__annotate__  s   € ÷ 	Añ 	A Dñ 	Ar<   c                  ó@   <€ S F  p \        V SR ,          4       K  	  R# )rW   N)rý  )Ú_deferred_agentÚ_deferred_agentsr5   s    €€r0   Ú_teardown_deferredÚ-_run_one_job_body.<locals>._teardown_deferred  s   ø€ ó $4�Ü$ _°c¸$µiÖ@ó $4r<   rî  r;  r)  )r5   r"  rª   rc  )rÏ  rÐ  r5  rK  )Úfail_empty_responsezkJob '%s': fire claim ownership lost after completed delivery; recording the delivered run's terminal statuszbJob '%s': transport cancellation arrived before terminal completion; recording the interrupted run)Úfinish_interrupted_run)Úfinish_completed_run)ÚCronExecutionUnknown)Úgive_up_execution)Úpause_for_unknown©r2  z,Cron %s paused with unverified admission: %szError processing job %s: %sr$  Ú
suppressedr?  rS  rB  r@  rC  z/Failed to record interrupted run for job %s: %srD  z0Failed to finish execution record for job %s: %s)6rr  rS   r}  r‚  rA   r<  r8   r¼  r+  ræ   r%  r=  r9  rÂ  Útools.terminal_scoperÎ  rÆ  r&  rÏ  r£   r)  r  r   rb  rÊ  r…  r   rp  rŠ  r‡  rB  Úcron.scheduler_bookkeepingr×  ry  rn  rØ  rÙ  rû  rÚ  r@   r!  rÛ  rÜ  rB   rª   r  rŠ   Ú__traceback__rX   rS  r4  r  rA  r2  )*r5   rÏ  rÐ  r5  r;  rI  rJ  rK  rŽ  rc  Ú_side_effect_fenceÚ_fire_claim_ownership_lostr  r‡  rB  Ú_fire_scope_tokensÚ_terminal_scope_tokenÚ_identity_tokenrÎ  rÏ  rÕ  Ú_run_kwargsr"  r5  r$  rª   rc  r�  r×  ry  rØ  rÙ  r  rÚ  rÛ  rÜ  Ú	_err_textrE  Úmark_kwargsrA  Ú
record_errrÔ  s*   f$$$$$$$                                 @r0   rL  rL  Õ  s3  ù€ ô ˜3 
Ó=€EØ—‘€JØ×0Ñ0ÐØ!&§¡Ðà—7‘7˜>Ó*€LßÜ'Ø��I˜h¸#¿'¹'ÐBVÓ:WôYØY]õ_ˆä
ˆs Ô
.€CØÐØ€NàÐØ ÐØ€OðA8ô
 8Ó9Ðô
 ˜c $�i×(Ò(Ü�K‰KØHØ—‘˜  D¥	Ó*ô,ô Ø eØKõMð ôT 	˜OÔ,ØÒ)Ü$Ð%7Ô8Ø Ò,ÝAá Ð!6Ö7ñ -ôO +¨3°Ó=ˆØÒ"Ü�N‰NÐXÐZ]Ð^bÕZcÔdØôB 	˜OÔ,ØÒ)Ü$Ð%7Ô8Ø Ò,ÝAá Ð!6Ö7ñ -õ}	,ñ !?Ô?OÓ?QÓ RÐð "$Ð÷	Añ 	Að #Ð$4Ø˜LØ˜Lð*ˆð ×ÑÒ)Ø*/×*<Ñ*<ˆK˜Ñ'ð	Ü5<¸SÑ5PÀKÑ5PÑ2ˆG�V˜^¨Uñ &×'Ò'ÙÔ Ü'¨¨ZÔFØôp 	˜OÔ,ØÒ)Ü$Ð%7Ô8Ø Ò,ÝAá Ð!6Ö7ñ -ôs *EÀSÈ'ÐSXÐZhÓ)iÑ&ˆ�˜ô ˜S¨'¸È~Ô^ˆð		!Ü!Ø�5˜.¨&¸8ÐX_Ø /õ1ð 23×1EÑ1EÀq×GWÑGW áÔ à×'×'Ð'ä'¨¨ZÔFØôF 	˜OÔ,ØÒ)Ü$Ð%7Ô8Ø Ò,ÝAá Ð!6Ö7ñ -õI 	CÙ˜A˜~Ô.á%×'Ò'ð
 #(×";Ñ";Ó"=ÐØ×#×#Ð#¨A×,<×,<Ð,<×EXÜ—‘ðDà˜•Iõ÷
 'Ü—N‘Nð8à˜D�	ô#ô ,¨C°ÔJØôX 	˜OÔ,ØÒ)Ü$Ð%7Ô8Ø Ò,ÝAá Ð!6Ö7ñ -ô[ % S¨¥Y°×@Ò@ÝIÙ" 3¨ÔEØôN 	˜OÔ,ØÒ)Ü$Ð%7Ô8Ø Ò,ÝAá Ð!6Ö7ñ -õQ 	DÙ# A zÓ@ôH 	˜OÔ,ØÒ)Ü$Ð%7Ô8Ø Ò,ÝAá Ð!6Õ7ð -øôI ô 	ñ Ô Øð		ûô( .ô 	0Ø+/ˆA×(ð	0ûð 23×1EÑ1EÀq×GWÑGW áÕ ûôL õ >ÝAÜ�aÐ-×.Ò.Ý9ÝBÙ˜c $�i¨´s¸1³vÔ>Ù˜l´3°q³6Õ:Ü�L‰LÐGÈÈTÍÐTUÔVÛôt 	˜OÔ,ØÒ)Ü$Ð%7Ô8Ø Ò,ÝAá Ð!6Ö7ñ -ôc ˜“F×.Ð.œd 1›g×.Ñ.ˆ	Ü�‰Ø)Ø��IØÜ˜1“g˜q !§/¡/Ð2ð	 	ô 	4ð
 (Ðô �qœ)×$Ò$ß&Ü˜qÔ"@×AÒAÙ.×0Ò0ä/EØ�Y¨ô0>Ñ,ˆNÐ,ð	cä-¨c°$­i¸×IÒIÜ5°c¸$µi×@Ò@à �ØÒ)Ø9C�KÐ 5Ñ6Ü˜a¤×+Ò+Ø4B�KÐ 0Ñ1Ý?Ù ×$Ò$à15�K Ñ.Ü˜S �Y¨¨yÑH¸KÒHùÜô 	cä�L‰LÐJÈCÐPTÍIÐWa×bÑbûð	cúð	dÜØ e°9ÐO_öaøäô 	dÜ�L‰LÐKÈSÐQUÍYÐXb×cÑcûð	dúä˜!œY×'Ò'ØÛô 	˜OÔ,ØÒ)Ü$Ð%7Ô8Ø Ò,ÝAá Ð!6Ö7ñ -ûðK>ûôD 	˜OÔ,ØÒ)Ü$Ð%7Ô8Ø Ò,ÝAá Ð!6Õ7ð -ús=  ÂAR Ä-R Å;AR ÇP3 ÇR Ç!R È%!R ÉQ
 É/R Ê	R ËR Ë"!R ÌR ÌR Ì%R Í)R Î(R Ï7R Ð3QÑR Ñ
Q ÑQ# ÑQ Ñ Q# Ñ# RÒR Ò\;ÒA/\6Ô\> Ô5\6ÕA+\6Ö3"\6×\6×(A*Y.ÙY.Ù-\6Ù.Z!Ù9ZÚ\6ÚZ!Ú!\6Ú%Z5Ú4\6Ú5[(Û [#Û\6Û#[(Û(\6Ü\> Ü6\;Ü;\> Ü>/]-Ústderr_pathc                ór   € V ^8„  d   QhR\         P                  R\        R\        \        ,          R\
        /# )r4   Úprocessr  rë  r6   )Ú
subprocessÚPopenrB   r   r   r9   )r:   s   "r0   r;   r;   ¯  sB   € ÷ F5ñ F5Ü×ÑðF5ô ðF5ô œ$•ð	F5ô
 
ñF5r<   c               ó&  a€ R V3R llp  V P                  RR7      p\        S4      pV'       d   VP                  R4      R9   d   R# ^ RIH	p V! V4      p\        SVR	7      '       g6   \        4        \        S4      pV'       d   VP                  R4      R9   d   R# R
p	Ve   ^ RIHp
 V
! V4      p	\        V V	 24      h  \        P                   d9    T! 4       '       g    KÝ  T P                  4       pTf   ^ RIHp T! T 4        R#  Lði ; i)a‹  Preserve ``run_one_job``'s synchronous contract after handoff.

The worker owns the durable execution and survives this gateway process.
The caller nevertheless waits while it remains alive so manual/background
callers do not release their in-process guard or report stale job state.
A gateway replacement may kill this waiter; it does not kill the scoped
worker or change its ledger ownership.
c                ó$   € V ^8„  d   QhR\         /# rÄ   rh  )r:   s   "r0   r;   Ú9_wait_for_external_cron_worker_body.<locals>.__annotate__½  s   € ÷ Kñ Kœ$ñ Kr<   c                  óp   <€ \        S4      p \        T ;'       d    V P                  R 4      \        9   4      # )r?  )r>  r9   rA   r:  )Úcurrentr  s    €r0   Ú_is_terminalÚ9_wait_for_external_cron_worker_body.<locals>._is_terminal½  s/   ø€ Ü Ó-ˆÜ�G×IÐI §¡¨HÓ 5Ô9IÑ IÓJÐJr<   TrÝ  rÃ  )Ú"reap_terminal_worker_in_backgroundr?  )Úexternal_worker_exited_reasonrÝ  r$   ©Úexternal_worker_stderr_tail)r&  r%  )rz  rî  ÚTimeoutExpiredÚpollrÌ  r÷  r>  rA   rQ  rø  rC  rA  r  rú  r  )rí  r  rë  rõ  Ú
returncoder÷  rô  rø  r2  Ústderr_tailrú  s   &d$        r0   Ú#_wait_for_external_cron_worker_bodyrÿ  ¯  s  ø€ ÷Kð Kð ð	Ø Ÿ™¨c˜Ó2ˆJô    Ó-ˆß�w—{‘{ 8Ó,Ð0GÔGÙõ 	Pá.¨zÓ:ˆÜ% l¸6×BÓBÜ*Ô,ô $ LÓ1ˆGß˜7Ÿ;™; xÓ0Ð4KÔKÙØˆØÒ"ÝNá5°kÓBˆKÜ˜f˜X k ]Ð3Ó4Ð4øô[ ×(Ñ(ô 	Ù—>’>Úð !Ÿ™›ˆJØÒ!Ý]á2°7Ô;Úñ	 "ð	ús   �C Ã!DÃ("DÄDc                   ó   € ] tR tRtRtRtR# )rP  iø  zIThe waiter failed after the worker was spawned and may own the execution.rù   Nrú   rù   r<   r0   rP  rP  ø  s   † ÝSr<   rP  r½   Úhandoff_filesc                óº   € V ^8„  d   QhR\         P                  R\        R\        \        ,          R\        \
        R3,          R\        \
        ,          R\        /# )r4   rí  r  r½   r  .rë  r6   )rî  rï  rB   r   rn   r   r9   )r:   s   "r0   r;   r;   ü  s]   € ÷ ñ Ü×Ñðô ðô ”S�Mð	ô
 œ˜s˜Õ#ðô œ$•ðô 
ñr<   c          	      ó¾  €  \        WVR 7      VeM   \        V4      p\        ;_uu_ 4        \        P	                  V4       \
        P	                  V4       RRR4       V F  p VP                  RR7       K  	  #   + '       g   i     L-; i  \         d     K<  i ; i  \         d   p\        \        T4      4      ThRp?ii ; i  Tea   \        T4      p\        ;_uu_ 4        \        P	                  T4       \
        P	                  T4       RRR4       M  + '       g   i     M; iT F(  p TP                  RR7       K    \         d     K&  i ; i	  i ; i))r  rë  NT©Ú
missing_ok)rÿ  r\  rŽ  rT  rÛ  rœ  Úunlinkr-  rX   rP  rB   )rí  r  r½   r  rë  Ú_keyr@  Ú
wait_errors   &$$$$   r0   Ú_wait_for_external_cron_workerr	  ü  s  € ðÜ2Ø¸Kô
ð ÒÜ  Ó(ˆDß–Ü,×4Ñ4°TÔ:Ü'×/Ñ/°Ô5÷ ó
 #ˆEðØ—‘¨�Ö-ò #÷ —ûô ô Úðûô ô OÜ-¬c°*«oÓ>ÀJÐNûðOûð ÒÜ  Ó(ˆDß–Ü,×4Ñ4°TÔ:Ü'×/Ñ/°Ô5÷ ——�úó
 #ˆEðØ—‘¨�Ö-øÜô Úðúò #ús|   ‚B  «+A;Á$BÁ;BÂBÂBÂ CÂ+C Ã CÃC ÃEÃ&+D	Ä	EÄD*Ä%EÄ3EÅEÅE	ÅEÅE	ÅEc                ó0   € V ^8„  d   QhR\         R\        /# r3   r7   )r:   s   "r0   r;   r;     s   € ÷ nñ n¤dð n¬tñ nr<   c                óH  € \        V R,          4      p\        V R,          4      p\        4       R,          R,          pW1 R2,          pW1 R2,          pW1 R2,          p\        P                  RR	R
\        V4      R\        V4      .p^ RIHp ^ RIHp	 ^ RIH	p
H
p ^ RIHpHpHp V! 4       ;'       g    V	! 4       p \        \!        4       P#                  R4      ;'       g    / P#                  RR4      4      pV! VRV RV 2VR7      pVP&                  R8X  d   R# \)        V4      f   \+        R4      h\-        V4        VP/                  R4       \2        P4                  ! V\2        P6                  \2        P8                  ,          \2        P:                  ,          R4      p \2        P<                  ! VRRR7      ;_uu_ 4       p\>        P@                  ! RV R\        \        4       PC                  4       4      RV/V4       VPE                  4        \2        PF                  ! VPI                  4       4       RRR4       \        4       PC                  4       p\O        4       ;_uu_ 4        T! T
! TR R"\        T4      /R#7      4      pRRR4       T! X4      pR6 F  pTPQ                  TR4       K  	  ^ R$I)H*p \W        \X        4      PC                  4       PZ                  PZ                  pT! TT4      pR%T\\        &    \2        P4                  ! T\2        P6                  \2        P8                  ,          \2        P^                  ,          R4      p \`        Pb                  ! TPd                  \        T4      T\`        Pf                  \`        Pf                  TR \i        4       R&7      p\2        Pj                  ! T4       \l        ;_uu_ 4        \n        Pq                  \s        T4      4       RRR4       \t        Pv                  ! 4       \x        ,           p\t        Pv                  ! 4       T8  Ed   TP{                  4       '       Ed    \>        P|                  ! TP                  R'R7      4      p TPM                  R R!7       \‡        T\ˆ        4      '       d   TP#                  R4      T8w  d(   \€        P‹                  R*T4       \…        TTTYF3TR)7      # \€        P�                  R+TTP#                  R,4      TTP&                  4       \�        TTP#                  R,4      ;'       g    TP�                  TP&                  R-8H  R.7       \…        TTTYF3TR)7      # TP“                  4       pTeº   \l        ;_uu_ 4        \n        P•                  \s        T4      4       RRR4       TPM                  R R!7       ^ R/IKHLp T! T4      pTPM                  R R!7       TP&                  R-8X  d1   T! T4      '       d#   \+        R0\2        Pš                  ! 4        R124      h\+        R2T R3T 24      h\t        Pœ                  ! R44       EK&  \€        PŸ                  R5T\x        4       \…        TTTYET3TR)7      #   \$         d    Rp ELti ; i  \0         d     EL-i ; i  + '       g   i     ELW; i  \J         d    TPM                  R R!7       h i ; i  + '       g   i     EL>; i  \2        Pj                  ! T4       i ; i  \J         d'    TPM                  R R!7       TPM                  R R!7       h i ; i  + '       g   i     ELC; i  \$         d=    \€        Pƒ                  R(T4       \…        TTTYF3TR)7      u TPM                  R R!7       # i ; i  TPM                  R R!7       i ; i  + '       g   i     EL; i)7u…  Launch *job* outside the managed gateway process when required.

Returns ``False`` outside a managed systemd gateway (in-process path).  In
managed topology the job always goes to an external worker with the #101940
ownership handoff: in a transient user scope, or â€” when no user D-Bus
session exists and ``cron.require_restart_safe_scope`` is false â€” as a
direct subprocess (process separation kept, cgroup isolation lost).

A fire routed to a profile other than the process's own is multiplexed at THIS boundary too.
``run_one_job`` switches the context on in ``_install_fire_secret_scope``, which runs AFTER
this handoff, so a routed desktop fire on the managed path serialized ``multiplex_active=False``
and built the worker environment with the launch profile's residue and no scrub (review on
f5f88d5058). Enable it for exactly this span; the worker then re-establishes it from the payload.
r  rW   r`   zexternal-workersz.jsonz.readyú.stderrz-mzcron.schedulerú--external-worker-fileú
--ack-file)Úis_multiplex_activer±  )Úbuild_subprocess_envÚstrip_launch_profile_env)Úrestart_safe_gateway_child_argvÚscoped_spawn_lost_user_busÚsystemd_user_bus_envÚrequire_restart_safe_scopeFzcron-z-exec-)Úunit_suffixr  Ú
in_processNz;cron execution claim changed before external worker handoffiÀ  é€  Úwr  r  r5   rZ  Úmultiplex_activeTr  ÚHERMES_HOME)Úscrub_secretsÚinherit_profile_homeÚextra)Úpin_hermes_tree_on_pythonpathr“  )r�  ÚenvÚstdinÚstdoutÚstderrÚstart_new_sessionÚcreationflagsrk  zhCron external worker %s published an unreadable acknowledgement; treating handoff as ownership-uncertain)r  r½   r  rë  z]Cron external worker acknowledgement mismatch for %s; treating handoff as ownership-uncertainzKCron job '%s' handed to restart-safe worker pid=%s execution=%s dispatch=%srÉ  Úscoped)rÊ  rù  zUrestart-safe systemd scope could not be created: the user D-Bus session at /run/user/z²/bus disappeared after the gateway started. On a system-level service install, run `sudo loginctl enable-linger <gateway-user>`; the next fire dispatches without scope isolation.zCcron external worker exited before ownership acknowledgement (exit r„   gš™™™™™©?zqCron external worker for job '%s' did not acknowledge within %.0fs; leaving the durable execution claim untouched)ÚHERMES_INTERACTIVEÚHERMES_GATEWAY_SESSIONÚHERMES_EXEC_ASK)PrB   r£   ÚsysÚ
executabler·  r  r¸  r²  Útools.environments.localr  r  Útools.process_registryr  r  r  r9   r   rA   rX   r  r?  r  r)  Úchmodr-  r\  r  ÚO_WRONLYÚO_CREATÚO_EXCLÚfdopenr  ÚdumprT  ÚflushÚfsyncÚfilenor   r  rR  rÚ  Úcron.scheduler_worker_envr  r   Ú__file__r  r   ÚO_TRUNCrî  rï  ÚargvÚDEVNULLr   r  rŽ  rT  rÌ  r\  r˜  rõ  r;  rÛ  ÚloadsÚ	read_textræ   r0  r	  r@   r8   rª   r%  rÍ  rÉ  rü  rÛ  r  rú  ÚgetuidÚsleepr&  ) r5   r  r½   Úhandoff_dirÚpayload_pathÚack_pathrë  rÆ  r  r²  r  r  r  r  r  r  r  ÚdispatchÚfdÚpayload_filerZ  Ú
worker_envÚ_presence_varr  Ú	repo_rootÚ	stderr_fdrí  ÚdeadlineÚacknowledgementrý  rú  rþ  s    &                               r0   rO  rO    s³  € ô �s˜>Õ*Ó+€LÜ��T•‹^€FÜ"Ó$ vÕ-Ð0BÕB€KØ >°Ð!7Õ7€LØ˜~¨VÐ4Õ4€Hà .°Ð 8Õ8€Kä�‰ØØØ ÜˆLÓØÜˆH‹ð€Gõ 7Ý;ßW÷ñ ñ +Ó,×EÐEÑ0CÓ0EÐð+Ü%)Ü!Ó#×'Ñ'¨Ó/×5Ð5°2×:Ñ:Ð;WÐY^Ó_ó&
Ð"ñ
 /ØØ˜F˜8 6¨,¨Ð8Ø#=ô€Hð
 ‡}�}˜Ô$Ùä% lÓ3Ò;ÜØIó
ð 	
ô �[Ô!ðØ×Ñ˜%Ô ô 
�Š�œrŸ{™{¬R¯Z©ZÕ7¼"¿)¹)ÕCÀUÓ	K€BðÜ�YŠY�r˜3¨×1Õ1°\Ü�IŠIà˜3Ø"¤CÔ(8Ó(:×(BÑ(BÓ(DÓ$EØ&Ð(8ðð
 ôð ×ÑÔ Ü�HŠH�\×(Ñ(Ó*Ô+÷ 2ô $Ó%×-Ñ-Ó/€Lô 
×	Õ	ñ .Ñ.BØ*Ø!%Ø ¤# lÓ"3Ð4ô/
ó ˆ
÷ 
ñ & jÓ1€Jó
ˆð
 	�‰�} dÖ+ñõ HÜ”X“×&Ñ&Ó(×/Ñ/×6Ñ6€IÙ.¨z¸9ÓE€JØ #€JŒ}ÑðÜ—G’G˜K¬¯©´r·z±zÕ)AÄBÇJÁJÕ)NÐPUÓVˆ	ð	 Ü ×&Ò&Ø—‘Ü˜	“NØÜ ×(Ñ(Ü!×)Ñ)Ø Ø"&Ü0Ó2ô	ˆGô �HŠH�YÔ÷ 
ŽÜ$×(Ñ(¬°vÓ)>Ô?÷ 
ô �~Š~ÓÔ"@Õ@€HÜ
�.Š.Ó
˜XÕ
%Ø�?‰?×Óð1Ü"&§*¢*¨X×-?Ñ-?ÈÐ-?Ó-UÓ"V‘ð —‘¨4�Ô0ä˜´×5Ò5Ø"×&Ñ& ~Ó6¸,ÔFä—‘ð>à ôô
 6ØØ!-Ø!Ø#/Ð"=Ø +ôð ô �K‰KØ]ØØ×#Ñ# EÓ*ØØ—‘ôô )ØØ×#Ñ# EÓ*×9Ð9¨g¯k©kØ'Ÿ}™}°Ñ8õô
 2ØØ)ØØ+Ð9Ø'ôð ð —\‘\“^ˆ
ØÒ!ß–Ü,×4Ñ4´]À6Ó5JÔK÷ à×Ñ¨4ÐÔ0ÝNÙ5°kÓBˆKØ×Ñ¨$ÐÔ/Ø�}‰} Ô(Ñ-GÈ
×-SÒ-Sô #ð!Ü!#§¢£ ð .HðHóð ô ðØ#˜ A k ]ð4óð ô 	�
Š
�4×ô ‡N�Nð	8àÜ&ô	ô *ØØ!ØØ#¨{Ð;Øôð øôm ô +Ø%*Ó"ð+ûô$ ô Úðú÷ 2×1Ð1ûô ô Ø×Ñ tÐÔ,Øðú÷ 
×	Ð	ûôR �HŠH�YÕûÜô Ø×Ñ tÐÔ,Ø×Ñ dÐÔ+Øðú÷
 
�ˆûô ô Ü× Ñ ð>à ôô
 6ØØ!-Ø!Ø#/Ð"=Ø +ôñ ð —‘¨4�Õ0ðûð —‘¨4�Õ0ú÷L —�úsÃ   Â<$Y Ã!Y Å Y0 Æ"!Z ÇA1ZÈ4Z É&Z8Ë8A[' Í	A[ Î[' Ï\Ð<&\/ Õ+^ÙY-Ù,Y-Ù0Y?Ù>Y?ÚZ	ÚZ ÚZ ÚZ5Ú8[		Û[$Û$[' Û'1\Ü\,	Ü/2]6Ý!]9 Ý5]6Ý6]9 Ý9^Þ^!	c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r4   rA  rB  r6   )r   r9   )r:   s   "r0   r;   r;   
  s&   € ÷ n3ñ n3¬tð n3¼tð n3Ìñ n3r<   c           
     óú
  €  \         P                  ! V P                  RR7      4      pVR,          p\        VR,          4      P	                  4       p\        VR,          4      p  T P                  RR7       ^ R
IHpHpHpHp	Hp
 ^ RIHp ^ RIHp ^ RIHpHp T! 4       pR;pp T! T4      p\1        TP3                  RR	4      4      pT	! T4       ^ RIHp T! 4        T! T4       T
! T! T4      \        T4      R7      p^ RIHp TP=                  R\>        P@                  R7       \C        T4      ;_uu_ 4        T! T4      fD   \        PE                  RT4        RRR4       Te	   T! T4       T	! T4       Te   T! T4       R	# R	#  TPF                  PI                  RRR7       TPK                  TPL                   R\N        PP                  ! 4        24      p\N        PR                  ! T\N        PT                  \N        PV                  ,          \N        PX                  ,          R4      p \N        PZ                  ! TRRR7      ;_uu_ 4       p\         P\                  ! R\N        PP                  ! 4       RT/T4       TP_                  4        \N        P`                  ! TPc                  4       4       RRR4       \N        Pd                  ! TT4       \N        Ph                  P3                  R4      pT\N        Ph                  R&    \k        TRRR	R7      p\l        Pn                  ! \        4      ;_uu_ 4        TPq                  R4      P                  RR7       RRR4       TTf"   \N        Ph                  Ps                  RR4       MT\N        Ph                  R&   uuRRR4       Te	   T! T4       T	! T4       Te
   T! T4       # #   \         d@    \        P                  RT 4         T P                  RR7       R	#   \         d     R	# i ; ii ; i  \         d     EL¢i ; i   T P                  RR7       i   \         d     i i ; i; i  + '       g   i     EL£; i  \f         d    TP                  RR7       h i ; i  \         dE    \        P                  RT4        RRR4       Te	   T! T4       T	! T4       Te   T! T4       R	# R	# i ; i  + '       g   i     EL†; i  Tf"   \N        Ph                  Ps                  RR4       i T\N        Ph                  R&   i ; i  + '       g   i     M; i Te	   T! T4       T	! T4       Te   T! T4       R# R#   Te	   T! T4       T	! T4       Te
   T! T4       i i ; i) zýAdopt and execute one gateway-dispatched cron payload.

The execution row is created by the gateway before spawn, then transferred
here before the ready acknowledgement is published.  No side effect runs
unless that durable ownership transfer succeeds.
rk  r  r5   rZ  r  z.Cron external worker could not load payload %sTr  F)Úbuild_profile_secret_scoper  rÁ  Úset_multiplex_activer°  )Úadopt_claimed_executionr³  )Úreset_hermes_home_overrideÚset_hermes_home_overrideNr  )Údiscover_pluginsr¶  )ÚGatewayStartupMixinz5Cron external worker: config hook registration failed)ÚlevelzUCron external worker refused execution %s: durable ownership could not be established)ÚparentsÚexist_okz.tmpr  r  r  rÉ  zCCron external worker could not publish ready acknowledgement for %sr=  ©rÏ  rÐ  r5  r  ):r  r<  r=  r   rT  rB   rX   ræ   r0  r  r-  r·  rN  r  rÁ  rO  r°  r!  rP  r,  r´  r$  rQ  rR  r9   rA   Úhermes_cli.pluginsrS  Úgateway.run_startuprT  Ú_register_config_hooksÚloggingÚWARNINGr6  rª   r  ÚmkdirÚ	with_namerc   r\  Úgetpidr  r/  r0  r1  r2  r3  r4  r5  r6  rY  r   rN  r^  r³  r´  Úwith_suffixrÚ  )rA  rB  Úpayloadr5   rZ  r  rN  r  rÁ  rO  r°  rP  r´  rQ  rR  Úprevious_multiplexÚ
home_tokenÚsecret_tokenr  rS  rT  Úack_tmp_pathrD  Úack_fileÚold_external_executionr&  s   &&                        r0   Ú_run_external_worker_payloadri  
  sÐ  € ðÜ—*’*˜\×3Ñ3¸[Ð3ÓIÓJˆØ�e�nˆÜ˜G NÕ3Ó4×<Ñ<Ó>ˆÜ˜3˜~Õ.Ó/‰ð
	Ø×Ñ¨4ÐÔ0÷õ õ 8ÝD÷ñ
 -Ó.ÐØ $Ð$€J�ðI3Ù-¨lÓ;ˆ
Ü §¡Ð,>ÀÓ FÓGÐÙÐ-Ô.õ
 	8áÔÙ& |Ô4Ù'Ñ(BÀ<Ó(PÔ_bÐcoÓ_pÔqˆõ
 	<à×2Ñ2ØCÌ7Ï?É?ð 	3ô 	\ä˜L×)Õ)Ù& |Ó4Ò<Ü—‘ð/à ôð
 ÷ *ð` Ò#Ù˜|Ô,ÙÐ/Ô0ØÒ!Ù& zÖ2ñ "ðWØ—‘×%Ñ%¨d¸TÐ%ÔBð  (×1Ñ1°X·]±]°OÀ4ÌÏ	Ê	ËÀ}Ð2UÓV�Ü—W’W˜\¬2¯;©;¼¿¹Õ+CÄbÇiÁiÕ+OÐQVÓW�ðÜŸš 2 s°W×=Õ=ÀÜŸ	š	 5¬"¯)ª)«+°~À|Ð"TÐV^Ô_Ø Ÿ™Ô(ÜŸš §¡Ó!2Ô3÷ >ô —J’J˜|¨XÔ6ô &(§Z¡Z§^¡^Ð4RÓ%SÐ"Ø9EŒB�J‰JÐ5Ñ6ðXÜ'¨°dÀÈuÔU�	ô  ×(Ò(¬×1Õ1Ø×(Ñ(¨Ó3×:Ñ:ÀdÐ:ÔK÷ 2à à)Ò1Ü—J‘J—N‘NÐ#AÀ4ÕHàAW”B—J‘JÐ=Ñ>÷] *Ñ)ð` Ò#Ù˜|Ô,ÙÐ/Ô0ØÒ!Ù& zÕ2ð "øôC ô Ü×ÑÐIÈ<ÔXØð	Ø×Ñ¨4ÐÖ0øÜô 	Úð	úðûô ô 	Úð	ûð	Ø×Ñ¨4ÐÕ0øÜô 	Ùð	ý÷v >×=Ð=ûô
 %ô Ø ×'Ñ'°4Ð'Ô8Øðûô ô Ü× Ñ ØYØ ôð ÷A *ð` Ò#Ù˜|Ô,ÙÐ/Ô0ØÒ!Ù& zÖ2ñ "ð1ú÷ 2×1Ð1ûð *Ò1Ü—J‘J—N‘NÐ#AÀ4ÕHàAW”B—J‘JÐ=Ò>ú÷] *×)úÐ)ð` Ò#Ù˜|Ô,ÙÐ/Ô0ØÒ!Ù& zÖ2ñ "øð Ò#Ù˜|Ô,ÙÐ/Ô0ØÒ!Ù& zÕ2ð "ús#  ‚A!N> Á%P Â%BU Ä8"TÅU ÆB Q<È(!QÉ	A#Q	Ê,QË2TË>1S"Ì/"S	Í	S"Í8TÎ
U Î>!PÏP Ï!O5 Ï5PÐPÐPÐP ÐPÐPÐQÐP2Ð1QÐ2Q Ð=QÐ?Q Ñ QÑQÑ	QÑQ9Ñ9Q<Ñ<!SÒTÒU Ò)U Ó
SÓTÓSÓ	S"Ó":TÔTÔT/	Ô*U Õ#U:c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   r;   {  s   € ÷ =ñ = tñ =r<   c                 óœ   €  ^ RI Hp  V ! 4       P                  4        R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)zøBest-effort: tell the active scheduler provider the job set changed. Call AFTER a successful
store mutation so an external provider can re-provision/cancel the one-shot; no-op for the
built-in. Kept out of cron/jobs.py (import cycle). Never raises.©Úresolve_cron_schedulerz!on_jobs_changed notify failed: %sN)r¸  rm  Úon_jobs_changedrX   ræ   rç   )rm  r  s     r0   Ú_notify_provider_jobs_changedro  {  s;   € ð=ÝBÙÓ ×0Ñ0Ö2øÜô =Ü�‰Ð8¸!×<Ò<ûð=ús   ‚ ŸAªAÁAc                   óf   a a€ ] tR tRt oRtV3R lV 3R lltV3R lR ltV3R lR ltR	tVt	V ;t
# )
ÚCronSchedulerRegistrationErrori†  zFA job was persisted but its first external trigger was not registered.c                ó*   <€ V ^8„  d   QhRS[ RS[RR/# )r4   r5   Úcauser6   N)r8   rX   )r:   r€   s   "€r0   r;   Ú+CronSchedulerRegistrationError.__annotate__‰  s"   ø€ ÷ 
ñ 
™Dð 
©ð 
°tñ 
r<   c                ó€   <€ Wn         W n        \        SV `  R VR,           R\	        V4      P
                   R24       R# )rU  rW   z:' was saved, but its first scheduler registration failed (zS). Do not create a duplicate. Pause/resume or update the job to retry registration.N)r5   rs  r…   r†   r  rŠ   )r‡   r5   rs  rˆ   s   &&&€r0   r†   Ú'CronSchedulerRegistrationError.__init__‰  sF   ø€ ØŒØŒ
Ü‰ÑØ˜˜T�˜ð $$Ü$(¨£K×$8Ñ$8Ð#9ð :OðOö	
r<   c                ó    <€ V ^8„  d   QhRS[ /# rÄ   rv   )r:   r€   s   "€r0   r;   rt  ’  s   ø€ ÷ 
ñ 
™cñ 
r<   c                óz   € V P                   P                  R4      ;'       g    V P                   R,          pRV R2# )zEHuman-facing variant for chat/CLI surfaces (no exception class name).rc   rW   zSaved cron job 'u¤   ', but couldn't register it with the external scheduler yet. The job is kept â€” don't re-create it; pause/resume or edit it (e.g. via /cron) to retry registration.)r5   rA   )r‡   rè  s   & r0   Úuser_messageÚ+CronSchedulerRegistrationError.user_message’  s<   € à—‘—‘˜VÓ$×6Ð6¨¯©°­ˆà˜u˜gð &Nð Nð	
r<   c                ó    <€ V ^8„  d   QhRS[ /# rÄ   rï   )r:   r€   s   "€r0   r;   rt  ›  s   ø€ ÷ #ñ #™ñ #r<   c           
     óN   € R\        V 4      RV P                  R,          RRRRRR/# )	zDReturn the public partial-failure contract without provider details.rª   r½   rW   Ú	job_savedTÚscheduler_registeredFÚretry_create)rB   r5   rk  s   &r0   Úto_dictÚ&CronSchedulerRegistrationError.to_dict›  s3   € ð ”S˜“YØ�d—h‘h˜t•nØ˜Ø" EØ˜Eð#ð 	#r<   )rs  r5   )rŠ   r‹   rŒ   r�   rŽ   r†   ry  r€  r�   r�   r‘   r’   s   @@r0   rq  rq  †  s+   ù‡ € ÙP÷
ó 
÷
ð 
÷#÷ #ð #r<   rq  c                ó$   € V ^8„  d   QhR\         /# rÄ   rï   )r:   s   "r0   r;   r;   ¥  s   € ÷ ñ ¼ñ r<   c                 óÎ   € ^ RI Hp ^ RIHp V! R/ V B pVP	                  RR4      '       g   V#  V! 4       P                  V4       V#   \         d   p\        Y44      ThRp?ii ; i)zHPersist one job and register its first trigger with the active provider.)Ú
create_jobrl  ÚenabledTNrù   )rË   r„  r¸  rm  rA   Úregister_jobrX   rq  )r  r„  rm  r5   rë   s   ,    r0   Ú&create_job_with_scheduler_registrationr‡  ¥  sj   € å$Ý>á
Ñ
�vÑ
€CØ�7‰7�9˜d×#Ò#Øˆ
ð@ÙÓ ×-Ñ-¨cÔ2ð €Jøô ô @Ü,¨SÓ6¸CÐ?ûð@ús   °A ÁA$ÁAÁA$g     Àr@c                ó:   € V ^8„  d   QhR\         \        ,          /# rÄ   )rO   rB   )r:   s   "r0   r;   r;   Ä  s   € ÷ !Kñ !K¤T¬#¥Yñ !Kr<   c                 ó(  € \        4       p \        P                  ! \        4      ;_uu_ 4        ^ RIHp V P                  V! 4       4       RRR4       \        P                  ! \        4      ;_uu_ 4        \        \        4      P                  4       P                  P                  pVR,          P                  4       '       d   V P                  \        V4      4       RRR4       \        P                  ! \        4      ;_uu_ 4        ^ RIHp V! 4        FÝ  p\        VP!                  R4      ;'       g    R4      P#                  4       pV'       d    \        V4      P%                  4       '       g   K^   \&        P(                  ! . RORRRR	^VR
R7      pVP*                  ^ 8X  dN   VP,                  P#                  4       '       d,   V P                  VP,                  P#                  4       4       KÛ  KÝ  Kß  	  RRR4       \/        V 4       Uu. uF-  p\        V4      R,          P%                  4       '       g   K+  VNK/  	  up#   + '       g   i     EL ; i  + '       g   i     EL�; i  \         d     EKc  i ; i  + '       g   i     LŽ; iu upi )zÞRepos whose ``.worktrees/`` to keep pruned: the hermes checkout, job workdir repo roots and
every repo this profile created a worktree in (``worktree_registry``), filtered to those that
actually have a ``.worktrees/`` dir.)Úregistered_reposNz.gitr§  r  r$   Tr  rY  F)Úcapture_outputr¾   r  Úerrorsrä  r�  Úcheckz
.worktrees)Úgitz	rev-parsez--show-toplevel)r  r³  r´  rX   Úhermes_cli.worktree_registryrŠ  rW  r   r8  rT  r  rÛ  rÌ  rB   rË   r¨  rA   r&   r  rî  rË  rý  r"  r  )ÚreposrŠ  Úinstall_rootr¨  r5   r  Úproberj  s           r0   Ú_worktree_maintenance_reposr“  Ä  sÇ  € ô “€Eä	×	Ò	œY×	'Õ	'ÝAØ�‰Ñ%Ó'Ô(÷ 
(ô
 
×	Ò	œY×	'Õ	'ÜœH“~×-Ñ-Ó/×6Ñ6×=Ñ=ˆØ˜6Õ!×)Ñ)×+Ò+Ø�I‰I”c˜,Ó'Ô(÷ 
(ô
 
×	Ò	œY×	'Õ	'Ý'á–;ˆCÜ˜#Ÿ'™' )Ó,×2Ð2°Ó3×9Ñ9Ó;ˆGß¤$ w£-×"6Ñ"6×"8Ò"8ÙðÜ"ŸšÚ;Ø#'¨d¸WØ$¨a°WÀEôK�ð ×#Ñ# qÔ(¨U¯\©\×-?Ñ-?×-AÒ-AØ—I‘I˜eŸl™l×0Ñ0Ó2Ö3ñ .BÑ(ñ ÷ 
(ô" ˜e”}ÓJ‘}�!¬¨a«°<Õ)?×(GÑ(G×(I�AˆA‘}ÑJÐJ÷7 
(×	'Ð	'ú÷
 
(×	'Ð	'ûô& ô Ûðú÷ 
(×	'üò" Ksg   ­IÁ4A)IÄ-I<Ä5I<Å!I<Å4AI)Ç)I)Ç.I<È(JÈ8JÉI	ÉI&	É)I9	É4I<É8I9	É9I<É<J	c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   r;   è  s   € ÷ %*ñ %*¨ñ %*r<   c                 óØ  € ^ RI p ^ RIHp \        V! 4       4      p\        P
                  ! 4       p\        ;_uu_ 4        \        ;'       g    / pVP                  V4      pVe   W5,
          \        8  d    RRR4       R# / VCW#/CsRRR4       R R lp\        P                  ! V P                  ! 4       P                  V3RRR7      P                  4        R#   + '       g   i     LZ; i)aö  Throttled worktree prune from the cron tick, on a daemon thread so the tick never waits on
git. Same pruner as ``hermes -w`` startup (idle dirty/unpushed trees archived before removal,
live trees untouched). Throttled per profile home: a multiplexed tick runs once per served
profile, and each must sweep its own registered repos under its own config. The thread runs in
a copy of the caller's context so the profile-home override travels with it. Errors never
propagate: GC is hygiene, not scheduling.N)r   c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   Ú5_maybe_run_worktree_maintenance.<locals>.__annotate__ý  s   € ÷ Mñ M�$ñ Mr<   c                  ó  €  \        4       p V '       g   R # ^ RIHp V  F  p V! V4       K  	  R #   \         d    \        P                  RTRR7        K8  i ; i  \         d    \        P                  RRR7        R # i ; i)N)Ú_prune_stale_worktreesz'Cron worktree maintenance failed for %sTr$  z!Cron worktree maintenance skipped)r“  Úhermes_cli.worktree_opsr™  rX   ræ   rç   )r�  r™  Úrepos      r0   Ú_runÚ-_maybe_run_worktree_maintenance.<locals>._runý  sy   € ð	MÜ/Ó1ˆEßÙÝFã�ðaÙ*¨4Ö0ó øô !ô aÜ—L‘LÐ!JÈDÐ[_�L×`ðaûäô 	MÜ�L‰LÐ<ÀtˆL×Lð	Mús6   ‚A –A ¢0ªA °#AÁA ÁAÁA Á"B Á?B zcron-worktree-pruneT)rñ  r  rc   rò  )rÈ  r$  r   rB   r˜  rõ  Ú_worktree_maintenance_lockÚ_last_worktree_maintenance_atrA   Ú&_WORKTREE_MAINTENANCE_INTERVAL_SECONDSrô  rö  rÉ  rË  r÷  )rÈ  r   r¦   r   ÚstampsrÙ   rœ  s          r0   Ú_maybe_run_worktree_maintenancer¢  è  s·   € ó å0ä‰Ó Ó!€DÜ
�.Š.Ó
€Cß	#Ö	#Ü.×4Ð4°"ˆØ�z‰z˜$ÓˆØÒ ¥
Ô-SÔ SØ÷	 
$Ñ	#ð
 )>¨6Ð(=°4Ñ(=Ð%÷ 
$õMô ×Ò˜K×4Ò4Ó6×:Ñ:À$ÀÐOdØ ô"ß"'¡%¦'÷/ 
$×	#ús   ¾8CÂ CÃC)	c                ó  € Rp \        V RRR7      p\        '       d=   \        P                  ! V\        P                  \        P                  ,          4       V# \
        '       d5   \
        P                  ! VP                  4       \
        P                  ^4       V#   \         dã   pTe|   \        P                  ! \        4      ;_uu_ 4        TP                  4        RRR4       M  + '       g   i     M; i\        T4      '       d   \        P                  R4        Rp?R# \!        T4      '       d   \        P#                  RT4       h TP$                  \&        P(                  9  d   \        P#                  RT4       h Rp?ii ; i)u  Open + non-blocking lock the tick file (fcntl / msvcrt). Returns the fd, or None on genuine
contention. A real OSError (esp. EMFILE/ENFILE) must NOT pass as contention â€” the scheduler
would look healthy while no job runs â€” so it is re-raised for the ticker to record a FAILED
tick.Nr  r  r  u0   Tick skipped â€” another instance holds the lockuj   Cron tick could not acquire tick lock: %s â€” scheduler will attempt fd reclamation and retry with backoffz)Cron tick could not acquire tick lock: %s)r  r±  ÚflockÚLOCK_EXÚLOCK_NBrµ  Úlockingr6  ÚLK_NBLCKr-  r³  r´  r  r·  ræ   r%  rÁ  rª   r°  r7  ÚUNWRITABLE_ERRNOS)Ú	lock_fileÚlock_fdrë   s   &  r0   Ú_acquire_tick_lockr¬    s  € ð
 €Gðô �y #°Ô8ˆß‹5Ü�KŠK˜¤§¡´·±Õ!>Ô?ð ˆ÷ ‹VÜ�NŠN˜7Ÿ>™>Ó+¬V¯_©_¸aÔ@ØˆøÜô ØÒÜ×$Ò$¤W×-Õ-Ø—‘”÷ .×-×-Ð-úä(¨×-Ò-Ü—‘ÐNÔOÝÜ˜S×!Ò!ä�L‰Lð@àôð 	ð �Y‰Yœl×<Ñ<Ô<Ü�L‰LÐDÀcÔJØûðúsC   „AB ÁB Á&5B ÂF	Â'&FÃC'Ã	FÃ'C7Ã2.FÄ&AFÆF	c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   r;   4  s   € ÷ ñ  4ñ r<   c                 ó  € \         '       dX   \        P                  ! \        \        34      ;_uu_ 4        \         P
                  ! V \         P                  4       R R R 4       Mq\        '       df   \        P                  ! \        \        34      ;_uu_ 4        \        P                  ! V P                  4       \        P                  ^4       R R R 4       V P                  4        R #   + '       g   i     L"; i  + '       g   i     L5; ir?   )r±  r³  r´  r-  ÚIOErrorr¤  ÚLOCK_UNrµ  r§  r6  ÚLK_UNLCKr  )r«  s   &r0   Ú_release_tick_lockr²  4  s�   € ßƒuÜ× Ò ¤'¬7Ð!3×4Õ4Ü�KŠK˜¤§¡Ô/÷ 5Ð4ç	‹Ü× Ò ¤'¬7Ð!3×4Õ4Ü�NŠN˜7Ÿ>™>Ó+¬V¯_©_¸aÔ@÷ 5à‡M�M†O÷ 5×4ú÷ 5×4ús   µ&C'Â5C:Ã'C7	Ã:D
	c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   r;   >  s   € ÷ Kñ K ñ Kr<   c                 óz  € \        \        4       4      p \        P                  ! 4       p\        P                  V 4      pVe   W,
          \        8  d   R# T\        V &    ^ RIHp V! 4       pV'       d   \        P                  RV4       R# R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)a  Dead-owner reclaim: a run that died mid-flight would leave its row 'claimed' forever. Rows
whose owner process is proved gone are released (_owner_is_live), as are rows whose live owner
holds a claim older than the derived stale bound (the process is not killed). Throttled.N)rA  ziReclaimed %d cron execution(s) whose owner process died before reaching a terminal state (marked unknown)z'Dead-owner execution reclaim failed: %s)r   r£   r˜  rõ  Ú_last_dead_owner_reap_atrA   Ú!_DEAD_OWNER_REAP_INTERVAL_SECONDSr!  rA  ræ   r&  rX   rç   )Ú	_reap_keyÚ	_reap_nowÚ
_last_reaprA  Ú
_reclaimedÚ	_reap_excs         r0   Ú_maybe_reap_dead_ownersr¼  >  s¢   € ô  Ô 0Ó 2Ó3€IÜ—’Ó €IÜ)×-Ñ-¨iÓ8€JàÒØÕ"Ô%FÔFáØ*3Ô˜YÑ'ð
KÝBá3Ó5ˆ
ßÜ�N‰NðDàöñ øô
 ô KÜ�‰Ð>À	×JÒJûðKús   ÁB Á4B ÂB:ÂB5Â5B:c                ó(   € V ^8„  d   QhR\         RR/# )r4   r=  r6   N©rO   )r:   s   "r0   r;   r;   ^  s   € ÷ >ñ >¬Tð >°dñ >r<   c           	     ó¸  a€ \        \        4       4      o\        ;QJ d#    V3R l\         4       F  '       g   K   RM	  RM! V3R l\         4       4      '       g   R# T p\        P
                  ! \        4      ;_uu_ 4        \         Uu0 uF  q"^ ,          S8X  g   K  V^,          kK  	  ppV  Uu0 uF,  p\        V\        4      '       g   K  VP                  R4      kK.  	  ppW58:  g   ^ RI
Hp V! 4       pRRR4        \        V4       R# u upi u upi   + '       g   i     L(; i  \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)z¬Bound the in-flight set BEFORE the dedup guard so a leaked claim is force-released now
rather than eating every later fire until restart. Skipped when nothing is in flight.c              3   ó:   <"  € T F  q^ ,          S8H  x € K  	  R# 5i)ry  Nrù   )rC   r‹  rC  s   & €r0   rE   Ú1_sweep_stale_inflight_for_tick.<locals>.<genexpr>b  s   øé € ÐAÑ0@¨�1�v˜Ö$Ó0@ùs   ƒTFNrW   r§  z Stale in-flight sweep failed: %s)r   r£   rJ   r�  r³  r´  rX   r@   r8   rA   rË   r¨  rI  ræ   r&  )	r=  Ú_sweep_jobsr‹  Ú_inflight_idsrº  Ú_due_idsÚ_load_all_jobsr  rC  s	   &       @r0   Ú_sweep_stale_inflight_for_tickrÆ  ^  sõ   ø€ ô "Ô"2Ó"4Ó5€Kß‹3ÔAÕ0@ÓA�3�3Š3ÔAÕ0@ÓA×AÒAÙØ€KÜ	×	Ò	œY×	'Õ	'Ý+;ÓUÑ+; CÀ1½vÈÑ?Tœ˜˜QŸ˜Ñ+;ˆÐUÙ)1ÓI© A´ZÀÄ4×5H”K�A—E‘E˜$–K©ˆÐIØÔ(Ý=á(Ó*ˆK÷ 
(ð>Ü˜[Ö)ùò VùÚI÷ 
(×	'ûô ô >Ü�‰Ð9¸1×=Ò=ûð>úsN   Â	DÂDÂ DÂ-DÂ3DÃDÃ%DÄD- Ä
DÄD*	Ä-EÄ8EÅEc                ó:   € V ^8„  d   QhR\         \        ,          /# rÄ   )r   re   )r:   s   "r0   r;   r;   r  s   € ÷ ñ ¤x´¥}ñ r<   c                 ó.  €  \        R4      P                  4       p V '       d   \        V 4      ;'       g    R#  \        P                  ! \        4      ;_uu_ 4        \        4       ;'       g    / p\        V\        4      '       d   VP                  R/ 4      M/ P                  R4      pVe    \        V4      ;'       g    RuuRRR4       #  RRR4       R#   \        \        3 d    \
        P                  R4        LÆi ; i  + '       g   i     R# ; i)zXMax workers: env > config.yaml > unbounded (HERMES_CRON_MAX_PARALLEL=1 restores serial).ÚHERMES_CRON_MAX_PARALLELNz?Invalid HERMES_CRON_MAX_PARALLEL value; defaulting to unboundedr`   Úmax_parallel_jobs)r   r&   re   r(   rÖ   ræ   r&  r³  r´  rX   r   r@   r8   rA   )Ú_env_parrâ  Ú_cfg_pars      r0   Ú_resolve_max_parallel_workersrÍ  r  sß   € ðZÜ#Ð$>Ó?×EÑEÓGˆßÜ�x“=×(Ð( DÐ(ð ô 
×	Ò	œY×	'Õ	'Ü“×#Ð# ˆÜ-7¸¼t×-DÒ-D�E—I‘I˜f bÔ)È"×QÑQÐReÓfˆØÒÜ�x“=×(Ð( D÷	 
(Ò	'ð  ÷ 
(ñ
 øô œ	Ð"ô ZÜ�‰ÐXÖYðZúç	'Ö	'ñ
 ús)   ‚2C µC ÁA#DÂ?DÃ&D Ã?D ÄD	c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   r;   ‚  s   € ÷ Dñ D˜Dñ Dr<   c                 ó€   €  ^ RI Hp  V ! 4        R#   \         d"   p\        P	                  RT4        Rp?R# Rp?ii ; i)z’Reap MCP stdio orphans (only PIDs flagged by tools.mcp_tool._run_stdio's finally block);
run AFTER jobs finish so live sessions are never touched.)Ú_kill_orphaned_mcp_childrenz'Post-tick MCP orphan cleanup failed: %sN)Útools.mcp_tool_lifecyclerÐ  rX   ræ   rç   )rÐ  Ú_es     r0   Ú_sweep_mcp_orphansrÓ  ‚  s5   € ðDÝHÙ#Ö%øÜô DÜ�‰Ð>À×CÒCûðDús   ‚ ‘=œ8¸=c                ó<   € V ^8„  d   QhR\         R\        R\        /# )r4   r5   r5  r6   r7   )r:   s   "r0   r;   r;   Œ  s&   € ÷ Sñ Sœ$ð S¼ð SÄ$ñ Sr<   c           	     óŒ  €  \        V R,          RR7      pT'       g   \        T R,          RRR7       R# \        T\        4      '       d   \        T4      M
\        T 4      pT R,          TR&   T P	                  R4      TR&   \        YaY#R7      #   \         dh   p\        P                  ! TRT P	                  R4      ;'       g
    T R,           R2RT .4       \        T R,          T R,          R	T 24        R
p?R# R
p?i\         d;   p\        T R,          T R,          R\        T4      P                   RT 24       h R
p?ii ; i)z4Run one due job via the shared ``run_one_job`` body.rW   T)Ú
return_jobzskipped job 'rc   Ú'r1  r  z$Cron store unwritable; not started: NFzFire claim failed: rõ  z+Fire claim lost; execution was not started.r!  r9  rX  )r,  r-  r7  Únote_unwritablerA   rB  r   r  rŠ   r=  r@   r8   r^  )r5   rÏ  rÐ  r5  Úclaimedrë   Úclaimed_jobs   &&&&   r0   Ú_process_due_jobrÛ  Œ  s3  € ð
Ü$ S¨¥Y¸4Ô@ˆ÷ ÜØ�Õ¨Ð6cõ	eáä#-¨g´t×#<Ò#<”$�w”-Ä$ÀsÃ)€KØ"% nÕ"5€K�ÑØ(+¯©Ð0DÓ(E€KÐ$Ñ%Ü�{¸DÔRÐRøô# ô Ü×$Ò$ S¨M¸#¿'¹'À&»/×:VÐ:VÈSÐQUÍYÐ9WÐWXÐ*YÐ[bÐehÐdiÔjÜ"Ø�Õ  T¥Ð.RÐSVÐRWÐ,Xô	ZåûÜô Ü"Ø�Õ  T¥Ð.AÄ$ÀsÃ)×BTÑBTÐAUÐUWÐX[ÐW\Ð,]ô	_àûðús*   ‚B ÂEÂAC;Ã;EÄEÄ	5D>Ä>Ec                óX   € V ^8„  d   QhR\         R\        P                  P                  /# )r4   r5   r€  )r8   ru  rv  rw  )r:   s   "r0   r;   r;   ¥  s*   € ÷ `ñ `œDð `¬
×(:Ñ(:×(MÑ(Mñ `r<   c           	     óÒ  a aaaa€ S R,          oS P                  RS4      oR V VV3R llpR V3R llp\        4       '       d   V! 4        V! 4        R# \        4       o\        SSR7      '       g   \        P                  R	S4       R# \        4       pRp \        SR
S P                  R4      R7      p\        S VR,          R7      p\        V4       \        P                  ! 4       pYxT3TT3R llp
 TP%                  T
4      p\.        ;_uu_ 4        \1        ST4      p\2        P                  T4      SJ d
   T\4        T&   RRR4       T#   \         dp   p	\        STSR7       T! 4        Te.   \        TR,          SR\        T	4      P                    RT	 24       \        P#                  RSTf   RMRT	4        Rp	?	R# Rp	?	ii ; i  \         d   p\        STSR7       T! 4        \'        TR,          RRT 2R7       \)        T\*        4      '       d   \        T4      '       d	   T! 4        M\        P-                  RST4        Rp?R# Rp?ii ; i  + '       g   i     T# ; i)z‘Submit with the in-flight dedup guard; None if a prior tick's run is still in flight.
Running-set membership is released in the worker's finally.rW   rc   c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   Ú(_submit_with_guard.<locals>.__annotate__«  s   € ÷ &ñ &¨$ñ &r<   c                 óþ   <€ SP                  R4      p \        V \        4      '       d   V P                  R4      R8X  g   R#  \        S4       R#   \         d#   p\
        P                  RST4        Rp?R# Rp?ii ; i)uP  Best-effort claim cleanup on dispatch-failure paths. Only one-shots carry a run_claim;
clear_run_claim takes _jobs_lock + full load/save and can raise on degraded paths
(shutdown, EMFILE) â€” a claim expiring at TTL beats crashing the tick.

Only one-shot jobs carry a ``run_claim`` (stamped by get_due_jobs, #59229), so recurring jobs skip
the call entirely â€” clear_run_claim acquires _jobs_lock (blocking cross-process flock) and does a
full load_jobs read, and the dispatch-failure paths fire exactly when the process can least afford N
pointless lock/read round-trips (interpreter shutdown, EMFILE).  clear_run_claim itself does
load_jobs/save_jobs file I/O; on those degraded paths it can raise, and these early-exits exist
precisely to skip cleanly â€” a stale claim expiring at the TTL is a better outcome than crashing the
tick (#86522).
r^   r_   ré  Nz\Could not clear run_claim for job '%s' after dispatch failure: %s (claim will expire at TTL))rA   r@   r8   r.  rX   ræ   r&  )Ú	_scheduleÚ	claim_errr5   r½   Ú	job_labels     €€€r0   Ú_clear_run_claim_best_effortÚ8_submit_with_guard.<locals>._clear_run_claim_best_effort«  sk   ø€ ð —G‘G˜JÓ'ˆ	Ü˜9¤d×+Ò+°	·±¸fÓ0EÈÔ0OÙð	&Ü˜FÖ#øÜô 	&Ü�N‰Nð9à˜9÷&ò &ûð	&ús   ÁA ÁA<ÁA7Á7A<c                ó   € V ^8„  d   QhRR/# rl   rù   )r:   s   "r0   r;   rß  Ã  s   € ÷ ^ñ ^ dñ ^r<   c                  ó4   <€ \         P                  R S 4       R# )u8   Job '%s' not dispatched â€” interpreter is shutting downNr.  )rã  s   €r0   Ú_not_dispatched_shutdownÚ4_submit_with_guard.<locals>._not_dispatched_shutdownÃ  s   ø€ Ü�‰ÐQÐS\Ö]r<   N)rS   u%   Job '%s' already running â€” skippingÚbuiltinr9  r:  rÍ  ©r¦   rS   zDispatch preparation failed: rõ  z&Job '%s' not dispatched: %s failed: %szexecution creationzdispatch preparationc                 óˆ   <€  VP                  SV 4      \        V R ,          VSR7       #   \        T R ,          TSR7       i ; i)rW   rë  )rË  rÜ  )rº  Úctxr¦   Úprocess_jobÚregistration_owners   &&&€€r0   Ú_run_and_releaseÚ,_submit_with_guard.<locals>._run_and_releaseî  s;   ø€ ð	NØ—7‘7˜;¨Ó*ä  $¥¨dÐ:LÖMøÔ  $¥¨dÐ:LÖMús	   ƒ* ªAFzExecutor dispatch failed: r!  zJob '%s' not dispatched: %s)rA   r¤  rh  r×  ræ   r%  r£   r<  r8   r   rÈ  rÉ  rX   rÜ  rB  r  rŠ   r0  rÊ  r=  r@   r  rª   rŽ  r\  rÕ  rÔ  )r5   r€  rî  rä  rè  Ú_claim_homerV  Údispatched_jobÚ_ctxÚexecution_errrð  r#  Ú
submit_errÚ_submit_keyr½   rã  rï  s   f&f           @@@r0   Ú_submit_with_guardrø  ¥  s3  ü€ ð ��Y€FØ—‘˜ Ó'€I÷&ò &÷0^ð ^ô "×#Ò#Ù Ô"Ù$Ô&ÙÜ›ÐÜ# FÐ2D×EÓEÜ�‰Ð;¸YÔGÙô #Ó$€Kà€IðÜ$Ø˜9¸¿¹Ð@TÓ8UôWˆ	ä˜c°	¸$µÔ@ˆÜ˜NÔ+Ü×'Ò'Ó)ˆð *¸+÷ Nð NðØ�k‰kÐ*Ó+ˆ÷ 
ŽÜ# F¨KÓ8ˆÜ'×+Ñ+¨KÓ8Ð<NÓNØ,/Ô˜[Ñ)÷ 
ð €JøôG ô 
ä˜F¨Ð<NÕOÙ$Ô&ØÒ Ü& y°¥¸Ø/´°]Ó0C×0LÑ0LÐ/MÈRÐP]ÈÐ_ôbä×ÑÐAÀ9Ø1:Ò1BÑ-ÐH^Ø&ô	(õ ûð
ûô( ô 	Ü˜F¨Ð<NÕOÙ$Ô&ÜØ�d�O UÐ4NÈzÈlÐ2[õ	]ä�j¤,×/Ò/Ô4NÈz×4ZÒ4ZÙ$Õ&ä�L‰LÐ6¸	À:ÔNÝûð	ú÷ 
Žð €Jús?   ÂAE Ã4G	 Ä/IÅGÅA$GÇGÇ	IÇA3IÉIÉI&	c                ó(   € V ^8„  d   QhR\         RR/# )r4   rv  r6   Nr¾  )r:   s   "r0   r;   r;     s   € ÷ 'ñ '¬dð '°tñ 'r<   c                óŽ   a€ V '       g   \        4        R# \        V 4      .oR V3R llpV  F  pVP                  V4       K  	  R# )zšAsync (gateway ticker) mode: sweep via a done-callback after the LAST job completes; sweep
inline when nothing was dispatched (all skipped / no due jobs).Nc                óP   € V ^8„  d   QhR\         P                  P                  RR/# )r4   Ú_fr6   N)ru  rv  ÚFuture)r:   s   "r0   r;   Ú6_sweep_mcp_orphans_when_all_done.<locals>.__annotate__  s&   € ÷ 	!ñ 	!”Z×'Ñ'×.Ñ.ð 	!°4ñ 	!r<   c           	      ód  <€ S^ ;;,          ^,          uu&   \         P                  ! \        4      ;_uu_ 4        V P                  4       pVe.   \        P                  RV\        V4      WP                  3R7       RRR4       S^ ,          ^ 8:  d   \        4        R# R#   + '       g   i     L,; i)ry  Nz(Cron job future failed in async mode: %sr$  )	r³  r´  rX   r0  ræ   rª   r  rá  rÓ  )rü  Ú_excÚ
_remainings   & €r0   Ú_on_doneÚ2_sweep_mcp_orphans_when_all_done.<locals>._on_done  sƒ   ø€ Ø�1�˜Õ‹Ü× Ò ¤×+Õ+Ø—<‘<“>ˆDØÒÜ—‘Ø>ÀÜ" 4›j¨$×0BÑ0BÐCð ô E÷ ,ð �a�=˜AÔÜÖ ñ ÷ ,×+ús   ¹ABÂB/	)rÓ  r»   rÍ  )rv  r  rü  r  s   &  @r0   Ú _sweep_mcp_orphans_when_all_doner    s@   ø€ ÷ ÜÔÙÜ�g“,�€J÷	!ð 	!ó ˆØ
×Ñ˜XÖ&ó r<   )r  )rÔ  r™  r˜  r§  rš  )rÇ  r/  r0  )
rþ  r`  ra  rÿ  r   r  r.  rl  r·  r1  )r�  r€  rx  r¸  r–  ry  Ú__main__r  )Úadd_helpT)r  Úrequiredr  )Úsetup_loggingr`   )rª  r  )r5  Úheadlessc                ó˜  € V ^8„  d   Qh/ ^ \         9   d/   \        \        \        P                  P
                  3,          ;R&   ^\         9   d&   \        \        \        \        ,          3,          ;R&   ^\         9   d   \        \        \        3,          ;R&   ^\         9   d
   \        ;R&   ^\         9   dH   \        \        \        \        \        \        \        ,          \        3,          3,          3,          ;R&   ^\         9   d
   \        ;R&   ^\         9   d   \        \        \        3,          ;R&   ^\         9   d
   \        ;R&   ^\         9   d
   \        ;R	&   ^	\         9   d
   \        ;R
&   ^
\         9   d
   \        ;R&   ^\         9   d
   \        ;R&   ^\         9   d
   \        ;R&   ^\         9   d
   \        ;R&   ^\         9   d
   \        ;R&   ^\         9   d
   \        ;R&   ^\         9   d   \        R,          ;R&   ^\         9   d   \        \        \        3,          ;R&   ^\         9   d   \        \        ,          ;R&   # )r4   r}  r~  r_  r�  r�  rT  r›  rœ  r™  r±  rÔ  rÕ  r  r  rV  rì  Nr§  rµ  rŸ  )Ú__conditional_annotations__r8   rB   ru  rv  rw  r   re   r   r  rn   rh  rO   rÆ   )r:   s   "r0   r;   r;      sö  € ÷ ñ ÷f GÒ F””cœ:×-Ñ-×@Ñ@Ð@ÕAÑ Fñg÷h :Ò 9œD¤¤h¬s¥mÐ!3Õ4Ñ 9ñi÷J +Ò *”dœ3¤˜9•oÑ *ñK÷j Ò ”#Ñ ñk÷l QÒ P”dœ5¤$¤v¬u´X¼cµ]ÄDÐ5HÕ/IÐ'IÕ"JÐJÕKÑ Pñm÷t *Ò )œcÑ )ñu÷z ,Ò +”dœ5¤#˜:Õ&Ñ +ñ{÷F %Ò $œÑ $ñG÷P Ò ”Ñ ñQ÷T  Ò ”dÑ ñU÷V Ò ”$Ñ ñW÷b (Ò 'œdÑ 'ñc÷h Ò ”sÑ ñi÷j Ò ”$Ñ ñk÷L "Ò !”cÑ !ñM÷h  Ò ”dÑ ñi÷\( !Ò  Œd�T�kÑ  ñ](÷t} 0Ò /œ$œs¤E˜zÕ*Ñ /ñu}÷|} 5Ò 4œx¬�~Ñ 4ò}}r<   r?   )r£  r¤  r¥  rù   g     Õ@(M  r  rŽ   ÚatexitÚconcurrent.futuresru  r³  rÈ  r°  r  r\  r\  r¸   rî  r*  rô  r˜  r‰  Údataclassesr   r   r   r   r±  ÚImportErrorrµ  Úpathlibr   Útypingr   r	   r
   r   r   r   r   r  ÚinsertrB   r8  r  Úcron.worker_bootstrapr   r   r$  r   r   Ú/hermes_cli.observability.shared_metrics_gatewayr   r   Úcron.env_settingsr   Úhermes_cli._subprocess_compatr   rá  r   r   r—  r   r   Úhermes_timer   r×   r   Úagent.interrupt_compatr   Úagent.delegation_contextr   r   Úagent.memory_providerr    Úagent.session_activityr!   Úagent.turn_failure_copyr"   Ú	getLoggerrŠ   ræ   r1   rK   rT   rZ   rj   rs   rz   r  r|   Úcompiler˜   rœ   r¨   rÂ   rÌ   rÍ   rÚ   rì   rò   rö   rX   rø   r  r  r  r(  rË   r)  r*  r+  r,  r-  r.  r/  r0  r1  r2  r3  r4  r5  r6  r`   r7  Úcron.execution_identityr8  r9  r!  r:  r;  r<  r=  r>  r?  r@  rA  rB  rC  Úcron.scheduler_livenessrD  rE  rà  rF  r2  rN  rR  rX  r}  r~  r\  r_  r`  rd  r  r�  r�  rT  r›  rœ  ÚLockrŽ  r™  r±  rÔ  rh  r  rÕ  r  r  r  rá  rV  rf  rs  r’  r�  r£  r¢  rÄ  rÇ  rÍ  r×  rÜ  r²  rì  rö  rµ  r  r  r&  r0  r;  rI  rd  rj  rn  rr  r�  r…  rŠ  ÚregisterrŽ  r–  r�  r¤  r§  r£   r¬  r·  r¼  rÁ  rÈ  rÜ  Ú_DEFAULT_SCRIPT_TIMEOUTÚ_SCRIPT_TIMEOUTrö  r(  r'  rå  rù  rû  r  r  r8  rG  rI  re  rs  r|  rz  r¢  rª  r±  rÒ  rã  r   r9  rU  rZ  rb  rn   r9   rd  rs  rˆ  ru  r©  r«  r½  rÙ  rÛ  r  rý  r4  r^  ra  rb  rn  rp  rr  r…  r   rS  r¼  rÂ  ÚcontextmanagerrR  rÆ  rÊ  rL  rÿ  rP  r	  rO  ri  ro  rq  r‡  r¶  rµ  r   rŸ  rž  r“  r¢  r¬  r²  r¼  rÆ  rÍ  rÓ  rÛ  rø  r  Úcron.scheduler_tickr  Úcron.scheduler_deliveryrÔ  r™  r˜  r§  rš  Úcron.scheduler_scriptrÇ  r/  r0  Úcron.scheduler_promptrþ  r`  ra  rÿ  r   r  r.  rl  r·  r1  Úcron.scheduler_preflightr�  r€  rx  r¸  r–  ry  r:  ÚargparseÚArgumentParserÚparserÚadd_argumentÚ
parse_argsr  Úhermes_loggingr  Ú
SystemExitÚexternal_worker_filerg  r;   )r  s   @r0   Ú<module>r3     s	  øð÷ð ó Û Û Û Û Û Û Û 	Û 	Û Û 
Û Û Û Ý !ß ,Ñ ,ðÛõ ß G× GÑ Gð ‡�‡��‘3‘t˜H“~×,Ñ,×3Ñ3Ó4Ô 5ç Cß =ß bÝ .Ý <÷'ç Pß 9Ý 9÷Kå +Ý 1Ý <à	×	Ò	˜8Ó	$€òõBjõ	X÷ð õ0õ:õô
�lô 
ð& —*’*ÐOÓP€õ
?õ#õLBðJ &)Ð "õhõ@ð&Ø;?÷õ0hõ	Qô	 ô 	õõ0õ$õDV÷.a÷ a÷ a÷ aõ ß M÷X÷ X÷ X÷ XÝ Að €ð 'Ð õ
6õ0ð$ EG€Ó FØ79Ð Ó 9÷hð hð )+Ð Ó *õõ@ñ ›Ð Ó ØNPÐ Ó Pñ %(£EÐ Ó )ð *,Ð Ó +ñ  #›uÐ Ó $Ø—“Ó €ð €Ó àÐ Ó ØÐ Ó ñ “(€à%'Ð Ó 'ð Ð Ó ØÐ Ó ØÐ ð #'Ð ñ  ›EÐ Ó !ô�xô ÷ñ õ 	[õ
õ@õXõD÷<Fð Fõ-ð$°4ð À÷ ò<-Ø=A÷-ð -õ.+ð4  Ð Ó õõ8õ&>õFõ(õ4õ T÷F@!ð @!ðF7Ø15÷7÷t+ð +÷ð õõõ&<õ'ð ‡ƒÐ'Ô (õ=õRõ
:÷*ð *ð$ !€Ó  õ-õ-õ
õCõ,õ&õ"ð0 Ð à)€Ø#Ð Ø&BÀQÕ&FÐ #à#&Ð  õð$'ØLP÷'÷T&ñ &õRõõ4>õn#2ðL ÷ð ó ðõ2Kõjõ0@õ><õ6EXõPõ"`õ"CõL,÷*rð rõj;÷|^Vð ^VõB:ð
Ð\^÷ ð �4˜˜c 8¨C¥=Ð0Õ1€
õWñt*Ð ÷J(ñ J(õZ
ð& ÷
*ð 
*ó ð
*õ'õT"÷Jñ ð0L4Ø9=ðL4Ø]aðL4à/3ðL4àSW÷L4ð^)Ø>B÷)õ8Q+ðhf>Øðf>Ø&*ðf>Ø<Aðf>à"&ðf>àSW÷f>ðR TÐ õLð,.gà ÷.gôb[ Yô [÷3ñ 3ðl ÷-ð -ó ñ-ö$dF÷N#,÷N&ð &÷6$ð $ð ×Òò)ó ñ)÷Að A÷
!ð 
!ðW8ØðW8Ø&*ðW8Ø<AðW8à"&ñW8àQUñW8ð 48ñW8ð )-÷	W8ò W8ñtF5ð #'÷	F5ò F5öRT lõ Tñð !ñ	ñ
 ')ñð #'÷ò ÷:nð n÷bn3ð n3÷b=ð =ö# \õ #÷>ð ñ, %*Ñ !Ø-/Ñ Ó /ñ *4Ñ &Ø04Ñ Ó 4Ø&Ÿ^›^Ó-Ñ ÷!Kð !K÷H%*ð %*ôP!÷Hð ÷Kð K÷@>ð >÷(ð ÷ Dð D÷Sð S÷2`ð `÷F'ð '÷. %Ñ $÷÷ ÷ ñ ÷÷ ñ ÷÷ ÷ ÷ ÷ õ ÷
÷ ÷ õ ð ‰zÔÙ 3§8¢8Ô+ÙÔÝá×(Ó(°%Õ8‰Ù×ÒÑ4¸4É$ÑÔOÙ×Ò™L¨t¹dÑÔCÙ× Ò Ó"‰ð
	ß4Ñ4âÑ&6Ó&8¹vÖFò Ú-©d×.GÒ.GÉÏÊ×WÒWˆAó
ð 	
Ø]^ó
ð 	
ò 	‘¡×%Ð%ñ- øðAI ô Ø€EðÞøØô ØŒðúð	ûðbI ô 	Ùð	ús<   Á` Þ+`6 à	`3à`!à!	`/à*`3à.`/à/`3à6a à?a 