+
    jHàjþs ã                   ó´  a € R\ tÊ0 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t^ RIHt ^ RIHtHt ^ RIHt ^ RIHt ^ RIHtHt ^ RIHtHtH t H!t!H"t"H#t#H$t$H%t%H&t& ^ RI'H(t)H*t+H,t-H.t/H0t0H1t2 ^ R	I3H4t4 ^ R
I5H6t6 ^ RI7H8t8H9t9H:t:H;t;H<t< ^ RI=H>t>H?t?H@t@HAtAHBtBHCtCHDtDHEtEHFtFHGtGHHtHHItIHJtJHKtK ^ RILHMtMHNtNHOtOHPtPHQtQHRtRHStS ^ RITHUtUHVtVHWtW ^ RIXHYtY ^ RIZH[t[H\t\ ^ RI]H^t^ ^ RI_H`t` ^ RIaHbtb ^ RIcHdtd ^ RI3te^ RIftg^ RIhHiti ^ RIjHktkHltlHmtmHntnHotoHptpHqtqHrtrHstsHtttHutuHvtvHwtw ^ RIxHyty ^ RIzH{t{ ^ RI|H}t} ^ RI~Ht ^ RI€H�t� ^ RI‚HƒtƒH„t„H…t…H†t† ^ RI‡HˆtˆH‰t‰HŠtŠ ^ RI‹HŒtŒ ^ RI�HŽtŽ ^ R I�H�t� ^ R!I‘H’t’ ^ R"I“H”t” ^ R#I•H–t–  ^ RI—t—]EP2                  ! ]š4      t›R$tœ]œ3R% R& llt�R' R( ltžR) R* ltŸ ! R+ R,] 4      t¡ ! R- R.] 4      t¢R/ R0 lt£]¤! R1R204      t¥]%! R34      t¦]! 4       R4,          ;t§t¨R5t©^R6utªt«R7t¬R8 R9 lt­R:t®R]t¯] ^ k R; R< lt°R=R:/R> R? llt±R^t²R@ RA lt³RB RC lt´]
EPj                  ! RD4      t¶RE RF lt·RG RH lt¸RIt¹RJtºRKt»RLt¼R_RMR:/RN RO lllt½]¾! 4       t¿] ^k ]EP€                  ! 4       tÁRPtÂ]EP†                  RQ8H  tÄRR RS ltÅRT RU ltÆRV RW ltÇ ! RX RY]Y][]–]d]^]`]”]’]�]Ž]Œ]y]{]}]]�]b4      tÈ ! RZ R[4      tÉR#   ]˜ d    Rt— ELDi ; i)`a-  SQLite state store for Hermes Agent: session metadata, message history, model
config, FTS5 search. WAL mode (concurrent readers + one writer); compression
splits sessions via parent_session_id chains; sessions are source-tagged
('cli', 'telegram', ...). Batch-runner / RL trajectories live elsewhere.
N)Údeque)ÚcontextmanagerÚsuppress©ÚPath)Úmake_user_dir)Úget_hermes_homeÚmkdir_under_hermes_home)	ÚAnyÚCallableÚDictÚIteratorÚListÚOptionalÚTupleÚTypeVarÚcast)ÚTITLE_SOURCE_DERIVEDÚTITLE_SOURCE_LLMÚTITLE_SOURCE_USERÚescape_likeÚ_placeholdersÚstat_db_file_identity)Úread_only_db_uri)Úholder_pid_checkable)ÚSTORAGE_CORRUPTÚmark_storage_corruptÚnote_storage_errorÚstorage_corrupt_reasonÚstorage_state)Ú_DELETED_WAL_GENERATION_MSGÚ_DISK_IO_ERROR_MARKERÚ_STATE_DB_CORRUPT_MSGÚ_STATE_DB_GENERATION_KEYÚ_STATE_DB_REPLACED_MSGÚDeletedWalGenerationErrorÚ!SessionCompressionInProgressErrorÚStateDbCorruptErrorÚStateDbReplacedErrorÚ_is_no_more_rowsÚclassify_persistence_errorÚis_malformed_db_errorÚis_malformed_schema_errorÚis_sqlite_lock_error)Ú_STATE_DB_GUARD_BYPASS_ENVÚ_in_test_contextÚ_is_production_state_dbÚ_real_platform_state_rootÚ_register_test_instanceÚ_set_last_init_errorÚget_last_init_error)Ú_READ_POOL_MAXÚ_proc_fd_targetsÚ_read_budget_for)ÚSessionSessionsMixin)ÚSessionFtsSetupMixinÚload_fts5_cjk_extension)ÚSessionPortabilityMixin)ÚSessionTelegramTopicsMixin)ÚSessionProfileRepairMixin)ÚSessionSchemaMixin)Úlog_write_lock_holders)Ú_connect_tracked_dbÚ_fd_is_truly_unlinkedÚ_prepare_connection_retirementÚ_read_sqlite_application_idÚ_stat_sqlite_sidecar_identityÚ_watched_sqlite_sidecar_pathsÚ!has_invalid_sqlite_header_preopenÚis_zeroed_state_dbÚquarantine_cross_process_lockÚquarantine_invalid_state_dbÚRetiredGenerationCaptureErrorÚcapture_retired_wal_generationÚrefuse_deleted_wal_generation)ÚSessionMessagesMixin)ÚSessionPruneRewriteMixin)ÚSessionApiContentMixin)ÚSessionCoverageMixin)ÚSessionRewindMixin)Ú_WAL_INCOMPAT_MARKERSÚ_on_disk_journal_modeÚapply_database_pragmasÚapply_wal_with_fallback)Ú_claim_repair_attemptÚpreflight_db_writabilityÚrepair_state_db_schema)ÚSessionTitlesMixin)ÚSessionUsageMixin)ÚSessionMaintenanceMixin)ÚSessionGatewayMixin)ÚSessionCompressionMixin)ÚSessionSearchMixini N  c                ó<   € V ^8„  d   QhR\         R\        R\        /# )é   ÚkeyÚfallbackÚreturn©ÚstrÚint)Úformats   "Ú1/home/ubuntu/.hermes/hermes-agent/hermes_state.pyÚ__annotate__ri   _   s"   € ÷ 
ñ 
¤cð 
´Sð 
ÔRUñ 
ó    c                óÌ   €  ^ RI Hp V! 4       P                  R4      ;'       g    / P                  V 4      pVf   V# \        V4      pV^ 8¼  d   V# T#   \         d    Tu # i ; i)za``sessions.<key>`` from config.yaml (lazy import: circular at load), else *fallback*; 0 disables.)Úload_config_readonlyÚsessions)Úhermes_cli.configrl   Úgetrf   Ú	Exception)ra   rb   rl   ÚvalueÚlimits   &&   rh   Ú_configured_transcript_limitrs   _   sh   € ðÝ:Ù%Ó'×+Ñ+¨JÓ7×=Ð=¸2×BÑBÀ3ÓGˆØŠ=ØˆOÜ�E“
ˆØ œ
ˆuÐ0¨Ð0øÜô ØŠðús!   ‚"A ¥A ½A ÁA ÁA#Á"A#c                ó$   € V ^8„  d   QhR\         /# ©r`   rc   ©rf   )rg   s   "rh   ri   ri   l   ó   € ÷ ?ñ ?¤cñ ?rj   c                  ó   € \        R 4      # )Úmax_resume_messages©rs   © rj   rh   Úresolved_max_resume_messagesr|   l   ó   € Ü'Ð(=Ó>Ð>rj   c                ó$   € V ^8„  d   QhR\         /# ru   rv   )rg   s   "rh   ri   ri   p   rw   rj   c                  ó   € \        R 4      # )Úmax_export_messagesrz   r{   rj   rh   Úresolved_max_export_messagesr�   p   r}   rj   c                   óF   a a€ ] tR t^tt o]R3V3R lV 3R llltRtVtV ;t# )ÚSessionResumeTooLargeErrorzacross its lineagec                ó,   <€ V ^8„  d   QhRS[ RS[ RS[/# )r`   Úmessage_countrr   Úscope)rf   re   )rg   Ú__classdict__s   "€rh   ri   Ú'SessionResumeTooLargeError.__annotate__u   s%   ø€ ÷ 

ñ 

Ù ð

Ù),ð

ÙJMñ

rj   c                ó\   <€ WuV n         V n        W0n        \        SV `  R V RV R24       R# )z+This session is too long to reload safely (z messages; limit zñ). Start a fresh chat and keep a copy with the dashboard Sessions page's Export action or `hermes sessions export --format md --session-id <id>` (neither is capped), or raise the limit with `hermes config set sessions.max_resume_messages 0`.N)r…   rr   r†   ÚsuperÚ__init__)Úselfr…   rr   r†   Ú	__class__s   &&&&€rh   r‹   Ú#SessionResumeTooLargeError.__init__u   sC   ø€ ð *7Ð&ˆÔ˜DœJØŒ
Ü‰ÑØ9¸-¸ÐHYÐZ_ÐY`ð aGð Gö	
rj   )rr   r…   r†   ©	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú_MAX_SAFE_MESSAGESr‹   Ú__static_attributes__Ú__classdictcell__Ú__classcell__©r�   r‡   s   @@rh   rƒ   rƒ   t   s   ù‡ € à/AÐPd÷

÷ 

õ 

rj   rƒ   c                   óD   a a€ ] tR t^‚t o]3V3R lV 3R llltRtVtV ;t# )ÚSessionExportTooLargeErrorc                ó,   <€ V ^8„  d   QhRS[ RS[RS[/# )r`   Ú
session_idr…   rr   rd   )rg   r‡   s   "€rh   ri   Ú'SessionExportTooLargeError.__annotate__ƒ   s"   ø€ ÷ 
ñ 
¡3ð 
±sð 
Á3ñ 
rj   c                ó`   <€ WVuV n         V n        V n        \        SV `  R V RVR R24       R# )z	Session 'z' has more than Ú,zÝ exportable messages; the JSON/JSONL backup is built in memory and capped per session. Use the dashboard Sessions page's streaming Export action, or set sessions.max_export_messages: 0 in config.yaml to disable the guard.N)rœ   r…   rr   rŠ   r‹   )rŒ   rœ   r…   rr   r�   s   &&&&€rh   r‹   Ú#SessionExportTooLargeError.__init__ƒ   sB   ø€ Ø:DÐUZÐ7ˆŒ˜Ô+¨T¬Zä‰ÑØ˜
�|Ð#3°E¸!°9ð =ið iö	
rj   )rr   r…   rœ   r�   r˜   s   @@rh   rš   rš   ‚   s   ù‡ € ØI[÷ 
÷ 
õ 
rj   rš   c                ó0   € V ^8„  d   QhR\         R\        /# )r`   Úholderrc   ©re   Úbool)rg   s   "rh   ri   ri   �   s   € ÷ ñ ´Sð ¼Tñ rj   c                ó  € \         P                  ! RT ;'       g    R4      pV'       d   \        VP                  ^4      4      M^ pV^ 8:  g   V\        P
                  ! 4       8X  d   R# \        V 4      '       g   R# \        e    \        P                  ! V4      '       * # \        P                  R8X  d   R#  \        P                  ! V^ 4       R#   \         d     R# i ; i  \         d     R# \        \        3 d     R# i ; i)am  True only when a ``pid=<n>`` lock holder's local PID is provably gone.
Reclaim on kernel proof only: unstructured/same-process holders (another
thread's live lease) and any probe doubt keep the lease until TTL expiry
(PID reuse must never steal a live lease; a wrongly-kept one self-heals).
Foreign/unstamped PID namespaces defer to TTL: see ``hermes_state_pidns``.z(?:^|:)pid=(\d+)(?::|$)Ú FÚntT)ÚreÚsearchrf   ÚgroupÚosÚgetpidr   ÚpsutilÚ
pid_existsrp   ÚnameÚkillÚProcessLookupErrorÚOSErrorÚOverflowError)r¢   ÚmatchÚpids   &  rh   Ú(_compression_lock_holder_process_is_deadr¶   �   sÓ   € ô �IŠIÐ0°&·,°,¸BÓ?€Eß!&Œ#ˆe�k‰k˜!‹nÔ
¨A€CØ
ˆa„x�3œ"Ÿ)š)›+Ô%ÙÜ ×'Ò'ÙÜÒð	Ü×(Ò(¨Ó-Ô-Ð-ô
 
‡w�w�$„ÙðÜ
�Š��QŒñ
 øô ô 	Úð	ûô ô ÚÜ”]Ð#ô Úðús0   ÂC Â8C# ÃC ÃC Ã#DÃ1DÄ DÄDÚautoÚcustomÚTústate.dbç      N@gš™™™™™©?ç      @c                ó$   € V ^8„  d   QhR\         /# ru   r   )rg   s   "rh   ri   ri   È   s   € ÷ mñ mœ$ñ mrj   c                 óN   € \         \        8w  d   \         # \        4       R,          # )z´Default state DB path at CALL time: a re-pointed ``DEFAULT_DB_PATH`` wins, else
``get_hermes_home()`` is resolved fresh (a runtime HERMES_HOME redirect works regardless of import).rº   )ÚDEFAULT_DB_PATHÚ_IMPORT_DEFAULT_DB_PATHr   r{   rj   rh   Ú_default_db_pathrÁ   È   s    € ô .Ô1HÔHŒ?ÐlÌoÓN_ÐblÕNlÐlrj   Fc                ó(   € V ^8„  d   QhR\         RR/# )r`   Údb_pathrc   Nr   )rg   s   "rh   ri   ri   Õ   s   € ÷ ñ ¤Dð ¨Tñ rj   c           
     ób  € \         '       g:   \        P                  P                  \        4      '       g   \        4       '       g   R#  \        V 4      P                  4       P                  4       p\        4       3 Uu. uF
  q"f   K  TNK  	  pp\         F:  p TP                  \        T4      P                  4       P                  4       4       K<  	  T F-  p\        Y4      '       g   K  \        RT RT R\         R24      h	  R#   \         d     R# i ; iu upi   \         d     K˜  i ; i)a<  Raise before any connection/mkdir/pragma/byte probe when a pytest-context process
(env OR ancestry) resolves a production DB.

Env alone is not enough: a child spawned with a rebuilt environment loses ``PYTEST_*`` and
``HERMES_HOME`` together, which is precisely the state in which it writes to production (#82770).
NzAlive-system guard: test attempted to open production state.db at z (under real Hermes root u  ). Tests must run against a temporary HERMES_HOME â€” pass an explicit tmp db_path or let the hermetic conftest redirect HERMES_HOME. If this test genuinely needs the live database, mark it with @pytest.mark.live_system_guard_bypass â€” or, for a spawned child process, export z=1 in its environment.)Ú_STATE_DB_GUARD_BYPASSr«   Úenvironro   r.   r/   r   Ú
expanduserÚresolverp   r1   Ú _STATE_DB_GUARD_EXTRA_DENY_ROOTSÚappendr0   ÚRuntimeError)rÃ   ÚresolvedÚrÚrootsÚextraÚroots   &     rh   Ú_ensure_test_isolationrÑ   Õ   s  € ÷ Ó¤§¡§¡Ô0J×!KÒ!KÔSc×SeÒSeÙðÜ˜“=×+Ñ+Ó-×5Ñ5Ó7ˆô 3Ó4Ñ6ÓHÑ6�1�QˆQÑ6€EÐHß1ˆð	Ø�L‰Lœ˜e›×/Ñ/Ó1×9Ñ9Ó;Ö<ñ 2ó
 ˆÜ" 8×2Ô2ÜðØ'˜jÐ(AÀ$Àð H)ô
 *DÐ(Dð E#ð#ó	ð 	ó øô ô ÚðüâHøô ô 	Úð	ús0   Á	'D Á=DÂDÂ6DÄDÄDÄD.Ä-D.Úcreate_mainc                ó4   € V ^8„  d   QhR\         R\        RR/# )r`   rÃ   rÒ   rc   N©r   r¤   )rg   s   "rh   ri   ri   ö   s!   € ÷ 8ñ 8¤Dð 8¼$ð 8È4ñ 8rj   c               óÀ  € \         P                  R8X  d   R# T pV'       dÃ   \         P                  \         P                  ,          \         P                  ,          p\        \         R4      '       d   V\         P                  ,          p\        \         R4      '       d   V\         P                  ,          p \         P                  ! W#R4      p\         P                  ! V4       VV P                  V P                  R,           4      V P                  V P                  R,           4      3 F�  p \         P                  ! V4      p\        P                   ! TP"                  4      '       d   KB  \        P$                  ! TP"                  4      '       g   Kj  \         P&                  ! TR4       Kƒ  	  R#   \         d     LÙ\         d     R# i ; i  \         d     K³  i ; i)u  Create/tighten a writable state database and its sidecars to 0600.

SQLite otherwise creates ``state.db``, ``-wal``, and ``-shm`` according to
the process umask (commonly 0644 under 0022). Read-only SessionDB
attachments never call this helper and remain observational.

Existing files are tightened with ``chmod(2)`` on the path: opening the
file and closing that descriptor would drop every POSIX ``fcntl`` lock the
process holds on its inode â€” including the locks of an already-open SQLite
connection to the same database. A lock-losing close in one process lets a
sibling's connection take the shared-memory DMS exclusively at its own
close, checkpoint, and unlink the sidecars while long-lived holders
(gateway, desktop ``hermes serve``) keep using the deleted inodes.
r§   NÚ
O_NOFOLLOWÚ	O_CLOEXECi€  z-walz-shm)r«   r¯   ÚO_WRONLYÚO_CREATÚO_EXCLÚhasattrrÖ   r×   ÚopenÚcloseÚFileExistsErrorÚIsADirectoryErrorÚ	with_nameÚlstatÚFileNotFoundErrorÚstatÚS_ISLNKÚst_modeÚS_ISREGÚchmod)rÃ   rÒ   Ú	main_pathÚflagsÚfdÚpathÚsts   &$     rh   Ú_secure_state_db_filesrí   ö   sP  € ô 
‡w�w�$„Ùà€Ißô —‘œbŸj™jÕ(¬2¯9©9Õ4ˆÜ”2�|×$Ò$Ø”R—]‘]Õ"ˆEÜ”2�{×#Ò#Ø”R—\‘\Õ!ˆEð		Ü—’˜¨5Ó1ˆBô �HŠH�RŒLð 	Ø×Ñ˜'Ÿ,™,¨Õ/Ó0Ø×Ñ˜'Ÿ,™,¨Õ/Ó0óˆð	Ü—’˜$“ˆBô �<Š<˜Ÿ
™
×#Ò#áÜ�|Š|˜BŸJ™J×'Ò'ÙÜ
�Š��uÖó%øô ô 	ÙÜ ô 	ò ð	ûô$ !ô 	Úð	ús0   Â7F0 Ä-GÆ0GÆ=GÇGÇ
GÇGÇGc                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# ©r`   Úmsgrc   ©Údictre   r
   r¤   )rg   s   "rh   ri   ri   8  s&   € ÷ ^ñ ^¬t´C¼°H­~ð ^Ä$ñ ^rj   c                óö   € \        V \        4      '       d   V P                  R4      R9  d   R# V P                  R4      p\        V\        4      ;'       d$    VP	                  4       P                  \        4      # )z€Persisted harness prompt (older builds wrote the forked curator's turns
