+
    jHàj45  ã                  ó   € R t ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RI	H
t
HtHt ^ RIHt  ! R R4      t]! R	R
7       ! R R4      4       tR R ltR R ltR tR tR tRR ltR tR tR tR tR R ltRR/R ltR# ) a�  One SessionAuthority per reserved profile home; resolved by the active runtime scope.

A multiplexing gateway owns every profile under ``profiles/`` plus the default home. Each
home has its own ``state.db``, admission ledger, runtime epoch and control identity, so each
gets its own authority. Every consumer already runs inside the routed profile's
``_profile_runtime_scope`` (that is what the multiplex fixes on main established), so the
authority for "the profile this code is acting for" is the one keyed by the active home.

A single-profile gateway is a map of one: the launch home's authority answers every lookup,
scoped or not, exactly as before.
)Úannotations)Ú	dataclass)ÚPath)ÚAny)Úget_hermes_homeÚget_hermes_home_overrideÚhermes_home_key©ÚRuntimeStoreErrorc                  ó´   € ] tR t^tRtRR/R ltRR R lltR R	 ltR
 tR t	R R lt
R tR R lt]R 4       tR tR tR tR R ltR R ltR R ltRtR# )ÚSessionAuthoritiesz;Registry of authorities keyed by ``hermes_home_key(home)``.ÚmultiplexedFc               	ób   € \        V4      V n        / V n        / V n        \	        V4      V n        R # ©N)r   Ú
launch_keyÚ_by_keyÚ_namesÚboolr   )ÚselfÚlaunch_homer   s   &&$Ú@/home/ubuntu/.hermes/hermes-agent/gateway/session_authorities.pyÚ__init__ÚSessionAuthorities.__init__   s+   € Ü)¨+Ó6ˆŒØ*,ˆŒØ-/ˆŒô   Ó,ˆÖó    Nc               ó   € V ^8„  d   QhRR/# ©é   ÚreturnÚNone© )Úformats   "r   Ú__annotate__ÚSessionAuthorities.__annotate__!   s   € ÷ $ñ $°ñ $r   c                	óÂ   € \        V4      pW@P                  9   d   \        R V 24      hW P                  V&   W0P                  V&   W@P                  8w  d
   RV n        R# R# )z duplicate session authority for TN)r   r   ÚRuntimeErrorr   r   r   )r   ÚhomeÚ	authorityÚnameÚkeys   &&&& r   ÚaddÚSessionAuthorities.add!   sX   € Ü˜dÓ#ˆØ—,‘,ÔÜÐ!AÀ$ÀÐHÓIÐIØ%�‰�SÑØ�‰�CÑØ—/‘/Ô!Ø#ˆDÖñ "r   c               ó   € V ^8„  d   QhRR/# r   r   )r    s   "r   r!   r"   *   s   € ÷ &ñ &¨$ñ &r   c                óž   € \        V4      pW0P                  9  g   V P                  V,          e   \        RV 24      hW P                  V&   R# )zRFill the slot reserved by ``add(home, None, name=...)`` once the authority exists.Nz'no reserved session authority slot for )r   r   r$   )r   r%   r&   r(   s   &&& r   ÚreplaceÚSessionAuthorities.replace*   sC   € ä˜dÓ#ˆØ—l‘lÔ" d§l¡l°3Õ&7Ò&CÜÐ!HÈÈÐOÓPÐPØ%�‰�SÓr   c                ó¾   € \        V4      pW P                  8X  d   \        R4      hV P                  P	                  VR4       V P
                  P	                  VR4      # )z|Drop *home*'s slot (a parked boot, a hot-unserved profile); returns the authority or None.
