+
    jHàj4
 ã                  ó   € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHtHtHtHtHt ^ RIHt ^ RIHt ^ RIHt ^ RIHtHtH t H!t!H"t" ]PF                  ! R	4      t$R
t%Ršt&^t'^t(R›t)Rt*Rœt+R�t,Rt-Ržt.Rt/R R lt0R R lt1R R lt2R R lt3R R lt4R R lt5RR/R R llt6R R lt7]Pp                  R  R! l4       t9R" R# lt:]6t;R$ R% lt<R& R' lt=R( R) lt>R* R+ lt?R, R- lt@R. R/ ltAR0 R1 ltBR2 R3 ltCR4 R5 ltDR6 R7 ltER8 R9 ltFR: R; ltGR< R= ltHR> R? ltIR@R/RA RB lltJRC RD ltK](3RE RF lltLRG RH ltMRI RJ ltNRK RL ltORMRNROR/RP RQ lltPRRRS/RT RU lltQRRRS/RV RW lltRRX RY ltSRZ R[ ltTR\ R] ltUR^ R_ ltV]Pp                  R` Ra l4       tWRbRRcR/Rd Re lltXRf Rg ltY]
P´                  ! Rh4      t[]
P´                  ! Ri4      t\]
P´                  ! Rj4      t]Rk Rl lt^Rm Rn lt_Ro Rp lt`Rq Rr ltaRŸRs Rt lltbRuRv/Rw Rx lltcRy Rz ltdR{R/R| R} llteR~R/R R€ lltfR� R‚ ltgRƒ R„ lthR… R† ltiR‡ Rˆ ltjR‰ RŠ ltkR‹ RŒ ltlR�]iRŽR�3R�]jR‘R’3R“]kR”R•3R–]lR—R33tmR˜ R™ ltnR# ) z½state.db repair, backup and writability preflight (split from hermes_state).

Patchable helpers are looked up as module globals at call time, so tests patch ``hermes_state_repair.<name>``.
)ÚannotationsN)ÚPath)ÚAnyÚDictÚListÚOptionalÚTuple)Úget_hermes_home)Úreport_startup_progress)Úread_only_db_uri)Ú_acquire_db_flockÚ_clear_lock_holder_recordÚ_describe_lock_holderÚ_read_lock_holder_recordÚis_advisory_lock_contentionÚhermes_stategš™™™™™¹?i   g{®Gáz”?zyFree disk space, then retry (or recover manually with `hermes sessions recover --source {db_path} --inspect-only` first).c               ó   € V ^8„  d   QhRR/# ©é   Údb_pathr   © )Úformats   "Ú8/home/ubuntu/.hermes/hermes-agent/hermes_state_repair.pyÚ__annotate__r   H   s   € ÷ Yñ Y�tñ Yó    c                ó$   a € V 3R l\          4       # )z>The three SQLite sidecar paths for *db_path* (present or not).c              3  óh   <"  € T F'  pSP                  SP                  V,           4      x € K)  	  R # 5i©N©Ú	with_nameÚname)Ú.0Úsuffixr   s   & €r   Ú	<genexpr>Ú_sidecars.<locals>.<genexpr>J   s*   øé € ÐXÑCW¸ˆG×Ñ˜gŸl™l¨VÕ3×4Ð4ÓCWùs   ƒ/2)Ú_DB_SIDECAR_SUFFIXES©r   s   fr   Ú	_sidecarsr'   H   s   ø€ äXÕCWÓXÐXr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   ÚwhatÚstrÚreturnúOptional[str]r   )r   s   "r   r   r   M   s!   € ÷ ñ ˜4ð  sð °}ñ r   c                óÞ   €  ^ RI HpHp  V! WR7      ;_uu_ 4        V! 4       uuRRR4       #   \         d    R \        r4 L9i ; i  + '       g   i     R# ; i  T\        3 d     R# i ; i)a³  Run *reader()* under ``hermes_cli.sqlite_safe_read.offline_file_access``.

``close()`` on ANY raw descriptor cancels every POSIX advisory lock this process holds on the file,
including a peer connection's RESERVED lock (``sqlite_safe_read`` rule 1), so a raw read is only safe with
no live connection; ``None`` when that makes it unsafe or the file is unreadable. Scaffold/embed installs
without hermes_cli have no tracked connections.)ÚLiveConnectionErrorÚoffline_file_accessc                ó,   € \         P                  ! 4       # r   )Ú
contextlibÚnullcontext)Ú_pÚ_ks   &,r   Ú<lambda>Ú_read_offline.<locals>.<lambda>W   s   € ÄZ×E[ÒE[ÔE]r   )r)   N)Úhermes_cli.sqlite_safe_readr.   r/   ÚImportErrorÚOSError)r   r)   Úreaderr.   r/   s   &&&  r   Ú_read_offliner;   M   sf   € ðhßXðÙ  ×4Ö4Ù“8÷ 5Ò4øô ô hÙ4]Ô`gÒ0ðhú÷ 5×4Ð4ûà¤Ð)ô Úðús<   ‚. ‹A œA£
A ®AÁAÁA	ÁA ÁA ÁA,Á+A,c               ó    € V ^8„  d   QhRRRR/# ©r   r   r   r+   Úboolr   )r   s   "r   r   r   _   s   € ÷ ñ  4ð ¨Dñ r   c                óÐ   € ^ RI HpHp T;_uu_ 4        \        V 4      V9   d    RRR4       R# VP	                  \        V 4      4        RRR4       R#   + '       g   i     R# ; i)zÁClaim the one-shot per-process repair attempt for *db_path*: True for the first caller, False
afterwards (bounds the repair/reopen loop and stops concurrent callers racing surgery on one file).)Ú_repair_attempt_lockÚ_repair_attempted_pathsNFT)r   r@   rA   r*   Úadd)r   r@   rA   s   &  r   Ú_claim_repair_attemptrC   _   sL   € ÷ Kß	Ò	Üˆw‹<Ð2Ô2Ø÷ 
Ñ	ð 	 ×#Ñ#¤C¨£LÔ1Ø÷	 
×	×	Ò	ús   “A¯AÁA%	c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r   r   r"   r*   r)   Útailr   )r   s   "r   r   r   j   s(   € ÷ ñ ˜Tð ¨3ð °cð Àñ r   c                ó  € V P                  V P                  V,           4      p VP                  P                  RRR7       WDP	                  R4      3#   \
         d+   p\        P                  RT RT 2YE4       TR3u Rp?# Rp?ii ; i)zDOpen ``<db>.<suffix>`` for locking; on failure warn and return None.T)ÚparentsÚexist_okza+bzCould not open state.db u    lock %s (%s) â€” N)r   r    ÚparentÚmkdirÚopenr9   ÚloggerÚwarning)r   r"   r)   rE   Ú	lock_pathÚexcs   &&&&  r   Ú_open_lock_filerP   j   sƒ   € à×!Ñ! '§,¡,°Õ"7Ó8€IðØ×Ñ×Ñ t°dÐÔ;ØŸ.™.¨Ó/Ð/Ð/øÜô Ü�‰Ð1°$°Ð7IÈ$ÈÐPÐR[ÔaØ˜$ˆÕûðús   ¤.A ÁBÁBÁ=BÂBc               ó    € V ^8„  d   QhRRRR/# )r   Ú	flag_namer*   r+   ÚNoner   )r   s   "r   r   r   u   s   € ÷ Cñ C Cð C¨Dñ Cr   c                ó„   € ^ RI pV P                  ^ 4       VP                  V P                  4       \	        W!4      ^4       R# )é    N)ÚmsvcrtÚseekÚlockingÚfilenoÚgetattr)ÚhandlerR   rV   s   && r   Ú_msvcrt_lockr\   u   s+   € ÛØ
‡K�K�„NØ
‡N�N�6—=‘=“?¤G¨FÓ$>ÀÖBr   c               ó   € V ^8„  d   QhRR/# )r   r+   rS   r   )r   s   "r   r   r   {   s   € ÷ Dñ D Tñ Dr   c                ó¼   € ^ RI Hp V'       d   \        V R4       R# ^ RIpVP	                  V P                  4       VP                  VP                  ,          4       R# )zJTake the advisory lock on *handle* without waiting (raises on contention).©Ú_IS_WINDOWSÚLK_NBLCKN)r   r`   r\   ÚfcntlÚflockrY   ÚLOCK_EXÚLOCK_NB)r[   r`   rb   s   &  r   Ú_try_lock_nonblockingrf   {   s6   € å(ßÜ�V˜ZÖ(ãØ�‰�F—M‘M“O U§]¡]°U·]±]Õ%BÖCr   Úclear_recordFc               ó    € V ^8„  d   QhRRRR/# )r   rg   r>   r+   rS   r   )r   s   "r   r   r   …   s   € ÷ 
8ñ 
8°$ð 
8À4ñ 
8r   c          	     ó°  € ^ RI Hp \        P                  ! V 4      ;_uu_ 4        \        P                  ! \
        4      ;_uu_ 4        V'       d   \        V R4       MA^ RIpV'       d   \        V 4       VP                  V P                  4       VP                  4       RRR4       RRR4       R#   + '       g   i     L; i  + '       g   i     R# ; i)z>Drop the advisory lock on *handle* (best effort) and close it.r_   ÚLK_UNLCKN)r   r`   r1   ÚclosingÚsuppressr9   r\   rb   r   rc   rY   ÚLOCK_UN)r[   rg   r`   rb   s   &$  r   Ú_release_lock_handlern   …   sv   € å(Ü	×	Ò	˜F×	#Õ	#¤Z×%8Ò%8¼×%AÕ%AßÜ˜ Õ,ãßÜ)¨&Ô1Ø�K‰K˜Ÿ™›¨¯©Ô7÷ &B×	#Ñ	#×%A×%Aú×	#×	#Ð	#ús)   ¥#CÁ!B1	Á*5B1	ÂCÂ1CÂ<CÃC	c               ó    € V ^8„  d   QhRRRR/# )r   rN   r   ÚtimeoutÚfloatr   )r   s   "r   r   r   ’   s   € ÷ 2ñ 2¨Dð 2À5ñ 2r   c                ód  € \         P                  ! 4       V,           p  \        V4       R#   \        \        3 ds   p\        T4      '       g   \        P                  RY4        Rp?R# \         P                  ! 4       T8¼  d    Rp?R# \         P                  ! \        4        Rp?K�  Rp?ii ; i)zeWindows counterpart of ``_acquire_db_flock``: True / False (timed out) / None (non-contention error).Tue   Could not acquire state.db repair lock %s (%s) â€” skipping schema surgery on a non-contention error.NF)
ÚtimeÚ	monotonicrf   ÚBlockingIOErrorr9   r   rL   rM   ÚsleepÚ_REPAIR_LOCK_POLL_SECONDS)rN   r[   rp   ÚdeadlinerO   s   &&&  r   Ú_acquire_repair_lock_windowsry   ’   s€   € ä�~Š~Ó 'Õ)€HØ
ð
	2Ü! &Ô)ÙøÜ¤Ð)ô 	2Ü.¨s×3Ò3Ü—‘ð  7Ø8AôHåÜ�~Š~Ó 8Ô+ÝÜ�JŠJÔ0×1Ò1ûð	2ús    Ÿ, ¬B/½'B*Á*B*Â
B*Â*B/c               ó   € V ^8„  d   QhRR/# r   r   )r   s   "r   r   r   ¤   s   € ÷ (ñ (¨ñ (r   c           
   #  óì  "  € ^ RI HpHp \        V RRR4      w  r4Vf   Rx € R# Rp V'       d   \	        W4V4      pM\        \        V4      WB\        R4      w  rTVf   RpM;V'       g4   \        P                  RY2\        V'       d   RM
\        V4      4      4       Vx € V'       d   \        VR	R
7       R# VP                  4        R#   T'       d   \        TR	R
7       i TP                  4        i ; i5i)a±  Serialize state.db schema surgery across processes.

Yields True when this process holds the repair lock, False when the bounded acquire timed out or the lock
file could not be opened; on False the caller must NOT do surgery (unlocked surgery IS the interleaving
this prevents). ``flock``: the kernel drops it when the holder dies (a pidfile would wedge every future
repair); a forked child inheriting the fd is the exception, so the acquire records pid + start time and
breaks a provably dead holder's lock. Bounded because a live repairer can sit in ``VACUUM`` for minutes.
An unopenable lock file (no space/inodes/descriptors) fails closed too: a sibling that opened ITS handle
before the disk filled may be inside surgery.

The acquire is still bounded because a *live* repairer can legitimately sit in ``VACUUM`` for minutes on
a large DB, and an unbounded wait would hang the caller's open with no traceback (the failure shape of
#36644).
)r`   Ú_REPAIR_LOCK_TIMEOUT_SECONDSz.repair.lockÚrepairzOskipping schema surgery rather than running it without cross-process authority.NFzstate.db repair locku¢   state.db repair lock %s held by another process for more than %.0fs â€” skipping schema surgery in this process to avoid racing the repairer. Recorded holder: %s.T)rg   )r   r`   r|   rP   ry   r   r*   rw   rL   rM   r   r   rn   Úclose)r   r`   r|   rN   r[   Úacquireds   &     r   Ú_cross_process_repair_lockr€   £   sÓ   é € ÷  GÜ'Ø� Ð+|ó~Ñ€Ià‚~ØŠÙØ€HðßÜ3°IÐGcÓd‰Hä0´°Y³ÀÜ1JÐLbó dÑˆHàÒØ‰HßÜ�N‰Nð hà$Ü0¿±ÔJbÐciÓJjÓkômð ŠçÜ  °d×;à�L‰LŽNø÷ Ü  °dÖ;à�L‰L�Nüs'   ‚%C4¨C	 °8C	 Á)7C	 Â )C4Ã	(C1Ã1C4c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r+   zOptional[Any]r   )r   s   "r   r   r   Ï   s   € ÷ 
ñ 
°ð 
¸ñ 
r   c                ó–   € \        V RRR4      w  r Ve   \        V4       V#   \        \        3 d    TP	                  4         R# i ; i)zÑNon-blocking cross-process lock for one auto-maintenance pass (None = skip the pass: otherwise two startups
both pass the interval check and the second prunes a row the first has only just closed recoverably).z.auto-maintenance.lockzauto-maintenancezskipping automatic maintenance.N)rP   rf   ru   r9   r~   )r   Ú
_lock_pathr[   s   &  r   Ú"_try_acquire_auto_maintenance_lockr„   Ï   sY   € ô )¨Ð2JÐL^ð  aBó  CÑ€JðØÒÜ! &Ô)ØˆøÜœWÐ%ô Ø�‰ŒÚðús   ’# £!AÁAc               ó    € V ^8„  d   QhRRRR/# ©r   Úconnúsqlite3.Connectionr+   rS   r   )r   s   "r   r   r   ß   s   € ÷ Iñ IÐ0ð I°Tñ Ir   c                ó2  €  V P                  R4      P                  4       ^ ,          pV P                  R\        V4      ^,           R,           24       R#   \        P                  \
        \        3 d"   p\        P                  RT4        Rp?R# Rp?ii ; i)aa  Increment the schema cookie after direct ``sqlite_master`` surgery.

Ordinary DDL bumps it and peers compare it before running a prepared statement (how they discard a cached
schema); ``writable_schema=ON`` edits do NOT, so live connections would keep firing triggers into
``messages_fts*`` shadow tables that no longer exist. Best-effort, never raises.zPRAGMA schema_versionzPRAGMA schema_version=iÿÿÿz)Could not bump state.db schema cookie: %sN)	ÚexecuteÚfetchoneÚintÚsqlite3ÚDatabaseErrorÚ	TypeErrorÚ
IndexErrorrL   rM   )r‡   ÚcurrentrO   s   &  r   Ú_bump_schema_cookier’   ß   sy   € ðIØ—,‘,Ð6Ó7×@Ñ@ÓBÀ1ÕEˆà�‰Ð-¬s°7«|¸aÕ/?À:Õ.MÐ-NÐOÖPøÜ×!Ñ!¤9¬jÐ9ô IÜ�‰ÐBÀC×HÒHûðIús   ‚AA Á BÁ5BÂBc               ó    € V ^8„  d   QhRRRR/# )r   ÚheadÚbytesr+   r   )r   s   "r   r   r   í   s   € ÷ ñ  ð ¨%ñ r   c                ó’   € \        V 4      ^`8  d   V # \        V 4      p\         F  w  r#RW2,
          ,          WV% K  	  \        V4      # )zJZero the commit-counter fields so ordinary writes don't re-key the ledger.ó    )ÚlenÚ	bytearrayÚ#_FINGERPRINT_VOLATILE_HEADER_RANGESr•   )r”   ÚbufÚstartÚends   &   r   Ú_mask_volatile_headerrž   í   sA   € ä
