+
    jHàj'5  ã                  óò  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RI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 ]P$                  ! ]4      tR R	 ltR
 R ltR R ltR R ltR R ltR R ltR R ltR+R R lltR R ltR]3R]3R]3R]3R]3R]33tR ]R!&   ] ;QJ d    . R" ] 4       F  NK  	  5M! R" ] 4       4      t!R ]R#&   R$]33t"R ]R%&   R& R' lt#R+R( R) llt$]R*8X  d   ]%! ]$! 4       4      hR# ),ah  Home maintenance shared by explicit updates and bounded boot maintenance.

Config migration owns backup/rollback; skills sync owns content merging; the
SQLite guard detects damage without repairing it. Boot bounds these home
steps per revision. The explicit scope CLI also provisions runtimes through
PM. Launcher publication belongs to hermes_cli._launchers.
)ÚannotationsN)ÚdatetimeÚtimezoneÚUTC)ÚPath)ÚIterable)Ú
expose_cli)Úinstall_rootc               ó$   € V ^8„  d   QhRRRRRR/# )é   Úpathr   ÚstampÚstrÚreturn© )Úformats   "Ú;/home/ubuntu/.hermes/hermes-agent/hermes_cli/post_update.pyÚ__annotate__r      s&   € ÷ Eñ E�tð E Cð E¨Dñ Eó    c                ó.  € V P                  V P                   R V 24      pVP                  4       '       g   V# \        ^R4       F@  pV P                  V P                   R V RV 24      pVP                  4       '       d   K>  Vu # 	  \	        RV  24      h)z.bak-iè  Ú.z#could not choose a backup path for )Ú	with_nameÚnameÚexistsÚrangeÚRuntimeError)r   r   ÚbaseÚindexÚ	candidates   &&   r   Ú_backup_pathr      sŒ   € Ø�>‰>˜TŸY™Y˜K u¨U¨GÐ4Ó5€DØ�;‰;�=Š=ØˆÜ�q˜$–ˆØ—N‘N d§i¡i [°°e°W¸A¸e¸WÐ#EÓFˆ	Ø×Ñ×!Ô!ØÒñ  ô Ð<¸T¸FÐCÓ
DÐDr   c               ó    € V ^8„  d   QhRRRR/# )r   ÚpathszIterable[Path]r   Údictr   )r   s   "r   r   r   '   s   € ÷ 	ñ 	˜Nð 	¨tñ 	r   c                óè   € \         P                  ! \        4      P                  R 4      p/ pV  F@  pVP	                  4       '       g   K  \        W14      p\        P                  ! W44       WBV&   KB  	  V# )z%Y%m%dT%H%M%SZ)r   Únowr   ÚstrftimeÚis_filer   ÚshutilÚcopy2)r!   r   Úbackupsr   Údests   &    r   Ú_backup_existingr+   '   s]   € Ü�LŠLœÓ×&Ñ&Ð'7Ó8€EØ€GÛˆØ�|‰|�~Š~ÙÜ˜DÓ(ˆÜ�Š�TÔ Ø�‹ñ ð €Nr   c               ó    € V ^8„  d   QhRRRR/# )r   r)   r"   r   Úlistr   )r   s   "r   r   r   3   s   € ÷ ñ ˜dð  tñ r   c                óº   € . pV P                  4        FD  w  r#VP                  4       '       g   K  \        P                  ! W24       VP	                  V4       KF  	  V# ©N)Úitemsr&   r'   r(   Úappend)r)   ÚrestoredÚoriginalÚbackups   &   r   Ú_restore_backupsr5   3   sI   € Ø€HØ#ŸM™MžOÑˆØ�~‰~×ÒÙÜ�Š�VÔ&Ø�‰˜Ö!ñ	 ,ð
 €Or   c               ó   € V ^8„  d   QhRR/# ©r   r   r"   r   )r   s   "r   r   r   =   s   € ÷ )Dñ )D˜Tñ )Dr   c                 óì  € ^ RI Hp HpHpHp ^ RIHpHp V ! 4       w  rgWg8¼  d   RRRR/# Wd8  d"   \        P                  RV! 4       4       RRRR/# \        V! 4       V! 4       34      p V! R	RR
7       T ! 4       w  ršY—8  dO   \        T4      p\        RT RT	 R2T'       d#   RP                  R T 4       4      ,           4      hR,           4      hRRRT RT 2/#   \         d    \        T4       h i ; i)a  Migrate config.yaml to the current schema, non-interactively.