The launch slot is never removed.z.the launch session authority cannot be removedN)r   r   r$   r   Úpopr   )r   r%   r(   s   && r   ÚremoveÚSessionAuthorities.remove1   sM   € ô ˜dÓ#ˆØ—/‘/Ô!ÜÐOÓPÐPØ�‰�‰˜˜TÔ"Ø�|‰|×Ñ  TÓ*Ð*r   c                ó†   € \        VP                  4      pW P                  8X  d   R# V P                  P	                  V4      # )z¢Served profile name for *authority*; None for the launch profile (its adapters are
``runner.adapters``, its session keys the historical ``agent:main`` namespace).N)r   Ú
profile_idr   r   Úget)r   r&   r(   s   && r   Úprofile_nameÚSessionAuthorities.profile_name:   s5   € ô ˜i×2Ñ2Ó3ˆØŸo™oÔ-ˆtÐG°4·;±;·?±?À3Ó3GÐGr   c               ó   € V ^8„  d   QhRR/# )r   r   Úintr   )r    s   "r   r!   r"   @   s   € ÷ !ñ !˜ñ !r   c                	ó,   € \        V P                  4      # r   )Úlenr   ©r   s   &r   Ú__len__ÚSessionAuthorities.__len__@   s   € Ü�4—<‘<Ó Ð r   c                	óH   € \        V P                  P                  4       4      # r   )Úiterr   Úvaluesr<   s   &r   Ú__iter__ÚSessionAuthorities.__iter__C   s   € Ü�D—L‘L×'Ñ'Ó)Ó*Ð*r   c               ó   € V ^8„  d   QhRR/# ©r   r   r   r   )r    s   "r   r!   r"   F   s   € ÷ 5ñ 5 Dñ 5r   c                	ó2   € \        V4      V P                  9   # r   )r   r   ©r   r%   s   &&r   Ú__contains__ÚSessionAuthorities.__contains__F   s   € Ü˜tÓ$¨¯©Ñ4Ð4r   c                	ó<   € V P                   V P                  ,          # r   )r   r   r<   s   &r   ÚlaunchÚSessionAuthorities.launchI   s   € à�|‰|˜DŸO™OÕ,Ð,r   c                óJ   € V P                   P                  \        V4      4      # )zEAuthority owning *home*, or None when this process does not serve it.)r   r5   r   rG   s   &&r   Úfor_homeÚSessionAuthorities.for_homeM   s   € à�|‰|×Ñ¤°Ó 5Ó6Ð6r   c                	óF   € V P                  V4      pVf   \        R4      hV# )NÚprofile_mismatch)rN   r
   )r   r%   r&   s   && r   ÚrequireÚSessionAuthorities.requireQ   s(   € Ø—M‘M $Ó'ˆ	ØÒÜ#Ð$6Ó7Ð7ØÐr   c                óÐ   € V P                   '       d   \        4       f   V P                  V P                  ,          # V P                  P	                  \        \        4       4      4      # )uÝ  Authority for the active runtime scope.

Unscoped code (startup, shutdown, background watchers) belongs to the launch profile.
Scoped code that names a home this process does not serve gets ``None``: a routed
profile must never fall back to the launch profile's ledger â€” including once a removed
secondary leaves only the launch slot (a late callback of that profile). Only a runtime
that never multiplexed is a map of one that answers every scope with the launch authority.
)r   r   r   r   r5   r   r   r<   s   &r   ÚactiveÚSessionAuthorities.activeW   sI   € ð ××ÐÔ#;Ó#=Ò#EØ—<‘< §¡Õ0Ð0Ø�|‰|×Ñ¤´Ó0AÓ BÓCÐCr   c               ó   € V ^8„  d   QhRR/# )r   r   Úlistr   )r    s   "r   r!   r"   d   s   € ÷ oñ o˜ñ or   c                ó¦   € \        V P                  P                  4       4       Uu. uF  qf   K  \        VRR4      '       d   K  VNK!  	  up# u upi )z®Authorities that accept work: not a reserved-but-unbuilt slot, not one retiring (a
failed serve or an unserve whose turn outlived Stop keeps its slot but refuses admissions).ÚretiringF)rX   r   rA   Úgetattr©r   Úas   & r   ÚservingÚSessionAuthorities.servingd   sC   € ô   §¡× 3Ñ 3Ó 5Ô6ÓnÑ6�a”ÔPWÐXYÐ[eÐgl×Pm—�Ñ6ÑnÐnùÒns   ¦A°AÁAc               ó   € V ^8„  d   QhRR/# )r   r   z
list[dict]r   )r    s   "r   r!   r"   j   s   € ÷ \ñ \ ñ \r   c                	ó|   € V P                  4        Uu. uF  pR VP                  RVP                  /NK  	  up# u upi )r4   r%   )r^   r4   r\   s   & r   Úserved_profilesÚ"SessionAuthorities.served_profilesj   s1   € ØLPÏLÉLÌNÓ[ÉNÀq�˜qŸ|™|¨V°Q·\±\ÓBÉNÑ[Ð[ùÒ[s   “#9c               ó   € V ^8„  d   QhRR/# )r   r   zfrozenset[str]r   )r    s   "r   r!   r"   m   s   € ÷ ?ñ ?˜^ñ ?r   c                	óB   € \        R  V P                  4        4       4      # )c              3  ó8   "  € T F  qP                   x € K  	  R # 5ir   )r4   )Ú.0r]   s   & r   Ú	<genexpr>Ú1SessionAuthorities.profile_ids.<locals>.<genexpr>n   s   é € Ð>©~¨!Ÿž«~ùs   ‚)Ú	frozensetr^   r<   s   &r   Úprofile_idsÚSessionAuthorities.profile_idsm   s   € ÜÑ>¨t¯|©|¬~Ó>Ó>Ð>r   )r   r   r   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r)   r-   r1   r6   r=   rB   rH   ÚpropertyrK   rN   rR   rU   r^   rb   rk   Ú__static_attributes__r   r   r   r   r      so   † ÙEð-°5ô -÷$õ&ò+òHõ!ò+õ5ð ñ-ó ð-ò7òòDõoõ\÷?ñ ?r   r   T)Úfrozenc                  óV   € ] tR t^qt$ RtR]R&   R]R&   R]R&   RtR	]R
&   RtR]R&   RtR# )ÚLocalBota  One local bot this process serves: its profile ``name``, ``home`` and owning ``authority``.
``problem`` says why a client cannot address it by that name (None when it can); ``retiring``
marks one being unserved, which still owns its rooms but takes no new work.Ústrr'   r   r%   r   r&   Nz
str | NoneÚproblemFr   rZ   r   )	rm   rn   ro   rp   rq   Ú__annotations__rx   rZ   rs   r   r   r   rv   rv   q   s-   ‡ ñSð ƒIØ
ƒJØƒNØ€GˆZÓØ€Hˆd×r   rv   c               ó   € V ^8„  d   QhRR/# )r   r   zlist[LocalBot]r   )r    s   "r   r!   r!   }   s   € ÷ ñ ˜.ñ r   c                ó|  € ^ RI Hp \        V RR4      pVf-   \        V RR4      pVe   \        VP                  4      V3.M. pMe\        VP                  P                  4       4       Uu. uF8  qUf   K  VP                  V4      ;'       g    \        VP                  4      V3NK:  	  ppV! R V 4       4      p. pV Fw  w  rƒRp	Wh,          ^8”  d   Rp	MV\        VP                  4      8w  d   Rp	VP                  \        V\        VP                  4      W9\        \        VRR	4      4      4      4       Ky  	  V# u upi )
a!  The local bots this gateway serves, one per built authority, by the name the registry
reserved each under (the launch profile keeps ``served_profile_name``). The one answer to
"which bots are local here" for both the Bots roster (``profiles.list``) and group seating
(``session_hosted_members``). A name two homes answer to, or one that is not its home's own
name (a linked ``profiles/<name>`` resolves outside ``profiles/`` and reads as ``default``), is
flagged rather than bound: a client routes, and the member transport names, a bot by name.)ÚCounterÚsession_authoritiesNÚsession_authorityc              3  ó*   "  € T F	  w  rVx € K  	  R # 5ir   r   )rg   r'   Ú_s   &  r   rh   Úlocal_bots.<locals>.<genexpr>�   s   é € Ð/©™g˜d•T«ùs   ‚z$two served homes answer to that namez*a linked profile home is not supported yetrZ   F)Úcollectionsr|   r[   Úserved_profile_namer4   rX   r   rA   r6   Úappendrv   r   r   )
Úrunnerr|   Úregistryr&   Úpairsr]   ÚcountsÚbotsr'   rx   s
   &         r   Ú
