fix(pm): resolve the install stamp in pm.paths so sealed stages can read it

b207701287 routed PM's stamp reads through hermes_cli.steward.install_stamp_path.
The Docker runtime base runs PM before hermes_cli ships (only __init__ and
runtime_state are copied), so ensure() died with No module named
'hermes_cli.steward'. The resolver is an install-root path built only on
pm.paths.install_root/repo_root; move it there and point every reader at it.
This commit is contained in:
ethernet
2026-09-24 11:08:35 -04:00
parent 8d8edf4cda
commit 87d0fadded
9 changed files with 27 additions and 27 deletions

View File

@@ -186,7 +186,7 @@ def step_adopt_blessed_checkout(project_root: Path | None = None) -> dict:
if not (root / ".git").exists():
return {"ok": True, "skipped": "not-a-checkout"}
from hermes_cli.steward import install_stamp_path
from pm.paths import install_stamp_path
stamp_path = install_stamp_path(root)
if stamp_path.exists():
return {"ok": True, "skipped": "already-stamped"}

View File

@@ -24,7 +24,6 @@ import sys
from pathlib import Path
from typing import Optional
BUILD_INFO_NAME = "install-stamp.json"
UPDATE_MECHANISMS = ("self", "app-installer", "electron-updater", "external", "microsoft-store")
STEWARD_DESKTOP = "desktop-app"
@@ -177,23 +176,6 @@ def steward_uninstall_message(steward: str, platform: "str | None" = None) -> st
return _STEWARD_UNINSTALL_FALLBACK.format(steward=steward)
def install_stamp_path(project_root: Path) -> Path:
"""THE stamp location for ``project_root``, shared by every stamp reader.
Beside the code in checkouts, Docker and desktop payloads. A Nix package
bakes the stamp outside the store's package dir and its wrapper carries
``HERMES_INSTALL_ROOT`` for the executing tree only — so the executing
tree resolves through pm.paths.install_root, any other tree is taken
literally. Two resolvers here once classified Nix as "unknown".
"""
from pm.paths import install_root, repo_root
root = Path(project_root)
if root.resolve() == repo_root():
root = install_root()
return root / BUILD_INFO_NAME
def read_install_stamp(project_root: Path) -> dict:
"""The build stamp of ``project_root``, or ``{}``.
@@ -201,6 +183,8 @@ def read_install_stamp(project_root: Path) -> dict:
path on a malformed stamp — a tree we cannot prove is ours still
refuses (see :func:`sealed_steward`), so garbage degrades safely.
"""
from pm.paths import install_stamp_path
try:
data = json.loads(install_stamp_path(project_root).read_text(encoding="utf-8-sig"))
except (OSError, ValueError):

View File

@@ -32,7 +32,8 @@ def _is_sealed(project_root: Path) -> bool:
"""
if (project_root / ".git").exists():
return False
from hermes_cli.steward import install_stamp_path, read_install_stamp
from hermes_cli.steward import read_install_stamp
from pm.paths import install_stamp_path
stamp_path = install_stamp_path(project_root)
data = read_install_stamp(project_root)
if not data:

View File

@@ -109,9 +109,8 @@ def _calver_release_version(repo_dir: Path) -> tuple[str, int] | None:
# --- Install stamp reader ---------------------------------------------------
def _resolve_stamp_file() -> Path | None:
"""The executing tree's stamp (steward.install_stamp_path owns the location)."""
from hermes_cli.steward import install_stamp_path
from pm.paths import repo_root
"""The executing tree's stamp (pm.paths.install_stamp_path owns the location)."""
from pm.paths import install_stamp_path, repo_root
p = install_stamp_path(repo_root())
return p if p.is_file() else None

View File

@@ -107,7 +107,7 @@ def store_root(project_root: Path) -> Path:
if not store.is_relative_to(root.parent):
raise RuntimeError("payload store escapes its root")
return store
from hermes_cli.steward import install_stamp_path
from pm.paths import install_stamp_path
for directory in (root, *root.parents):
stamp = install_stamp_path(directory)

View File

@@ -18,6 +18,22 @@ def install_root() -> Path:
return Path(env) if env else repo_root()
def install_stamp_path(project_root: Path) -> Path:
"""THE stamp location for ``project_root``, shared by every stamp reader.
Beside the code in checkouts, Docker and desktop payloads. A Nix package
bakes the stamp outside the store's package dir and its wrapper carries
``HERMES_INSTALL_ROOT`` for the executing tree only — so the executing
tree resolves through install_root, any other tree is taken literally.
PM reads it in sealed stages (the Docker runtime base) before hermes_cli
ships, so it lives here rather than beside the stewards.
"""
root = Path(project_root)
if root.resolve() == repo_root():
root = install_root()
return root / "install-stamp.json"
def lockfile_path() -> Path:
return Path(__file__).resolve().parent / "lock.json"

View File

@@ -61,7 +61,7 @@ def _resident_runtime() -> tuple[Path, Path] | None:
if payload is not None:
runtime = payload / "pm-runtime"
else:
from hermes_cli.steward import install_stamp_path
from pm.paths import install_stamp_path
stamp_path = install_stamp_path(project)
try:

View File

@@ -23,7 +23,7 @@ def embedded_context(tmp_path, monkeypatch):
"""Running tree = sealed desktop-app; legacy checkout at the managed root."""
bundle = tmp_path / "bundle" / "repo"
bundle.mkdir(parents=True)
# The code-scoped stamp (hermes_cli.steward.BUILD_INFO_NAME).
# The code-scoped stamp (pm.paths.install_stamp_path).
(bundle / "install-stamp.json").write_text(
json.dumps({"commit": "a" * 40, "distribution": "desktop-app", "updateMechanism": "electron-updater"})
)

View File

@@ -68,7 +68,7 @@ def _fake_project_root(monkeypatch, tmp_path: Path, *, git: bool, distribution:
if git:
(root / ".git").mkdir()
if distribution is not None:
# The code-scoped stamp (see hermes_cli.steward.BUILD_INFO_NAME).
# The code-scoped stamp (see pm.paths.install_stamp_path).
(root / "install-stamp.json").write_text(
json.dumps({"distribution": distribution, "updateMechanism": "external"})
, encoding="utf-8")