Same shape as scripts/docker_config_migrate.py: back up config + .env,
migrate, verify the version advanced, restore the backups on failure.
No-op when the on-disk version is current (the 99% case).
)Úcheck_config_versionÚget_config_pathÚget_env_pathÚmigrate_config)ÚSUPPORT_FLOOR_VERSIONÚsupport_floor_messageÚokTÚskippedz
up-to-datezconfig migration skipped: %szbelow-support-floorF)ÚinteractiveÚquietz,migration did not advance config version to z (still z); restored: z, c              3  ó8   "  € T F  p\        V4      x € K  	  R # 5ir/   )r   )Ú.0Úps   & r   Ú	<genexpr>Ú&step_migrate_config.<locals>.<genexpr>d   s   é € Ð2© Aœ˜QŸ˜«ùs   ‚ÚnoneÚmigratedz->)Úhermes_cli.configr9   r:   r;   r<   Úhermes_cli.config_migrationsr=   r>   ÚloggerÚwarningr+   Ú	Exceptionr5   r   Újoin)r9   r:   r;   r<   r=   r>   Úcurrent_verÚ
latest_verr)   Úpost_verÚ_r2   s               r   Ústep_migrate_configrT   =   s,  € ÷ó ÷ñ
 3Ó4Ñ€KØÔ Ø�d˜I |Ð4Ð4ØÔ*ô 	�‰Ð5Ñ7LÓ7NÔOØ�d˜IÐ'<Ð=Ð=ä¡Ó 1±<³>ÐBÓC€GðÙ 5°Õ5ñ 'Ó(�K€HØÔÜ# GÓ,ˆÜØ:¸:¸,ð GØ�Z˜}ð.ç6>ˆt�y‰yÑ2©Ó2Ó2õLó
ð 	
ð EKõLó
ð 	
ð
 �$˜
 { m°2°j°\Ð$BÐCÐCøô ô Ü˜Ô!Øðús   Á)
C ÃC3c               ó   € V ^8„  d   QhRR/# r7   r   )r   s   "r   r   r   m   s   € ÷ 
ñ 
˜$ñ 
r   c            
     óÌ   € ^ RI Hp  V ! RR7      ;'       g    / pRRR\        VP                  R4      ;'       g    . 4      R\        VP                  R4      ;'       g    . 4      /# )z~Sync bundled skills into the active home. Content-diffed, respects
user modifications and deletions; converges on repeat runs.)Úsync_skillsT)rB   r?   ÚcopiedÚupdated)Útools.skills_syncrW   ÚlenÚget)rW   Úresults     r   Ústep_sync_skillsr^   m   s^   € õ .á˜tÔ$×*Ð*¨€FàˆdØ”#�f—j‘j Ó*×0Ð0¨bÓ1Ø”3�v—z‘z )Ó,×2Ð2°Ó3ðð r   c               ó   € V ^8„  d   QhRR/# r7   r   )r   s   "r   r   r   ~   s   € ÷ +ñ +˜Tñ +r   c                 ó  € ^ RI Hp  ^ RIHp V ! 4       R,          pVP	                  4       '       g   RRRR/# V! VRRR7      pVP                  R	4      '       d   RR/# VP                  R
R4      p\        P                  RV4       RRRV/# )a  Verify the active home's state.db is intact.

Boot bootstrap has no pre-update snapshot to restore from (that pairing
lives in ``hermes update``), so this is detection: a corrupt db is
surfaced loudly in the log instead of the user silently losing session
search. Read-only, idempotent.
©Úget_hermes_home)Úverify_sqlite_integrityzstate.dbr?   Tr@   zno-state-db)Úcheck_headerÚ
run_pragmaÚvalidÚmessagezunknown erroru|   state.db failed integrity check after a code update: %s â€” restore a backup with `hermes backup` tooling or contact supportFÚerror)Úhermes_constantsrb   Úhermes_cli.backuprc   r   r\   rL   rh   )rb   rc   Ú
state_pathr]   rg   s        r   Ústep_state_db_guardrl   ~   s’   € õ 1Ý9á Ó" ZÕ/€JØ×Ñ×ÒØ�d˜I }Ð5Ð5Ù$ Z¸dÈtÔT€FØ‡z�z�'×ÒØ�dˆ|ÐØ�j‰j˜ OÓ4€GÜ
‡L�Lð	Kàôð
 �%˜ 'Ð*Ð*r   c               ó   € V ^8„  d   QhRR/# r7   r   )r   s   "r   r   r   ˜   s   € ÷ ñ  tñ r   c                 ó<   € ^ RI Hp  ^ RIHp V! V ! 4       4       RR/# )a   Drop the active home's cached live plugin catalog after a code change.