local_botsrŠ   }   s<  € õ $Ü�vÐ4°dÓ;€HØÒÜ˜FÐ$7¸Ó>ˆ	ØLUÒLaÔ% i×&:Ñ&:Ó;¸YÐGÑHÐgi‰ô ˜x×/Ñ/×6Ñ6Ó8Ô9óLÙ9�Qô T�(×'Ñ'¨Ó*×OÐOÔ.AÀ!Ç,Á,Ó.OÐQRÓSÙ9ð 	ð LáÑ/©Ó/Ó/€FØ€DÛ ‰ˆØˆØ�<˜!ÔØ<‰GØÔ(¨×)=Ñ)=Ó>Ô>ØBˆGØ�‰”H˜T¤4¨	×(<Ñ(<Ó#=¸yÜ!¤'¨)°ZÀÓ"GÓHóJö 	Kñ !ð €KùòLs   Á)D9Á3D9ÂD9c               ó   € V ^8„  d   QhRR/# )r   r   rw   r   )r    s   "r   r!   r!   š   s   € ÷ 4ñ 4 ñ 4r   c                ó2   € ^ RI Hp V! V 4      ;'       g    R# )a`  Canonical profile id of a served home: ``default`` for the root, the directory name for
``profiles/<name>`` (via ``hermes_constants.profile_name_for_home``, the resolver main uses).
Any other custom HERMES_HOME is the process's own single profile and keeps the ``default``
label the CLI reports for it (``hermes -p`` never targets such a home by name).)Úprofile_name_for_homeÚdefault)Úhermes_constantsr�   )r%   r�   s   & r   rƒ   rƒ   š   s   € õ
 7Ù  Ó&×3Ð3¨)Ð3r   c                ó  € \        V RR4      pVfi   \        V RR4      pVeV   \        VP                  P                  4      P	                  4       P
                  \        V4      P	                  4       8X  d   V# R# VP                  V4      # )zGExplicit per-home lookup for callers that already know the routed home.r}   Nr~   )r[   r   ÚdbÚdb_pathÚresolveÚparentrN   )r…   r%   r†   r&   s   &&  r   Úauthority_for_homer•   £   s{   € ä�vÐ4°dÓ;€HØÒÜ˜FÐ$7¸Ó>ˆ	ØÒ ¤T¨)¯,©,×*>Ñ*>Ó%?×%GÑ%GÓ%I×%PÑ%PÔTXÐY]ÓT^×TfÑTfÓThÔ%hØÐÙØ×Ñ˜TÓ"Ð"r   c                ó,   € \        V \        V4      4      # r   )r•   r   )r…   r4   s   &&r   Úauthority_for_profile_idr—   ®   s   € Ü˜f¤d¨:Ó&6Ó7Ð7r   c                ó^   € \        V RR4      pVf   \        V RR4      # VP                  4       # )z¢Authority for the active runtime scope (see ``SessionAuthorities.active``); the single
