+
    jHàjx$  ã                   óä   a € R t0 t R t^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RI	H
t
 ]P                  ! R4      tRt/ s] ^ k R R ltRRRR	R
/R R llltR tR R ltR R ltRRRR	R
/R R llltR# )zLIn-process tick admission and dispatch; job execution stays in scheduler.py.N)Ústore_health)Úis_recurringzcron.schedulerg      ¬@c                ó(   € V ^8„  d   QhR\         RR/# )é   ÚreasonÚreturnN)Ústr)Úformats   "Ú8/home/ubuntu/.hermes/hermes-agent/cron/scheduler_tick.pyÚ__annotate__r      s   € ÷ 4ñ 4¤ð 4¨ñ 4ó    c                ó   € \         P                  ! 4       p\        P                  R4      p\        P                  RR4      pW 8w  g   V\	        V4      ,
          \
        8¼  d   \        P                  RV 4       RV RV/sR# )z?Log the yield at error level once per episode (skew signature).r   Úatg        u³   Cron tick yielded: this process is running stale code (%s) and a fresher gateway owns the runtime lock â€” jobs will fire from that process. Restart this one to reclaim its ticks.N)ÚtimeÚ	monotonicÚ_last_yield_logÚgetÚfloatÚ_YIELD_LOG_INTERVAL_SECONDSÚloggerÚerror)r   ÚnowÚlast_reasonÚlast_ats   &   r
   Ú_log_tick_yield_oncer      so   € ô �.Š.Ó
€CÜ!×%Ñ% hÓ/€KÜ×!Ñ! $¨Ó,€GØÔ ¤u¨W£~Õ!5Ô:UÔ UÜ�‰ð>ð ô		ð
   ¨¨sÐ3‚Or   Úcan_dispatchÚheadlessFc                ó$   € V ^8„  d   QhR\         /# )r   r   ©Úbool)r	   s   "r
   r   r   !   s   € ÷ 
1ñ 
1Üñ
1r   c                óÀ   € ^ RI Hp VP                  4       ;_uu_ 4       pV'       g    RRR4       ^ # \        WW#VVR7      uuRRR4       #   + '       g   i     R# ; i)é    )Ú
retirementN)r   r   )Úhermes_cli.backend_retirementr"   ÚworkÚ_tick_admitted)ÚverboseÚadaptersÚloopÚsyncr   r   r"   Úadmitteds   &&&&$$  r
   Útickr+   !   sF   € å8ð 
�‰×	Ô	˜hßØ÷ 
Ñ	ô ˜g°È,Ø'/ô1÷ 
×	×	Ó	ús   Ÿ
A³AÁA	c                ó2  € V P                  4       w  rV P                  V4        V P                  V4      #   \         dV   pTP                  \
        P                  9  d   h \
        P                  ! TRRTR7       T P                  4         Rp?R# Rp?ii ; i)a  The tick lock fd, or None when this tick must not run: another ticker holds the lock, or
the store cannot be written (read-only/full/denied: the lock file cannot even be created), in
which case the store is marked degraded and the MCP orphan sweep still runs.ztick lock unavailableÚlock)Úcron_dirN)	Ú_get_lock_pathsÚ_ensure_cron_dirÚ_acquire_tick_lockÚOSErrorÚerrnor   ÚUNWRITABLE_ERRNOSÚnote_unwritableÚ_sweep_mcp_orphans)Ú_schedÚlock_dirÚ	lock_fileÚexcs   &   r
   Ú_acquire_tick_lock_or_degrader;   .   sƒ   € ð !×0Ñ0Ó2Ñ€HØ
×Ñ˜HÔ%ðØ×(Ñ(¨Ó3Ð3øÜô Ø�9‰9œL×:Ñ:Ô:ØÜ×$Ò$ SÐ*AÀ6ÐT\Õ]Ø×!Ñ!Ô#Ýûðús   ¥6 ¶BÁA
BÂBc                ó0   € V ^8„  d   QhR\         R\         /# )r   Údue_jobsr   )Úlist)r	   s   "r
   r   r   >   s   € ÷ 
<ñ 
<´ð 
<¼$ñ 
<r   c                ó†  €  T P                  V Uu. uF  q"R,          NK  	  up4       V# u upi   \         d†   pT Uu. uF  p\        T4      '       g   K  TNK  	  Mu upi pp\        P                  ! TR\        T4       R2RT4       T Uu. uF  p\        T4      '       d   K  TNK  	  Mu upi upu Rp?# Rp?ii ; i)zìPersist the recurring jobs' advance before any runs; when the store refuses it, drop them
(no durable advance -> a crash mid-run would re-fire them, so skipping is the at-most-once
side). One-shots still go through their own fire claim.Úidzskipped z recurring job(s)ÚadvanceN)Úadvance_next_runsr2   r   r   r5   Úlen)r7   r=   Újobr:   ÚjÚskippeds   &&    r
   Ú_advance_or_drop_recurringrG   >   s£   € ð<Ø× Ñ ±xÓ!@±x° d§) )±xÑ!@ÔAØˆùò "Aøäô <Ù&Ó:™h˜¬,°q¯/—1�1šhùÒ:ˆÐ:Ü×$Ò$ S¨H´S¸³\°NÐBSÐ*TÐV_ÐahÔiÙ#Ó;™8�a¬<¸¯?—�š8ùÔ;Õ;ûð<úsI   ‚0 ‘+¢0 «0 °C »B;¿AÁAÁ2B;ÂB.Â'B.Â-B;Â5C Â;C c                ó(   € V ^8„  d   QhR\         RR/# )r   r   r   Nr   )r	   s   "r
   r   r   K   s   € ÷ %ñ %´ð %¸$ñ %r   c                óì   € ^ RI Hp V'       d   V! RR7       MV! 4         ^ RIHp V! 4        V P                  4        R#   \         d)   pT P
                  P                  RTRR7        Rp?L@Rp?ii ; i)	zpAdmission reconcile, legacy upgrade drain and dead-owner reap, run under the tick lock