Bundled/sealed app updates never run ``hermes update``'s maintenance tail,
so without this a pre-update snapshot out-votes the newer in-tree catalog
for the rest of its TTL (#119340). Per home, like the boot record.
ra   )Úinvalidate_live_cache_for_homer?   T)ri   rb   Úhermes_cli.plugin_catalogro   )rb   ro   s     r   Ústep_drop_live_plugin_catalogrq   ˜   s   € õ 1ÝHá"¡?Ó#4Ô5Ø�$ˆ<Ðr   c               ó    € V ^8„  d   QhRRRR/# )r   Úproject_rootzPath | Noner   r"   r   )r   s   "r   r   r   ¦   s   € ÷ X.ñ X.¨kð X.ÀTñ X.r   c           
     óæ  € ^ RI p^ RIp^ RIHp V f   \	        4       M
\        V 4      pV! 4       R,          \        R4      3pVR,          P                  4       '       g   RRRR	/# ^ R
IHp V! V4      pVP                  4       '       d   RRRR/# Rp VP                  4       pRp	T F  p
 YŠP                  4       8X  d   Rp	 MK  	  T	'       g   RRRR/# ^ RIHp  T! TRR7      pTf¼   R^RRRRR\        P                   ! \"        4      P%                  4       /p TP'                  \)        T4      RRR7      w  pp\*        P,                  ! TRRR7      ;_uu_ 4       pTP/                  TP1                  T^R7      R ,           4       RRR4       \*        P2                  ! TT4       \        P5                  R!T4       RRR"\)        T4      /#   \         d
    RRRR/u # i ; i  \         d     EKI  i ; i  \         d*   p\        P                  RT4       RRRRT 2/u Rp?# Rp?ii ; i  + '       g   i     L­; i  \         d*   p\        P                  RT4       RRRRT 2/u Rp?# Rp?ii ; i)#u  One-time adoption of shipped stampless installs (birth certificate).

Main-era curl|sh / Setup installs created a ``.git`` checkout at a
blessed managed root but never wrote a stamp â€” under the stamp-pure
ladder they would all classify as "somebody's working tree" and
`hermes update` would refuse them. This step writes the missing fact
exactly once: blessed root + ``.git`` + no stamp â†’ a minimal stamp
with ``updateMechanism: self``.

The blessed-root table lives HERE and only here â€” it is a one-time
birth certificate for shipped installs, not a classification rung
(hermes_cli.steward never path-matches). Once pre-stamp installs
are extinct this step and the table can be deleted.

* ``.git`` anywhere else â†’ never adopted.
* An existing stamp (any content) â†’ untouched.
* nix/docker/sealed populations are excluded by construction: their
  update mechanisms replace the tree wholesale with a
  build-time-stamped one, and sealed payloads always ship stamps.
* Read-only tree (nix-like) â†’ soft skip with a debug log, no crash.
Nra   zhermes-agentz/usr/local/lib/hermes-agentz.gitr?   Tr@   znot-a-checkout)Úinstall_stamp_pathzalready-stampedzunresolvable-rootFznot-a-blessed-root)Úwrite_source_stamp)Úadoptedz2blessed-checkout adoption skipped (unwritable): %szunwritable: ÚschemaVersionÚupdateMechanismÚselfÚsourceÚadoptionÚ	adoptedAtz.install-stamp.z.tmp)ÚdirÚprefixÚsuffixÚwzutf-8)Úencoding)ÚindentÚ
z6adopted blessed checkout at %s (updateMechanism: self)rw   )ÚjsonÚtempfileri   rb   r	   r   r   Úpm.pathsru   ÚresolveÚOSErrorÚhermes_cli.source_stamprv   rL   Údebugr   r$   r   Ú	isoformatÚmkstempr   ÚosÚfdopenÚwriteÚdumpsÚreplaceÚinfo)rs   r…   r†   rb   ÚrootÚblessedru   Ú
stamp_pathÚresolved_rootÚ
is_blessedr   rv   Ú
identifiedÚexcr   ÚfdÚtmp_nameÚhandles   &                 r   Ústep_adopt_blessed_checkoutrž   ¦   s|  € ó, Ûå0à)Ò1Œ<Œ>´t¸LÓ7I€Dñ 	Ó˜NÕ*ÜÐ*Ó+ð€Gð
 �6�M×!Ñ!×#Ò#Ø�d˜IÐ'7Ð8Ð8Ý+Ù# DÓ)€JØ×Ñ×ÒØ�d˜IÐ'8Ð9Ð9à€Mð<ØŸ™›ˆð €JÛˆ	ð	Ø× 1Ñ 1Ó 3Ô3Ø!�
