diff --git a/ansible/roles/heph/defaults/main.yml b/ansible/roles/heph/defaults/main.yml
index 04d9c88..e5eea36 100644
--- a/ansible/roles/heph/defaults/main.yml
+++ b/ansible/roles/heph/defaults/main.yml
@@ -15,6 +15,13 @@ heph_repo_url: https://forge.eblu.me/eblume/hephaestus.git
heph_bin_dir: /Users/erichblume/.cargo/bin
heph_binary: "{{ heph_bin_dir }}/hephd"
+# rustc/cargo here are rustup shims. The bare (non-mise) environment that the
+# launchagent and ansible run in falls back to rustup's *default* toolchain,
+# which can lag behind heph's rust-version floor (Cargo.toml: 1.89). Pin the
+# channel explicitly so both the bootstrap build and unattended self-update
+# always use a current toolchain regardless of the host's rustup default.
+heph_rust_toolchain: stable
+
heph_data_dir: /Users/erichblume/.local/share/heph
heph_db: "{{ heph_data_dir }}/heph.db"
heph_socket: "{{ heph_data_dir }}/hephd.sock"
diff --git a/ansible/roles/heph/tasks/main.yml b/ansible/roles/heph/tasks/main.yml
index f27d39c..7a45fe3 100644
--- a/ansible/roles/heph/tasks/main.yml
+++ b/ansible/roles/heph/tasks/main.yml
@@ -38,6 +38,7 @@
heph hephd
environment:
PATH: "{{ heph_bin_dir }}:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
+ RUSTUP_TOOLCHAIN: "{{ heph_rust_toolchain }}"
when: not heph_binary_stat.stat.exists
changed_when: true
notify: Restart heph
diff --git a/ansible/roles/heph/templates/heph.plist.j2 b/ansible/roles/heph/templates/heph.plist.j2
index 9b3b3bf..19a2367 100644
--- a/ansible/roles/heph/templates/heph.plist.j2
+++ b/ansible/roles/heph/templates/heph.plist.j2
@@ -37,6 +37,10 @@
{{ heph_bin_dir }}:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
HOME
/Users/erichblume
+
+ RUSTUP_TOOLCHAIN
+ {{ heph_rust_toolchain }}
StandardOutPath
{{ heph_log_dir }}/mcquack.heph.out.log
diff --git a/docs/reference/services/hephaestus.md b/docs/reference/services/hephaestus.md
index 6faf3ab..838e440 100644
--- a/docs/reference/services/hephaestus.md
+++ b/docs/reference/services/hephaestus.md
@@ -43,7 +43,11 @@ hephd --mode server --http-addr 0.0.0.0:8787 --db ~/.local/share/heph/heph.db
reconcile their op-log against.
- **Self-update** (10-minute poll) rebuilds `hephd` from the forge when a newer
release tag appears (`cargo install --git https://forge.eblu.me/eblume/hephaestus.git`).
- Indri's Rust toolchain (`~/.cargo/bin`) is on the agent's `PATH` for this.
+ Indri's Rust toolchain (`~/.cargo/bin`) is on the agent's `PATH` for this, and
+ the plist pins `RUSTUP_TOOLCHAIN=stable` — the
+ launchagent runs without mise, so a bare `cargo` shim would otherwise fall back
+ to rustup's *default* toolchain, which can lag behind heph's `rust-version` floor
+ (1.89) and silently fail the build.
- **PWA** (`--web-root`) serves the [heph-pwa] mobile shell; Caddy terminates TLS
at `heph.ops.eblu.me` so the PWA runs in a secure context (service worker,
install-to-home-screen, voice capture).