launch authority when the runner predates the registry (bare test runners).r}   Nr~   )r[   rU   )r…   r†   s   & r   Úactive_authorityr™   ²   s6   € ô �vÐ4°dÓ;€HØÒÜ�vÐ2°DÓ9Ð9Ø�?‰?ÓÐr   Nc                ó–   € \        V 4      pVf   ^ RIHp V! V 4       Ve   Ve$   V! 4       VP                  Jd   ^ RIHp V! R4      hV# )aQ  The active scope's authority, or a refusal: retryable (``runtime_draining``) while its
profile is parked, else ``profile_mismatch``. With *store* (a callable returning the caller's
SessionDB, called only once an authority exists), that store must be the authority's: an API
adapter bound to another profile's SessionDB never admits here.)Úrefuse_parked_scoper	   rQ   )r™   Úgateway.run_runtimer›   r‘   Úhermes_state_runtimer
   )r…   Ústorer&   r›   r
   s   &&   r   Úrequire_active_authorityrŸ   »   sL   € ô
 ! Ó(€IØÒÝ;Ù˜FÔ#ØÒ˜UÒ.±5³7À)Ç,Á,Ó3NÝ:ÙÐ 2Ó3Ð3ØÐr   c                óf   € \        V R R4      pVe   \        V4      # \        V RR4      pVe   V.# . # )r}   Nr~   )r[   rX   ©r…   r†   r&   s   &  r   Úall_authoritiesr¢   Ê   sB   € Ü�vÐ4°dÓ;€HØÒÜ�H‹~ÐÜ˜Ð 3°TÓ:€IØ#Ò/ˆIˆ;Ð7°RÐ7r   c                ó–   € \        V RR4      pVe   VP                  4       # \        V RR4      pVe   \        VRR4      '       g   V.# . # )a  The authorities that accept work (``SessionAuthorities.serving``: no reserved-but-unbuilt slot,
none retiring): what startup recovery, service creation and cross-ledger reads cover. Shutdown
keeps ``all_authorities``, so a retained authority's live writer is still settled.r}   Nr~   rZ   F)r[   r^   r¡   s   &  r   Úserving_authoritiesr¤   Ò   sY   € ô �vÐ4°dÓ;€HØÒØ×ÑÓ!Ð!Ü˜Ð 3°TÓ:€IØ#Ò/¼À	È:ÐW\×8]Ò8]ˆIˆ;ÐeÐceÐer   c                óB   € \        V RR4      '       d   \        R4      hR# )zµRefuse a verb reached through a stale connection to a retired authority: its ownership is
released, and until a successor bumps the epoch its own epoch still passes the store fence.ÚretiredFÚruntime_retiredN)r[   r
   )r&   s   &r   Úrequire_servingr¨   Ý   s$   € ô ˆy˜) U×+Ò+ÜÐ 1Ó2Ð2ñ ,r   c                óÖ   € ^ RI Hp V P                  V4      pV'       g   V# V P                  P	                  4       ;_uu_ 4       pV! WC4      uuRRR4       #   + '       g   i     R# ; i)a
  The admission identity a physical store row answers to: its compression root, then the