ˆ4ƒy�2„~ØˆÜ
�D‹/€Cß9‰
ˆØ  C¥KÕ0ˆ�#Šñ :ä�‹:Ðr   c               ó    € V ^8„  d   QhRRRR/# )r   Útotal_bytesrŒ   r+   r   )r   s   "r   r   r   ÷   s   € ÷ _ñ _¨sð _°sñ _r   c                óJ   € \        \        \        V \        ,          4      4      # )zLFree space required *beyond* the copy itself, for a volume of *total_bytes*.)ÚmaxÚ_REPAIR_BACKUP_MIN_FREE_BYTESrŒ   Ú_REPAIR_BACKUP_FREE_FRACTION)r    s   &r   Ú_repair_backup_headroom_bytesr¥   ÷   s   € äÔ,¬c°+Ô@\Õ2\Ó.]Ó^Ð^r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Úrefusalr*   r+   z#tuple[Optional[str], int, int, int]r   )r   s   "r   r   r   ü   s'   € ÷ 
Nñ 
N˜$ð 
N¨ð 
NÐ1Tñ 
Nr   c                ó`  €  V P                  4       P                  \        R \        V 4       4       4      ,           p\        P
                  ! V P                  4      pRY#P                  \        TP                  4      3#   \         d%   pRT P                   RT RT R2^ ^ ^ 3u Rp?# Rp?ii ; i)a#  ``(error, bundle_bytes, free_bytes, headroom_bytes)`` for *db_path*'s volume (main file plus every PRESENT
sidecar); *error* is set (and the sizes zero) on stat()/disk_usage() failure. Fails CLOSED: the nearly-full
volume these guards exist for is exactly where they are most likely to fail.c              3  ó„   "  € T F6  qP                  4       '       g   K  VP                  4       P                  x € K8  	  R # 5ir   )ÚexistsÚstatÚst_size©r!   Úps   & r   r#   Ú_disk_budget.<locals>.<genexpr>  s*   é € Ð+gÑFXÀ×\dÑ\d×\fÔ,<¨A¯F©F«H×,<Ö,<ÓFXùs
   ‚A ž"A z"could not determine free space on z (z); refusing the z$ rather than risk filling the volumeN)r«   r¬   Úsumr'   ÚshutilÚ
disk_usagerI   r9   Úfreer¥   Útotal)r   r§   ÚneedÚusagerO   s   &&   r   Ú_disk_budgetr·   ü   s¨   € ð/Ø�|‰|‹~×%Ñ%¬Ñ+gÄiÐPWÔFXÓ+gÓ(gÕgˆÜ×!Ò! '§.¡.Ó1ˆð �—z‘zÔ#@ÀÇÁÓ#MÐMÐMøô ô /Ø4°W·^±^Ð4DÀBÀsÀeÐK[Ð\cÐ[dð e%ð %Ø'(¨!¨Qð/õ 	/ûð/ús   ‚AA> Á>B-Â	B(Â"B-Â(B-c               ó    € V ^8„  d   QhRRRR/# ©r   r   r   r+   r,   r   )r   s   "r   r   r   	  s   € ÷ ]ñ ]¨ð ]°-ñ ]r   c                óì   € \        V R4      w  rr4Ve   V# W2^V,          ,           V,           8¼  d   R# RVR,          R RV P                   RVR,          R R^V,          R,          R R	VR,          R R
2# )zEReturn an error unless snapshot, VACUUM and promotion can fit safely.zrepair snapshotNúonly ç    eÍÍAú.2fúGB free on z"; the repair snapshot needs up to zGB, VACUUM may need another zGB, and z8GB must remain as headroom. Free disk space, then retry.)r·   rI   )r   ÚerrorÚsnapshot_bytesr³   Úheadrooms   &    r   Ú_repair_scratch_space_errorrÂ   	  s–   € ä,8¸ÐBSÓ,TÑ)€E˜4ØÒØˆð   ^Õ!3Õ4°xÕ?Ô?ÙØ�D˜3•J˜sÐ# ;¨w¯~©~Ð.>Ð>`Ø Õ# CÐ(Ð(DÀaÈ.ÕFXÐ\_ÕE_Ð`cÐDdÐdlØ˜#�~˜cÐ"Ð"Zð\ð ]r   c               ó    € V ^8„  d   QhRRRR/# r¹   r   )r   s   "r   r   r     s   € ÷ 
>ñ 
> dð 
>¨}ñ 
>r   c           
     óæ   € \         P                  V R7      p\        V R4      w  r#rEVe   V RV 2# WC,
          V8¼  d   R# RVR,          R RV P                   R	VR,          R R
VR,          R RV 2
# )zÕDisk guard for the forensic copy: reason to refuse, or None. A full raw copy on a nearly-full volume (which a
preceding repair loop may itself have caused) can finish off the disk and every process on the machine.r&   zforensic copyNz. r»   r¼   r½   r¾   z; copying the damaged DB needs zGB and must leave zGB headroom. )Ú_MANUAL_RECOVER_HINTr   r·   rI   )r   Úhintr¿   rµ   r³   rÁ   s   &     r   Ú_backup_free_space_errorrÇ     s™   € ô  ×&Ñ&¨wÐ&Ó7€DÜ".¨w¸Ó"HÑ€E�ØÒØ�˜˜4˜&Ð!Ð!Ø…{�hÔÙØ�D˜3•J˜sÐ# ;¨w¯~©~Ð.>Ð>]Ð^bÐehÕ^hÐilÐ]mð nØ •^ CÐ(¨°d°Vð=ð >r   c               ó    € V ^8„  d   QhRRRR/# )r   Úsource_pathr   r+   rq   r   )r   s   "r   r   r   $  s   € ÷ nñ n°$ð n¸5ñ nr   c                ó&  € ^ RI Hp ^ pV .\        V 4      O FN  p\        P                  ! \
        4      ;_uu_ 4        W#P                  4       P                  ,          pRRR4       KP  	  \        W\        ,          4      #   + '       g   i     Ky  ; i)z½Bound one SQLite snapshot by source size incl. sidecars (a WAL can hold committed rows not yet in the
main file), so a healthy large-database copy is not cut off by the repair-lock timeout.)r|   N)
r   r|   r'   r1   rl   ÚFileNotFoundErrorr«   r¬   r¢   Ú0_REPAIR_SNAPSHOT_MIN_THROUGHPUT_BYTES_PER_SECOND)rÉ   r|   Úsource_bytesÚ	candidates   &   r   Ú _repair_snapshot_timeout_secondsrÏ   $  sr   € õ :Ø€LØ!Ð;¤I¨kÓ$:Ó;ˆ	Ü× Ò Ô!2×3Õ3ØŸN™NÓ,×4Ñ4Õ4ˆL÷ 4Ñ3ñ <ô Ð+Ô<lÕ-lÓmÐm÷ 4×3Ð3ús   ¼!A?Á?Bc               ó    € V ^8„  d   QhRRRR/# ©r   rO   ÚBaseExceptionr+   r>   r   )r   s   "r   r   r   /  s   € ÷ nñ n¨-ð n¸Dñ nr   c                óV  a € \        S \        P                  4      '       g   R# \        \        S RR4      ;p\        4      '       d+   V^ÿ,          \        P
                  \        P                  39   # \        ;QJ d    V 3R lR 4       F  '       g   K   R# 	  R# ! V 3R lR 4       4      # )u  Whether a pre-strategy SQLite failure proves deterministic corruption.

Lock contention, timeouts, disk-full and I/O failures are environmental â€” a retry may succeed, so they
must not burn the repair ledger. Only SQLite's corruption/image result codes prove deterministic damage.FÚsqlite_errorcodeNc              3  óZ   <"  € T F   q\        S4      P                  4       9   x € K"  	  R # 5ir   ©r*   Úlower©r!   ÚmrO   s   & €r   r#   Ú3_repair_failure_consumes_attempt.<locals>.<genexpr>;  s!   øé € ÐmÑ.l¨”C˜“H—N‘NÓ$Ö$Ó.lùó   ƒ(+T)zfile is not a databasez database disk image is malformed)Ú
isinstancer�   rŽ   rZ   rŒ   ÚSQLITE_CORRUPTÚSQLITE_NOTADBÚany)rO   Ú
error_codes   f r   Ú _repair_failure_consumes_attemptrá   /  s…   ø€ ô
 �cœ7×0Ñ0×1Ò1ÙÜ¤¨Ð-?ÀÓ FÐF�*Ì×LÒLà˜TÕ!¤w×'=Ñ'=¼w×?TÑ?TÐ&UÑUÐU÷ ‹3ÔmÑ.lÓm�3Œ3ÐmŠ3Ðmˆ3ÔmÑ.lÓmÓmÐmr   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r+   r   )r   s   "r   r   r   >  s   € ÷ Eñ E ð E¨$ñ Er   c                óF   € V P                  V P                  R ,           4      # )z.repair-attempts.jsonr   r&   s   &r   Ú_repair_ledger_pathrä   >  s   € Ø×Ñ˜WŸ\™\Ð,CÕCÓDÐDr   c               ó    € V ^8„  d   QhRRRR/# r¹   r   )r   s   "r   r   r   B  s   € ÷ :ñ :˜Tð : mñ :r   c                ó0   a € R V 3R llp\        S RV4      # )aï  Cheap identity for a damaged DB file: size + a bounded content sample.