Ùñ 4ñ ÷ Ø�d˜IÐ';Ð<Ð<å:ð=ñ (¨°dÔ;ˆ
ð Òð ˜QØ˜vØ�jØœŸš¤cÓ*×4Ñ4Ó6ð	
ˆð		AØ#×+Ñ+Ü˜“IÐ&7Àð ,ó ‰LˆB�ô —’˜2˜s¨W×5Õ5¸Ø—‘˜TŸZ™Z¨°a˜ZÓ8¸4Õ?Ô@÷ 6ä�JŠJ�x Ô,ô ‡K�KÐHÈ$ÔOØ�$˜	¤3 t£9Ð-Ð-øôW ô <Ø�d˜IÐ':Ð;Ò;ð<ûô ô 	Ûð	ûô ô =ô 	�‰ÐIÈ3ÔOØ�d˜I¨°c°UÐ';Ð<Õ<ûð	=ú÷" 6×5ûô ô 	AÜ�L‰LÐMÈsÔSØ˜$ 	¨\¸#¸Ð+?Ð@Õ@ûð	Aúsy   ÂG Â)GÃ
G2 ÄAH< Å*H)ÆH< ÇGÇGÇG/Ç.G/Ç2H&Ç=H!ÈH&È!H&È)H9	È4H< È<I0ÉI+É%I0É+I0c               ó   € V ^8„  d   QhRR/# r7   r   )r   s   "r   r   r     s   € ÷ !0ñ !0 ñ !0r   c                 ó  € ^ RI p ^ RIHpHp V P	                  4       pV'       g   RRRR/# V! 4       '       d   RRRR/# V! 4       '       g   RRRR/# . p. pV FC  p VR	8X  d   V P                  RRR
7       MV P                  VRR7       VP                  V4       KE  	  V'       d   RRRRP                  V4      RV/# RRRV/#   \         d8   p\        P                  RYg4       TP                  T RT 24        Rp?K©  Rp?ii ; i)zÒExplicit refresh of PM's drifted packages; never selected by boot.

PM supplies package identities, not diagnostic text to parse. Its own
ensure/sync operations own freshness checks and publication under lock.
N)Úlazy_installs_allowedÚsealedr?   Tr@   Úcurrentr¢   zlazy-installs-disabledÚvenv)ÚexplicitÚevict_incompatible_plugins)r¥   z!provision_runtimes: %s failed: %sú: Frh   z; Ú	refreshed)ÚpmÚ
pm.installr¡   r¢   ÚdriftÚ	sync_venvÚensurer1   rN   rL   rM   rO   )r©   r¡   r¢   Úproblemsr¨   Úerrorsr   rš   s           r   Ústep_provision_runtimesr°     s  € ó ß8à�x‰x‹z€HßØ�d˜I yÐ1Ð1Ù‡x‚xð �d˜I xÐ0Ð0Ù ×"Ò"Ø�d˜IÐ'?Ð@Ð@à€IØ€FÛˆð	,Ø�vŒ~Ø—‘ dÀt�ÕLà—	‘	˜$¨�	Ô.Ø×Ñ˜TÖ"ñ ÷ Ø�e˜W d§i¡i°Ó&7¸ÀiÐPÐPØ�$˜ YÐ/Ð/øô ô 	,Ü�N‰NÐ>ÀÔJØ�M‰M˜T˜F " S EÐ*×+Ò+ûð	,ús   Á?CÃDÃ,D Ä DÚadopt_blessed_checkoutr<   rW   Ústate_db_guardÚdrop_live_plugin_catalogr   ÚtupleÚ
HOME_STEPSc              #  óD   "  € T F  q^ ,          R8w  g   K  Vx € K  	  R# 5i)é    rW   Nr   )rD   Ústeps   & r   rF   rF   4  s   é € ð ÙˆT¨¥7¨mÑ#;‡D‚D“Zùs   ‚ –
 ÚBOOT_HOME_STEPSÚprovision_runtimesÚMACHINE_STEPSc               ó    € V ^8„  d   QhRRRR/# )r   Ústepsr   r   r"   r   )r   s   "r   r   r   =  s   € ÷ ñ �Xð  $ñ r   c                ó´   € / pV  F  w  r# V! 4       W&   K  	  V#   \          d3   p\        P                  RY$4       RRR\        T4      /Y&    Rp?KM  Rp?ii ; i)uõ   Run steps in order; one failure never stops the rest.