into real sessions; replaying them hijacks the session).ÚroleFÚcontent>   ÚuserÚsystem)Ú
isinstancerò   ro   re   ÚlstripÚ
startswithÚ_REVIEW_HARNESS_PREFIXES©rð   rõ   s   & rh   Ú%_is_background_review_harness_messagerý   8  sZ   € ô �cœ4× Ò  C§G¡G¨F£OÐ;MÔ$MÙØ�g‰g�iÓ €GÜ�gœsÓ#×]Ð]¨¯©Ó(8×(CÑ(CÔD\Ó(]Ð]rj   c                ó    € V ^8„  d   QhR\         \        \        \        3,          ,          R\         \        \        \        3,          ,          /# ©r`   Úmessagesrc   ©Úlistrò   re   r
   )rg   s   "rh   ri   ri   A  s7   € ÷ ñ ¬t´D¼¼c¸µNÕ/Cð ÌÌTÔRUÔWZÐRZÍ^ÕH\ñ rj   c                ó
  € V '       g   V # . pRpRpV  Fl  p\        V4      '       d   V'       * pRpK  V'       d3   Rp\        V\        4      '       d   VP                  R4      R8X  d   RpKY  RpVP	                  V4       Kn  	  V# )zZDrop harness messages and the curator-mode assistant reply that immediately followed each.FTrô   Ú	assistant)rý   rø   rò   ro   rÊ   )r   ÚoutÚskip_next_assistantÚprevious_was_harnessrð   s   &    rh   Ú _strip_background_review_harnessr  A  sŠ   € çØˆØ "€CØÐØ ÐÛˆÜ0°×5Ò5ð ';Ô":ÐØ#'Ð ÙßØ"'ÐÜ˜#œt×$Ò$¨¯©°«¸KÔ)GØ',Ð$ÙØ$ÐØ�
‰
�3Žñ ð €Jrj   z^\[[A-Za-z_][A-Za-z0-9_.-]*\]$c                óR   € V ^8„  d   QhR\         \        \        3,          R\        /# rï   rñ   )rg   s   "rh   ri   ri   ]  s&   € ÷ dñ d¬D´´c°­Nð d¼tñ drj   c                ó6  € \        V \        4      '       d.   V P                  R4      R8w  g   V P                  R4      '       g   R# V P                  R4      p\        V\        4      ;'       d-    \	        \
        P                  VP                  4       4      4      # )z•Assistant tool-call turn whose content is a bare ``[marker]`` (an older
conversation_loop persisted a local template's marker as the final response).rô   r  Ú
tool_callsFrõ   )rø   rò   ro   re   r¤   Ú_STALE_TOOL_CALL_MARKER_REÚ	fullmatchÚstriprü   s   & rh   Ú"_is_stale_tool_call_marker_messager  ]  sp   € ô �cœ4× Ò  C§G¡G¨F£O°{Ô$BÈ#Ï'É'ÐR^×J_ÒJ_ÙØ�g‰g�iÓ €GÜ�gœsÓ#×cÐc¬Ô-G×-QÑ-QÐRY×R_ÑR_ÓRaÓ-bÓ(cÐcrj   c                ó    € V ^8„  d   QhR\         \        \        \        3,          ,          R\         \        \        \        3,          ,          /# rÿ   r  )rg   s   "rh   ri   ri   f  s7   € ÷ ñ ¬T´$´s¼C°xµ.Õ-Að ÄdÌ4ÔPSÔUXÐPXÍ>ÕFZñ rj   c                ó�   € ^ p\        \        V 4       F  pRVR&   V^,          pK  	  V'       d   \        P                  RV4       V # )z‡Blank stale ``[marker]`` assistant content (replaying it teaches the model
to keep emitting it); tool_call/result pairing stays intact.r¦   rõ   zMCleared %d stale tool-call marker message(s) while restoring session (#78148))Úfilterr  ÚloggerÚinfo)r   Úrepairedrð   s   &  rh   Ú_strip_stale_tool_call_markersr  f  sL   € ð €HÜÔ8¸(ÖCˆØˆˆI‰Ø�A�Šñ D÷ Ü�‰Ø[Ð]eô	
ð €Orj   z/Sessions will not be saved until this is fixed.zC If the database lives on a network drive, move it to a local disk.zUthe session database could not be opened; it may be on a network or unsupported drivezbMove it to a local disk (`hermes {profile_arg}doctor` shows where it is), then start Hermes again.Údetailsc                ó<   € V ^8„  d   QhR\         R\        R\         /# )r`   Úprefixr  rc   r£   )rg   s   "rh   ri   ri   |  s(   € ÷ "ñ "Üð"ô ð"ô 	ñ	"rj   c               ó  a€ ^ RI Hp V! 4       p\        4       oS'       g   V  R\         RV R2# ^ RIHp V! S4      pVP                  VP                  Rr‡p\        ;QJ d#    V3R l\         4       F  '       g   K   RM	  R	M! V3R l\         4       4      '       d4   VP                  R
8X  d   \        \        P                  RV4      rvM\        pV  RV R\         RV V 2p	V'       d   ^ RIHp
 V	RV
! S4       2,          p	V	# )u;  User-facing one-liner: ``<prefix>: <gloss>. <consequence> <action>[ network hint]``.

The cause table lives in ``hermes_state_user_copy`` so CLI, gateway and TUI agree. Chat
surfaces (gateway, TUI) get the one-liner; ``details=True`` (the CLI banner) appends a
``Details: <raw cause>`` line for the raw SQLite text. Network filesystems (NFS/SMB/FUSE/ZFS)
cannot host SQLite's write-ahead log: when the raw cause carries one of those markers the
message names the network-drive suspicion, because ``hermes doctor --fix`` cannot repair a
mount â€” only moving the file can.)Úprofile_cli_selectorz. z Run `hermes z&doctor` to check the storage location.)Údescribe_storage_failurer¦   c              3   óH   <"  € T F  qSP                  4       9   x € K  	  R # 5i©N)Úlower)Ú.0ÚmÚcauses   & €rh   Ú	<genexpr>Ú0format_session_db_unavailable.<locals>.<genexpr>•  s   øé € Ð
=Ñ'< !�—‘“ÖÓ'<ùs   ƒ"TFÚunknownz{profile_arg}ú: Ú )Ústorage_failure_detailsz

Details: )Úhermes_constantsr  r4   Ú_SESSION_DB_CONSEQUENCEÚhermes_state_user_copyr  ÚglossÚactionÚanyrR   r"  Ú_NETWORK_DRIVE_GLOSSÚ_NETWORK_DRIVE_ACTIONÚreplaceÚ_NETWORK_DRIVE_HINTr(  )r  r  r  Úprofile_argr  Úfailurer,  r-  ÚhintÚtextr(  r"  s   &$         @rh   Úformat_session_db_unavailabler7  |  sñ   ø€ õ 6á&Ó(€KÜÓ!€Eßàˆh�bÔ0Ð1°¸{¸mð L ð  ð	
õ @Ù& uÓ-€GØ!Ÿ-™-¨¯©¸�4€Eß
ƒsÔ
=Õ'<Ó
=‡s‡s‚sÔ
=Õ'<Ó
=×=Ò=Ø�=‰=˜IÔ%Ü0Ô2G×2OÑ2OÐP_ÐalÓ2m‘6ä&ˆDØˆX�R˜�w˜bÔ!8Ð 9¸¸6¸(À4À&ÐI€DßÝBØ�+Ñ5°eÓ<Ð=Ð>Õ>ˆØ€Krj   g      ^@Úwin32c                ó$   € V ^8„  d   QhR\         /# ru   ©r¤   )rg   s   "rh   ri   ri   «  s   € ÷ :ñ :¬Tñ :rj   c                 ól   € \        \        RR4      RJ;'       d    \        \        P                  R4      # )z`Whether this runtime can switch off SQLite's close-time checkpoint (Python 3.12+ ``setconfig``).Ú SQLITE_DBCONFIG_NO_CKPT_ON_CLOSENÚ	setconfig)ÚgetattrÚsqlite3rÛ   Ú
Connectionr{   rj   rh   Ú#_close_time_checkpoint_configurablerA  «  s3   € ä”GÐ?ÀÓFÈdÐR÷ 9ð 9Üœ×*Ñ*¨KÓ8ð:rj   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# ©r`   rœ   rc   )re   r   r   )rg   s   "rh   ri   ri   ±  s   € ÷ ñ ´ð Ä(Ì4Å.ñ rj   c                ó  € \        T ;'       g    R4      P                  4       pV'       d	   V'       g   R# \        4       R,          p\        VRRR7       W2 R2,          pVP	                  RRR	7      ;_uu_ 4       pV Fa  pVf   K	  \        V\        4      '       d   TMR
\        V4      /pVP                  \        P                  ! VR\         R7      R,           4       Kc  	  RRR4       V#   + '       g   i     T# ; i)z—Append pending messages to HERMES_HOME/sessions/<id>.jsonl (state.db was replaced under a
live process). Returns the path, or None if nothing to write.r¦   Nrm   T)ÚparentsÚexist_okz.jsonlÚaúutf-8)Úencodingrõ   F)Úensure_asciiÚdefaultÚ
)
re   r  r   r   rÜ   rø   rò   ÚwriteÚjsonÚdumps)rœ   r   ÚsidÚsessions_dirrë   Úhandlerð   Úrecords   &&      rh   Údivert_session_transcript_jsonlrT  ±  sÉ   € ô ˆj×Ð˜BÓ
×
%Ñ
%Ó
'€Cß—hÙÜ"Ó$ zÕ1€LÜ�,¨°tÕ<Ø˜E ˜.Õ(€DØ	�‰�3 ˆ×	)Ô	)¨VÛˆCØŒÜ *¨3´× 5Ò 5™¸IÄsÈ3ÃxÐ;P�Ø—‘œTŸZšZ¨¸UÌCÔPÐSWÕWÖXñ ÷ 
*ð
 €K÷ 
*Ö	)ð
 €Kús   Á;C-ÂAC-Ã-C>	c                óh   € V ^8„  d   QhR\         R\        \        \        \        3,          ,          /# )r`   rÃ   rc   )r   r  Útuplerf   re   )rg   s   "rh   ri   ri   Ä  s'   € ÷ <ñ <¤tð <´´U¼3Ä¸8µ_Õ0Eñ <rj   c                ó.   € \         P                  ! V 4      # )z5Compatibility delegate to the state-holder authority.)Ú_state_holdersÚforeign_state_db_holders)rÃ   s   &rh   Ú_foreign_state_db_holdersrZ  Ä  s   € ä×2Ò2°7Ó;Ð;rj   c                   óð  a € ] tR tRt o RtR†tRRRutttRt	RRut