EXCLUDES mtime: a malformed-schema DB still accepts writes, so live writers, checkpoints and the
strategies move mtime between passes; keyed on mtime every pass looked like a NEW file and the attempt
counter reset forever. Hashing a multi-GB file per open is the cost this ledger avoids, so sample the
head/tail slices any real repair, truncation or restore must change.

``None`` = identity unavailable (:func:`_read_offline`; a live peer is expected here since this runs
BEFORE ``_backup_db_file``'s live-connection guard). Callers MUST NOT substitute a differently-shaped key:
the ledger compares for equality, so alternating shapes never match and the unbounded loop returns.c               ó   € V ^8„  d   QhRR/# ©r   r+   r*   r   )r   s   "r   r   Ú%_db_fingerprint.<locals>.__annotate__M  s   € ÷ eñ e�Sñ er   c            	     óú  <€ SP                  4       p \        SR 4      ;_uu_ 4       pVP                  \        4      pVP	                  \        ^ V P                  \        ,
          4      4       V P                  \        8”  d   VP                  \        4      MRpRRR4       V P                   R\        P                  ! \        X4      X,           4      P                  4       R,           2#   + '       g   i     LZ; i)Úrbr   NÚ::Né    N)r«   rK   ÚreadÚ_FINGERPRINT_SAMPLE_BYTESrW   r¢   r¬   ÚhashlibÚsha256rž   Ú	hexdigest)ÚstÚfhr”   rE   r   s       €r   Ú_sampleÚ _db_fingerprint.<locals>._sampleM  s°   ø€ Ø�\‰\‹^ˆÜ�'˜4× Ô  BØ—7‘7Ô4Ó5ˆDØ�G‰G”C˜˜2Ÿ:™:Ô(AÕAÓBÔCØ9;¿¹ÔF_Ô9_�2—7‘7Ô4Ô5ÐehˆD÷ !ð —*‘*�˜QœwŸ~š~Ô.CÀDÓ.IÈDÕ.PÓQ×[Ñ[Ó]Ð^aÕbÐcÐdÐd÷	 !× ús   ¦A2C*Ã*C:	Úfingerprint©r;   )r   rõ   s   f r   Ú_db_fingerprintrù   B  s    ø€ ÷eð eô ˜ -°Ó9Ð9r   c               ó    € V ^8„  d   QhRRRR/# r¹   r   )r   s   "r   r   r   W  s   € ÷ >ñ > dð >¨}ñ >r   c                ó0   a € R V 3R llp\        S RV4      # )uÂ  Recovery-image identity for forensic-backup dedupe: whole file + sidecars.

A DIFFERENT relation from :func:`_db_fingerprint` (never conflate them): the fingerprint answers "same
repair epoch?" from head+tail only, and a live writer can commit into an *interior* page while preserving
size and both 64 KiB slices â€” reusing a backup on that basis hands the operator a snapshot predating real
user data. A forensic copy must claim byte identity, so this digests the ENTIRE main file plus every
present sidecar (the WAL can hold uncheckpointed frames). ``None`` when a live connection makes the read
unsafe (:func:`_read_offline`) â€” the caller then takes a fresh backup, never a false reuse.

See #87409.
c               ó   € V ^8„  d   QhRR/# rè   r   )r   s   "r   r   Ú._backup_content_identity.<locals>.__annotate__c  s   € ÷ 
"ñ 
"�Sñ 
"r   c                 óÞ  <a€ \         P                  ! 4       p R S3.R \        \        \	        S4      4       4       OpV Fˆ  w  r#V P                  RV RVP                  4       P                   R2P                  4       4       \        VR4      ;_uu_ 4       o\        V3R lR4       F  pV P                  V4       K  	  RRR4       KŠ  	  V P                  4       #   + '       g   i     K­  ; i)Úmainc              3  ó\   "  € T F"  w  rVP                  4       '       g   K  W3x € K$  	  R # 5ir   )rª   )r!   Úsfxr®   s   &  r   r#   Ú<_backup_content_identity.<locals>._digest.<locals>.<genexpr>e  s$   é € Ð'{Ñ?l±V°SÐpq×pxÑpx×pz¬¨­Ó?lùs   ‚,¡,Ú rì   rë   c                 ó&   <€ S P                  R4      # )i   i   )rî   )rô   s   €r   r5   Ú;_backup_content_identity.<locals>._digest.<locals>.<lambda>k  s   ø€ ¨"¯'©'°+Ô*>r   r   N)rð   rñ   Úzipr%   r'   Úupdater«   r¬   ÚencoderK   Úiterrò   )ÚhasherÚmembersÚlabelÚpathÚchunkrô   r   s        @€r   Ú_digestÚ)_backup_content_identity.<locals>._digestc  sÈ   ù€ Ü—’Ó!ˆØ˜GÐ$Ð|Ñ'{¼sÔCWÔYbÐcjÓYkÔ?lÓ'{Ð|ˆÛ"‰KˆEð �M‰M˜B˜u˜g Q t§y¡y£{×':Ñ':Ð&;¸2Ð>×EÑEÓGÔHÜ�d˜D×!Ô! RÜ!Ô">ÀÖD�EØ—M‘M %Ö(ñ E÷ "Ñ!ñ	 #ð ×ÑÓ!Ð!÷ "×!Ð!ús   Â)CÃC,zbackup-identityrø   )r   r  s   f r   Ú_backup_content_identityr  W  s   ø€ ÷
"ð 
"ô ˜Ð"3°WÓ=Ð=r   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r+   údict[str, Any]r   )r   s   "r   r   r   q  s   € ÷ ñ  ð ¨.ñ r   c                ó   € \         P                  ! \        \        4      ;_uu_ 4        \        P
                  ! \        V 4      P                  R R7      4      p\        V\        4      '       d   TM/ uuRRR4       #   + '       g   i     / # ; i)úutf-8©ÚencodingN)
r1   rl   r9   Ú
ValueErrorÚjsonÚloadsrä   Ú	read_textrÜ   Údict)r   Úraws   & r   Ú_read_repair_ledgerr  q  s^   € Ü	×	Ò	œW¤j×	1Õ	1Ü�jŠjÔ,¨WÓ5×?Ñ?ÈÐ?ÓQÓRˆÜ  ¤d×+Ò+‰s°÷ 
2×	1×	1Ñ	1ð €Iús   ¨A	A<Á<B	c               ó    € V ^8„  d   QhRRRR/# r=   r   )r   s   "r   r   r   x  s   € ÷ ]ñ ]°4ð ]¸Dñ ]r   c                óf  € \        V 4      pVP                  R4      p\        V 4      p Ve   W#8H  MC\        V\        4      ;'       d-    VP                  V P                  4       P                   R24      pT;'       d#    \        TP                  R^ 4      4      \        8¬  #   \         d     R# i ; i)aâ  Whether *db_path* has already burned its cross-restart repair budget.

True only when the ledger records ``_MAX_PERSISTENT_REPAIR_ATTEMPTS`` failures against the CURRENT
fingerprint. Never raises; a missing/corrupt ledger or unstatable DB reads as "not exhausted" (the
in-process claim and cross-process lock still bound one run). Fingerprint unavailable (live connection) ->
compare the SIZE the ledger recorded, otherwise a peer connection hides an exhausted budget on every pass.r÷   rì   FÚfailed_attempts)r  Úgetrù   rÜ   r*   Ú
startswithr«   r¬   r9   rŒ   Ú_MAX_PERSISTENT_REPAIR_ATTEMPTS)r   ÚledgerÚrecordedÚfpÚsames   &    r   Ú%_persistent_repair_attempts_exhaustedr)  x  s¦   € ô ! Ó)€FØ�z‰z˜-Ó(€HÜ	˜Ó	!€BðØ!#¢ˆxŠ~Ü�x¤Ó%×[Ð[¨(×*=Ñ*=ÀÇÁÃ×AWÑAWÐ@XÐXYÐ>ZÓ*[ð 	ð ×\Ð\”C˜Ÿ
™
Ð#4°aÓ8Ó9Ô=\Ñ\Ð\øô ô Úðús   ©B! Á-B! Â!B0Â/B0c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r+   r*   r   )r   s   "r   r   r   Š  s   € ÷ _ñ _°ð _¸ñ _r   c                ót   € ^ RI Hp V! 4       pR\         RV RV  RV RV  R\        V 4      P                   R2# )z±The stable operator-facing diagnostic for an exhausted repair budget. The ``hermes`` commands
carry the profile selector: a bare ``hermes`` follows ``active_profile`` (#105887).)Úprofile_cli_selectorz$automatic repair has already failed u¹    times on this exact file â€” the corruption is beyond the schema/FTS repair strategies (likely b-tree page damage). Manual recovery required: restore a backup, or salvage with `hermes zsessions recover --source z; --inspect-only`, then (if it reports recoverable) `hermes zÁ --output recovered-state.db` (recovery snapshots the damaged file first, then runs the page-level `.recover` lane on the copy; do NOT point a raw `sqlite3` shell at the live database). Delete z$ to force another automatic attempt.)Úhermes_constantsr,  r$  rä   r    )r   r,  Úprofile_args   &  r   Ú"_persistent_repair_exhausted_errorr/  Š  sj   € õ 6Ù&Ó(€KØ2Ô3RÐ2Sð TCàCNÀ-ÐOiÐjqÐirð sIØITÈÐUoÐpwÐoxð yô *¨'Ó2×7Ñ7Ð8Ð8\ð^ð _r   r÷   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r   r   Úrepairedr>   r÷   r,   r+   rS   r   )r   s   "r   r   r   ˜  s/   € ÷ Kñ K Dð K°tð KÈ-ð KÐcgñ Kr   c          
     óT  € \        V 4      p V'       d   VP                  RR7       R# \        V 4      pVP                  R4      pVe   TM
\	        V 4      pVf   \        V\        4      '       g   R# TpWV8X  d#   \        VP                  R^ 4      4      ^,           M^p\        P                  P                  4       P                  RR7      pVP                  \        P                  ! RVRVRV/4      R	R
7       R#   \         d"   p	\        P!                  RT	4        Rp	?	R# Rp	?	ii ; i)uN  Update the persistent attempt ledger after a repair pass. Never raises.

Keys on the post-attempt fingerprint (what the NEXT exhaustion probe sees). If a live connection makes it
unavailable, keep the recorded key and still increment â€” dropping the pass lets a peer reset the budget
every time. Never write a differently shaped key.T©Ú
missing_okNr÷   r!  Úseconds)ÚtimespecÚlast_attemptr  r  z+Could not update state.db repair ledger: %s)rä   Úunlinkr  r"  rù   rÜ   r*   rŒ   ÚdatetimeÚnowÚ	isoformatÚ
write_textr  ÚdumpsÚ	ExceptionrL   rM   )
r   r1  r÷   Úledger_pathr%  r&  r'  ÚattemptsÚstamprO   s
   &$$       r   Ú_record_repair_outcomerB  ˜  s  € ô & gÓ.€KðKßØ×Ñ¨$ÐÔ/ÙÜ$ WÓ-ˆØ—:‘:˜mÓ,ˆØ'Ò3‰[¼ÈÓ9QˆØŠ:Ü˜h¬×,Ò,ñ ØˆBØ@HÄ”3�v—z‘zÐ"3°QÓ7Ó8¸1Ö<ÐTUˆÜ×!Ñ!×%Ñ%Ó'×1Ñ1¸9Ð1ÓEˆØ×ÑœtŸzšz¨=¸"Ð>OÐQYÐ[iÐkpÐ*qÓrð  ~EÐö  	FøÜô KÜ�‰ÐDÀc×JÒJûðKús$   �C; ©AC; Á2BC; Ã;D'ÄD"Ä"D'c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r+   z