before due jobs are read.)Úreconcile_pendingF)Úallow_connect)Údrain_legacy_pendingz(Legacy Bot Chat pending drain failed: %sT)Úexc_infoN)Úcron.scheduler_authorityrJ   Úcron.bot_chat_legacyrL   Ú	Exceptionr   ÚwarningÚ_maybe_reap_dead_owners)r7   r   rJ   rL   Ú_legacy_excs   &&   r
   Ú_pre_dispatch_housekeepingrT   K   sg   € õ ;ßÙ¨Ö.áÔðfÝ=ÙÔð ×"Ñ"Ö$øô ô fØ�‰×ÑÐHÈ+Ð`dÐ×eÑeûðfús   ¡A  Á A3ÁA.Á.A3c                ó<   € V ^8„  d   QhR\         R\         R\         /# )r   r&   r)   r   r   )r	   s   "r
   r   r   \   s)   € ÷ p+ñ p+Üðp+Ü:>ðp+äñp+r   c               óh	  a aaa€ ^ RI Ho SP                  4       pVe@   \        RV^ ,           RV^,           24       SP	                  V^ ,          V^,          4      h\        S4      pVf   ^ #  \        P                  ! \        4      ;_uu_ 4        ^ RI	H
p V! RSP                  4      '       d    RRR4       SP                  V4       ^ #  RRR4       Ve=   V! 4       '       g0   SP                  P                  R4        SP                  V4       ^ # \        SV4        SP                  4        SP#                  4       p
SP%                  V
4       V'       d   ^ R	IHp V! V
4      p
V
'       g{   S '       d:   SP                  P+                  R
SP-                  4       P/                  R4      4       \0        P2                  ! 4        SP5                  4         SP                  V4       ^ # \0        P6                  ! V
4      '       d%   SP5                  4         SP                  V4       ^ # S '       dD   SP                  P+                  RSP-                  4       P/                  R4      \9        V
4      4       \;        SV
4      p
V
'       g%   SP5                  4         SP                  V4       ^ # SP=                  4       pS '       d1   SP                  P+                  R\9        V
4      V'       d   TMR4       R VVVV 3R llp. p. pSP?                  V4      pV
 FH  pSPA                  VVV4      pVf   K  VPC                  V4       V'       d   K7  VPC                  R4       KJ  	  V'       ds   \D        PF                  PI                  V4       F#  p VPC                  VPK                  4       4       K%  	  SP5                  4        \O        V4      SP                  V4       # SPQ                  V4       \O        V4      SP                  V4       #   + '       g   i     ELH; i  \          d(   p	SP                  P                  RT	4        Rp	?	ELRp	?	ii ; i  \          d:   pSP                  PM                  RT4       TPC                  R4        Rp?EK  Rp?ii ; i  SP                  T4       i ; i)aŸ  Check and run all due jobs. File-locked so only one tick runs at a time (gateway ticker vs
standalone daemon / manual tick). ``can_dispatch``: optional gate; false leaves due jobs for the
next allowed tick. ``headless``: the tick runs outside any gateway (system crontab, ``hermes
cron tick``) and must refuse agent jobs rather than spawn one. Returns the number of jobs
executed (0 if another tick holds the lock).)Ú	schedulerNzboot=z disk=)Úcheck_pausedÚcronz7Cron dispatch paused while gateway drains existing workz(Worktree maintenance dispatch failed: %s)Ú!refuse_agent_jobs_without_gatewayz%s - No jobs duez%H:%M:%Sz%s - %s job(s) duez.Running %d job(s) in parallel (max_workers=%s)Ú	unboundedc                ó0   € V ^8„  d   QhR\         R\        /# )r   rD   r   )Údictr   )r	   s   "r
   r   Ú$_tick_admitted.<locals>.__annotate__¯   s   € ÷ 	Iñ 	Iœdð 	I¤tñ 	Ir   c                 ó,   <€ SP                  V SSS4      # )N)Ú_process_due_job)rD   r7   r'   r(   r&   s   &€€€€r
   Ú_process_jobÚ$_tick_admitted.<locals>._process_job¯   s   ø€ Ø×*Ñ*¨3°¸$ÀÓHÐHr   TzCron job future failed: %sF))rY   rW   Ú#_should_yield_tick_to_fresh_gatewayr   ÚCronTickYieldedr;   Ú
contextlibÚsuppressÚImportErrorÚagent.estoprX   r   Ú_release_tick_lockÚdebugrT   Ú_maybe_run_worktree_maintenancerP   Úget_due_jobsÚ_sweep_stale_inflight_for_tickÚcron.scheduler_gateway_gaterZ   ÚinfoÚ_hermes_nowÚstrftimer   Úrecheck_idler6   Údispatch_blockedrC   rG   Ú_resolve_max_parallel_workersÚ_get_parallel_poolÚ_submit_with_guardÚappendÚ
concurrentÚfuturesÚas_completedÚresultr   ÚsumÚ _sweep_mcp_orphans_when_all_done)r&   r'   r(   r)   r   r   Ú_skewÚlock_fdÚ_estop_check_pausedÚ_wt_excr=   rZ   Ú_max_workersra   Ú_resultsÚ_all_futuresÚpoolrD   ÚfutÚfr:   r7   s   fff&$$               @r
   r%   r%   \   sÜ  û€ õ )ð
 ×6Ñ6Ó8€EØÒÜ˜u U¨1¥X J¨f°U¸1µX°JÐ?Ô@Ø×$Ñ$ U¨1¥X¨u°Q­xÓ8Ð8ä+¨FÓ3€GØ‚ÙðZ+ä× Ò ¤×-Õ-ÝGÙ" 6¨6¯=©=×9Ò9Ø÷ .ðp 	×!Ñ! 'Ö*ðm :÷ .ð
 Ò#©L¯NªNØ�M‰M×ÑÐ YÔZØðb 	×!Ñ! 'Ö*ô_ 	# 6¨8Ô4ð	UØ×2Ñ2Ô4ð ×&Ñ&Ó(ˆØ×-Ñ-¨hÔ7ßÝUÙ8¸ÓBˆHççð —‘×"Ñ"Ð#5°v×7IÑ7IÓ7K×7TÑ7TÐU_Ó7`ÔaÜ×%Ò%Ô'Ø×%Ñ%Ô'Øðn 	×!Ñ! 'Ö*ôk ×(Ò(¨×2Ò2ð ×%Ñ%Ô'Øðb 	×!Ñ! 'Ö*÷_ Ø�M‰M×ÑÐ3°V×5GÑ5GÓ5I×5RÑ5RÐS]Ó5^Ô`cÐdlÓ`mÔnô
 .¨f°hÓ?ˆßØ×%Ñ%Ô'ØðL 	×!Ñ! 'Ö*ðI ×;Ñ;Ó=ˆßØ�M‰M×ÑØ@Ü�H“ß ,‘°+ô?÷
	Ió 	Ið
 ˆØˆØ×(Ñ(¨Ó6ˆÛˆCØ×+Ñ+¨C°°|ÓDˆCØŠ{ÙØ×Ñ Ô$ß‘4Ø—‘ Ö%ñ ÷ Ü×'Ñ'×4Ñ4°\ÖB�ð+Ø—O‘O A§H¡H£JÖ/ñ Cð ×%Ñ%Ô'Ü�x“=ð
 	×!Ñ! 'Õ*ð 	×/Ñ/°Ô=Ü�8‹}à×!Ñ! 'Õ*÷q .×-Ð-ûô ô 	UØ�M‰M×ÑÐ JÈG×TÒTûð	UûôD !ô +Ø—M‘M×'Ñ'Ð(DÀcÔJØ—O‘O E×*Ó*ûð+ûð 	×!Ñ! 'Õ*úsÕ   Á0"R Â!PÂ3R ÃR Ã(R ÄR Ä$P" Ä4(R ÅR Å3R Å;AR Ç-R È	R È-R È5A'R Ê0R ËBR ÍR Í/"R ÎQÎ1R Ï!R ÐP	Ð	R Ð"QÐ-QÑ	R ÑQÑR ÑRÑ"-RÒR ÒRÒR ÒR1c                ób   € V ^8„  d   Qh/ ^ \         9   d   \        \        \        3,          ;R&   # )r   r   )Ú__conditional_annotations__r]   r   Úobject)r	   s   "r
   r   r      s$   € × RÑ R÷ (Ò '””cœ6�kÕ"Ñ 'ò Sr   )TNNT)r‰   Ú__doc__Úconcurrent.futuresrx   re   Úloggingr   rY   r   Úcron.constantsr   Ú	getLoggerr   r   r   r   r+   r;   rG   rT   r%   r   )r‰   s   @r
   Ú<module>r�      s‡   øðÞ Rã Û Û Û å Ý 'à	×	Ò	Ð+Ó	,€ð %Ð Ø%'€Ó 'õ4ñ
1ÈDð 
1Ø÷
1ð 
1òõ 
<õ%ñ"p+ØW[ðp+à÷p+ò p+r   