local creation id a canonical reset forks under (a reset child is not a compression child, so
``logical_owner`` alone stops at the child and misses the conversation's admissions).)Úlocal_lineage_ownerN)Úhermes_state_localrª   Úlogical_ownerr‘   Ú	_read_ctx)r&   Ú
session_idrª   ÚsidÚconns   &&   r   Úadmission_ownerr±   ä   sK   € õ 7Ø
×
!Ñ
! *Ó
-€CßØˆ
Ø	�‰×	Ñ	×	!Ô	! TÙ" 4Ó-÷ 
"×	!×	!Ó	!ús   ÁAÁA(	c               ó   € V ^8„  d   QhRR/# rE   r   )r    s   "r   r!   r!   ð   s   € ÷ ñ ¨dñ r   c           
     ó"  €  \        V P                  P                  RV\        W4      34      4      #   \         dR   p\        T RR4      '       g   h ^ RIpTP                  R4      P                  RT\        T RR4      T4        Rp?R	# Rp?ii ; i)
a  Whether *authority*'s store holds a canonical admission for *session_id*. A parked profile's
retained (retiring) store that cannot answer counts as holding one: startup auto-resume fails
closed for that entry instead of stopping the boot or resuming a turn that FIFO may own.zISELECT 1 FROM session_admissions WHERE target_session_id IN (?,?) LIMIT 1rZ   FNzgateway.runz?Skipping auto-resume of %s: retained store %s cannot answer: %sr4   Ú?T)	r   r‘   Ú	_read_oner±   Ú	Exceptionr[   ÚloggingÚ	getLoggerÚwarning)r&   r®   Úexcr·   s   &&  r   Úholds_admissionr»   ð   s’   € ð
Ü�I—L‘L×*Ñ*ØWØœ¨Ó?Ð@óBó Cð 	Cøô ô Ü�y *¨e×4Ò4ØÛØ×Ñ˜-Ó(×0Ñ0Ð1rØ1;¼WÀYÐP\Ð^aÓ=bÐdgô	iåûðús   ‚/2 ²B½AB	Â	BÚhydrate_secretsFc               ó>  € ^ RI Hp \        V RR4      p\        \        VRR4      RR4      '       g   ^ RIHp V! 4       # \        \        V P                  4      4      pVP                  4       '       d   VP                  4       '       g   V! 4       # ^ RI
Hp V! WQR	7      # )
u9  Runtime scope of the profile that owns *authority* â€” under multiplex only.

Owner-side handlers (RPC dispatch, cron submit, admitted execution) must read config, jobs
and policy for the OWNING profile, never the launch profile's ambient scope. A
single-profile gateway keeps its ambient scope byte-for-byte: entering a scope there
would read the profile's config/.env for every handler, including bypass (--safe-mode)
launches that must never touch the profile YAML. Test peers with symbolic ids ('fixture')
likewise keep the ambient scope.

A standalone gateway that already hosts a second home (a profile created over the wire froze
the launch env and made unscoped secret reads fail closed) binds the launch profile's own scope
instead: unbound, every launch-profile session.create raised UnscopedSecretError (#141623).
)Únullcontextr…   NÚconfigÚmultiplex_profilesF)Ú#launch_profile_scope_if_multiplexed)Ú_profile_runtime_scope)r¼   )Ú
contextlibr¾   r[   Ú!tui_gateway.launch_profile_policyrÁ   r   rw   r4   Úis_absoluteÚis_dirÚgateway.runrÂ   )r&   r¼   r¾   r…   rÁ   r%   rÂ   s   &$     r   Úowner_scoperÈ     s~   € õ 'Ü�Y ¨$Ó/€FÜ”7˜6 8¨TÓ2Ð4HÈ%×PÒPÝYÙ2Ó4Ð4Ü”�I×(Ñ(Ó)Ó*€DØ×Ñ×Ò T§[¡[§]¢]Ù‹}ÐÝ2Ù! $ÔHÐHr   r   )rq   Ú
__future__r   Údataclassesr   Úpathlibr   Útypingr   r�   r   r   r   r�   r
   r   rv   rŠ   rƒ   r•   r—   r™   rŸ   r¢   r¤   r¨   r±   r»   rÈ   r   r   r   Ú<module>rÍ      s’   ðñ
õ #å !Ý Ý ç WÑ WÝ 2÷X?ñ X?ñv �$Ô÷ð ó ðõõ:4ò#ò8òôò8òfò3ò	.õð"I¨eö Ir   