list[Path]r   )r   s   "r   r   r   ³  s   € ÷ =ñ =¨ð =°*ñ =r   c                óT  € V P                    R2p V P                  P                  4        Uu. uFN  q"P                   P                  V4      '       g   K%  VP                   P	                  \
        4      '       d   KL  VNKP  	  pp\        TR RR7      # u upi   \         d    . u # i ; i)z8Timestamped forensic backups of *db_path*, newest first.ú.malformed-backup-c                ó   € V P                   # r   )r    )r®   s   &r   r5   Ú-_existing_malformed_backups.<locals>.<lambda>º  s   €  q§v¢vr   T)ÚkeyÚreverse)r    rI   Úiterdirr#  Úendswithr%   r9   Úsorted)r   Úprefixr®   Úfounds   &   r   Ú_existing_malformed_backupsrO  ³  s•   € à—‘ˆ~Ð/Ð0€FðØ#ŸN™N×2Ñ2Ô4ó  AÑ4�q¿¹×8IÑ8IÈ&×8Q”ÐZ[×Z`ÑZ`×ZiÑZiÔj~×Z—�Ñ4ˆð  Aô �%Ñ-°tÔ<Ð<ùò AøÜô ØŠ	ðús.   ‘B ­"BÁ"BÁ;BÂB ÂB ÂB'Â&B'c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   ÚkeeprŒ   r+   rS   r   )r   s   "r   r   r   ½  s'   € ÷ Vñ V dð V°#ð VÐSWñ Vr   c                óÞ   € \        V 4      VR  F+  pV.\        V4      O F  p VP                  RR7       K  	  K-  	  R#   \         d"   p\        P                  RY44        Rp?KG  Rp?ii ; i)zADelete all but the *keep* newest forensic backups (and sidecars).NTr3  z&Could not prune stale DB backup %s: %s)rO  r'   r8  r9   rL   rM   )r   rQ  ÚstaleÚvictimrO   s   &&   r   Ú_prune_malformed_backupsrU  ½  si   € ä,¨WÓ5°d°eÓ<ˆØÐ0œy¨Ó/Ó0ˆFðVØ—‘¨�Ö.ó 1ó =øô ô VÜ—‘ÐGÈ×UÒUûðVús   ¤A Á A,ÁA'Á'A,c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r   r   ÚstagingÚbackup_pathr+   rS   r   )r   s   "r   r   r   Ç  s(   € ÷ ñ  Dð °4ð Àdð Ètñ r   c           
     óÖ  € WV3p\        \        \        V 4      4       UUu. uFa  w  rEVP                  4       '       g   K  WQP	                  VP
                  V,           4      VP	                  VP
                  V,           4      3NKc  	  ppp. p V.VO F  w  r‰p
\        P                  ! W‰4       K  	  . VOVN F-  w  r¹p\        P                  ! Wœ4       VP                  V4       K/  	  R# u uppi   \         dl    . R . TOTN 4       OTO FT  p\        P                  ! \        4      ;_uu_ 4        TP                  RR7       RRR4       KB    + '       g   i     KS  ; i	  h i ; i)uk  Copy DB + sidecars to *staging* names, then rename each into place.

ORDER MATTERS: the main DB name is the bundle's commit marker (what ``_existing_malformed_backups``
counts), so sidecars publish FIRST and the main DB LAST â€” a failure partway never leaves a countable
backup over a missing sidecar. On failure, staging files AND anything promoted are removed.c              3  ó*   "  € T F	  w  rq2x € K  	  R # 5ir   r   )r!   Ú_sÚstagedÚ_ds   &   r   r#   Ú)_publish_backup_bundle.<locals>.<genexpr>Ø  s   é € ÐHÑ6G¡N B°œÓ6Gùs   ‚Tr3  N)r  r%   r'   rª   r   r    r±   Úcopy2ÚosÚreplaceÚappendr>  r1   rl   r9   r8  )r   rW  rX  rÿ   r"   ÚsidecarÚsidecarsÚ	publishedÚsrcr\  Ú_dstÚ_srcÚdstrT  s   &&&           r   Ú_publish_backup_bundlerj  Ç  sO  € ð ˜kÐ*€Dä'*Ô+?ÄÈ7ÓASÔ'TôjÙ'T‘O�FÐX_×XfÑXf×Xhô v�×+Ñ+¨G¯L©L¸6Õ,AÓBÀK×DYÑDYÐZe×ZjÑZjÐmsÕZsÓDtÓuÙ'Tð ñ jà€Ið
Ø"&Ð!2¨Ó!2ÑˆC˜Ü�LŠL˜Ö%ñ "3à!2 8Ð!2¨TÓ!2ÑˆD˜#Ü�JŠJ�vÔ#Ø×Ñ˜SÖ!ó "3ùójøô ô ØUÑHÐ6G¸Ð6GÀ$Ñ6GÓHÐUÈ9ÓUˆFÜ×$Ò$¤W×-Õ-Ø—‘¨�Ô.÷ .×-×-Ò-úñ Vð 	ð	ús2   ¡C,Á AC,ÂAC2 Ã2AE(Ä3E	Å
E(ÅE!ÅE(c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r+   z$tuple[Optional[Path], Optional[str]]r   )r   s   "r   r   r   Þ  s   € ÷ 82ñ 82˜Tð 82Ð&Jñ 82r   c           	     ó
  € \         P                  ! \        4      ;_uu_ 4        ^ RIHp V! V 4      '       d+   RV  R2p\
        P                  RW4       RV3uuRRR4       #  RRR4       \        P                  P                  4       P                  R4      pV P                  V P                   RV 24      p\        P                  ! ^4       F>  pVP                  4       '       g    M'V P                  V P                   RV RV 24      pK@  	   V P                   R	2V P                   R
23 Fb  pV P                  P!                  V4       F@  p\         P                  ! \"        4      ;_uu_ 4        VP%                  RR7       RRR4       KB  	  Kd  	  \         P                  ! \"        4      ;_uu_ 4        \'        V 4      R,          ;p'       dY   \)        V 4      p	V	eJ   \)        V^ ,          4      V	8X  d3   \
        P+                  RV^ ,          4       V^ ,          R3uuRRR4       # RRR4       \-        V 4      ;pe   \
        P                  RW4       RV3# \/        W P                  V P                   RV 24      V4       \1        V 4       VR3#   + '       g   i     EL:; i  + '       g   i     EKm  ; i  + '       g   i     L›; i  \2         d(   p
\
        P5                  RY
4       RRT
 23u Rp
?
# Rp
?
ii ; i)uç  Raw-copy a (possibly malformed) DB plus sidecars to a timestamped backup.

Raw bytes on purpose: the DB won't open cleanly, so preserve them exactly for forensics. Returns ``(backup_path,
None)`` or ``(None, reason)``; repair treats a refused backup as a HARD STOP because the bundle is the recovery
path when every strategy fails. Refuses while a connection to this DB is live in the process: the raw read would
``close()`` a descriptor and cancel that connection's POSIX advisory locks (``hermes_cli.sqlite_safe_read``) â€”
real case: one SessionDB enters repair while the gateway holds others.

Dedupe: reuse the newest backup when byte-identical to the current recovery image (``_backup_content_identity``
â€” NOT mtime, NOT ``_db_fingerprint``); a repair loop once re-copied the same bytes on every restart. Staging
names live OUTSIDE the ``.malformed-backup-`` prefix: inside it they count as a backup, sort NEWEST (prune kept
partials, deleted intact copies) and dedupe could return one with no real forensic copy on disk.

Refusal reasons (``_backup_free_space_error`` / ``_MANUAL_RECOVER_HINT``) point operators at the safe lane,
`hermes sessions recover --source <db> --inspect-only`, never at a raw sqlite3 shell on the live file.

