"""Hermes shared fabric profile isolation primitives.""" from __future__ import annotations from dataclasses import dataclass from pathlib import Path import os from .tenant_context import ValidationError, require_ident @dataclass(frozen=True) class HermesProfile: tenant_id: str cell_id: str profile_id: str hermes_home: Path workspace: Path def __post_init__(self) -> None: require_ident("tenant_id", self.tenant_id, tenant=True) for name in ("cell_id", "profile_id"): require_ident(name, getattr(self, name)) if not self.hermes_home.is_absolute() or not self.workspace.is_absolute(): raise ValidationError("profile paths must be absolute") @property def environment(self) -> dict[str, str]: return { "HERMES_HOME": str(self.hermes_home), "HOME": str(self.hermes_home), "AIOS_TENANT_ID": self.tenant_id, "AIOS_CELL_ID": self.cell_id, "AIOS_PROFILE_ID": self.profile_id, } def prepare(self) -> None: self.hermes_home.mkdir(parents=True, exist_ok=True) self.workspace.mkdir(parents=True, exist_ok=True) os.chmod(self.hermes_home, 0o700) os.chmod(self.workspace, 0o700) def assert_path_allowed(self, path: str | Path) -> None: target = Path(path).resolve() for root in (self.hermes_home.resolve(), self.workspace.resolve()): if target == root or root in target.parents: return raise ValidationError("path escapes profile isolation boundary")