tR	tR
Rutt^2tRR^utttRRRutttR‡RˆuttRt]V 3R lR l4       t]V 3R lR l4       t]V 3R lR l4       t]V 3R lR l4       tV 3R lR ltR‰V 3R lR lltV 3R lR  lt V 3R! lR" lt!V 3R# lR$ lt"RŠV 3R% lR& llt#V 3R' lR( lt$V 3R) lR* lt%V 3R+ lR, lt&V 3R- lR. lt'V 3R/ lR0 lt(V 3R1 lR2 lt)V 3R3 lR4 lt*]+R5R6/V 3R7 lR8 ll4       t,R‹V 3R9 lR: llt-RŒV 3R; lR< llt.R�R=RR>R/V 3R? lR@ lllt/R�R>R/V 3RA lRB lllt0R�V 3RC lRD llt1R�V 3RE lRF llt2V 3RG lRH lt3V 3RI lRJ lt4V 3RK lRL lt5V 3RM lRN lt6V 3RO lRP lt7V 3RQ lRR lt8V 3RS lRT lt9V 3RU lRV lt:];V 3RW lRX l4       t<RŽV 3RY lRZ llt=V 3R[ lR\ lt>V 3R] lR^ lt?V 3R_ lR` lt@V 3Ra lRb ltARcR/V 3Rd lRe lltBV 3Rf lRg ltCV 3Rh lRi ltDV 3Rj lRk ltEV 3Rl lRm ltFV 3Rn lRo ltGV 3Rp lRq ltHRr tIV 3Rs lRt ltJR�tKR�tLR‘tM^dtN]OtP]QtR]StT]P^ ]R^]T^/tURutVRvtWRwtXRxtYV 3Ry lRz ltZR{R/V 3R| lR} llt[V 3R~ lR lt\V 3R€ lR� lt]V 3R‚ lRƒ lt^V 3R„ lt_R…t`V taR# )’Ú	SessionDBiÏ  zVSQLite-backed session storage with FTS5 search; many reader threads, one writer (WAL).g      4@r»   g      à?r¼   g{®Gáz”?g333333Ã?g       @g      Ð?ç      ð?éè  iô  i'  iPÃ  g      >@c                óF   <€ V ^8„  d   QhRS[ S[,          RS[ S[,          /# )r`   Úsystem_promptrc   ©r   re   )rg   r‡   s   "€rh   ri   ÚSessionDB.__annotate__  s#   ø€ ÷ ñ ±(¹3µ-ð ÁHÉSÅMñ rj   c                óž   € Vf   R # \         P                  ! VP                  R4      4      P                  4       pV P	                  RW!34       V# )NrH  zAINSERT OR IGNORE INTO system_prompts (hash, prompt) VALUES (?, ?))ÚhashlibÚsha256ÚencodeÚ	hexdigestÚexecute)Úconnr`  Úprompt_hashs   && rh   Ú_store_system_promptÚSessionDB._store_system_prompt  sJ   € àÒ ÙÜ—n’n ]×%9Ñ%9¸'Ó%BÓC×MÑMÓOˆØ�‰ØOØÐ(ô	
ð Ðrj   c                ó   <€ V ^8„  d   QhRR/# ©r`   rc   Nr{   )rg   r‡   s   "€rh   ri   rb    s   ø€ ÷ 
ñ 
°Tñ 
rj   c                ó(   € V P                  R 4       R# )zÔDELETE FROM system_prompts WHERE NOT EXISTS (SELECT 1 FROM sessions WHERE sessions.system_prompt_hash = system_prompts.hash) AND NOT EXISTS (SELECT 1 FROM sessions WHERE sessions.tool_names = system_prompts.hash)N)rh  ©ri  s   &rh   Ú#_delete_unreferenced_system_promptsÚ-SessionDB._delete_unreferenced_system_prompts  s   € à�‰ðVö	
rj   c                óP   <€ V ^8„  d   QhRS[ P                  RS[S[S[3,          /# )r`   Úrowrc   )r?  ÚRowrò   re   r
   )rg   r‡   s   "€rh   ri   rb    s'   ø€ ÷ ñ ™wŸ{™{ð ©t±C¹°H­~ñ rj   c                ó¤  € \        V 4      pR F1  pRV R2V9   g   K  VP                  RV R24      pW!9   g   K-  W1V&   K3  	  VP                  R4      '       d   VP                  R4      '       EgF   VP                  R4      pRp\        V\        4      '       d!   V'       d    \
        P                  ! V4      pM\        V\         4      '       d   Tp\        V\         4      '       dÏ   VP                  R4      '       gQ   VP                  R4      p\        V\        4      '       d*   VP                  4       '       d   VP                  4       VR&   VP                  R4      '       gQ   VP                  R4      p\        V\        4      '       d*   VP                  4       '       d   VP                  4       VR&   V#   \        \        3 d    Rp Lûi ; i)r`  Ú_Ú	_resolvedÚ_reset_fromÚ_branched_fromÚmodel_configN)r`  Ú
tool_names)
rò   Úpopro   rø   re   rN  ÚloadsÚ	TypeErrorÚ
ValueErrorr  )rt  ÚdataÚcolumnrÌ   ÚrawÚcfgrq   s   &      rh   Ú_session_row_dictÚSessionDB._session_row_dict  si  € ä�C‹yˆÛ5ˆFØ�6�(˜)Ð$¨Ö,ØŸ8™8 a¨ x¨yÐ$9Ó:�Ø–>Ø#+˜“Lñ	 6ð —‘˜×'Ò'¨D¯H©HÐ5E×,FÓ,FØ—(‘(˜>Ó*ˆCØˆCÜ˜#œs×#Ò#¯ðÜŸ*š* S›/‘Cô ˜C¤×&Ò&Ø�Ü˜#œt×$Ò$Ø—x‘x ×.Ò.ØŸG™G MÓ2�EÜ! %¬×-Ò-°%·+±+·-²-Ø.3¯k©k«m˜˜]Ñ+Ø—x‘xÐ 0×1Ò1ØŸG™GÐ$4Ó5�EÜ! %¬×-Ò-°%·+±+·-²-Ø16·±³˜Ð-Ñ.Øˆøô "¤:Ð.ô Ø’Cðús   Â$F9 Æ9GÇGc                óH   <€ V ^8„  d   QhRS[ S[P                  ,          RR/# )r`   ri  rc   N©r   r?  r@  )rg   r‡   s   "€rh   ri   rb  6  s*   ø€ ÷ Rñ R©±×1CÑ1CÕ(Dð RÈñ Rrj   c                ó†   € V f   R#  V P                  4        R#   \         d    \        P                  RRR7        R# i ; i)zCClose a partially initialized connection without masking its error.Nz&Could not close a SessionDB connectionT©Úexc_info)rÝ   rp   r  Údebugrp  s   &rh   Ú_close_connection_quietlyÚ#SessionDB._close_connection_quietly5  s=   € ð Š<Ùð	RØ�J‰JŽLøÜô 	RÜ�L‰LÐAÈDˆL×Qð	Rús   ˆ š"A ¿A c                ó$   <€ V ^8„  d   QhRS[ RR/# )r`   Úlabelrc   N©re   )rg   r‡   s   "€rh   ri   rb  ?  s   ø€ ÷ Sñ S©cð S°dñ Srj   c                óœ   €  VP                  4        R#   \         d-   p\        P                  RY P                  T4        Rp?R# Rp?ii ; i)zUClose *conn*; a failing close leaks a tracked fd: logged at WARNING, never swallowed.z%s close failed for %s: %sN)rÝ   rp   r  ÚwarningrÃ   )rŒ   ri  r�  Úexcs   &&& rh   Ú_close_conn_loggedÚSessionDB._close_conn_logged?  s;   € ð	SØ�J‰JŽLøÜô 	SÜ�N‰NÐ7¸ÇÁÈc×RÒRûð	Sús   ‚ ”AŸ!AÁANFc                ó4   <€ V ^8„  d   QhRS[ R,          RS[/# )r`   rÃ   NÚ	read_onlyrÔ   )rg   r‡   s   "€rh   ri   rb  F  s#   ø€ ÷ _.ñ _.¡ t¥ð _.¹tñ _.rj   c                ó<  € T;'       g    \        4       V n        \        V P                  4       W n        R V n        Rp \
        P                  ! ^4      pVP                  P                  RR4       RVP                  P                   RVP                   2V n        ?\        P                  ! 4       V n        \         P"                  ! \$        R7      V n        \)        V P                  4      V n        V P*                  P,                  V n        \        P                  ! 4       V n        RV n        RV n        R^ uV n        V n        RV n        ^ V n        / V n        R;V n         V n!        RV n"        \        P                  ! 4       V n#        RV n$        RV n%        / V n&        RR	uV n'        V n(        RV n)        R;V n*        ;V n+        V n,        R;V n-        ;V n.        V n/        RV n0        \c        4       V n2        \        Pf                  ! \        P                  ! 4       4      V n4        RV n5        R;V n6        V n7        RV n8        RV n9        Rp V'       d   V Pu                  4        M/\w        4       '       g   \y        4       V n$        V P{                  4        V P}                  4        R
p T'       g'   T P`                  Ruq`n0        T P…                  T4       R# T P*                  P‡                  T 4       \‰        T 4       R#   \         d     ELii ; i  ?i ; i  \         d*   p\        \�        T4      P‚                   RT 24       h Rp?ii ; i  T'       g&   T P`                  Ruq`n0        T P…                  T4       i T P*                  P‡                  T 4       \‰        T 4       i ; i)r%  Nr�   Ú?Ú.Ú:)ÚmaxsizeFg        r¦   Tr&  )ErÁ   rÃ   rÑ   r˜  Ú_creation_siteÚsysÚ	_getframeÚ	f_globalsro   Úf_codeÚco_nameÚf_linenorp   Ú	threadingÚLockÚ_lockÚqueueÚ	LifoQueuer5   Ú
_read_poolr7   Ú_read_budgetÚpermitsÚ_read_permitsÚ_read_conns_lockÚ_read_conns_closedÚ_read_open_failed_atÚ_wal_activeÚ_write_countÚ_db_file_identityÚ_db_file_application_idÚ_db_sidecar_identityÚ_db_replacedÚ_db_wal_generation_lostÚ_retired_generation_captureÚ_retired_capture_lockÚ_retire_connectionÚ_connection_pinnedÚ_wal_lock_guardÚ_db_corruptÚ_db_corrupt_reasonÚ_fts_usermerge_floor_appliedÚ_fts_enabledÚ
_fts_staleÚ_trigram_availableÚ_fts_cjk_loadedÚ_fts_cjk_availableÚ_fts_unavailable_warnedÚ_connr   Ú_token_queueÚ	ConditionÚ_token_queue_condÚ_token_writer_threadÚ_token_writer_stopÚ_token_writer_busyÚ_token_atexit_hookÚ_shared_registry_ownedÚ_open_read_onlyrA  rB   Ú_open_writerÚ_record_db_file_identityr3   Útyper�   r�  Úregisterr2   )rŒ   rÃ   r˜  ÚcallerÚinitialization_completer”  ri  s   &&&    rh   r‹   ÚSessionDB.__init__F  s,  € Ø×4Ð4Ô"2Ó"4ˆŒÜ˜tŸ|™|Ô,Ø"Œà'ˆÔØˆð	Ü—]’] 1Ó%ˆFà×#Ñ#×'Ñ'¨
°CÓ8Ð9¸¸6¿=¹=×;PÑ;PÐ:QÐQRÐSY×SbÑSbÐRcÐdð Ôð Ü—^’^Ó%ˆŒ
ô @E¿ºÔWeÔ?fˆŒô -¨T¯\©\Ó:ˆÔØ!×.Ñ.×6Ñ6ˆÔÜ )§¢Ó 0ˆÔð #(ˆÔð %(ˆÔ!Ø.3°QÐ+ˆÔ˜$Ô+ð 37ˆÔØ,-ˆÔ$Ø68ˆÔ!Ø;@Ð@ˆÔ˜DÔ8à;?ˆÔ(Ü%.§^¢^Ó%5ˆÔ"ØCGˆÔØ"'ˆÔØ%'ˆÔØ49¸2Ð1ˆÔ˜$Ô1Ø,1ˆÔ)ØHMÐMˆÔÐM˜DœO¨dÔ.Eð Y^Ð]ˆÔÐ]˜tÔ6¸Ô9UØˆŒ
ä#(£7ˆÔÜ!*×!4Ò!4´Y·^²^Ó5EÓ!FˆÔØ@DˆÔ!Ø<AÐAˆÔ $Ô"9Ø@DˆÔð ',ˆÔ#Ø"'Ðð	.ßØ×$Ñ$Õ&ô
 ;×<Ò<Ü.LÓ.N�DÔ+Ø×!Ñ!Ô#Ø×)Ñ)Ô+Ø&*Ñ#÷ +Ø#'§:¡:¨tÐ �”jØ×.Ñ.¨tÖ4ð ×!Ñ!×*Ñ*¨4Ô0ô (¨Ö-øôg ô 	Úð	ûñ ûôD ô 	ä ¤D¨£I×$6Ñ$6Ð#7°r¸#¸Ð!?Ô@Øûð	û÷
 +Ø#'§:¡:¨tÐ �”jØ×.Ñ.¨tÕ4ð ×!Ñ!×*Ñ*¨4Ô0ô (¨Õ-úsJ   ¿AK7 ÉAL Ë7LÌL	 ÌLÌL	 Ì	LÌMÌ$L>Ì>MÍM ÍANc                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  §  s   ø€ ÷ 2Añ 2A˜dñ 2Arj   c                ó   € \        V P                  P                  4        V P                  P                  4       '       d   \	        V P                  4      '       d¡   \        V P                  RRR7       \        V P                  4      ;_uu_ 4       pV'       g!   \        P                  RV P                  4       \        V P                  RR7       V P                  VR7       V P                  4        RRR4       M:\        V P                  RR7       V P                  RR7       V P                  4         V P)                  4        V P*                  '       d(   \,        P.                  ! V P                  4      V n        R# R#   + '       g   i     L[; i  \        P                   d¥   p\        T4      '       d   \        T P                  4      '       g   h \        P                  R	T4       T P!                  T P"                  4       \%        T P                  4      P'                  R