See #69603.
)Úhas_live_connectionza connection to z† is still open in this process; raw-copying it would cancel that connection's POSIX advisory locks. Close all SessionDB handles first.z&Refusing to raw-copy %s for backup: %sNz%Y%m%d_%H%M%SrE  Ú_z.backup-staging-*z.malformed-backup-*.incomplete*Tr3  :Né   NzBReusing existing forensic backup %s (identical to the damaged DB).z"Refusing forensic backup of %s: %sz.backup-staging-z%Could not back up malformed DB %s: %szbackup copy failed: )r1   rl   r8   r7   rm  rL   r¿   r9  r:  Ústrftimer   r    Ú	itertoolsÚcountrª   rI   Úglobr9   r8  rO  r  ÚinforÇ   rj  rU  r>  rM   )r   rm  ÚreasonrA  rX  ÚseqÚpatternÚoldÚnewestÚsrc_idrO   s   &          r   Ú_backup_db_filer{  Þ  s‹  € ô& 
×	Ò	œ[×	)Õ	)ÝCÙ˜w×'Ò'Ø(¨¨	ð 2^ð ^ˆFä�L‰LÐAÀ7ÔSØ˜�<÷ 
*Ò	)à'÷ 
*ô ×Ñ×!Ñ!Ó#×,Ñ,¨_Ó=€EØ×#Ñ# w§|¡| nÐ4FÀuÀgÐ$NÓO€KÜ�Š˜qÖ!ˆØ×!Ñ!×#Ò#ÙØ×'Ñ'¨7¯<©<¨.Ð8JÈ5È'ÐQRÐSVÐRWÐ(XÓYŠñ "ð2ð #Ÿ<™<˜.Ð(9Ð:¸w¿|¹|¸nÐLkÐ<lÓmˆGØ—~‘~×*Ñ*¨7Ö3�Ü×(Ò(¬×1Õ1Ø—J‘J¨$�JÔ/÷ 2Ñ1ó 4ñ nô × Ò ¤×)Õ)ä4°WÓ=¸bÕAÐAˆvÖAÜ1°'Ó:�ØÒ%Ô*BÀ6È!Å9Ó*MÐQWÔ*WÜ—K‘KÐ dÐflÐmnÕfoÔpØ! !�9 d˜?÷ *×)Ò)ô /¨wÓ7Ð7ˆFÒDÜ�L‰LÐ=¸wÔOØ˜�<ÐÜ˜w×(9Ñ(9¸W¿\¹\¸NÐJZÐ[`ÐZaÐ:bÓ(cÐepÔqä  Ô)Ø˜DÐ Ð ÷E 
*×	)Ð	)ú÷& 2×1Ñ1úç)×)ûô ô 2Ü�‰Ð>ÀÔMØÐ+¨C¨5Ð1Ð1Õ1ûð2úsg   £4JÄA!K Å2J(	Æ2K Æ7A(J=È
K È*0K É8K ÊJ%	Ê(J:Ê3
K Ê=K	ËK ËLËK=Ë7LË=Lc               ó    € V ^8„  d   QhRRRR/# )r   r®   r   r+   r>   r   )r   s   "r   r   r     s   € ÷ 	Fñ 	F�tð 	F ñ 	Fr   c                óî   € \         P                  \         P                  ,          p\         P                  ! W4      ;'       g4    V P	                  4       '       * ;'       g    \         P                  ! W4      # )aÛ  True when *p* is read-write for this user OR no longer exists.

The preflight lists the files first and checks them after, and a live sibling connection's last ``close()``
unlinks ``-wal``/``-shm`` in between (a concurrent quarantine can rename ``state.db`` aside the same way).
``os.access`` on the vanished path returns False, which is "gone", not "read-only". The final re-check covers
a sidecar that vanished and was recreated by the next opener before ``exists()`` ran.
)r`  ÚR_OKÚW_OKÚaccessrª   )r®   Úmodes   & r   Ú_rw_or_vanishedr‚    sF   € ô �7‰7”R—W‘WÕ€DÜ�9Š9�QÓ×EÐE Q§X¡X£Z¤×EÐE´2·9²9¸QÓ3EÐEr   Údb_labelzstate.dbÚdirectory_onlyc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r   r   rƒ  r*   r„  r>   r+   rS   r   )r   s   "r   r   r   %  s*   € ÷ %5ñ %5 dð %5¸ð %5Ð[_ð %5Ðlpñ %5r   c               ó(  € \        V 4      R8X  g!   \        V 4      P                  R4      '       d   R# Rp\        P                  ! \        4      ;_uu_ 4        \        \        4       4      P                  4       pRRR4       V P                  V P                  R,           4      V P                  V P                  R,           4      3pV'       d   RM1\        ;QJ d    . R V .VO 4       F  NK  	  5M! R V .VO 4       4      pV P                  R3.VO EFÔ  w  rgV'       d   VP                  4       '       d   \        V4      '       d   K7  V'       d   RMR	pR
p	\        P                  ! \        \        4      ;_uu_ 4        VRJ;'       d     VP                  4       P!                  V4      p	V	'       dx   \"        P$                  ! YfP'                  4       P(                  \&        P*                  ,          \&        P,                  ,          V'       d   \&        P.                  M^ ,          4       RRR4       V	'       d[   \"        P0                  ! V\"        P2                  \"        P4                  ,          4      '       d   \6        P9                  RWV4       EK�  VP                  P;                  R4      '       d   RMR	p
\<        P>                  ! T RV'       d   RMR RV RV RV RV
 24      h	  R#   + '       g   i     EL}; i  + '       g   i     Là; i)u  Refuse-or-repair read-only DB files BEFORE the first connection opens.

A stray read-only ``state.db`` / ``-wal`` / ``-shm`` (sudo run, restored backup, copied dotfiles) otherwise
surfaces as an opaque "attempt to write a readonly database" inside ``_init_schema``, and the obvious wrong
"fix" (deleting the ``-wal``) loses committed transactions. ``chmod u+rw`` repair only inside the Hermes home
tree (Hermes owns those files; ``chmod`` fails on files the user doesn't own, bounding the repair exactly);
otherwise fail fast naming the file and command. Never deletes/truncates a WAL sidecar â€” once writable, the
normal open checkpoints it. ``:memory:``/``file:`` skipped. Shared with ``kanban_db``.

Port of Kilo-Org/kilocode#12508's startup preflight. This preflight:
z:memory:zfile:Nú-walú-shmc              3  óX   "  € T F   qP                  4       '       g   K  VR 3x € K"  	  R# 5i)FN)Úis_filer­   s   & r   r#   Ú+preflight_db_writability.<locals>.<genexpr>8  s!   é € Ð+dÑ@T¸1×XaÑXa×Xc¬J¨Q°­JÓ@Tùs   ‚*ž*TÚxÚ Fz2%s preflight: repaired read-only %s (chmod u+rw%s)uv    Do NOT delete the -wal file â€” it contains committed data that will be merged into the database once it is writable.z is not writable: Ú	directoryÚfileÚ zf is read-only for this user. Hermes needs read-write access to open the database. Fix with: chmod u+rwz 'z4' (files owned by another user may need sudo/chown).r   ) r*   r#  r1   rl   r>  r   r	   Úresolver   r    ÚtuplerI   Úis_dirr‚  r9   r  Úis_relative_tor`  Úchmodr«   Úst_modeÚS_IRUSRÚS_IWUSRÚS_IXUSRr€  r~  r  rL   rt  rK  r�   ÚOperationalError)r   rƒ  r„  Úhomerd  Úfilesr®   r“  rŒ  Úin_scopeÚwal_notes   &$$        r   Úpreflight_db_writabilityrŸ  %  s9  € ô ˆ7ƒ|�zÔ!¤S¨£\×%<Ñ%<¸W×%EÒ%EÙØ€DÜ	×	Ò	œY×	'Õ	'Ü”OÓ%Ó&×.Ñ.Ó0ˆ÷ 
(ð ×!Ñ! '§,¡,°Õ"7Ó8¸'×:KÑ:KÈGÏLÉLÐ[aÕLaÓ:bÐc€Hß ‰B§e¤eÑ+dÀÐ@TÈ8Ñ@TÓ+d§e¡eÑ+dÀÐ@TÈ8Ñ@TÓ+dÓ&d€EØ—~‘~ tÐ,Ð5¨uÔ5‰	ˆß˜1Ÿ8™8Ÿ:š:¬/¸!×*<Ò*<Ùß‰C˜rˆØˆÜ× Ò ¤¬*×5Õ5Ø 4Ð'×LÐL¨A¯I©I«K×,FÑ,FÀtÓ,LˆHßÜ—’˜ŸF™F›H×,Ñ,¬t¯|©|Õ;¼d¿l¹lÕJ×^dÌdÏlÊlÐjkÕlÔm÷ 6÷ œŸ	š	 !¤R§W¡W¬r¯w©wÕ%6×7Ò7Ü�K‰KÐLÈhÐ[\Ô]ÚàOPÏvÉvÏÉÐ_e×OfÒOfñLØlnð 	ä×&Ò&ØˆjÐ*¿&©;ÀfÐ*MÈQÈqÈcð RQØQRÐPSÐSUÐVWÐUXð Y)Ø)1¨
ð4ó5ð 	5ó 6÷ 
(×	'Ð	'ú÷ 6×5ús   Á"K-Å>3LÆ2A7LË-K>	ÌLrp   g      @c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   rp   rq   r+   rˆ   r   )r   s   "r   r   r   M  s"   € ÷ ñ  Tð °uð ÐGYñ r   c               ó>   € ^ RI Hp V! W VRR7      p\        V4       V# )u  ``sqlite3.connect`` for the repair/probe paths, with macOS write barriers.

These paths bypass ``SessionDB``/:func:`apply_wal_with_fallback`, so they inherited ``synchronous=NORMAL`` and
no ``checkpoint_fullfsync`` â€” on Darwin an interrupted ``REINDEX``/``VACUUM``/``writable_schema`` rewrite leaves
half-written b-tree pages. Autocommit (``isolation_level=None``): DDL and ``VACUUM`` are illegal inside an
implicit transaction. Barriers are best-effort: on a malformed schema even ``PRAGMA synchronous=FULL`` raises,
so whole-file rewrites call :func:`_reapply_durability_barriers` once the schema parses again.

Tracked (:func:`hermes_cli.sqlite_safe_read.connect_tracked`) because repair connections hold the
strongest locks in the process (``locking_mode=EXCLUSIVE``, ``BEGIN IMMEDIATE``); an untracked fd let
the byte-level probes ``open()``/``close()`` the live file, which cancels every POSIX advisory lock this
process holds on it (sqlite.org/howtocorrupt Â§2.2) and lets an external writer commit mid-repair (#63386).
)Úconnect_trackedN)Útracking_pathrp   Úisolation_level)r7   r¢  Ú_reapply_durability_barriers)r   rp   r¢  r‡   s   &$  r   Ú_connect_repair_durabler¦  M  s#   € õ <á˜7À7Ð\`Ôa€DÜ  Ô&Ø€Kr   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   rp   rq   r   )r   s   "r   r   r   b  s   € ÷ Qñ Q˜$ð Q¨Eñ Qr   c               óB   € \         P                  ! \        WR7      4      # )zRA :func:`_connect_repair_durable` connection as a context manager, closed on exit.©rp   )r1   rk   r¦  )r   rp   s   &$r   Ú_repair_connrª  b  s   € ä×ÒÔ5°gÔOÓPÐPr   c               ó    € V ^8„  d   QhRRRR/# ©r   r‡   rˆ   r+   r>   r   )r   s   "r   r   r   g  s   € ÷ 
ñ 
Ð'9ð 
¸dñ 
r   c                ó\   € ^ RI HpHp  V! V 4       V! V 4       R#   \         d     R# i ; i)zßBest-effort (re)application of the macOS write barriers; True if accepted.
Call before ``VACUUM``/``REINDEX`` once the schema parses: a connection opened
on a malformed schema could not take them at open time. Never raises.)Ú_apply_macos_checkpoint_barrierÚ_enforce_macos_synchronous_fullTF)Úhermes_state_walr®  r¯  r>  )r‡   r®  r¯  s   &  r   r¥  r¥  g  s2   € ÷ bðÙ'¨Ô-Ù'¨Ô-ÙøÜô Úðús   Š œ+ª+c               ó    € V ^8„  d   QhRRRR/# r¬  r   )r   s   "r   r   r   t  s   € ÷ 
ñ 
Ð$6ð 
¸4ñ 
r   c           	     óô   € ^ RI Hp \        V 4      p\        P                  ! \
        4      ;_uu_ 4        ^ RIHpHp V! V! 4       RRRR7      ;pe   V! WRR7       RRR4       V#   + '       g   i     T# ; i)	a  Durability barriers for guest users of ``state.db`` that must inherit its owner's journal mode. Also
applies the configured ``database.synchronous`` level, a per-connection pragma that otherwise only
rides on the journal-mode setup path guests must not run.)Ú_apply_synchronous_pragma)Úcfg_getÚload_config_readonlyÚdatabaseÚsynchronousN)Údefaultzstate.db (guest)©rƒ  )	r°  r³  r¥  r1   rl   r>  Úhermes_cli.configr´  rµ  )r‡   r³  Úokr´  rµ  Úraw_synchronouss   &     r   Úapply_durability_barriersr½  t  sg   € õ ;Ü	% dÓ	+€BÜ	×	Ò	œY×	'Õ	'ßCÙ&Ñ';Ó'=¸zÈ=ÐbfÔgÐgˆOÒtÙ% dÐFXÕY÷ 
(ð €I÷	 
(Ö	'ð €Iús   ´(A&Á&A7	c               ó    € V ^8„  d   QhRRRR/# r†   r   )r   s   "r   r   r   �  s   € ÷ ñ Ð,ð °ñ r   c                óÄ   € \         P                  ! \        4      ;_uu_ 4        V P                  R4       RRR4       V P	                  4        R#   + '       g   i     L"; i)zJLeave EXCLUSIVE locking mode (so the file is never left pinned) and close.zPRAGMA locking_mode=NORMALN)r1   rl   r>  rŠ   r~   ©r‡   s   &r   Ú_close_unpinnedrÁ  �  s7   € ä	×	Ò	œY×	'Õ	'Ø�‰Ð1Ô2÷ 
(à‡J�J†L÷ 
(×	'ús   £AÁA	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Úbeginr*   r+   rˆ   r   )r   s   "r   r   r   ˆ  s"   € ÷ 
ñ 
˜Tð 
¨#ð 
Ð2Dñ 
r   c                ó’   € \        V RR7      p RVR3 F  pVP                  V4       K  	  V#   \         d    \        T4       h i ; i)z—Zero-timeout connection holding ``locking_mode=EXCLUSIVE`` after a rolled-back
*begin*; closed (unpinned) and re-raised when exclusion cannot be taken.g        r©  zPRAGMA locking_mode=EXCLUSIVEÚROLLBACK)r¦  rŠ   rÒ   rÁ  )r   rÃ  r‡   Ú	statements   &&  r   Ú_open_exclusiverÇ  ˆ  sV   € ô # 7°CÔ8€DðØ9¸5À*ÓMˆIØ�L‰L˜Ö#ñ Nð
 €Køô ô Ü˜ÔØðús	   �. ®Ac               ó   € V ^8„  d   QhRR/# r   r   )r   s   "r   r   r   –  s   € ÷ ñ ¨ñ r   c              #  óÊ   "  €  \        V R4      p TR3x € \	        T4       R#   \        P                  \        3 d   pRT3x €  Rp?R# Rp?ii ; i  \	        T4       i ; i5i)uï  Yield ``(conn, None)`` â€” one live connection that excludes writers for repair surgery â€” or ``(None,
exc)`` when exclusion could not be taken.

``locking_mode=EXCLUSIVE`` retains file-level exclusion after the short ``BEGIN EXCLUSIVE`` is rolled
back; the rollback is essential because ``Connection.backup`` uses this connection as *source* and later
as the promotion *destination*, both transaction-free. It stays open across the snapshot -> strategies ->
promotion window so no writer can commit a change promotion would overwrite. Existing readers make
acquisition fail rather than being disturbed (fail closed). Timeout 0: the cross-process lock already
serializes repairers, and a partial repair is less safe than "stop the gateway and retry".zBEGIN EXCLUSIVEN)rÇ  r�   ÚErrorr9   rÁ  )r   ÚguardrO   s   &  r   Ú_exclusive_repair_db_guardrÌ  •  sa   é € ðÜ Ð):Ó;ˆðØ�TˆkÒô 	˜Öøô �M‰Mœ7Ð#ô Ø�CˆiŠÝûðûô 	˜Õüs;   ‚A#„$ ‘A —A#¤A¿AÁA#ÁAÁA#ÁA Á A#Úsource_connectionÚdestination_connectionc          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   rÉ   r   Údestination_pathrÍ  zOptional[sqlite3.Connection]rÎ  r+   rS   r   )r   s   "r   r   r   ­  s9   € ÷ iñ i¨ð iÀð iØ/Kðià4Pðià\`ñir   c          	     óú  aa	€ \        V 4      o	\        P                  ! 4       S	,           oR VV	3R llp\        P                  ! 4       ;_uu_ 4       pT;'       g    VP                  \        V 4      4      pVe)   VP                  '       d   \        P                  ! R4      hT;'       g    VP                  \        V4      4      pVP                  VRV\        R7       RRR4       R#   + '       g   i     R# ; i)a&  Copy one complete SQLite snapshot without replacing either file inode: the online backup API folds
committed WAL frames into the source snapshot and writes the destination in one transaction (rolled
back if interrupted), so ``state.db`` is never swapped out from under handles that refer to it.c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Ú_statusrŒ   Ú
_remainingÚ_totalr+   rS   r   )r   s   "r   r   Ú-_copy_database_snapshot.<locals>.__annotate__·  s.   € ÷ jñ j ð j°#ð j¸sð jÀtñ jr   c                ó\   <€ \         P                  ! 4       S8¼  d   \        R SR R24      hR# )z/timed out copying SQLite repair snapshot after z.0fÚsN)rs   rt   ÚTimeoutError)rÓ  rÔ  rÕ  rx   Údeadline_secondss   &&&€€r   Ú_check_deadlineÚ0_copy_database_snapshot.<locals>._check_deadline·  s2   ø€ Ü�>Š>Ó˜xÔ'ÜÐ!PÐQaÐbeÐPfÐfgÐhÓiÐiñ (r   Nz:SQLite repair backup destination has an active transactioné   )ÚpagesÚprogressrv   )rÏ   rs   rt   r1   Ú	ExitStackÚenter_contextrª  Úin_transactionr�   ÚProgrammingErrorÚbackuprw   )
rÉ   rÐ  rÍ  rÎ  rÛ  ÚownedÚsourceÚdestinationrx   rÚ  s
   &&$$    @@r   Ú_copy_database_snapshotrè  ­  sÄ   ù€ ô 8¸ÓDÐÜ�~Š~ÓÐ"2Õ2€H÷jñ jô 