Returns ``{name: result_dict}``. A raising step records
``{"ok": False, "error": str}`` â€” the caller still writes its record so
a broken step cannot retrigger the slow path on every boot.
zpost-update step %s failed: %sr?   Frh   N)rN   rL   rM   r   )r½   Úresultsr   Úfuncrš   s   &    r   Ú	run_stepsrÁ   =  s_   € ð €GÛ‰
ˆð	=Ù ›FˆG‹Mñ ð €Nøô ô 	=Ü�N‰NÐ;¸TÔGØ! 5¨'´3°s³8Ð<ˆG�Mûð	=ús   ‹	šA¥'AÁAc               ó    € V ^8„  d   QhRRRR/# )r   Úargvzlist | Noner   Úintr   )r   s   "r   r   r   N  s   € ÷ ñ ˆ{ð  cñ r   c           	     ó   € ^ RI pVP                  RR7      pVP                  RRRR7       VP                  V 4      p\        P
                  ! \        P                  RR7       . pVP                  R9   d   VP                  \        4       VP                  R9   d   VP                  \        4       \        V4      pVP                  4        UUu. uF   w  rgVP                  R	4      '       d   K  VNK"  	  pppVP                  4        Fc  w  rgVP                  R	4      '       d   R	MR
VP                  R4       R2p	VP                  R4      p
\        RT RV
'       d   RV
 R2MT	 24       Ke  	  V'       d   ^# ^ # u uppi )z>Run the selected maintenance registry and report its failures.Nzhermes_cli.post_update)Úprogz--scopeÚall)ÚchoicesÚdefaultz%(message)s)Úlevelr   r?   zFAILED (rh   Ú)r@   z  post-update r§   z	skipped ()ÚhomeÚmachinerÇ   )rÌ   rÇ   )rÍ   rÇ   )ÚargparseÚArgumentParserÚadd_argumentÚ
parse_argsÚloggingÚbasicConfigÚINFOÚscopeÚextendrµ   r»   rÁ   r0   r\   Úprint)rÃ   rÎ   ÚparserÚargsÚselectedr¿   r   ÚresÚfailedÚstater@   s   &          r   ÚmainrÞ   N  s9  € ãà×$Ñ$Ð*BÐ$ÓC€FØ
×Ñ˜	Ð+EÈuÐÔUØ×Ñ˜TÓ"€Dä×ÒœgŸl™l°=ÕAà€HØ‡z�z�_Ô$Ø�‰œ
Ô#Ø‡z�zÐ'Ô'Ø�‰œÔ&Ü˜Ó!€GØ$+§M¡M¤OÔI¡O‘y�t¸3¿7¹7À4¿=�dˆd¡O€FÑIØ—]‘]–_‰	ˆØŸ™ Ÿš‘¨X°c·g±g¸gÓ6FÐ5GÀqÐ+IˆØ—'‘'˜)Ó$ˆÜ�˜t˜f BÇ¨°7°)¸1Ñ'=ÈeÐ&TÐUÖVñ %÷ ˆ1Ð˜AÐùó Js   ÃE:Ã.E:Ú__main__r/   )&Ú__conditional_annotations__Ú__doc__Ú
__future__r   rÒ   rŽ   r'   r   r   r   Úpathlibr   Útypingr   Úhermes_cli._launchersr   r‡   r	   Ú	getLoggerÚ__name__rL   r   r+   r5   rT   r^   rl   rq   rž   r°   rµ   Ú__annotations__r´   r¹   r»   rÁ   rÞ   Ú
SystemExit)rà   s   @r   Ú<module>rê      s%  øðôõ #ã Û 	Û ß ,Ñ ,Ý Ý å ,Ý !à	×	Ò	˜8Ó	$€õEõ	õõ)Dõ`
õ"+õ4÷X.õv!0ðR Ð:Ð;ØÐ*Ð+ØÐ$Ð%ØÐ*Ð+ØÐ!>Ð?Ø�:Ðð€
ˆEó ÷ ˜ñ ÙóŸ™ñ Ùóó €�ó ð Ð2Ð3ð€ˆuó õ÷"ð0 ˆzÔÙ
‘T“VÓ
Ðñ r   