4      '       g   h T P                  4         Rp?ELRp?ii ; i)z†Writable open: preflight, zero-byte quarantine, connect + schema (one in-place repair of a
malformed sqlite_master), generation stamp.rº   T)Údb_labelÚdirectory_onlyzAstartup quarantine lock for %s not acquired within 5s; proceeding©rÙ  ©Úalready_lockedNFu`   state.db schema is malformed (%s) â€” attempting automatic repair (a backup copy is made first).r  )r	   rÃ   ÚparentÚexistsrF   rW   rH   r  r“  Ú_handle_quarantine_if_invalidÚ$_connect_and_init_with_lock_patiencer?  ÚDatabaseErrorr,   rV   Úerrorr�  rÆ  rX   ro   Ú_ensure_db_file_generationr±  Ú
_lockguardÚholdr¼  )rŒ   Úlock_acquiredr”  s   &  rh   rÐ  ÚSessionDB._open_writer§  sª  € ô
 	  §¡× 3Ñ 3Ô4ð%	8ð —<‘<×&Ñ&×(Ò(Ô,MÈdÏlÉl×,[Ò,[ô )¨¯©À
Ð[_Õ`Ü2°4·<±<×@Ô@ÀMß(ÜŸ™Ø_Ø ŸL™Lôô -¨T¯\©\ÀJÕOØ×6Ñ6ÀmÐ6ÔTØ×=Ñ=Ô?÷ AÐ@ô )¨¯©À
ÕKØ×2Ñ2À%Ð2ÔHØ×9Ñ9Õ;ð 	×'Ñ'Ô)Ø××Ðô $.§?¢?°4·<±<Ó#@ˆDÖ ñ	 ÷C A×@ûô$ ×$Ñ$ô 	8ô -¨S×1Ò1Ô9NÈtÏ|É|×9\Ò9\ØÜ�L‰Lð8Ø9<ôð ×*Ñ*¨4¯:©:Ô6Ü)¨$¯,©,Ó7×;Ñ;¸J×GÒGØØ×5Ñ5×7Ò7ûð	8ús>   ¡A0F ÂA"FÃ3F Ã<9F ÆF	ÆF ÆF ÆIÆ)BIÉIc                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  Û  s   ø€ ÷  =ñ  = ñ  =rj   c                óv  € \        \        ^,           4       F„  p V P                  \        R7      ;V n        p \        VRR7       VP                  4       pV P                  VR4      RJ V n        V P                  '       d   V P                  VR4      RJ V n	         R# 	  R#   \         d    RT n        T P                  T4       h i ; i  \        P                   d[   p\        \        T4      P!                  4       9   pT\        8¼  g	   T'       g   h \"        P$                  ! \&        4        Rp?EK  Rp?ii ; i)a~  Read-only attach for cross-profile aggregation: no schema init, NO write
lock (sidebar polling never contends with that profile's backend); the DB
must exist. FTS flags are probed with SELECTs only, and the connection is
closed on ANY probe failure (malformed schema raises DatabaseError) so a
leaked tracked connection cannot block the forensic backup the writable heal takes next.©Útimeoutrº   rÛ  Úmessages_ftsTÚmessages_fts_trigramN)ÚrangeÚ_READ_ONLY_IOERR_RETRY_ATTEMPTSÚ_connect_read_onlyÚ_READ_BUSY_TIMEOUT_SrÆ  rT   ÚcursorÚ_fts_table_proberÀ  rÂ  ÚBaseExceptionr�  r?  ÚOperationalErrorr!   re   r  ÚtimeÚsleepÚ _READ_ONLY_IOERR_RETRY_BACKOFF_S)rŒ   Úattemptri  ró  ÚioerrÚ	transients   &     rh   rÏ  ÚSessionDB._open_read_onlyÛ  s  € ô Ô<¸qÕ@ÖAˆGð=Ø$(×$;Ñ$;ÔDXÐ$;Ó$YÐY�”
˜TðÜ*¨4¸*ÕEØ!Ÿ[™[›]�FØ(,×(=Ñ(=¸fÀnÓ(UÐY]Ð(]�DÔ%Ø×(×(Ð(à ×1Ñ1°&Ð:PÓQÐUYÐYð Ô/ò ó Bøô %ô Ø!%�D”JØ×2Ñ2°4Ô8Øðûô
 ×+Ñ+ô 
=ô 2´S¸³Z×5EÑ5EÓ5GÑG�	ØÔ=Ô=ÇYØÜ—
’
Ô;×<Ó<ûð
=ús/   ›C	¹A!B!Â!%CÃC	Ã	D8Ã2D3ÄD3Ä3D8c                ó:   <€ V ^8„  d   QhRS[ RS[P                  /# )r`   rì  rc   )Úfloatr?  r@  )rg   r‡   s   "€rh   ri   rb  ý  s!   ø€ ÷ ñ ©%ð ±G×4FÑ4Fñ rj   c           	     óŒ   € \        \        V P                  4      V P                  RRVRR7      p\        P                  Vn        V# )z»``mode=ro`` tracked connection with Row factory. check_same_thread=False: pooled connections
are borrowed by whichever thread reads next; exclusive ownership is enforced by pool checkout.TFN)Útracking_pathÚuriÚcheck_same_threadrì  Úisolation_level)r@   r   rÃ   r?  ru  Úrow_factory)rŒ   rì  ri  s   && rh   rñ  ÚSessionDB._connect_read_onlyý  s<   € ô #Ü˜TŸ\™\Ó*¸$¿,¹,ÈDØ#¨WÀdô
ˆô #Ÿ;™;ˆÔØˆrj   c                ó$   <€ V ^8„  d   QhRS[ RR/# )r`   rÝ  rc   Nr:  )rg   r‡   s   "€rh   ri   rb    s   ø€ ÷ -ñ -¹Dð -ÈTñ -rj   c                ón  € V P                   P                  4       '       d   \        V P                   4      '       g   R#  V P                   P                  4       P                  p\        V P                   VR7      pV'       d   RV 2MRpRT RT RT;'       g    V P                    R2p\        P                  V4       \        V4       VfV   V P                   P                  4       '       d4   \        V P                   4      '       d   \        P                  ! V4      hR# R# R#   \
         d    R	p LÐi ; i)
z•Quarantine a zero-byte/headerless state.db so a fresh one can open; if quarantine failed,
raise the clear message instead of opening the zeroed file.NrÜ  zmoved aside to z+left in place (it could not be moved aside)zstate.db was empty or damaged (z bytes) and has been zy; Hermes started with a fresh, empty session database. To bring old sessions back, run `hermes sessions recover --source zz --inspect-only`, or restore a snapshot with `/snapshot list` then `/snapshot restore <id>` (terminal `hermes` chat only).éÿÿÿÿ)rÃ   rß  rF   rã   Úst_sizer²   rI   r  rã  r3   r?  râ  )rŒ   rÝ  ÚzsizeÚqpathÚwhererð   s   &&    rh   rà  Ú'SessionDB._handle_quarantine_if_invalid  s  € ð —‘×#Ñ#×%Ò%Ô*KÈDÏLÉL×*YÒ*YÙð	Ø—L‘L×%Ñ%Ó'×/Ñ/ˆEô ,¨D¯L©LÈÔXˆß-2�/ % Ñ)Ð8eˆà-¨e¨WÐ4IÈ%Èð Q1à16×1FÐ1F¸$¿,¹,Ð0Gð Hjðjð 	ô 	�‰�SÔÜ˜SÔ!ØŠ=˜TŸ\™\×0Ñ0×2Ò2Ô7XÐY]×YeÑYe×7fÒ7fÜ×'Ò'¨Ó,Ð,ñ 8gÑ2‰=øô ô 	ØŠEð	ús   ¿$D$ Ä$D4Ä3D4c                ó4   <€ V ^8„  d   QhRS[ P                  /# ru   )r?  r@  )rg   r‡   s   "€rh   ri   rb    s   ø€ ÷ ñ ¡7×#5Ñ#5ñ rj   c                ó˜  € \        \        V P                  4      RRRR7      p \        P                  Vn        \        VRR7      pVR8H  ;'       d    \        V4      R8H  V n        \        V P                  4       \        VRR7       VP                  R4       \        V4      V n        V#   \         d    T P                  T4       h i ; i)	zÝConnect + WAL/pragma/tokenizer setup for a writer connection (no schema init). Short timeout:
jittered application-level retry handles contention, not SQLite's busy handler;
isolation_level=None: explicit BEGIN IMMEDIATE.Fr]  N)r  rì  r  rº   rÛ  ÚwalzPRAGMA foreign_keys=ON)r@   re   rÃ   r?  ru  r  rU   rS   r±  rí   rT   rh  r:   rÃ  rõ  r�  )rŒ   ri  Úmodes   &  rh   Ú_open_writer_connÚSessionDB._open_writer_conn  s»   € ô #Ü�—‘Ó°ÀÐUYô
ˆð	Ü&Ÿ{™{ˆDÔÜ*¨4¸*ÔEˆDð
  $ u™}×UÐUÔ1FÀtÓ1LÐPUÑ1UˆDÔô # 4§<¡<Ô0Ü" 4°*Õ=Ø�L‰LÐ1Ô2Ü#:¸4Ó#@ˆDÔ ð ˆøô ô 	Ø×*Ñ*¨4Ô0Øð	ús   ¤BB+ Â+C	c                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  7  s   ø€ ÷ ñ  4ñ rj   c                ó¨   € \        V P                  4       \        V P                  R R7       V P                  4       V n        V P                  4        R# )T)rÒ   N)rL   rÃ   rí   r  rÆ  Ú_init_schema©rŒ   s   &rh   Ú_connect_and_initÚSessionDB._connect_and_init7  s<   € ô 	& d§l¡lÔ3ô 	˜tŸ|™|¸Õ>Ø×+Ñ+Ó-ˆŒ
Ø×ÑÖrj   c                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  A  s   ø€ ÷ Dñ D°dñ Drj   c           
     óD  € \         P                  ! 4       V P                  ,           p  V P                  4        R#   \        P
                   dÐ   p\        T4      '       g   h T P                  T P                  4       \         P                  ! 4       pY18¼  d"   \        T P                  T P                  4       h \        P                  ! T P                  T P                  4      p\         P                  ! \!        T\#        Y,
          R4      4      4        Rp?Kó  Rp?ii ; i)a  Open + init, waiting out a sibling's write lock with jittered patience:
_init_schema's DDL runs on a 1s-timeout connection, so a sibling's VACUUM
or checkpoint used to fail the ENTIRE open and callers disabled
persistence for the whole run. Non-lock errors propagate immediately.Nçü©ñÒMbP?)r÷  Ú	monotonicÚ_WRITE_PATIENCE_Sr  r?  rö  r-   r�  rÆ  r?   rÃ   ÚrandomÚuniformÚ_WRITE_RETRY_SLOW_MIN_SÚ_WRITE_RETRY_SLOW_MAX_Srø  ÚminÚmax)rŒ   Údeadliner”  ÚnowÚjitters   &    rh   rá  Ú.SessionDB._connect_and_init_with_lock_patienceA  sÎ   € ô —>’>Ó# d×&<Ñ&<Õ<ˆØðDØ×&Ñ&Ô(ÙøÜ×+Ñ+ô 	DÜ+¨C×0Ò0ØØ×.Ñ.¨t¯z©zÔ:Ü—n’nÓ&�Ø”?Ü*¨4¯<©<¸×9OÑ9OÔPØÜŸš¨×(DÑ(DÀd×FbÑFbÓc�Ü—
’
œ3˜v¤s¨8­>¸5Ó'AÓB×CÒCûð	Dús   ©; »DÁCDÄDc                óD   <€ V ^8„  d   QhRS[ S[P                  ,          /# ru   rˆ  )rg   r‡   s   "€rh   ri   rb  ^  s   ø€ ÷ 'ñ '¡©×);Ñ);Õ <ñ 'rj   c                ó4  € V P                   '       d   V P                  '       d   R# V P                  ;_uu_ 4        V P                  pT;'       d$    \        P
                  ! 4       V,
          \        8  pV P                  '       g	   V'       d    RRR4       R#  RRR4       V P                  P                  V 4      '       g(   \        P                  R\        V P                  4       R# Rp V P                  \        R7      p\!        VRR7       V P"                  '       d   \%        V4       V#   + '       g   i     L�; i  \&         dÊ   pTe   T P)                  TR4       T P                  P+                  4        \-        T\.        P0                  4      '       g   h T P                  ;_uu_ 4        \        P
                  ! 4       T n        RRR4       M  + '       g   i     M; i\        P                  RT P                  RR	7        Rp?R# Rp?ii ; i)
as  Open a fresh read-only connection, or None when unavailable (callers
return it to self._read_pool). WAL only: WAL readers never block on the
writer, so reads skip self._lock; under DELETE journal mode (NFS fallback)
readers hit SQLITE_BUSY storms, so the legacy locked path stays. Autocommit
reads see everything committed so far (read-your-writes for flush-then-search).NzVread pool at capacity (%d) for %s; serving this read from the locked writer connectionrë  rº   rÛ  zpartially-opened read connz'read-only connection open failed for %sTrŠ  )r±  r˜  r®  r°  r÷  r  Ú_READ_OPEN_RETRY_SECONDSr¯  r«  Úacquirer  rŒ  r5   rÃ   rñ  rò  rT   rÃ  r:   rõ  r•  Úreleaserø   r?  ÚError)rŒ   Ú	failed_atÚbacking_offri  r”  s   &    rh   Ú_get_read_connÚSessionDB._get_read_conn^  s�  € ð ××Ð 4§>§> >ÙØ×"×"Ó"Ø×1Ñ1ˆIØ#×_Ð_¬¯ªÓ(8¸9Õ(DÔG_Ñ(_ˆKØ×&×&Ð&¯+Ø÷	 #Ñ"ð +6÷ #ð × Ñ ×(Ñ(¨×.Ò.Ü�L‰Lð+Ü,:¸D¿L¹Lôñ Øˆð	Ø×*Ñ*Ô3GÐ*ÓHˆDÜ" 4°*Õ=Ø×#×#Ð#Ü'¨Ô-ð ˆ÷? #×"ûô$ ô 	ð ÒØ×'Ñ'¨Ð.JÔKØ×Ñ×%Ñ%Ô'Ü˜c¤7§=¡=×1Ò1ØØ×&×&Ó&Ü,0¯NªNÓ,<�Ô)÷ '×&×&Ð&úä�L‰LÐBÀDÇLÁLÐ[_ˆLÔ`Ýûð	úsJ   »AD0ÂD0ÂD0Ã.A E Ä0E 	ÅHÅA%HÆ3GÇ	HÇG'Ç"*HÈHc                ó    <€ V ^8„  d   QhRS[ /# ru   r:  )rg   r‡   s   "€rh   ri   rb  ‡  s   ø€ ÷ ñ ©4ñ rj   c                ó–   €  V P                   P                  4       pT P	                  T4       R#   \        P                   d     R# i ; i)z^Close one idle pooled connection (a peer on the same file wants its permit); never a live one.FT)rª  Ú
get_nowaitr¨  ÚEmptyÚ_close_read_conn©rŒ   ri  s   & rh   Ú_evict_one_idle_read_connÚ#SessionDB._evict_one_idle_read_conn‡  sD   € ð	Ø—?‘?×-Ñ-Ó/ˆDð 	×Ñ˜dÔ#Ùøô �{‰{ô 	Úð	ús   ‚/ ¯AÁAc                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  �  s   ø€ ÷ (ñ (¨ñ (rj   c                óž   €  V P                  VR4       V P                  P                  4        R#   T P                  P                  4        i ; i)z»Close a pooled read connection and release its permit even when the close fails (withholding
it would narrow the read path forever). Over-releasing the BoundedSemaphore raises ValueError.z	read-connN)r•  r«  r.  r9  s   &&rh   r8  ÚSessionDB._close_read_conn�  s<   € ð	(Ø×#Ñ# D¨+Ô6à×Ñ×%Ñ%Ö'øˆD×Ñ×%Ñ%Õ'ús	   ‚0 °Ac                óD   <€ V ^8„  d   QhRS[ S[P                  ,          /# ru   rˆ  )rg   r‡   s   "€rh   ri   rb  ˜  s   ø€ ÷ )ñ )¡X©g×.@Ñ.@Õ%Añ )rj   c                óÚ   € V P                   '       d   V P                  '       d   R#  V P                  P                  4       #   \        P
                   d    T P                  4       u # i ; i)z“Borrow a read connection, opening on a miss; None when the read path is unavailable.
A pool hit costs no permit (the connection already holds one).N)r±  r˜  rª  r6  r¨  r7  r2  r  s   &rh   Ú_checkout_read_connÚSessionDB._checkout_read_conn˜  sU   € ð ××Ð 4§>§> >Ùð	)Ø—?‘?×-Ñ-Ó/Ð/øÜ�{‰{ô 	)Ø×&Ñ&Ó(Ò(ð	)ús   ¨A Á%A*Á)A*ÚreopenTc                óJ   <€ V ^8„  d   QhRS[ RS[S[P                  ,          /# )r`   rC  rc   )r¤   r   r?  r@  )rg   r‡   s   "€rh   ri   rb  £  s*   ø€ ÷ )Lñ )L¡4ð )L±8¹G×<NÑ<NÕ3Oñ )Lrj   c             #  óp  "  € V P                  4       pVep    Vx € RpV P                  ;_uu_ 4        V P                  '       g    V P                  P	                  V4       RpRRR4       V'       g   V P                  V4       R# V P                  ;_uu_ 4        V P                  f?   V'       g%   \        P                  ! RV P                   R24      hV P                  RR7       \        \        P                  V P                  4      pV P                   '       g   V P"                  '       d   Vx €  RRR4       R# VP%                  R4      P'                  4       ^ ,          pVP%                  R	\)        \*        R
,          4       24        Vx € \-        \        P.                  4      ;_uu_ 4        VP%                  R	\)        V4       24       RRR4       RRR4       R#   \
        P                   d     EL—i ; i  + '       g   i     EL¤; i  RpT P                  ;_uu_ 4        T P                  '       g;    T P                  P	                  T4       RpM  \
        P                   d     Mi ; iRRR4       M  + '       g   i     M; iT'       g   T P                  T4       i i ; i  + '       g   i     Lè; i  \-        \        P.                  4      ;_uu_ 4        TP%                  R	\)        T4       24       RRR4       i   + '       g   i     i ; i; i  + '       g   i     R# ; i5i)u¡  Yield a connection for read-only statements: a pooled read-only
connection with NO lock under WAL; otherwise (non-WAL, open failure,
ceiling reached) the writer connection under self._lock â€” deliberate
degradation: slower beats EMFILE, which the supervisor cannot see.
``reopen=False``: a read after ``close()`` raises instead of reopening the
writer (an optional reader must not hold a home that is being deleted).NFTúSessionDB for z
 is closedÚread©ÚcontextzPRAGMA busy_timeoutzPRAGMA busy_timeout=r^  )rA  r®  r¯  rª  Ú
put_nowaitr¨  ÚFullr8  r§  rÆ  r?  ÚProgrammingErrorrÃ   Ú_reopen_after_close_lockedr   r@  r±  r˜  rh  Úfetchonerf   rò  r   r/  )rŒ   rC  ri  ÚreturnedÚprevious_mss   &$   rh   Ú	_read_ctxÚSessionDB._read_ctx¢  sa  é € ð ×'Ñ'Ó)ˆØÒð0Ø’
à �Ø×*×*Ó*Ø×2×2Ð2ð!Ø ŸO™O×6Ñ6°tÔ<Ø'+˜H÷	 +÷  ð ×)Ñ)¨$Ô/ÙØ�Z�Z‹ZØ�z‰zÒ!ßÜ!×2Ò2°^ÀDÇLÁLÀ>ÐQ[Ð3\Ó]Ð]Ø×/Ñ/¸Ð/Ô?Üœ×*Ñ*¨D¯J©JÓ7ˆDØ××Ð 4§>§> >Ø’
Ø÷ ‰Zð Ÿ,™,Ð'<Ó=×FÑFÓHÈÕKˆKØ�L‰LÐ/´Ô4HÈ4Õ4OÓ0PÐ/QÐRÔSðLØ’
äœgŸm™m×,Õ,Ø—L‘LÐ#7¼¸KÓ8HÐ7IÐ!JÔK÷ -÷ ‰Zøô  %Ÿz™zô !Ú ð!ú÷ +×*Ð*ûð !�Ø×*×*Ó*Ø×2×2Ð2ð!Ø ŸO™O×6Ñ6°tÔ<Ø'+™HøÜ$Ÿz™zô !Ù ð!ú÷ +×*×*Ð*ú÷  ð ×)Ñ)¨$Õ/ð  ú÷( -×,û”XœgŸm™m×,Õ,Ø—L‘LÐ#7¼¸KÓ8HÐ7IÐ!JÔK÷ -×,×,Ð,ý÷ �ZˆZüs  ‚L6˜H œL6²G>ÁG"Á#L6Á3'L6ÂL"Â1A=L"Ä/L"Ä4
L6Ä>AL"ÆKÆ!L"Æ2J0	ÇL"Ç
L6Ç"G;Ç7G>Ç:G;Ç;G>Ç>H	È		L6ÈJ-È)I?	È=IÉI?	ÉI3É0I?	É2I3É3I?	É6	J-É?JÊ
J-ÊJ-Ê-L6Ê0K Ê;L"Ë"LË%LÌ	LÌLÌLÌL"Ì"L3	Ì-	L6c                ó$   <€ V ^8„  d   QhRS[ RR/# )r`   rI  rc   Nr‘  )rg   r‡   s   "€rh   ri   rb  Î  s   ø€ ÷  Añ  A±#ð  AÀDñ  Arj   c                ó�  € V P                   '       d(   \        P                  ! RV P                   RV R24      hV P                  '       dK   V P
                  '       g9   V P                  4       '       g#   V P                  RV P                   RV R24      hV P                  4        \        P                  RV P                  V4        V P                  4       V n        T P                  '       d(   \         P"                  ! T P                  4      T n        R
# R
#   \         d#   p\        P                  ! RT R	T 24      ThR
p?ii ; i)a+  Reopen the writer after ``close()`` raced a live caller (a teardown owner
set ``_conn = None`` while a worker still had a transcript flush to land).
Loud (WARNING) and bounded (only after an explicit close()). Caller holds
``self._lock``. No _init_schema: no DDL races with siblings during teardown.rF  z/ was closed (read-only handle); cannot serve a z after close()zstate.db connection for zF is quarantined after structural corruption; refusing to reopen for a z after close(). uq   state.db connection for %s was closed while a %s was still in flight â€” reopening (teardown/worker race, #94736)z'state.db connection was closed while a u†    was still in flight (a session-teardown path called close() before this worker finished â€” #94736) and the automatic reopen failed: N)r˜  r?  rL  rÃ   r½  r¶  Ú_db_file_was_replacedÚ_corrupt_errorÚ_halt_if_db_generation_changedr  r“  r  rÆ  rp   rö  r±  rå  ræ  r¼  )rŒ   rI  r”  s   && rh   rM  Ú$SessionDB._reopen_after_close_lockedÎ  sB  € ð
 �>�>ˆ>Ü×*Ò*Ø  §¡ ð /"Ø") ¨.ð:óð ð ××Ð T×%6×%6Ð%6¸$×:TÑ:T×:VÒ:VØ×%Ñ%Ø*¨4¯<©<¨.ð 9CØCJÀ)ð L"ð"óð ð
 	×+Ñ+Ô-Ü�‰ðBØCGÇ<Á<ÐQXô	