×	Ò	×	Ô	 5Ø"×TÐT e×&9Ñ&9¼,À{Ó:SÓ&TˆØ!Ò-Ð2H×2W×2WÐ2Wä×*Ò*Ð+gÓhÐhØ,×cÐc°×0CÑ0CÄLÐQaÓDbÓ0cˆØ�‰�k¨°ÔNgˆÔh÷ 
 ×	×	Ò	ús   Á:C)ÂC)Â+4C)Ã)C:	c               ó    € V ^8„  d   QhRRRR/# rÑ   r   )r   s   "r   r   r   Ä  s   € ÷ Sñ S˜=ð S¨Tñ Sr   c                óx   a € \         ;QJ d    V 3R lR 4       F  '       g   K   R# 	  R# ! V 3R lR 4       4      # )zW``no such table/column``: FTS5 / core tables not created yet (brand new file mid-init).c              3  óZ   <"  € T F   q\        S4      P                  4       9   x € K"  	  R # 5ir   rÖ   rØ   s   & €r   r#   Ú$_schema_not_built.<locals>.<genexpr>Æ  s!   øé € ÐRÑ.Q¨”C˜“H—N‘NÓ$Ö$Ó.QùrÛ   TF)zno such tablezno such column)rß   ©rO   s   fr   Ú_schema_not_builtrî  Ä  s.   ø€ ç‹3ÔRÑ.QÓR�3Œ3ÐRŠ3ÐRˆ3ÔRÑ.QÓRÓRÐRr   zUmessages_fts(_trigram|_cjk)?(_data|_idx|_content|_docsize|_config|_segdir|_segments)?z\bTree (\d+)\bzmissing from index (\S+)c               ó   € V ^8„  d   QhRR/# ©r   r+   r>   r   )r   s   "r   r   r   Ò  s   € ÷ ñ ÀDñ r   c                ó8  € V UUUu/ uF  w  r#qB'       g   K  \        V4      VbK  	  ppppV  Fá  p\        V4      pVP                  R4      '       d    R# \        P	                  V4      pV'       dQ   VP                  \        VP                  ^4      4      R4      pV'       d   \        P                  V4      '       g    R# \        P	                  V4      p	V	'       g   K´  \        P                  V	P                  ^4      4      '       d   Kà   R# 	  R# u upppi )a×  True when any damaged object named by ``PRAGMA integrity_check`` output lies outside
the FTS shadow set: a ``Tree N`` id mapped through ``sqlite_master.rootpage``, an index in
``row N missing from index X``, or the file's own freelist. Unparseable lines are not
counted (the FTS wording stays, which is incomplete rather than wrong). #88587: an FTS
rebuild cannot repair a canonical b-tree, and the ``.malformed-backup`` it leaves behind
is a snapshot of the same damage.ÚFreelistTr�  F)
rŒ   r*   r#  Ú_INTEGRITY_TREE_REÚsearchr"  ÚgroupÚ_FTS_OBJECT_REÚ	fullmatchÚ_INTEGRITY_MISSING_INDEX_RE)
Úintegrity_linesÚmaster_rowsÚrpÚ_typer    Úname_by_rootpageÚlineÚtextÚtreeÚmissings
   &&        r   Úintegrity_damage_is_structuralr  Ò  sÓ   € ñ >IÕO¹[©/¨"°TËBœœ˜B› š¹[ÐÒOÛˆÜ�4‹yˆØ�?‰?˜:×&Ò&ÚÜ!×(Ñ(¨Ó.ˆßØ#×'Ñ'¬¨D¯J©J°q«MÓ(:¸BÓ?ˆDßœN×4Ñ4°T×:Ò:ÚÜ-×4Ñ4°TÓ:ˆß‰7œ>×3Ñ3°G·M±MÀ!Ó4D×EÔEÚñ  ñ ùô Ps
   ‡D˜Dc               ó    € V ^8„  d   QhRRRR/# r=   r   )r   s   "r   r   r   é  s   € ÷ Yñ Y¨Dð Y°Tñ Yr   c                óÒ  €  \         P                  ! \        V 4      RRR7      p TP	                  R4      P                  4        Uu. uF  p\        T4      NK  	  ppTP	                  R4      P                  4        Uu. uF  p\        T^ ,          4      NK  	  pp TP                  4        \        \        P                  P                  R T 4       4      T4      #   \         P                   d     R# i ; iu upi u upi   \         P                   d     TP                  4        R# \         P                   d     TP                  4        R# i ; i  TP                  4        i ; i)a™  Read-only ``integrity_check`` + ``sqlite_master`` rootpage map on a fresh connection;
``integrity_damage_is_structural`` over the result. A check that RAISES instead of
reporting (a torn page under the walk) is structural too: no FTS-only fixture does that
while ``messages``/``sessions`` read cleanly, and the FTS rebuild ladder cannot help.
Cannot-open / locked stays False so the caller keeps the FTS path.Tg      ð?)Úurirp   FzASELECT rootpage, type, name FROM sqlite_master WHERE rootpage > 0úPRAGMA integrity_checkc              3  ó@   "  € T F  qP                  4       x € K  	  R # 5ir   )Ú
splitlines)r!   rþ  s   & r   r#   Ú1state_db_has_structural_damage.<locals>.<genexpr>þ  s   é € Ð%JÁE¸D§o¡o×&7Ð&7ÃEùs   ‚)r�   Úconnectr   rÊ  rŠ   Úfetchallr’  r*   rš  r~   rŽ   r  rq  ÚchainÚfrom_iterable)r   r‡   Úrrú  Úliness   &    r   Ústate_db_has_structural_damager  é  s8  € ðÜ�ŠÔ/°Ó8¸dÈCÔPˆð	Ø)-¯©ØOó*QßQYÑQYÓQ[ð*\ó ]ñ *\ A”u˜Q–xñ *\ˆð ]à$(§L¡LÐ1IÓ$J×$SÑ$SÔ$UÓVÑ$U˜q”�Q�q•T–Ñ$UˆÐVˆð 	�
‰
ŒÜ)Ü�‰×%Ñ%Ñ%JÁEÓ%JÓJÈKóYð Yøô �=‰=ô Úðüò]ùâVøÜ×#Ñ#ô Øð 	�
‰
Žô × Ñ ô Øà�
‰
Žðûð 	�
‰
�úsd   ‚"C ¥!D ÁC7Á#D Á=C<ÂD ÃC4Ã3C4Ã7
D ÄEÄE Ä)EÄ<EÄ=E ÅEÅE ÅE&c               ó    € V ^8„  d   QhRRRR/# r¹   r   )r   s   "r   r   r     s   € ÷ Lñ L˜tð L¨ñ Lr   c                óæ	  € ^ RI HpHp \        V 4      p \        P
                  ! V4      ;_uu_ 4        V! V4       VP                  R4      P                  4        VP                  R4      P                  4       pV Uu. uFE  qU'       g   K  \        V^ ,          4      P                  4       R8w  g   K3  \        V^ ,          4      NKG  	  ppV'       d#   RP                  VR,          4      uuRRR4       # VP                  R4      P                  4        \         F*  p VP                  R	V R
V R24      P                  4        K,  	  R\&        P(                  ! 4        2p
 VP                  R4       VP                  RV
R\&        P&                  ! 4       34       VP                  RV
RR\&        P&                  ! 4       34       \         F  p VP                  RV RV R24       K  	   \        P*                  ! \        P,                  4      ;_uu_ 4        TP                  R4       RRR4        RRR4       R# u upi   \        P                   dr   pTP                  T4      ;'       g    \!        T4      p	\#        T\        P$                  4      '       d	   T	'       g   RT RT 2u Rp?u uuRRR4       #  Rp?EK§  Rp?ii ; i  \        P$                   d=   pTP                  T4      '       g   \!        T4      '       g   h  Rp?EKE   Rp?EKL  Rp?ii ; i  \        P                   Ed   p\!        T4      '       g   R\        T4      P                  4       9   di    Rp?\        P*                  ! \        P,                  4      ;_uu_ 4        TP                  R4       RRR4       M  + '       g   i     M; iRRR4       R# RT 2u Rp?\        P*                  ! \        P,                  4      ;_uu_ 4        TP                  R4       RRR4       M  + '       g   i     M; iuuRRR4       # Rp?ii ; i  + '       g   i     EL!; i  \        P*                  ! \        P,                  4      ;_uu_ 4        TP                  R4       RRR4       i   + '       g   i     i ; i; i  + '       g   i     R# ; i  \        P                   d   p\        T4      u Rp?# Rp?ii ; i)u®  Probe a DB on a fresh connection. Returns None if healthy, else a reason.

Runs the first statement that trips the malformed-schema parse (``PRAGMA journal_mode``),
``integrity_check``, a ``sessions`` read, FTS5 MATCH probes and a rolled-back ``messages`` write â€” so FTS5
index corruption (reads and ``integrity_check`` pass, every ``INSERT INTO messages`` fails through the FTS
triggers) is reported as unhealthy.

See #50502.
)Ú	SessionDBÚload_fts5_cjk_extensionzPRAGMA journal_moder  r»  ú; :Né   NNzSELECT COUNT(*) FROM sessionszSELECT 1 FROM z WHERE z MATCH '""' LIMIT 1zfts5 read probe failed on ú: Ú_hermes_fts_health_probe_zBEGIN IMMEDIATEz>INSERT INTO sessions (id, source, started_at) VALUES (?, ?, ?)Ú_health_probezOINSERT INTO messages (session_id, role, content, timestamp) VALUES (?, ?, ?, ?)ÚuserÚ_fts_health_probeúINSERT INTO Ú(z) VALUES('flush')z no such tokenizer: cjk_unicode61rÅ  zfts5 write probe failed: )r   r  r  r¦  r1   rk   rŠ   r‹   r  r*   r×   ÚjoinÚ_FTS_TABLESr�   rŽ   Ú_is_fts5_unavailable_errorrî  rÜ   rš  rs   Útime_nsrl   rÊ  )r   r  r  r‡   Úrowsr  ÚproblemsÚ	fts_tablerO   ÚbenignÚprobe_session_ids   &          r   Ú_db_opens_cleanlyr'    s¶  € ÷ @ô
 # 7Ó+€Dð<Ü×Ò ×%Õ%ñ $ DÔ)Ø�L‰LÐ.Ó/×8Ñ8Ô:Ø—<‘<Ð 8Ó9×BÑBÓDˆDÙ+/ÓS©4 a³1œ	¼¸Q¸q½T»¿¹Ó9JÈdÑ9Rœ	œ˜A˜a�Dž	©4ˆHÐSßØ—y‘y ¨"¥Ó.÷ &Ò%ð �L‰LÐ8Ó9×BÑBÔD÷ )�	ðOØ—L‘L >°)°¸GÀIÀ;ÐNcÐ!dÓe×nÑnÖpñ )ð& ";¼4¿<º<»>Ð:JÐKÐð-Ø—‘Ð.Ô/Ø—‘Ð]Ø.°ÄÇÂÃÐMôOà—‘ÐnØ.°Ð8KÌTÏYÊYË[ÐYô[ç!,�Ið"ØŸ™ |°I°;¸aÀ	¸{ÐJ[Ð%\Ö]ò "-ô   ×(Ò(¬¯©×7Õ7Ø—L‘L Ô,÷ 8à÷s &Ñ%ùò Tøô ×,Ñ,ô 	Oð '×AÑAÀ#ÓF×`Ð`ÔJ[Ð\_ÓJ`�FÜ& s¬G×,DÑ,D×EÒEÏ&ð "<¸I¸;ÀbÈÈÐNÖN÷3 &Ò%ö* KQûð	Oûô4 #×3Ñ3ô "Ø )× DÑ DÀS× IÒ IÔM^Ð_b×McÒMcØ!ö NdÖ Iûð"ûô ×(Ñ(õ 9ô % S×)Ò)Ð-OÔSVÐWZÓS[×SaÑSaÓScÔ-cÛô  ×(Ò(¬¯©×7Õ7Ø—L‘L Ô,÷ 8×7×7Ð7ú÷o &Ñ%ðj 3°3°%Ð8Ô8ä×(Ò(¬¯©×7Õ7Ø—L‘L Ô,÷ 8×7×7Ð7ú÷o &Ò%ûðZ9ú÷ 8×7Ð7û”Z×(Ò(¬¯©×7Õ7Ø—L‘L Ô,÷ 8×7×7Ð7ý÷o &×%Ð%ûôt × Ñ ô Ü�3‹x�ûðús“  •S ³AR2Á>	H;Â"H;Â3H;Ã	!R2Ã*
