Commit Graph

4 Commits

Author SHA1 Message Date
ethernet cae085be59 feat: single desktop variant selector and baked install stamp
Replace HERMES_DESKTOP_BUNDLED with HERMES_DESKTOP_VARIANT. The variant is one value: bootstrap, bundled, or light. The stamp payload field records it.

Bake install-stamp.json into the electron bundle as an object literal. The app does not load a stamp file from resources anymore. Remove the extraResources entry and the loose-file loader. A new install-stamp.ts module owns the InstallStamp and ArtifactKind types.

Python reads a light stamp as an error: a light artifact has no Python runtime, so this state means the build is bad.
2026-08-10 19:37:17 -04:00
ethernet 4a783b1c21 unify install provenance on a single code-scoped install-stamp.json
one artifact replaces three: install-stamp.json (code-scoped) subsumes
.hermes_build_info.json (same schema, different name) and .install_method
(derivable). git checkouts carry no stamp at all — .git plus location is
the fact.

detect_install_method() now delegates to runtime_tree.install_method():
  stamp distribution (docker/nix/desktop-app)
  -> .git at a managed install root => git
  -> .git anywhere else => source (new)
  -> unknown

the new 'source' method makes hermes update refuse random src checkouts
outright and point at git pull (replaces the --yes-overridable ask-first
guard). nixos dies as a method value; /nix/store sniffing and the
HERMES_MANAGED ladder step die with it. HERMES_MANAGED keeps exactly one
job: the NixOS module's declarative config-write guard.

lazy_deps drops install-method inference entirely: the read-only guard
now probes site-packages writability directly.

no backwards compat: nothing reads the legacy stamps anymore. stage2-hook
keeps deleting stale home-scoped .install_method markers left by old
images.
2026-08-10 11:21:49 -04:00
ethernet c375b9c28a feat(desktop): gate uninstall actions on install provenance
The uninstall flow now reads the install stamp to learn who owns the
code. Three install kinds exist:

- standard (git checkout from the installer or 'hermes desktop'):
  keeps the full gui/lite/full flow.
- bundled (embedded payload): the app can only remove user data. The
  embedded CPython runs the uninstall module. The OS removes the app
  (Apps & Features / Trash / delete the AppImage).
- nix: the app can only remove user data. The UI shows 'managed by
  Nix' guidance instead of code-removal options.

A new mode 'data' (hermes uninstall --data) removes ~/.hermes user
data and the Electron userData dir, and keeps all code. This mode is
valid on every install kind.

The Python uninstaller enforces the same rule on its own: it reads
.hermes_build_info.json through runtime_tree and refuses the
code-removal modes on sealed trees, with instructions from the
steward. The renderer cannot make a managed install delete code.

loadInstallStamp now accepts a stamp with commit:null. A dirty Nix
build writes such a stamp, and the provenance fields must survive.
2026-08-10 11:21:49 -04:00
ethernet eb676fe66e change: derive install state from .git and the build stamp
hermes_cli/runtime_tree.py replaces install_manifest.py. A tree with
.git is a git checkout and `hermes update` owns it. A tree without
.git is sealed, and the distribution field of the build stamp names
the steward that replaces it (desktop-app, docker, nix). The refusal
message comes from a per-steward table.

.hermes-install.json dies: staging stops writing it into the payload,
the CLI never reads it, and the update channel lives in config.yaml
(update.channel; main is the default and keeps the current behavior).

Eject gates on Sealed(desktop-app) and is a full handoff: it tells
the user that Setup replaces the desktop app. --channel on a git
checkout writes config instead of a manifest.
2026-08-10 02:34:52 -04:00