ð	Ø×/Ñ/Ó1ˆDŒJð ××ÐÜ#-§?¢?°4·<±<Ó#@ˆDÖ ñ øô ô 	Ü×*Ò*Ø9¸'¸ð CUàUXÐTYð[óð ð	ûð	ús   ÃD ÄEÄ#E Å Ec                óh   <€ V ^8„  d   QhRS[ S[P                  .S[3,          RS[S[,          RS[/# )r`   ÚfnÚ
patience_src   )r   r?  r@  r¹   r   rÿ  )rg   r‡   s   "€rh   ri   rb  ð  sA   ø€ ÷ uñ uÙ™G×.Ñ.Ð/±Ð2Õ3ðuÙAIÉ%Åðuá	
ñurj   c                ó  € Vf   V P                   p\        P                  ! 4       V,           pRpRp V P                  RR7       Rp V P                  ;_uu_ 4        V P                  4        V P                  f   V P                  RR7       V P                  P                  R4        RpV! V P                  4      pV P                  P                  4         RRR4       T ;P                  ^,          un        T P                  T P                  ,          ^ 8X  d   T P                  4        T P                  T P                   ,          ^ 8X  d   T P#                  4        X#   \         d/     T P                  P                  4        h   \         d     h i ; ii ; i  + '       g   i     LË; i  \$         d\    Tf1   \'        \        P                  ! 4       T P(                  ,           T4      pT P+                  Y@P(                  4      '       d    EKà  h \,        P.                   Edä   p\1        T4      '       d   T P+                  Y24      '       d    Rp?EK%  \3        T4      P5                  4       p	\7        T\,        P8                  4      '       dž   \;        T4      '       dQ   T P+                  Y24      '       d    Rp?EK�  \=        T P>                  T4       \,        P8                  ! RTR	 R
24      Th\@        T	9   d1   T'       g)   T'       g!   T P+                  Y24      '       d
   Rp Rp?EKú  h \7        T\,        PB                  4      '       d¹   RT	9   g)   \E        T4      '       g   T PG                  T4      '       dB   T P                  ;_uu_ 4        T P                  4        RRR4       M  + '       g   i     M; iT PI                  YƒTR7      '       d    Rp?EK«  T PK                  T4      '       d   T PM                  T4       h Rp?ii ; i)ud  Run *fn(conn)* inside BEGIN IMMEDIATE with jittered lock retry; commit