S Ã5(R2Ä&I ÅR2Å!A+LÇK	Ç%LÇ*,R2ÈQ 	È(	R2È1S È;R2É K	ÉAK	Ê!K	Ê(K	Ê)R2Ê/
S Ê:R2ËK	ËR2Ë	L	Ë)L	ÌLÌL	ÌLÌP=Ì3/P8Í"QÍ&,R2ÎN-	Î$	R2Î-N=Î8R2Ï S Ï
P8ÏP=ÏQÏ,R2Ï?PÐ	R2ÐP*Ð%R2Ð-
S Ð8P=Ð=QÑ QÑ	R2Ñ-R/ÒRÒ	R/ÒR,Ò'R/Ò/R2Ò2S	Ò=S ÓS ÓS0Ó
S+Ó%S0Ó+S0c               ó    € V ^8„  d   QhRRRR/# r=   r   )r   s   "r   r   r   P  s   € ÷ hñ h 4ð h¨Dñ hr   c                ó8   € ^ RI pVP                  V \        R7      # )u   True when another process (or a connection outside this call) still holds ``db_path``.

The foreign-holder scan (``hermes_state_holders``) is the authority: any other process with the DB or a
WAL sidecar open, a deleted WAL generation, or an unknown/uninspectable holder fails CLOSED. The SQLite
probe (``locking_mode=EXCLUSIVE`` + ``BEGIN IMMEDIATE``) is only an additional positive signal â€” it cannot
see a ``journal_mode=DELETE`` reader and cannot run on a malformed file, which is why the scan comes first.N)Úconnect_repair_durable)Úhermes_state_holdersÚlive_writer_holds_dbr¦  )r   Ú_state_holderss   & r   Ú_live_writer_holds_dbr.  P  s   € ó 2Ø×.Ñ.¨wÔOfÐ.ÓgÐgr   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   Úreportr  Úverbr*   r¿   rO   zOptional[BaseException]r+   r   )r   s   "r   r   r   [  s1   € ÷ ñ ˜ð ¨sð ¸3ð ÐE\ð Ðhvñ r   c                óv   € Ve   \        V4      '       d   RV R&   W R&   \        P                  RV R2V4       V # )zÒRecord *error* on *report* and log it as ``state.db repair <verb>``. An
*exc* proving deterministic corruption consumes the persistent repair budget
(private ``_repair_attempted`` marker, popped by the caller).TÚ_repair_attemptedr¿   zstate.db repair z: %s)rá   rL   r¿   )r0  r1  r¿   rO   s   &&&&r   Ú_repair_skipr4  [  sC   € ð ‚Ô;¸C×@Ò@Ø&*ˆÐ"Ñ#Øˆ7�OÜ
‡L�LÐ# D 6¨Ð.°Ô6Ø€Mr   rä  Tc               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   rä  r>   r+   r  r   )r   s   "r   r   r   f  s&   € ÷ Cñ C Dð C°Tð CÀ^ñ Cr   c          
     ó>  € RRRRRRRR/p\        RRR	7       \        V 4      p V P                  4       '       g   V  R
2VR&   V# \        V 4      '       d   \	        VR\        V 4      4      # \        V 4      ;_uu_ 4       pV'       g+   \        V 4      f   RRuVR&   VR&   MRVR&   VuuRRR4       # Tp\        V 4      '       d   \	        VR\        V 4      4       MS\        V 4      '       d   \	        VRR4       M4\        V 4      p\        WVVR7      pVP                  R4      '       d   WTR&   VP                  RR4      '       g   VP                  R4      '       d&   \        V \        VP                  R4      4      R7       RRR4       V#   + '       g   i     X# ; i)aí  Repair a state.db whose ``sqlite_master`` is malformed or whose FTS indexes reject writes.

Two corruption classes: malformed schema / "duplicate object definition" (even ``PRAGMA`` fails), and FTS
write-corruption (reads and ``integrity_check`` pass, writes fail through ``messages_fts*`` triggers).
``_REPAIR_STRATEGIES`` run least-destructive first on a complete snapshot; a success is copied back
transactionally, so canonical rows are never modified by a failed attempt. A raw backup is taken first
unless ``backup=False``. Serialised across processes (gateway, Desktop backend and CLI open the same file;
concurrent ``writable_schema`` surgery is itself a corruption source). Returns ``{repaired, strategy,
backup_path, error}``.

See #50502.
r1  FÚstrategyNrX  r¿   g      Œ@Ústate_db_repair)Úphasez does not existÚskippedTÚrepaired_by_other_processz¢could not obtain the state.db repair lock (held by another process, or the lock file was unopenable); skipped schema surgery to avoid racing a concurrent repairerz¥a live writer still holds state.db; skipped schema surgery to avoid tearing b-tree pages under a concurrent writer. Stop the gateway (hermes gateway stop) and retry.)rä  r0  Újournal_mode_beforer<  r3  )r1  )r
   r   rª   r)  r4  r/  r€   r'  r.  Ú_probe_journal_mode_for_repairÚ_repair_state_db_schema_lockedr"  ÚpoprB  r>   )r   rä  r0  Úholding_lockÚresultÚbefore_modes   &$    r   Úrepair_state_db_schemarC  f  sš  € ð )¨%°¸TÀ=ÐRVÐX_ÐaeÐf€Fô ˜EÐ):Õ;Ü�7‹m€GØ�>‰>×ÒØ$˜I _Ð5ˆˆw‰Øˆô -¨W×5Ò5Ü˜F IÔ/QÐRYÓ/ZÓ[Ð[ä	# G×	,Ô	,°ßô ! Ó)Ò1Ø9=Ð?ZÐ6��zÑ" F¨:Ò$6ð$x��w‘à÷ 
-Ò	,ð ˆô 1°×9Ò9Ü˜ Ô,NÈwÓ,WÕXô # 7×+Ò+Ü˜ ð -uõ vô 9¸ÓAˆKÜ3°GÐSYØHSôUˆFà�z‰z˜*×%Ò%Ø0;Ð,Ñ-ð �:‰:Ð)¨5×1Ò1°V·Z±ZÀ
×5KÒ5KÜ" 7´T¸&¿*¹*ÀZÓ:PÓ5QÕR÷G 
-ðH €M÷I 
-Ö	,ðH €Mús   Á=(FÂ0BFÅFÅ%FÆF	c               ó    € V ^8„  d   QhRRRR/# r¹   r   )r   s   "r   r   r   ¬  s   € ÷ 	ñ 	¨Dð 	°]ñ 	r   c                óÈ   € ^ RI Hp  \        V 4      ;_uu_ 4       pV! V4      uuRRR4       #   + '       g   i     R# ; i  \        P                  \
        3 d     R# i ; i)uñ   Best-effort journal-mode probe: ``wal``/``delete``, or ``None`` when the file cannot be opened or
probed (malformed header, concurrent opener's locks â€” both expected on the repair path); callers then
fall back to ``database.journal_mode``.)Ú_on_disk_journal_modeN)r°  rF  rª  r�   rÊ  r9   )r   rF  r‡   s   &  r   r=  r=  ¬  sJ   € õ 7ðÜ˜'×"Ô" dÙ(¨Ó.÷ #×"×"Ó"ûä�M‰Mœ7Ð#ô Úðús(   ˆA ›.£
A ®?	¹A ¿A ÁA!Á A!r‡   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   rB  r,   r+   rS   r   )r   s   "r   r   r   ¸  s'   € ÷  Fñ  F°ð  FÀ=ð  FÐcgñ  Fr   c               óš  € ^ RI Hp  Vf1   \        V 4      ;_uu_ 4       pV! W@P                  R7      pRRR4       MV! W P                  R7      pV'       d#   XV8w  d   \        P                  RWV4       R# R# R#   + '       g   i     L<; i  \        P                  \        3 d"   p\        P                  RY4        Rp?R# Rp?ii ; i)u¼  Re-apply the journal mode after schema surgery.

``conn`` must be the exclusive repair guard connection when called from the repair path: opening a fresh
connection AFTER the guard released let a writer still holding the unlinked old ``-wal`` inode coexist with
a brand-new ``state.db-wal`` â€” two generations of one store. The reopen is the hazard, not the mode.

A rebuilt file comes back in the default (delete) mode; without this a corruption event silently moves a
WAL store out of WAL (the open-time WAL-reset gate never sees a flip made inside repair). Routed through
:func:`apply_wal_with_fallback`, not a direct pragma, so it inherits the WAL-reset gate (a vulnerable
runtime deliberately keeps DELETE; the journal_mode-changed WARNING is expected there), the macOS-NFS
silent-refusal handling and the WAL companions. ``before_mode`` is only for the log comparison; the target
is ``database.journal_mode``. Best-effort: the repair already succeeded, so failures log at WARNING.

See #89674.
See #89393.
The transactional promotion already leaves the destination in its pre-repair mode, so on that path this
is mostly the WAL-companion re-assertion; the reopen is the hazard, not the mode. See #101064.
)Úapply_wal_with_fallbackNr¹  z§state.db repair changed journal_mode %r -> %r (pre-surgery probe %r; restore resolved through apply_wal_with_fallback per database.journal_mode and the WAL-reset gate)zvstate.db repair at %s: post-surgery journal-mode restore failed (%s); verify with PRAGMA journal_mode on the next open)	r°  rI  rª  r    rL   rM   r�   rÊ  r9   )r   rB  r‡   rI  rå  ÚafterrO   s   &&$    r   Ú"_restore_journal_mode_after_repairrK  ¸  s­   € õ& 9ðFØŠ<Ü˜g×&Ô&¨%Ù/°ÇÁÔM�÷ 'Ð&ñ ,¨D¿<¹<ÔHˆEß˜5 KÔ/Ü�N‰Nð oà&¨{ö<ñ 0‰;÷	 '×&ûô �M‰Mœ7Ð#ô FÜ�‰ð 7Ø8?÷	Fò 	FûðFús3   ˆB ŸA;³#B ÁB Á;B	ÂB ÂC
Â)CÃC
r<  c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# )
r   r   r   rä  r>   r0  r  r<  r,   r+   r   )r   s   "r   r   r   Û  sB   € ÷ Klñ KlØðKlØ"ðKlØ,:ðKlØQ^ðKlàñKlr   c               ó   € V P                  V P                   R24      p\        V4      ;pe   \        VRRV 24      # \	        V 4      f   RRuVR&   VR&   V# V'       d:   \        V 4      w  rgV'       d   \        V4      MRVR	&   Vf   \        VRR
V 24      # \        V 4      ;_uu_ 4       w  r‰Vf   \        VRRV	 2V	R7      uuRRR4       # \        V 4      ;p
e   \        VRV
4      uuRRR4       #  \        WVR7        RTR&   \        YB4       TP                  R4      '       dB    \        Y@TR7       \         P#                  RTP                  R4      T 4       \%        YTR7       TP                  R4      '       g   \         P+                  RYR	,          4       T\        T4      ;pe   \         P#                  RT4       uuRRR4       #   \        \        P                  \        3 d5   p\        T4       \        TRRT  RT 2TR7      u Rp?uuRRR4       # Rp?ii ; i  \        \        P                  \        3 dG   pTP'                  RR\)        T4      R7       RT 2TR&   \         P+                  RT4        Rp?ELRp?ii ; i  \        T4      ;pe   \         P#                  RT4       i i ; i  + '       g   i     R# ; i)u)  Repair strategies for :func:`repair_state_db_schema`; caller holds the cross-process repair lock.

Strategies run on a SCRATCH COPY, copied back through SQLite's transactional backup API only once proven to open
cleanly, so a failed repair cannot modify or lose committed data (a WAL checkpoint of committed frames on guard
release is not a repair mutation). WHY not in place: the final strategy ends in ``VACUUM``, which rebuilds the
file from the schema SQLite can still parse â€” when the damage IS in the schema b-tree (the ``malformed database
schema ()`` class) every table hanging off the unreadable part is silently dropped, the probe still reports
malformed, and repair returned ``repaired=False`` having destroyed what it was asked to save.

The pre-repair backup (#69603) does not close this: it is a forensic artefact that nothing reads back,
so recovery still depends on a human noticing a ``.malformed-backup-*`` file and knowing what to do with
it. Not mutating the original in the first place is the property that holds without a human in the loop.
z.repair-scratchNÚabortedzBcould not remove a stale repair snapshot before probing state.db: TÚalready_healthyr1  r7  rX  zepre-repair backup refused; aborting schema repair to avoid mutating the only copy of the damaged DB: r:  z”could not acquire exclusive state.db repair ownership; skipped schema surgery to avoid overwriting a concurrent writer. Stop the gateway and retry: rí  )rÍ  z5could not stage a complete SQLite repair snapshot of r  r3  )rÎ  z;state.db repaired via '%s' and promoted transactionally: %srÀ  F)r1  r7  r3  z9repaired snapshot could not be promoted transactionally: r¿   z$state.db repair promotion failed: %sz¥state.db schema repair could not recover %s automatically (no committed canonical data was modified or lost; backup: %s); manual restore from backup may be required.z:Could not remove state.db repair snapshot after repair: %s)r   r    Ú_unlink_db_tripler4  r'  r{  r*   rÌ  rÂ   rè  r9   r�   rÊ  rÙ  Ú_run_repair_strategiesr"  rL   rM   rK  r  rá   r¿   )r   rä  r0  r<  ÚscratchÚcleanup_errorÚbpathÚbackup_errorÚ
live_guardÚguard_errorÚspace_errorrO   s   &$$$        r   r>  r>  Û  sû  € ð  ×Ñ 7§<¡< .°Ð @ÓA€GÜ*¨7Ó3Ð3ˆÒ@Ü˜F IÐ1sð  uBð  tCð  0Dó  Eð  	Eô ˜Ó!Ò)Ø15Ð7HÐ.ˆˆzÑ˜F :Ñ.ØˆßÜ-¨gÓ6Ñˆß.3¤ E¤
¸ˆˆ}ÑØŠ=Ü ¨	ð 4MØMYÈNð4\ó ]ð ]ô 
$ G×	,Ô	,Ñ0I°ØÒÜ ¨	ð 4xà#. -ð41à6AôC÷ 
-Ò	,ô
 7°wÓ?Ð?ˆKÒLÜ ¨	°;Ó?÷ 