is handled here (callers must not commit). Returns *fn*'s result.
BEGIN IMMEDIATE takes the WAL write lock up front so contention surfaces
immediately; on locked/busy the Python lock is released, a jitter slept,
and the WHOLE callback retried â€” *fn* must stay idempotent under retry.NFT)ÚstoragerM  rH  zBEGIN IMMEDIATEzQdatabase is locked (another Hermes process held the state.db write lock for over z.0fu‘   s â€” likely a long maintenance operation such as VACUUM, a large WAL checkpoint, or an older pre-update process; the database itself is healthy)znot a database)r&  r[  )'r  r÷  r  Ú_raise_if_db_corruptr§  Ú_raise_if_db_replacedrÆ  rM  rh  Úcommitrõ  Úrollbackrp   r²  Ú_CHECKPOINT_EVERY_N_WRITESÚ_try_wal_checkpointÚ_FTS_MERGE_EVERY_N_WRITESÚ_try_incremental_merge_ftsr&   r$  Ú_COMPRESSION_BUSY_WAIT_SÚ_sleep_before_write_retryr?  r/  r)   re   r  rø   rö  r-   r?   rÃ   r!   râ  r+   Ú_is_fts_write_corruption_errorÚ_enter_fts_fail_openÚ_is_structural_corruption_errorÚ_halt_db_corrupt)
rŒ   rZ  r[  r&  Úcompression_deadlineÚioerr_begin_retriedÚ
fn_startedÚresultr”  Úerr_msgs
   &&&       rh   Ú_execute_writeÚSessionDB._execute_writeð  sD  € ð ÒØ×/Ñ/ˆJÜ—>’>Ó# jÕ0ˆØ04Ðð $ÐØØ×%Ñ%¨dÐ%Ô3ð ˆJðUØ—Z—Z“ZØ×.Ñ.Ô0Ø—z‘zÒ)Ø×7Ñ7ÀÐ7ÔHØ—J‘J×&Ñ&Ð'8Ô9ð	Ø%)˜
Ù!# D§J¡J£˜ØŸ
™
×)Ñ)Õ+÷  ð  ×!Ò! QÕ&Õ!Ø×$Ñ$ t×'FÑ'FÕFÈ!ÔKØ×,Ñ,Ô.Ø×$Ñ$ t×'EÑ'EÕEÈÔJØ×3Ñ3Ô5Ø�øô )ô ð!Ø ŸJ™J×/Ñ/Ô1ð øô  )ô !Ø Øð!úðú÷  —Zûô, 5ô ð (Ò/Ü+.¬t¯~ª~Ó/?À$×B_ÑB_Õ/_ÐaiÓ+jÐ(Ø×1Ñ1Ø(×*GÑ*G÷ò ó ØÜ—=‘=õ .ô $ C×(Ò(¨T×-KÑ-KÈH×-aÒ-aÞÜ˜c›(Ÿ.™.Ó*�Ü˜c¤7×#;Ñ#;×<Ò<Ü+¨C×0Ò0Ø×9Ñ9¸(×OÒOÞ$ô /¨t¯|©|¸ZÔHÜ%×6Ò6ð<Ø<FÀsÐ;Kð LGðGóð  #ð#ô .°Ô8Ç×TgØ ×:Ñ:¸8×PÒPð /3Ð+Þ ØÜ˜c¤7×#8Ñ#8×9Ò9ð )¨GÔ3Ô7LÈS×7QÒ7QØ×>Ñ>¸s×CÒCà!ŸZŸZ›ZØ ×6Ñ6Ô8÷ (ŸZŸZ˜Zúð ×0Ñ0°ÐT^Ð0×_Ò_Þ à×;Ñ;¸C×@Ò@Ø×-Ñ-¨cÔ2Øûð].úsÀ   ÁF- ÁAFÂ(.EÃBF- ÅFÅ*FÆFÆF	ÆFÆF	ÆFÆFÆF*	Æ%F- Æ-A P
ÈP
È&P
È'(PÉA!PÊ>APÌPÌPÌ+APÍ;PÎN)Î 	PÎ)N9Î4!PÏPÏ3PÐP
Úmanyr[  c          
      óF   <€ V ^8„  d   QhRS[ RS[RS[RS[S[,          RR/# )r`   ÚsqlÚparamsrs  r[  rc   N)re   r
   r¤   r   rÿ  )rg   r‡   s   "€rh   ri   rb  g  s:   ø€ ÷ 8ñ 8Ùð8Ù #ð8Ù37ð8ÙMUÑV[Í_ð8à	ñ8rj   c               ó@   aaa€ VVV3R lpV P                  WTR7       R# )z8Run one INSERT/UPDATE/DELETE through ``_execute_write``.c                 óV   <€ S'       d   V P                   MV P                  ! SS4       R # r  )Úexecutemanyrh  )ri  rs  rv  ru  s   &€€€rh   Ú_doÚ!SessionDB._write_sql.<locals>._dok  s   ø€ ß!%ˆT×Ò¨4¯<©<Ð7¸¸fÖErj   ©r[  N©rq  )rŒ   ru  rv  rs  r[  rz  s   &ffd$ rh   Ú
_write_sqlÚSessionDB._write_sqlg  s   ú€ ÷	Fà×Ñ˜CÐÖ7rj   c                óB   <€ V ^8„  d   QhRS[ RS[RS[S[,          RS[/# )r`   ru  rv  r[  rc   )re   r
   r   rÿ  rf   )rg   r‡   s   "€rh   ri   rb  o  s/   ø€ ÷ ?ñ ?¡3ð ?±ð ?ÉÑRWÍð ?Ñdgñ ?rj   c               ó8   aa€ VV3R lpV P                  WCR7      # )z…Run one UPDATE/DELETE through ``_execute_write``; return rows changed
(``SELECT changes()`` when the driver reports None / negative).c                 ó¢   <€ V P                  SS4      P                  pVe   V^ 8  d'   V P                  R4      P                  4       ^ ,          pV# )NzSELECT changes())rh  ÚrowcountrN  )ri  rƒ  rv  ru  s   & €€rh   rz  Ú&SessionDB._write_rowcount.<locals>._dor  sG   ø€ Ø—|‘| C¨Ó0×9Ñ9ˆHØÒ 8¨a¤<ØŸ<™<Ð(:Ó;×DÑDÓFÀqÕI�ØˆOrj   r|  r}  )rŒ   ru  rv  r[  rz  s   &ff$ rh   Ú_write_rowcountÚSessionDB._write_rowcounto  s   ù€ ö	ð
 ×"Ñ" 3Ð"Ó>Ð>rj   c                óP   <€ V ^8„  d   QhRS[ RS[RS[S[P                  ,          /# ©r`   ru  rv  rc   )re   r
   r   r?  ru  )rg   r‡   s   "€rh   ri   rb  y  s0   ø€ ÷ \ñ \™Sð \©#ð \±xÁÇÁÕ7Lñ \rj   c                ó2   aa€ V P                  VV3R l4      # )z<``fetchone()`` of one read-only statement via ``_read_ctx``.c                 óD   <€ V P                  SS4      P                  4       # r  )rh  rN  ©ri  rv  ru  s   &€€rh   Ú<lambda>Ú%SessionDB._read_one.<locals>.<lambda>{  ó   ø€ °d·l±lÀ3ÈÓ6O×6XÑ6XÔ6Zrj   ©Ú_read_retrying_ioerr©rŒ   ru  rv  s   &ffrh   Ú	_read_oneÚSessionDB._read_oney  ó   ù€ à×(Ñ(Õ)ZÓ[Ð[rj   c                óP   <€ V ^8„  d   QhRS[ RS[RS[S[P                  ,          /# rˆ  )re   r
   r  r?  ru  )rg   r‡   s   "€rh   ri   rb  }  s0   ø€ ÷ \ñ \™Sð \©#ð \±t¹G¿K¹KÕ7Hñ \rj   c                ó2   aa€ V P                  VV3R l4      # )z<``fetchall()`` of one read-only statement via ``_read_ctx``.c                 óD   <€ V P                  SS4      P                  4       # r  )rh  Úfetchallr‹  s   &€€rh   rŒ  Ú%SessionDB._read_all.<locals>.<lambda>  rŽ  rj   r�  r‘  s   &ffrh   Ú	_read_allÚSessionDB._read_all}  r”  rj   c                óR   <€ V ^8„  d   QhRS[ S[P                  .S[3,          RS[/# )r`   rZ  rc   )r   r?  r@  r¹   )rg   r‡   s   "€rh   ri   rb  �  s.   ø€ ÷ ñ ¡x±×1CÑ1CÐ0DÁaÐ0GÕ'Hð ÉQñ rj   c                ó   € \        \        ^,           4       F/  p V P                  4       ;_uu_ 4       pV! V4      uuRRR4       u # 	  R#   + '       g   i     KF  ; i  \        P                   dj   pT\        8¼  g#   \
        \        T4      P                  4       9  d   \        T P                  T4       h \        P                  ! \        4        Rp?KÂ  Rp?i\        P                   d   p\        T P                  T4       h Rp?ii ; i)aê  Run an idempotent SELECT through ``_read_ctx``, retrying a transient SQLITE_IOERR.

A warm ``mode=ro`` pooled reader can hit the same millisecond-wide WAL transition window as a
read-only OPEN (#100436) when its statement executes or steps: a sibling process's checkpoint /
WAL reset / frame flush surfaces ``disk I/O error`` because a read-only connection cannot rewrite
the -shm index (#100871, WSL2 ext4-on-vhdx, multi-process). The window closes on its own, so
the statement is replayed on the SAME connection within the read-only IOERR budget -- never
closed and reopened (close() cancels this process's POSIX locks for every sibling connection),
never quarantined (busy is not broken). A persistent IOERR exhausts the budget and propagates.N)rï  rð  rQ  r?  rö  r!   re   r  r   rÃ   r÷  rø  rù  râ  )rŒ   rZ  rú  ri  r”  s   &&   rh   r�  ÚSessionDB._read_retrying_ioerr�  sÀ   € ô Ô<¸qÕ@ÖAˆGðØ—^‘^×%Ô%¨Ù˜d›8÷ &Ô%ó Bç%×%Ð%ûä×+Ñ+ô =ØÔ=Ô=ÔAVÔ^aÐbeÓ^f×^lÑ^lÓ^nÔAnÜ& t§|¡|°SÔ9ØÜ—
’
Ô;×<Ò<ûÜ×(Ñ(ô ô # 4§<¡<°Ô5Øûð	úsF   ›A ³A»
A ÁAÁA ÁA Á DÁ5ACÃDÃ0DÃ1DÄDc                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  š  s   ø€ ÷ (Gñ (G¨Dñ (Grj   c                óˆ  € V P                   '       g   V P                  f   R# \        P                  ! 4       P                  p V P
                  ;_uu_ 4        V P                  P                  R\        34      P                  4       pV'       d   V^ ,          '       gR   V P                  P                  R\        V34       V P                  P                  R\        34      P                  4       pV'       d"   V^ ,          '       d   \        V^ ,          4      pV P                  P                  R4      P                  4       pV'       d   \        V^ ,          ;'       g    ^ 4      M^ pV^ 8X  dC   \        VR,          ^4      R,          ;'       g    ^pV P                  P                  RV 24       W@n         V P                  P                  R4       RRR4       R#   \        P                   d     L!i ; i  + '       g   i     R# ; i  \        P                   d"   p\        P                  R	T4        Rp?R# Rp?ii ; i)
zÌMint a once-per-file generation stamp (state_meta + application_id). First opener wins (INSERT
OR IGNORE); application_id is written only while 0 so racers converge. PASSIVE checkpoint only.

See #45383.
Nú*SELECT value FROM state_meta WHERE key = ?z;INSERT OR IGNORE INTO state_meta (key, value) VALUES (?, ?)úPRAGMA application_id:Né   NiÿÿÿzPRAGMA application_id=úPRAGMA wal_checkpoint(PASSIVE)z%state.db generation stamp skipped: %s)r˜  rÆ  ÚuuidÚuuid4Úhexr§  rh  r#   rN  re   rf   r´  r?  r/  r  rŒ  )rŒ   Útokenrt  Ú
pragma_rowÚcurrentr”  s   &     rh   rä  Ú$SessionDB._ensure_db_file_generationš  s·  € ð �>�>ˆ>˜TŸZ™ZÒ/ÙÜ—
’
“× Ñ ˆð	GØ——“ð
 —j‘j×(Ñ(Ø@ÔC[ÐB]óç‘(“*ð ÷   A§¤Ø—J‘J×&Ñ&ØUÜ1°5Ð9ôð Ÿ*™*×,Ñ,ØDÜ1Ð3ó÷ ‘h“jð ÷ ˜3˜qŸ6œ6Ü  A¥›K�EØ!ŸZ™Z×/Ñ/Ð0GÓH×QÑQÓS�
ß5?œ#˜j¨�m×0Ð0¨qÔ1ÀQ�Ø˜a”<Ü" 5¨¥9¨bÓ1°JÕ>×DÐDÀ1�GØ—J‘J×&Ñ&Ð)?À¸yÐ'IÔJØ/6Ô,ðØ—J‘J×&Ñ&Ð'GÔH÷5 ‘øô6 —}‘}ô Ùðú÷7 —�ûô: �}‰}ô 	GÜ�L‰LÐ@À#×FÒFûð	Gús{   ÁH ÁAG7ÂAG7Ã7G7ÄAG7Å	G7Å0G7Æ'G7Æ7GÇH ÇG4Ç1G7Ç3G4Ç4G7Ç7H	ÈH ÈH ÈIÈ H<È<Ic                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  Ä  s   ø€ ÷ Bñ B¨$ñ Brj   c                óÂ  € \        V P                  4      V n        \        V P                  4      V n        \        V P                  4      pV'       d	   Wn        R# V P                  e[   V P                  '       gG    V P                  R4      pV'       d+   V^ ,          '       d   \        V^ ,          4      V n        R# R# R# R# R#   \        P                   d    Rp LQi ; i)z?Snapshot inode plus the on-disk generation header when present.Nr¢  )Ú_stat_db_file_identityrÃ   r³  rD   rµ  rC   r´  rÆ  r’  r?  r/  rf   )rŒ   Údisk_idr©  s   &  rh   rÑ  Ú"SessionDB._record_db_file_identityÄ  s¬   € ä!7¸¿¹Ó!EˆÔÜ$AÀ$Ç,Á,Ó$OˆÔ!Ü-¨d¯l©lÓ;ˆßØ+2Ö(Ø�Z‰ZÒ#¨D×,H×,HÐ,Hð"Ø!Ÿ^™^Ð,CÓD�
÷ ˜j¨ŸmœmÜ/2°:¸aµ=Ó/A�Ö,ñ ,‰zñ -IÑ#øô —=‘=ô "Ø!’
ð"ús   Á;C ÃCÃCc                ó    <€ V ^8„  d   QhRS[ /# ru   r:  )rg   r‡   s   "€rh   ri   rb  Ó  s   ø€ ÷ 
;ñ 
;¡tñ 
;rj   c                ó  € V P                   pVe   \        V P                  4      V8w  d   R# \        V P                  ;'       g    ^ 4      pV'       g   R# \        V P                  4      p\        T;'       d    W28g  4      # )zATrue when the path no longer names the file this instance opened.TF)r³  r®  rÃ   rf   r´  rC   r¤   )rŒ   ÚrecordedÚrecorded_appÚdisk_apps   &   rh   rU  ÚSessionDB._db_file_was_replacedÓ  si   € à×)Ñ)ˆØÒÔ$:¸4¿<¹<Ó$HÈHÔ$TÙÜ˜4×7Ñ7×<Ð<¸1Ó=ˆßÙä.¨t¯|©|Ó<ˆÜ�H×9Ð9 Ñ!9Ó:Ð:rj   c                ó    <€ V ^8„  d   QhRS[ /# ru   r:  )rg   r‡   s   "€rh   ri   rb  ß  s   ø€ ÷ ñ ©$ñ rj   c                ó
  a€ V P                   ;'       g    / p\        P                  ! V P                  4      oV'       dW   \        ;QJ d-    V3R lVP                  4        4       F  '       g   K   R# 	  R# ! V3R lVP                  4        4       4      # V P                  '       g   R# \        P                  P                  R4      '       d€   \        V P                  4      p \        \        P                  ! 4       4       FG  w  r4\        P                  ! V4      pRV9   g   K$  WR9   g   K,  \        WBV,          4      '       g   KF   R# 	  \#        V P                  4      pV'       d   W`n         R#   \          d     R# i ; i)a  True when the WAL/SHM generation this handle opened is gone. Recorded
generation: pure stat (no /proc walk on healthy writes). Empty identity
(WAL appeared after open, or cleared by a clean close()): probe
/proc/self/fd for deleted sidecars and adopt the current ones once clean.c              3   ód   <"  € T F%  w  r\        \        SV,           4      4      V8g  x € K'  	  R # 5ir  )r®  r   )r   ÚsuffixÚidentÚbases   &  €rh   r#  Ú5SessionDB._wal_generation_was_lost.<locals>.<genexpr>ç  s+   øé € ð ÙZjÉÈÔ&¤t¨D°6­MÓ':Ó;¸uÖDÓZjùs   ƒ-0TFÚlinuxz
 (deleted))rµ  r«   ÚfspathrÃ   r.  Úitemsr±  rŸ  Úplatformrú   rE   r6   r¬   rX  Úcanonical_sqlite_pathrA   r²   rD   )rŒ   r³  ÚwatchedÚtargetÚfd_pathÚ	canonicalÚcurrent_identityr¼  s   &      @rh   Ú_wal_generation_was_lostÚ"SessionDB._wal_generation_was_lostß  s,  ø€ ð
 ×,Ñ,×2Ð2°ˆÜ�yŠy˜Ÿ™Ó&ˆßß“3ô ØZb×ZhÑZhÔZjó—3”3ð ’3ð �3ô ØZb×ZhÑZhÔZjóó ð ð ××ÐÙÜ�<‰<×"Ñ" 7×+Ò+Ü3°D·L±LÓAˆGðÜ'7¼¿	º	»Ö'D‘O�FÜ .× DÒ DÀVÓ L�IØ$¨Ö.°9Ö3GÜ 5°gÀyÕ?Q× RÔ RÚ#ñ	 (Eô 9¸¿¹ÓFÐßØ(8Ô%Ùøô ô Úðús*   Ã%=E3 Ä'E3 Ä/E3 Å	E3 ÅE3 Å3FÆFc                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  ü  s   ø€ ÷ Iñ I°ñ Irj   c                ó8  € V P                   '       g   V P                  4       '       d@   RV n         V P                  4        \        P	                  \
        4       \        \
        4      hV P                  '       g   V P                  4       '       dR   RV n        V P                  4         V P                  R4       \        P	                  \        4       \        \        4      hR#   \         d,   p\        P	                  RT P                  T4        Rp?L[Rp?ii ; i)zÃStop writes (logging once) when the file was replaced or its WAL/SHM generation
is gone: never run in-file repair on a new generation, never keep committing on a
split WAL. Both flags are sticky.TÚhaltz}Could not capture the retired WAL generation of %s at halt: %s. close() retries the capture and refuses to settle without it.N)r¶  rU  Ú_disable_close_time_checkpointr  rã  r$   r(   r·  rÈ  Ú_capture_retired_generationrJ   rÃ   r    r%   )rŒ   r”  s   & rh   rW  Ú(SessionDB._halt_if_db_generation_changedü  sà   € ð ××Ð × :Ñ :× <Ò <Ø $ˆDÔØ×/Ñ/Ô1Ü�L‰LÔ/Ô0Ü&Ô'=Ó>Ð>Ø×'×'Ð'¨4×+HÑ+H×+JÒ+JØ+/ˆDÔ(Ø×/Ñ/Ô1ðØ×0Ñ0°Ô8ô �L‰LÔ4Ô5Ü+Ô,GÓHÐHñ ,Køô
 1ô Ü—‘ðDØEIÇ\Á\ÐSV÷ñ ûðús   Â(C# Ã#DÃ.!DÄDc                ó&   <€ V ^8„  d   QhRS[ RS[/# )r`   Útriggerrc   )re   r   )rg   r‡   s   "€rh   ri   rb    s   ø€ ÷ ñ ±3ð ¹4ñ rj   c           	     óh  € V P                   ;_uu_ 4        V P                  e   V P                  uuRRR4       # \        V P                  \	        V P
                  ;'       g    / 4      VR7      pW n        RRR4       \        P                  RV P                  VX4       V#   + '       g   i     L4; i)a  Durably capture the lost WAL generation this handle still holds open, once per handle.

The quarantine keeps the retired frames from being checkpointed under wrong page numbers,
but they live only in an unlinked inode that dies with this process's last descriptor, and
the canonical DeletedWalGenerationError remediation is to stop the writers. Capturing at the
first halt (or at close(), whichever sees the loss first) makes "preserve" outlive the
process. Raises RetiredGenerationCaptureError; nothing is mutated on failure.N)Úsidecar_identityrÑ  z�Captured the retired WAL generation of %s at %s to %s; read its manifest.json before deciding whether those frames belong on top of the file now at the path.)r¹  r¸  rK   rÃ   rò   rµ  r  r“  )rŒ   rÑ  Úartifacts   && rh   rÎ  Ú%SessionDB._capture_retired_generation  s—   € ð ×'×'Ó'Ø×/Ñ/Ò;Ø×7Ñ7÷ (Ò'ô 6Ø—‘¬t°D×4MÑ4M×4SÐ4SÐQSÓ/TÐ^eôˆHð 08Ô,÷ (ô 	�‰ðNØOSÏ|É|Ð]dÐfnô	
ð ˆ÷ (×'ús   •B!º'B!Á"B!Â!B1	c                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  *  s   ø€ ÷ .ñ . tñ .rj   c                óª   € V P                   '       d   \        \        4      hV P                  '       d   \	        \
        4      hV P                  4        R# )zHSticky-flag fast path (no log spam on every write), then the live probe.N)r¶  r(   r$   r·  r%   r    rW  r  s   &rh   r_  ÚSessionDB._raise_if_db_replaced*  s>   € à××ÐÜ&Ô'=Ó>Ð>Ø×'×'Ð'Ü+Ô,GÓHÐHØ×+Ñ+Ö-rj   c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r`   r”  rc   )rõ  r¤   )rg   r‡   s   "€rh   ri   rb  3  s   ø€ ÷ 
ñ 
±-ð 
ÁDñ 
rj   c                óØ   € \        V\        P                  4      ;'       dJ    \        V\        4      '       * ;'       d-    V P	                  V4      '       * ;'       d    \        V4      R8H  # )z†Bare SQLITE_CORRUPT/NOTADB with no FTS provenance: canonical B-tree/schema/freelist damage,
never repairable from the live write path.Úcorrupt)rø   r?  râ  r'   rh  r*   )Úclsr”  s   &&rh   rj  Ú)SessionDB._is_structural_corruption_error2  se   € ô
 �sœG×1Ñ1Ó2÷ =ð =Ü˜sÔ$7Ó8Ô8÷=ð =à×6Ñ6°sÓ;Ô;÷=ð =ô +¨3Ó/°9Ñ<ð		
rj   c                ó&   <€ V ^8„  d   QhRS[ RS[/# ©r`   r  rc   )re   r'   )rg   r‡   s   "€rh   ri   rb  =  s    ø€ ÷ jñ j¡Sð jÑ2Eñ jrj   c                óD   € \        V \         RV P                   R24      # )zDBuild the quarantine error for this handle (message assembled once).z	 (cause: Ú))r'   r"   r¾  )rŒ   r  s   &&rh   rV  ÚSessionDB._corrupt_error=  s(   € ä" f XÔ.CÐ-DÀIÈd×NeÑNeÐMfÐfgÐ#hÓiÐirj   c                ó$   <€ V ^8„  d   QhRS[ RR/# )r`   r”  rc   N)rõ  )rg   r‡   s   "€rh   ri   rb  A  s   ø€ ÷ ñ ¡Mð °dñ rj   c           	     óT  € RV n         \        V4      V n        \        V P                  V4       V P                  4        \        P                  RV P                  VV P                  4       V P                  4       pR F(  p\        WR4      f   K  \        W#\        W4      4       K*  	  W!h)z@Quarantine this handle and raise; never run in-file repair here.Tzþstate.db %s reported structural corruption outside the FTS indexes (%s); quarantining this handle: no further writes, no automatic reopen, no explicit WAL checkpoint at close. Stop the gateway and run `hermes sessions recover --source %s --inspect-only`.N)Úsqlite_errorcodeÚsqlite_errorname)r½  re   r¾  r   rÃ   rÍ  r  rã  rV  r>  Úsetattr)rŒ   r”  ÚerrÚattrs   &&  rh   rk  ÚSessionDB._halt_db_corruptA  s™   € àˆÔÜ"% c£(ˆÔô 	˜TŸ\™\¨3Ô/Ø×+Ñ+Ô-Ü�‰ðTð VZ×UaÑUaÐcfØ�L‰Lô	
ð ×!Ñ!Ó#ˆÛ<ˆDÜ�s $Ó'Ô3Ü˜¤7¨3Ó#5Ö6ñ =ð Ðrj   c                ó    <€ V ^8„  d   QhRS[ /# ru   r:  )rg   r‡   s   "€rh   ri   rb  V  s   ø€ ÷ ñ ±ñ rj   c                óê   € \        \        RR4      pV P                  p\        VRR4      pVe   Vf   R#  V! VR4       R#   \         d'    \        P                  RT P                  RR7        R# i ; i)aÍ  Best-effort SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE (Python 3.12+): sqlite3's
close() otherwise runs the internal last-connection checkpoint that wrote
the incident's pages under wrong page numbers (see StateDbCorruptError and
the generation-loss halts).
<3.12 has no setconfig, so a lost-generation handle is retired unclosed
instead (see close()): closing its last descriptor could both run that
checkpoint and discard committed data present only in an unlinked WAL.r<  Nr=  FTz–Could not disable SQLite's close-time checkpoint on the quarantined handle for %s; closing it may checkpoint retired frames over the newer generation.rŠ  )r>  r?  rÆ  rp   r  rã  rÃ   )rŒ   Úflagri  r=  s   &   rh   rÍ  Ú(SessionDB._disable_close_time_checkpointV  s…   € ô ”wÐ BÀDÓIˆØ�z‰zˆÜ˜D +¨tÓ4ˆ	ØŠ<˜9Ò,ñ
 ð
	Ù�d˜DÔ!ñ øô ô 	ô �L‰LðVà—‘ tð ô ò
 ð	ús   ¶	A Á-A2Á1A2c                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  t  s   ø€ ÷ +ñ + tñ +rj   c                ó^   € V P                   '       g   V P                  V4       RV n         R# R# )a  Retain the exact quarantined connection past GC and interpreter teardown (once per handle).

Takes the connection as a parameter: callers are lock-held close paths, and the
writer-conn thread-safety audit flags self._conn in functions outside `with self._lock`.TN)r»  rº  r9  s   &&rh   Ú_pin_connectionÚSessionDB._pin_connectiont  s+   € ð
 ×&×&Ð&Ø×#Ñ# DÔ)Ø&*ˆDÖ#ñ 'rj   c                ó    <€ V ^8„  d   QhRS[ /# ru   r:  )rg   r‡   s   "€rh   ri   rb  }  s   ø€ ÷  $ñ  $±ñ  $rj   c                óÐ  € RV n         V P                  4       '       * ;'       d    V P                  RJp V P                  R4      p\        P                  RT P                  T4       T'       d!   \        P                  RT P                  4       T#   \         dK   pT'       d   T P                  T P                  4       \        P                  RT P                  T4       h Rp?ii ; i)ac  Capture the retired generation; return whether the handle must be retired unclosed.

Where SQLite's close-time checkpoint cannot be switched off (no setconfig, Python < 3.12),
sqlite3_close would write the retired frames over the newer generation, so the exact
connection is retired unclosed instead. A failed capture leaves the handle open for a retry
-- but the pin is taken FIRST on such a runtime: every production caller reaches close()
through hermes_state_registry.release_or_close, which swallows the error, so an interpreter
exit before the retry must not be able to checkpoint the stale frames either.TNrÝ   z›Could not capture the retired WAL generation of %s at close: %s. The handle stays open and close() retries the capture; those frames are NOT yet preserved.zóSkipping the close-time WAL checkpoint for %s: this handle's WAL/SHM generation was deleted or replaced; the retired generation is captured at %s. Stop the other writers before reopening and inspect the capture before deciding its disposition.ztRetaining the quarantined connection for %s unclosed: this runtime cannot switch off SQLite's close-time checkpoint.)r·  rÍ  rº  rÎ  rJ   rñ  rÆ  r  rã  rÃ   r“  )rŒ   Úretire_without_closerÔ  r”  s   &   rh   Ú_settle_lost_generation_lockedÚ(SessionDB._settle_lost_generation_locked}  sÕ   € ð (,ˆÔ$Ø#'×#FÑ#FÓ#HÔH×pÐpÈT×MdÑMdÐlpÐMpÐð		Ø×7Ñ7¸Ó@ˆHô 	�‰ð`ð �L‰L˜(ô		
÷  Ü�N‰Nð=Ø>B¿l¹lôð $Ð#øô' -ô 	ß#Ø×$Ñ$ T§Z¡ZÔ0Ü�L‰LðWØX\×XdÑXdÐfiôð ûð	ús   ´B ÂC%ÂAC Ã C%r]  c                ó$   <€ V ^8„  d   QhRS[ RR/# )r`   r]  rc   Nr:  )rg   r‡   s   "€rh   ri   rb  Ÿ  s   ø€ ÷ 	=ñ 	=©tð 	=Àñ 	=rj   c               ó  € V P                   '       d   V P                  4       hV'       d_   \        V P                  4      \        8X  d?   V P                  \        P                  ! R \        V P                  4       R24      4       R# R# R# )zDdatabase disk image is malformed (reported earlier in this process: rá  N)	r½  rV  r   rÃ   r   rk  r?  râ  r   )rŒ   r]  s   &$rh   r^  ÚSessionDB._raise_if_db_corruptŸ  sn   € Ø××ÐØ×%Ñ%Ó'Ð'ß”} T§\¡\Ó2´oÔEð ×!Ñ!¤'×"7Ò"7ØVÜ)¨$¯,©,Ó7Ð8¸ð;ó#<ö =ñ	 F‰7rj   c                ó,   <€ V ^8„  d   QhRS[ RS[ RS[/# )r`   r&  r[  rc   )rÿ  r¤   )rg   r‡   s   "€rh   ri   rb  ª  s"   ø€ ÷ ñ ±%ð ÁUð Étñ rj   c           	     ól  € \         P                  ! 4       pW18¼  d   R# W1V,
          ,
          V P                  8¬  p\        P                  ! V'       d   V P
                  V P                  3MV P                  V P                  3!  p\         P                  ! \        V\        W,
          R4      4      4       R# )z¶Sleep one jitter interval if the budget allows; True = retry, False = deadline passed. Small
jitter for the first _WRITE_RETRY_SLOW_AFTER_S, then slow; never overshoots the deadline.Fr  T)r÷  r  Ú_WRITE_RETRY_SLOW_AFTER_Sr   r!  r"  r#  Ú_WRITE_RETRY_MIN_SÚ_WRITE_RETRY_MAX_Srø  r$  r%  )rŒ   r&  r[  r'  Úslowr(  s   &&&   rh   rg  Ú#SessionDB._sleep_before_write_retryª  s‰   € ô �nŠnÓˆØŒ?ÙØ Õ+Õ,°×0NÑ0NÑNˆÜ—’ßLPˆT×)Ñ)¨4×+GÑ+GÑHØ×)Ñ)¨4×+BÑ+BÐCñˆô 	�
Š
”3�vœs 8¥>°5Ó9Ó:Ô;Ùrj   c                óF   <€ V ^8„  d   QhRS[ S[S[S[3,          ,          /# ru   )r  rV  rf   re   )rg   r‡   s   "€rh   ri   rb  ¸  s!   ø€ ÷ 7ñ 7©4±±c¹3°hµÕ+@ñ 7rj   c                ó,   € \        V P                  4      # )zQForeign processes holding this DB or its WAL sidecars (see hermes_state_holders).)rZ  rÃ   r  s   &rh   rZ  Ú#SessionDB._foreign_state_db_holders¸  s   € ä(¨¯©Ó6Ð6rj   c                ó0   <€ V ^8„  d   QhRS[ S[,          /# ru   ra  )rg   r‡   s   "€rh   ri   rb  ¼  s   ø€ ÷ ñ ¡H©S¥Mñ rj   c                óš   € V P                   '       d   RV P                   R2# V P                  '       d   R# V P                  '       d   R# R# )uç  Why this handle must not checkpoint or run in-file repair, or None. A corrupted image has
torn B-trees; a replaced file or a deleted/replaced WAL generation would checkpoint under
wrong page numbers into the main DB -- the shutdown-time cause of #105670. Precedence note:
close() evaluates generation loss BEFORE calling this (and skips it entirely when lost â€”
a lost generation settles through the capture path, not the quarantine advisory), while
the halt path checks replaced first.zstructural corruption (rá  za replaced state.db filez&a deleted WAL generation (split-brain)N)r½  r¾  r¶  r·  r  s   &rh   Ú_quarantine_reasonÚSessionDB._quarantine_reason¼  sG   € ð ××ÐØ,¨T×-DÑ-DÐ,EÀQÐGÐGØ××ÐÙ-Ø×'×'Ð'Ù;Ùrj   c                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  Ë  s   ø€ ÷ Gñ G Tñ Grj   c                ód  € V P                  4       e   R#  V P                  ;_uu_ 4        V P                  f    RRR4       R# V P                  '       d,   \        P
                  ! V P                  V P                  4       V P                  P                  R4      P                  4       pV'       d4   V^,          ^ 8”  d&   \        P                  RV^,          V^,          4       RRR4       R#   + '       g   i     R# ; i  \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)a`  Best-effort PASSIVE WAL checkpoint; never raises. PASSIVE never blocks writers;
TRUNCATE corrupted B-trees on 65K+ page databases under exclusive-lock I/O pressure.

Previous TRUNCATE strategy caused B-tree corruption on large databases (65K+ pages) due to the
exclusive-lock I/O pressure from checkpointing thousands of frames at once (issue #45383).
Nr¤  z(WAL checkpoint: %d/%d pages checkpointedz#WAL checkpoint (PASSIVE) failed: %s)r  r§  rÆ  r¼  rå  ræ  rÃ   rh  rN  r  rŒ  rp   r“  )rŒ   ro  r”  s   &  rh   rc  ÚSessionDB._try_wal_checkpointË  sØ   € ð ×"Ñ"Ó$Ò0Ùð
	GØ——“Ø—:‘:Ò%Ø÷ ‘ð ×'×'Ð'Ü—O’O D§L¡L°$×2FÑ2FÔGØŸ™×+Ñ+Ð,LÓM×VÑVÓX�ß˜f Q�i¨!œmÜ—L‘LÐ!KÈVÐTUÍYÐX^Ð_`ÕXaÔb÷ ——’ûô ô 	GÜ�N‰NÐ@À#×FÒFûð	GúsL   –D ªC/ºD ÁC/ÁAC/Â23C/Ã%D Ã/D 	Ã:D Ä D ÄD/ÄD*Ä*D/c                ó   <€ V ^8„  d   QhRR/# )r`   rc   r\  r{   )rg   r‡   s   "€rh   ri   rb  à  s   ø€ ÷ ñ ˜;ñ rj   c                ó   € V # )uð  ``with SessionDB(path) as db:`` closes on exit; owners must release deterministically.

Ownership of a SessionDB should be released explicitly. Historically an instance with a started
token writer pinned ITSELF (bound-method writer target plus a strong ``atexit`` drain hook), so
``__del__`` never ran for exactly the instances that leaked descriptors (#88033). The writer now
retires after an idle window and the atexit hook holds only a weak reference, so abandoned handles
are eventually collectible â€” but "eventually, after the idle window and a GC cycle" is not a release
policy. Call sites owning a handle are still expected to close it deterministically (see the
ownership comments in ``run_agent.py`` and ``tui_gateway/methods_session.py``).
r{   r  s   &rh   Ú	__enter__ÚSessionDB.__enter__à  s	   € ð ˆrj   c                ó    <€ V ^8„  d   QhRS[ /# ru   r:  )rg   r‡   s   "€rh   ri   rb  í  s   ø€ ÷ ñ ©Tñ rj   c                ó&   € V P                  4        R # ©F)rÝ   )rŒ   Úexc_typer”  Útbs   &&&&rh   Ú__exit__ÚSessionDB.__exit__í  s   € Ø�
‰
ŒÙrj   c                óP  € V P                   '       d   ^ RIHp V! V 4       R# V P                  4        V P                  Ruq n        Ve   \
        P                  ! V4       V P                  ;_uu_ 4        RV n        RRR4       V P                  4       '       d   K  V P                  ;_uu_ 4        V P                  '       Edk   V P                  '       * ;'       dB    V P                  ;'       g.    \        V P                  4      ;'       d    V P!                  4       pT;'       d    V P#                  4       pV'       d   RMV P%                  4       pVe-   \&        P)                  RV P*                  WPP*                  4       M6V P                  '       g%   V'       g    V P                  P-                  R4       \2        P                  ! V P4                  4       V'       d$   V P7                  V P                  4       RV n        M+V P                  Ruqpn        V P9                  V4       / V n        RRR4       V P:                  P                  V 4       R#   + '       g   i     ELà; i  \.         d!   p\&        P1                  RT4        Rp?LÕRp?ii ; i  + '       g   i     Lo; i)u3  Drain queued token deltas, then a PASSIVE checkpoint on writable handles
(NOT TRUNCATE: a full WAL reset races the gateway's live writer, tearing
B-tree pages). A registry-shared instance RELEASES one refcount instead.

Drains queued token deltas first (the background writer needs the connection). Read-only connections
never request a checkpoint. See #45383.
When this instance is shared (opened via ``hermes_state_registry.acquire``), ``close()`` RELEASES one
refcount instead of tearing down the connection: the registry owns the lifecycle and only closes on
the final release (#90837). This prevents one caller's close from tearing down the writer connection
that other callers in the same process are still using â€” while still letting legacy ``close()`` call
sites return their reference instead of leaking it.
)r.  NTzÄSkipping the close-time WAL checkpoint for %s: this handle observed %s. Take a snapshot of state.db, -wal and -shm before restarting, then run `hermes sessions recover --source %s --inspect-only`.r¤  z,WAL checkpoint (PASSIVE) at close failed: %s)rÎ  Úhermes_state_registryr.  Ú_stop_token_writerrÍ  ÚatexitÚ
unregisterr®  r¯  r:  r§  rÆ  r˜  r·  r¤   rµ  rÈ  rö  r  r  r“  rÃ   rh  rp   rŒ  rå  r¼  rñ  r�  r«  )rŒ   r.  ÚhookÚgeneration_lostrõ  Úquarantine_reasonr”  ri  s   &       rh   rÝ   ÚSessionDB.closeñ  s  € ð ×&×&Ð&Ý5Ù�DŒMÙØ×ÑÔ!Ø(,×(?Ñ(?ÀÐ%ˆÔ%ØÒÜ×Ò˜dÔ#à×"×"Ó"Ø&*ˆDÔ#÷ #à×,Ñ,×.Ò.ÙØ�Z�Z‹ZØ�z�z‰zØ&*§n¡nÔ"4÷ #ð #Ø×0Ñ0÷ ]ð ]Ü˜T×6Ñ6Ó7×[Ð[¸D×<YÑ<YÓ<[ð  ð (7×'`Ð'`¸4×;^Ñ;^Ó;`Ð$ß,;¡DÀ×AXÑAXÓAZÐ!Ø$Ò0Ü—N‘Nðlð Ÿ™Ð&7¿¹õ	ð ŸŸ˜·ðZð Ÿ
™
×*Ñ*Ð+KÔLô ×"Ò" 4×#7Ñ#7Ô8ß'Ø×(Ñ(¨¯©Ô4Ø!%�D•Jà'+§z¡z°4Ð$�Dœ*Ø×2Ñ2°4Ô8ð 13�DÔ-÷I ðJ 	×Ñ×$Ñ$ TÖ*÷S #×"Ð"ûô: %ô ZÜŸ™Ð%SÐUX×YÑYûðZú÷3 �Zúsn   Á4IÂ0+JÃJÃ0JÄJÄ'JÅ AJÆJÆI'Æ8'JÇ AJÉI$	É'JÉ2JÊJÊJÊJÊJ%	c                ó   <€ V ^8„  d   QhRR/# rn  r{   )rg   r‡   s   "€rh   ri   rb  2  s   ø€ ÷ ñ ˜ñ rj   c                óŠ   € V P                   P                  R4      e    V P                  4        R# R#   \         d     R# i ; i)zmSafety net: close() if the caller forgot. Attribute access stays
guarded: module teardown order is undefined.rÆ  N)Ú__dict__ro   rÝ   rp   r  s   &rh   Ú__del__ÚSessionDB.__del__2  s@   € ð �=‰=×Ñ˜WÓ%Ò1ðØ—
‘
–ñ 2øô ô Úðús   Ÿ3 ³AÁAzBot Chatz json:Ú	reactionsaz  id, role, content, tool_call_id, tool_calls, tool_name, effect_disposition, finish_reason, reasoning, reasoning_content, reasoning_details, codex_reasoning_items, codex_message_items, platform_message_id, observed, _compressed_summary, timestamp, token_count, active, api_content, display_kind, display_metadata, message_uid, absorbed_message_uids, tool_call_uids, tool_call_uidc                ó6   <€ V ^8„  d   QhRS[ RS[S[ ,          /# )r`   ra   rc   )re   r   )rg   r‡   s   "€rh   ri   rb  l  s   ø€ ÷ /ñ /™Cð /¡H©S¥Mñ /rj   c                óÖ   € V P                   ;_uu_ 4        V P                  P                  RV34      P                  4       pRRR4       Xf   R# V^ ,          #   + '       g   i     L; i)z“Read state_meta[key] on self._lock (not _read_ctx): fts_rebuild_step reads progress before its
write transaction and a WAL reader would not see it.r¡  N)r§  rÆ  rh  rN  )rŒ   ra   rt  s   && rh   Úget_metaÚSessionDB.get_metal  sQ   € ð �Z�Z‹ZØ—*‘*×$Ñ$Ð%QÐTWÐSYÓZ×cÑcÓeˆC÷ à’{ˆtÐ.¨¨A­Ð.÷ �Zús   •,AÁA(	ró  c                óT   <€ V ^8„  d   QhRS[ RS[ RS[S[P                  ,          RR/# )r`   ra   rq   ró  rc   N)re   r   r?  ÚCursor)rg   r‡   s   "€rh   ri   rb  s  s3   ø€ ÷ 
/ñ 
/™Cð 
/©ð 
/¹ÁÇÁÕ8Pð 
/Ð\`ñ 
/rj   c               ób   € RpVe   VP                  WAV34       R# V P                  WAV34       R# )u�   Upsert state_meta[key]; with ``cursor`` the write is inline (the caller already holds a
transaction â€” nesting BEGIN IMMEDIATE would deadlock).zgINSERT INTO state_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.valueN)rh  r~  )rŒ   ra   rq   ró  ru  s   &&&$ rh   Úset_metaÚSessionDB.set_metas  s5   € ðDð 	ð ÒØ�N‰N˜3 e Ö-à�O‰O˜C u Ö.rj   c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r`   Úworkspaces_rootrc   rd   )rg   r‡   s   "€rh   ri   rb    s   ø€ ÷ (ñ (¹Cð (ÁCñ (rj   c                ó¼   a aa€ \        V4      P                  R4      oS'       g   ^ # RS 2oS P                  S4      R8X  d   ^ # VVV 3R lpS P                  V4      # )zŸRetag legacy kanban worker rows from ``cli`` to ``kanban`` by cwd under the board's workspaces
root; gated once per root via state_meta. Returns rows retagged.z/\zkanban_worker_source_retagged:Ú1c                 ó¨   <€ \        S4      pV P                  R SV R2V R234      pVP                  ;'       g    ^ pSP                  SRVR7       V# )zzUPDATE sessions SET source = 'kanban' WHERE source = 'cli' AND (cwd = ? OR cwd LIKE ? ESCAPE '\' OR cwd LIKE ? ESCAPE '\')z/%z\\%r2  )ró  )Ú_escape_likerh  rƒ  r-  )ri  Úescró  ÚretaggedÚgater  rŒ   s   &   €€€rh   rz  Ú3SessionDB.retag_kanban_worker_sessions.<locals>._doˆ  sb   ø€ Ü˜vÓ&ˆCØ—\‘\ð-ð ˜C˜5 ˜¨ u¨E ]Ð3ó	ˆFð —‘×+Ð+¨!ˆHØ�M‰M˜$ ¨FˆMÔ3ØˆOrj   )re   Úrstripr(  rq  )rŒ   r0  rz  r7  r  s   f& @@rh   Úretag_kanban_worker_sessionsÚ&SessionDB.retag_kanban_worker_sessions  sX   ú€ ô �_Ó%×,Ñ,¨UÓ3ˆßÙØ/°¨xÐ8ˆØ�=‰=˜Ó #Ô%Ù÷	ð ×"Ñ" 3Ó'Ð'rj   c                ó&   <€ V ^8„  d   QhRS[ RS[/# rC  r£   )rg   r‡   s   "€rh   ri   rb  –  s   ø€ ÷ ñ ±#ð ¹$ñ rj   c                óž   € V P                  V4      pV'       g   R# V P                  R\        V4       R2\        V4      4      p\	        V4      # )ub  True when this session â€” or any segment of the compression lineage a resume would
materialize â€” belongs to the Kanban dispatcher (``source``/``created_source`` =
``'kanban'``): the transcript of a worker run, not a human conversation (#68779).

Both columns are checked: ``source`` is live routing state the dispatcher tags
(``HERMES_SESSION_SOURCE=kanban``) and the legacy retag rewrites, while immutable
``created_source`` survives later surface flips. The lineage is the VERIFIED
compression chain (``_resume_lineage_ids``) â€” exactly the rows a resume loads â€” so a
worker transcript stays kanban-owned across rotations, while a delegate/branch child
of a worker (a DIFFERENT conversation) is not swept in. Plain classification, not a
gate: the resume-time guard (``hermes_cli/kanban_resume_guard.py``) owns the decision
and the dispatcher-owned exemption.Fz$SELECT 1 FROM sessions WHERE id IN (z>) AND (source = 'kanban' OR created_source = 'kanban') LIMIT 1)Ú_resume_lineage_idsrš  r   rV  r¤   )rŒ   rœ   ÚlineageÚrowss   &&  rh   Úis_kanban_owned_sessionÚ!SessionDB.is_kanban_owned_session–  sU   € ð ×*Ñ*¨:Ó6ˆßÙØ�~‰~Ø2´=ÀÓ3IÐ2Jð KKð Kä�'‹Nóˆô �D‹zÐrj   c                óL   <€ V ^8„  d   QhRS[ RS[S[S[ S[ 3,          ,          /# rß  )re   r  rV  )rg   r‡   s   "€rh   ri   rb  ¬  s(   ø€ ÷ 2ñ 2¡sð 2©t±E¹#¹s¸(µOÕ/Dñ 2rj   c                ó¨   € V'       g   . # V P                  R\        V4      R,           34      pV Uu. uF  q3^ ,          V^,          3NK  	  up# u upi )uŽ   ``[(key, value), ...]`` for state_meta keys starting with the literal
``prefix`` (LIKE wildcards escaped) â€” e.g. ``loop:<session_id>`` rows.z=SELECT key, value FROM state_meta WHERE key LIKE ? ESCAPE '\'Ú%)rš  r4  )rŒ   r  r@  rt  s   &&  rh   Úlist_meta_prefixÚSessionDB.list_meta_prefix¬  sS   € ÷ ØˆIØ�~‰~ØLÌ|Ð\bÓOcÐfiÕOiÐNkó
ˆñ -1Ó1©D S�Q•˜˜Q�Ó ©DÑ1Ð1ùÒ1s   ²Ac                ó:   <€ V ^8„  d   Qh/ S[ S[R3,          ;R&   # )r`   .Ú_AUTO_PRUNE_STALE_OPEN_SOURCES)rV  re   )rg   r‡   s   "€rh   ri   rb  Ï  s   ø‡ ‚ ñ %*©#¨s¨(¥Oñ ò rj   )'rÆ  r»  rž  r½  r¾  r´  r³  r¶  rµ  r·  rÄ  rÃ  rÀ  rÁ  rÅ  r¿  r§  r«  r¯  r®  r°  r­  rª  rº  r¹  r¸  rÎ  rÍ  rÇ  rÉ  rÌ  rË  rÊ  rÂ  r±  r¼  r²  rÃ   r˜  )ÚcliÚcronÚkanbanÚacpÚ
api_serverÚsubagentÚtoolÚ	recoveredi  P i  �)NFr  )rM  r  )r{   )r¦   )Úinput_tokensÚoutput_tokensÚcache_read_tokensÚcache_write_tokensÚreasoning_tokensÚapi_call_count)Úestimated_cost_usdÚactual_cost_usd)	ÚmodelÚcost_statusÚcost_sourceÚpricing_versionÚbilling_providerÚbilling_base_urlÚbilling_modeÚsourceÚtask)br�   r‘   r’   r“   Ú__doc__rI  r  Ú_TRANSCRIPT_WRITE_PATIENCE_SÚ_ACTIVITY_WRITE_PATIENCE_Srf  rþ  rÿ  rý  r"  r#  rb  rd  Ú_FTS_MERGE_MAX_PAGES_PER_INDEXÚ_FTS_MERGE_COMMANDS_PER_PASSÚ_IMPORT_MAX_SESSIONSÚ _IMPORT_MAX_MESSAGES_PER_SESSIONÚ_IMPORT_MAX_TOTAL_MESSAGESÚ_IMPORT_MAX_SESSION_BYTESÚ_IMPORT_MAX_TOTAL_BYTESÚ_TOKEN_WRITER_IDLE_SECONDSÚstaticmethodrk  rq  r…  r�  r•  r‹   rÐ  rÏ  rñ  rà  r  r  rá  r2  r:  r8  rA  r   rQ  rM  rq  r~  r…  r’  rš  r�  rä  rÑ  rU  rÈ  rW  rÎ  r_  Úclassmethodrj  rV  rk  rÍ  rñ  rö  r^  rg  rZ  r  rc  r  r  rÝ   r#  Ú_TOKEN_DELTA_SUM_FIELDSÚ_TOKEN_DELTA_COST_FIELDSÚ_TOKEN_DELTA_ROUTE_FIELDSÚMAX_TITLE_LENGTHÚ_TITLE_SOURCE_DERIVEDr   Ú_TITLE_SOURCE_LLMr   Ú_TITLE_SOURCE_USERr   Ú_TITLE_SOURCE_RANKÚCANONICAL_BOT_CHAT_TITLEÚ_CONTENT_JSON_PREFIXÚREACTIONS_METADATA_KEYÚ_CONVERSATION_ROW_COLUMNSr(  r-  r:  rA  rF  Ú__annotate_func__r•   r–   ©r‡   s   @rh   r\  r\  Ï  s­  ø‡ € ñ að7Ð"ð SWÐX\Ð^aÐOÐÐ3Ð5Oð  #ÐØ-2°EÐ*ÐÐ*Ø #ÐØ7<¸eÐ4ÐÐ4à!#Ðð _cÐdgÐijÐ[ÐÐ=Ð?[àY\Ð^dÐflÐVÐÐ:Ð<VØ9HÐJZÐ6ÐÐ6à!%Ðà÷ó ðð ÷
ó ð
ð ÷ó ðð@ ÷Ró ðR÷Sð S÷_.ò _.÷B2Að 2A÷h =ð  =÷Dð ÷-ò -÷,ð ÷4ð ÷Dð D÷:'ð '÷Rð ÷(ð (÷)ð )ð ð)L¨$÷ )Lñ )Ló ð)L÷V Aò  A÷Duò uñn8Ø:?ð8Ø_c÷8ó 8ñ?Ð[_÷ ?ó ?÷\ò \÷\ò \÷ð ÷2(Gð (G÷TBð B÷
;ð 
;÷ð ÷:Ið I÷2ð ÷*.ð .ð ÷
ó ð
÷jò j÷ð ÷*ð ÷<+ð +÷ $ð  $ðD	=°e÷ 	=ò 	=÷ð ÷7ð 7÷ð ÷Gð G÷*ð ÷ð ò?+÷Bð ðÐð  IÐð!Ðð
 Ðð 1ÐØ(ÐØ*ÐØ.°Ð3CÀQÐHYÐ[\Ð]Ðð  *Ðð 'Ðà(Ðð	?ð ÷/ð /ð
/ÐSW÷ 
/ò 
/÷(ð (÷.ð ÷,2ð 2÷{& ƒ rj   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# )	ÚAsyncSessionDBi·  zšAsync door onto SessionDB: every call runs via asyncio.to_thread so a blocking SQLite call
never freezes the event loop (no method returns a live cursor).c                ó$   <€ V ^8„  d   QhRS[ RR/# )r`   Údbrc   N)r\  )rg   r‡   s   "€rh   ri   ÚAsyncSessionDB.__annotate__»  s   ø€ ÷ ñ ™9ð ¨ñ rj   c                ó   € Wn         R # r  ©Ú_db)rŒ   r�  s   &&rh   r‹   ÚAsyncSessionDB.__init__»  s   € ØŽrj   c                ó    <€ V ^8„  d   QhRS[ /# )r`   r¯   r‘  )rg   r‡   s   "€rh   ri   r‚  ¾  s   ø€ ÷ ñ ¡ñ rj   c                óf   a€ \        V P                  V4      o\        S4      '       g   S# V3R  lpV# )c               Ÿ   óT   <"  € \         P                  ! S.V O5/ VB G R j  x€L
 #  L5ir  )ÚasyncioÚ	to_thread)ÚargsÚkwargsré  s   *,€rh   Ú
_offloadedÚ.AsyncSessionDB.__getattr__.<locals>._offloadedÂ  s'   øé € Ü ×*Ò*¨4ÐA°$ÒA¸&ÑA×AÐAÑAùs   ƒ(¡&¢()r>  r…  Úcallable)rŒ   r¯   rŽ  ré  s   && @rh   Ú__getattr__ÚAsyncSessionDB.__getattr__¾  s-   ø€ Ü�t—x‘x Ó&ˆÜ˜�~Š~ØˆKõ	BàÐrj   r„  N)	r�   r‘   r’   r“   rc  r‹   r‘  r•   r–   r}  s   @rh   r  r  ·  s   ø‡ € ñG÷ð ÷ö rj   r  c                ó˜   € V ^8„  d   Qh/ ^ \         9   d   \        \        R3,          ;R&   ^\         9   d   \        \        ,          ;R&   # )r`   .rÉ   Ú_repair_attempted_paths)Ú__conditional_annotations__rV  r   Úsetre   )rg   s   "rh   ri   ri      sA   € ÷ ñ ÷` 8Ò 7¤%¬¨c¨	Õ"2Ñ 7ña÷B *Ò )œœS�Ñ )òCrj   r{   )z:Review the conversation above and update the skill libraryz;Review the conversation above and consider saving to memory)z/Hermes can't open its session history right now)Ër•  rc  rŠ  r  rd  rN  Úloggingr«   r¨  r   r¨   r?  rã   rŸ  r¥  r÷  r¥  Úcollectionsr   Ú
contextlibr   r   Úpathlibr   Úhermes_dir_aclr   r)  r   r	   Útypingr
   r   r   r   r   r   r   r   r   Úhermes_state_commonr   rt  r   ru  r   rv  r   r4  r   r   r®  Úhermes_state_holdersr   Úhermes_state_pidnsr   Úhermes_state_healthr   r   r   r   r   Úhermes_state_errorsr    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   Úhermes_state_guardr.   r/   r0   r1   r2   r3   r4   Úhermes_state_readpoolr5   r6   r7   Úhermes_state_sessionsr8   Úhermes_state_ftsr9   r:   Úhermes_state_portabilityr;   Úhermes_state_telegramr<   Úhermes_state_profile_repairr=   Úhermes_state_schemar>   rX  Úhermes_state_lockguardrå  Úhermes_state_lockownersr?   Úhermes_state_dbfiler@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   Úhermes_state_messagesrM   Úhermes_state_prune_rewriterN   Úhermes_state_api_contentrO   Úhermes_state_coveragerP   Úhermes_state_rewindrQ   Úhermes_state_walrR   rS   rT   rU   Úhermes_state_repairrV   rW   rX   Úhermes_state_titlesrY   Úhermes_state_usagerZ   Úhermes_state_maintenancer[   Úhermes_state_gatewayr\   Úhermes_state_compressionr]   Úhermes_state_searchr^   r­   ÚImportErrorÚ	getLoggerr�   r  r”   rs   r|   r�   r€  rƒ   rš   r¶   Ú	frozensetÚ_BARE_BILLING_PROVIDERSr¹   r¿   rÀ   r,  rð  rù  rò  rÁ   rÅ   rÉ   rÑ   rí   rû   rý   r  Úcompiler  r  r  r*  r2  r/  r0  r7  r–  r”  r¦  Ú_repair_attempt_lockÚ_REPAIR_LOCK_TIMEOUT_SECONDSrÁ  Ú_IS_WINDOWSrA  rT  rZ  r\  r  ri   )r•  s   @rh   Ú<module>rÂ     sÔ  øðöó Û Û Û Û Û 	Û Û Û 	Û Û Û 
Û Û Û Ý ß /Ý Ý (ç Eß V× VÕ V÷÷ õ 2Ý 3÷õ ÷÷ ÷ ÷ ÷÷ ñ ÷ UÑ TÝ 6ß JÝ <Ý <Ý AÝ 2Û -Û +Ý :÷÷ ÷ õ õ 7Ý ?Ý ;Ý 6Ý 2÷ó ÷ hÑ gÝ 2Ý 0Ý <Ý 4Ý <Ý 2ðÛð 
×	Ó	˜8Ó	$€àÐ ð <N÷ 
õ?õ?ô
 ô 
ô
 ô 
õñB $ V¨XÐ$6Ó7Ð áˆCƒL€ñ -<Ó,=À
Õ,JÐ J€Ð)ð  Ð ð EFÀtÐ AÐ Ð!Að
 Ð õmð Ð Ø57Ð  Ó 7õðB8À÷ 8ðxÐ õ^õð2  ŸZ›ZÐ(IÓJÐ õdõð LÐ Ø[Ð ØnÐ àhð ñ
"ð ÷"ð "ñN %(£EÐ Ó )Ø —~“~Ó'Ð ð  %Ð Ø�lŠl˜gÑ%€õ:õõ&<ôe2ØÐ.Ð0BÐDVØÐ7Ð9PØÐ0Ð2CÐEWØÐ2Ð4JÐL`Ðbtð  wPô	e2÷P'ó øðA3 ô ØƒFðús   ÆK
 Ë
	KËK