-Ò	,ð	Fô $ GÈ
ÕSð	lð +/ˆFÐ&Ñ'Ü" 7Ô3Ø�z‰z˜*×%Ò%ð
fÜ+¨GÐU_Õ`ô —N‘NÐ#`Ø#)§:¡:¨jÓ#9¸7ôDä6°wÐZdÕeØ—:‘:˜j×)Ò)ô —‘ð nà$¨]Õ&;ô=ð ô "3°7Ó!;Ð;�ÒHÜ—‘Ð[Ð]jÔk÷W 
-Ò	,øô œŸ™¬Ð5ô 	FÜ˜gÔ&Ü ¨	Ð5jÐkrÐjsÐsuÐvyÐuzÐ3{ð  BEô  Fô  F÷ 
-Ò	,ûð	Fûô  ¤§¡´Ð=ô NØ—M‘M¨5¸4Ü4TÐUXÓ4Yð "ô [à(aÐbeÐafÐ&g�F˜7‘OÜ—L‘LÐ!GÈ×MÒMûð	Nûô$ "3°7Ó!;Ð;�ÒHÜ—‘Ð[Ð]jÕkð Iú÷U 
-×	,Ð	,ús…   Â,J<ÃJ<Ã6GÄ'JÄ,H(Ä9A	JÆJÆ!%J<Ç H%Ç1H ÈH%ÈJ<È H%È%J<È( JÉ;J	ÊJÊ	JÊJÊ(J9Ê9J<Ê<K	c               ó    € V ^8„  d   QhRRRR/# )r   r  r   r+   r,   r   )r   s   "r   r   r   )  s   € ÷ 'ñ '˜Dð ' ]ñ 'r   c                óœ  € ^ RI Hp . pV .\        V 4      O F)  p\        ^
4       F  p VP	                  RR7        K'  	  K+  	  RP                  V4      ;'       g    R#   \
         db   p\        T\        4      '       d,   T'       d$   T^	8  d   \        P                  ! R4        Rp?K†  TP                  T RT 24        Rp?L‹Rp?ii ; i)zCRemove *path* and every SQLite sidecar; return any cleanup failure.r_   Tr3  gš™™™™™©?Nr  r  )r   r`   r'   Úranger8  r9   rÜ   ÚPermissionErrorrs   rv   rb  r  )r  r`   ÚfailuresrT  ÚattemptrO   s   &     r   rP  rP  )  s°   € å(Ø€HØÐ*œ) D›/Ó*ˆÜ˜R–yˆGð4Ø—‘¨�Ô.ò ó !ñ +ð �9‰9�XÓ×&Ð& $Ð&øô ô 4ä˜c¤?×3Ò3¿ÈÐRSÌÜ—J’J˜tÔ$ÝØ—‘ 6 (¨"¨S¨EÐ 2×3Ñ3ûð4ús#   ©AÁCÁ*CÂCÂ+CÃCc               ó    € V ^8„  d   QhRRRR/# r†   r   )r   s   "r   r   r   =  s   € ÷ ñ Ð0ð ¸4ñ r   c                óš   € V P                  R4       V! 4       '       d   \        V 4       V P                  R4       V P                  4        R# )zƒRun *edit* under ``writable_schema=ON``; bump the schema cookie when it
reports a change so live peers discard their cached schema.zPRAGMA writable_schema=ONzPRAGMA writable_schema=OFFN)rŠ   r’   Úcommit)r‡   Úedits   &&r   Ú_edit_sqlite_masterrc  =  s6   € ð 	‡L�LÐ,Ô-Ù‡v‚vÜ˜DÔ!Ø‡L�LÐ-Ô.Ø‡K�K†Mr   c               ó    € V ^8„  d   QhRRRR/# r†   r   )r   s   "r   r   r   G  s   € ÷ Vñ VÐ 2ð V°tñ Vr   c           
     óþ   € ^ RI Hp V! V 4       \         FP  p\        P                  ! \
        P                  4      ;_uu_ 4        V P                  RV RV R24       RRR4       KR  	  R#   + '       g   i     Kg  ; i)zˆFTS5 'rebuild' rewrites each index from the content table: the least-
destructive fix for an index that rejects writes while reads work.)r  r  r  z) VALUES('rebuild')N)r   r  r  r1   rl   r�   rš  rŠ   )r‡   r  Ú
table_names   &  r   Ú_strategy_rebuild_ftsrg  G  s^   € õ 5á˜DÔ!ß!ˆ
Ü× Ò ¤×!9Ñ!9×:Õ:Ø�L‰L˜<¨
 |°1°Z°LÐ@SÐTÔU÷ ;Ñ:ó "ß:×:Ð:ús   ÁA+Á+A<c               ó    € V ^8„  d   QhRRRR/# r†   r   )r   s   "r   r   r   R  s   € ÷ ñ Ð.ð °4ñ r   c                ó^   € \        V 4       V P                  R4       V P                  4        R# )zŽintegrity_check reports "wrong # of entries in index" when a B-tree
index drifts from its base table; REINDEX rewrites it from canonical rows.ÚREINDEXN)r¥  rŠ   ra  rÀ  s   &r   Ú_strategy_reindexrk  R  s!   € ô ! Ô&Ø‡L�L�ÔØ‡K�K†Mr   c               ó    € V ^8„  d   QhRRRR/# r†   r   )r   s   "r   r   r   [  s   € ÷ &ñ &Ð!3ð &¸ñ &r   c                ó2   a € R V 3R llp\        S V4       R# )zJDe-duplicate sqlite_master (lowest rowid per type/name wins), keeping FTS.c               ó   € V ^8„  d   QhRR/# rð  r   )r   s   "r   r   Ú,_strategy_dedup_schema.<locals>.__annotate__]  s   € ÷ ñ �Dñ r   c                 ó˜   <€ SP                  R 4      P                  4       p V  F  w  rr4SP                  RWV34       K  	  \        V 4      # )zhSELECT type, name, COUNT(*) AS c, MIN(rowid) AS keep FROM sqlite_master GROUP BY type, name HAVING c > 1zFDELETE FROM sqlite_master WHERE type IS ? AND name IS ? AND rowid <> ?)rŠ   r  r>   )ÚdupesÚtype_r    Ú_countrQ  r‡   s        €r   Ú_dedupÚ&_strategy_dedup_schema.<locals>._dedup]  sR   ø€ Ø—‘Øvó
ç
‰(‹*ð 	ó */Ñ%ˆE˜Ø�L‰LÐaØ tÐ,ö.ñ */ô �E‹{Ðr   N)rc  )r‡   rt  s   f r   Ú_strategy_dedup_schemarv  [  s   ø€ ÷ð ô ˜˜fÖ%r   c               ó    € V ^8„  d   QhRRRR/# r†   r   )r   s   "r   r   r   i  s   € ÷ ñ Ð$6ð ¸4ñ r   c                ó`   a € \        S V 3R l4       \        S 4       S P                  R4       R# )zÞDrop all FTS schema and VACUUM; indexes rebuild on the next open. The
destructive one, and why strategies run on a scratch copy: on a damaged
schema b-tree VACUUM silently drops every table hanging off the unreadable part.c                 ó:   <€ S P                  R 4      ;'       g    R# )z9DELETE FROM sqlite_master WHERE name LIKE 'messages_fts%'T)rŠ   rÀ  s   €r   r5   Ú+_strategy_drop_fts_vacuum.<locals>.<lambda>m  s   ø€  d§l¡lÐ3nÓ&o×&wÐ&wÐswÐ&wr   ÚVACUUMN)rc  r¥  rŠ   rÀ  s   fr   Ú_strategy_drop_fts_vacuumr|  i  s$   ø€ ô ˜ÔwÔxä  Ô&Ø‡L�L�Ör   Úrebuild_ftsz<state.db FTS indexes rebuilt in place (schema preserved): %sz-state.db FTS in-place rebuild pass failed: %sÚreindex_btreez/state.db B-tree indexes rebuilt via REINDEX: %sz state.db REINDEX pass failed: %sÚdedup_schemazRstate.db schema repaired by de-duplicating sqlite_master (FTS index preserved): %sz%state.db dedup repair pass failed: %sÚdrop_fts_rebuildzdstate.db schema repaired by dropping FTS schema; indexes will rebuild from messages on next open: %sc               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   r0  r  r+   r   )r   s   "r   r   r   ‚  s!   € ÷ ñ  Dð °.ð À^ñ r   c                óœ  € \          Fh  w  r#rE \        V 4      ;_uu_ 4       pV! V4       RRR4       \        V 4      pVf%   RVuVR&   VR&   \        P                  W@4       Vu # Ve   Kd  WqR&   Kj  	  V#   + '       g   i     LS; i  \        P                   d/   p\        T4      pTe   \        P                  YX4        Rp?L‰Rp?ii ; i)uÛ   Escalating repair attempts, applied to *db_path* IN PLACE â€” only ever a scratch copy nothing else holds open,
never the user's database. The "could not recover" log lives in the caller so it names the user's database.NTr1  r7  r¿   )Ú_REPAIR_STRATEGIESrª  r'  r�   rŽ   r*   rL   rM   )	r   r0  r    ÚbodyÚsuccess_msgÚfailure_msgr‡   ru  rO   s	   &&       r   rQ  rQ  ‚  s»   € ÷ 1CÑ,ˆ�Kð	1Ü˜g×&Ô&¨$Ù�T”
÷ 'ä& wÓ/ˆFð
 Š>Ø59¸4Ð2ˆF�:Ñ  zÑ 2Ü�N‰N˜;Ô0ØŠMØÔØ$�7‹Oñ 1Cð €M÷ '×&ûô ×$Ñ$ô 	1Ü˜“XˆFØÒ&Ü—‘˜{Ô0ÿøð	1ús-   ŽB¡	A5ªBÁ5BÂ BÂCÂ$CÃCi    )r‡  rˆ  z-journal))é   é   )é\   é`   i   )Úmessages_ftsÚmessages_fts_trigramÚmessages_fts_cjkr   )oÚ__doc__Ú
__future__r   r1   r9  rð   rq  r  Úloggingr`  Úrer±   r�   r«   rs   Úpathlibr   Útypingr   r   r   r   r   r-  r	   Úhermes_startup_watchdogr
   r+  r   Úhermes_state_commonr   r   r   r   r   Ú	getLoggerrL   rw   rÌ   r$  Ú_MAX_MALFORMED_BACKUPSr%   rï   rš   r£   r¤   r  rÅ   r'   r;   rC   rP   r\   rf   rn   ry   Úcontextmanagerr€   r„   Ú_release_auto_maintenance_lockr’   rž   r¥   r·   rÂ   rÇ   rÏ   rá   rä   rù   r  r  r)  r/  rB  rO  rU  rj  r{  r‚  rŸ  r¦  rª  r¥  r½  rÁ  rÇ  rÌ  rè  rî  Úcompilerö  ró  rø  r  r  r'  r.  r4  rC  r=  rK  r>  rP  rc  rg  rk  rv  r|  rƒ  rQ  r   r   r   Ú<module>r›     sÿ  ðñõ
 #ã Û Û Û Û Û Û 	Û 	Û Û Û Û Ý ß 3Õ 3å ,Ý ;Ý 1÷õ ð 
×	Ò	˜>Ó	*€àÐ à3CÐ 0ð #$Ð ØÐ ð 4Ð à!Ð ð
 ';Ð #ð !2Ð Ø#Ð ØJ€ð^Ð õYõ
õ$õõCõDð
8¸÷ 
8õ2ð" ×Ñô(ó ð(õV
ð "6Ð õIõõ_õ

Nõ]õ
>õnõnõEõ:õ*>õ4õ]õ$_ðKÐZ^÷ Kõ6=ð 9O÷ Võõ.82õv	Fð%5¸zð %5Ðbg÷ %5ðP¸s÷ ð*Q°C÷ Qõ

õ
õõ
ð ×Ñôó ðð.iØNRðiàSW÷iõ.Sð —’Ø\ó€ð —Z’ZÐ 1Ó2Ð Ø ŸjšjÐ)DÓEÐ õõ.Yõ0Lõ^h÷ðC¸D÷ CõL	ð FÐZ^÷  FðFKlØae÷Klõ\'õ(õVõõ&õð Ð)Ð+iØ4ð6àÐ'Ð)ZØ'ð)àÐ+ØYØ,ð.ð Ð2ØkÐmqðsð
Ð ÷r   