Fix fresh-checkout build + daemon startup under hero_proc supervision #48

Merged
mik-tf merged 1 commit from development_mik into development_crate_layout 2026-05-19 18:05:19 +00:00
Member

What this PR changes

Five small fixes to mycelium_network so it builds and runs cleanly on a fresh checkout.

1. Fix broken hero_admin_lib dep

crates/mycelium_admin/Cargo.toml had a path dep pointing at ../../../hero_website_framework/... — that path only resolves if hero_website_framework happens to be cloned as a sibling directory of mycelium_network. On most clones it doesn't exist, and cargo build --workspace fails at the manifest step before any code compiles.

Switched it to the git dep used by hero_voice and the other consumers:

hero_admin_lib = { version = "0.1.0", git = "https://forge.ourworld.tf/lhumina_code/hero_website_framework.git", branch = "development" }

2. Use workspace dep for herolib_core in mycelium_admin

The other four crates declare herolib_core = { workspace = true }. mycelium_admin had its own standalone git ref. Flipped it to match — one place to bump the version going forward.

3. Forward Hero env vars when CLI spawns the daemons

mycelium_cli --start registers two child processes (server + admin) with hero_proc. Those children were being spawned with only RUST_LOG set, so when herolib_core tried to resolve paths (PATH_ROOT, PATH_VAR, etc.) the daemon panicked at startup.

Added a small helper in crates/mycelium_cli/src/self_register.rs that forwards PATH_ROOT, PATH_VAR, PATH_BUILD, PATH_CODE, and HERO_SOCKET_DIR into both spawned actions if they're set in the calling shell. Same pattern used in hero_voice/main.rs.

4. Declare PATH_ROOT in each daemon's service.toml

When daemons are started via lab service <name> --start (instead of via the CLI orchestrator), the env block in service.toml is what gets forwarded into the spawned process. Added:

[[env]]
var     = "PATH_ROOT"
default = "~/hero"
desc    = "Hero install root..."

to mycelium_server, mycelium_admin, mycelium_server_msg, and mycelium_server_private. Without this, those daemons panic on startup under lab service supervision with PATH_VAR is not set.

5. Bump herolib_core pin in Cargo.lock

cargo update -p herolib_core — moves the pin from 3ff281d8 to 33b5a3fb. The new pin includes a fallback in herolib_core that derives PATH_VAR, PATH_BUILD, and PATH_CODE from PATH_ROOT when they aren't set explicitly. Without this update, even with PATH_ROOT correctly threaded through (changes 3 + 4 above), daemons still panic on missing PATH_VAR. With the update, setting just PATH_ROOT is enough.

What I verified

  • cargo build --workspace --release — works on a clean checkout. Before this PR it fails at the workspace manifest step.
  • lab build --release --install — 5/5 binaries built and installed.
  • mycelium_admin started cleanly and responded to:
    • GET /health{"service":"mycelium","status":"ok","version":"0.7.5"}
    • GET /.well-known/heroservice.json → canonical JSON
  • Confirmed the spawned daemon's env contains PATH_ROOT=... (i.e. change 3 is actually working end-to-end).
  • mycelium_server started, bound its UDS socket, loaded state, created the router — then hit Address already in use (os error 98) on TCP 9651 because my workstation already runs a legacy /usr/local/bin/mycelium daemon on those ports. That's a workstation issue, not a code issue, and a clean reviewer box should make it past the bind.

Tests

  • 31 unit tests pass across all crates except mycelium_sdk and mycelium_e2e.
  • mycelium_e2e/tests/three_node_linux.rs (4 tests) hit the same TCP 9651 conflict as above. Should pass on a box without the legacy daemon running.
  • mycelium_sdk lib test compile fails on Rust 2024 marking std::env::set_var/remove_var as unsafe:
    • crates/mycelium_sdk/src/lib.rs:79,82git blame shows both lines were authored in commit 161f06ef on 2026-04-18, before this PR. Latent since the workspace adopted edition 2024. Trivial fix (wrap the test body in unsafe { ... }), but I'm leaving it out of this PR to keep the scope tight. Happy to fold it in if you prefer.

Before this PR, cargo test --workspace couldn't compile at all because of the broken path dep in change 1, so these test-side issues weren't visible.

## What this PR changes Five small fixes to `mycelium_network` so it builds and runs cleanly on a fresh checkout. ### 1. Fix broken `hero_admin_lib` dep `crates/mycelium_admin/Cargo.toml` had a path dep pointing at `../../../hero_website_framework/...` — that path only resolves if `hero_website_framework` happens to be cloned as a sibling directory of `mycelium_network`. On most clones it doesn't exist, and `cargo build --workspace` fails at the manifest step before any code compiles. Switched it to the git dep used by `hero_voice` and the other consumers: ```toml hero_admin_lib = { version = "0.1.0", git = "https://forge.ourworld.tf/lhumina_code/hero_website_framework.git", branch = "development" } ``` ### 2. Use workspace dep for `herolib_core` in `mycelium_admin` The other four crates declare `herolib_core = { workspace = true }`. `mycelium_admin` had its own standalone git ref. Flipped it to match — one place to bump the version going forward. ### 3. Forward Hero env vars when CLI spawns the daemons `mycelium_cli --start` registers two child processes (server + admin) with `hero_proc`. Those children were being spawned with only `RUST_LOG` set, so when `herolib_core` tried to resolve paths (`PATH_ROOT`, `PATH_VAR`, etc.) the daemon panicked at startup. Added a small helper in `crates/mycelium_cli/src/self_register.rs` that forwards `PATH_ROOT`, `PATH_VAR`, `PATH_BUILD`, `PATH_CODE`, and `HERO_SOCKET_DIR` into both spawned actions if they're set in the calling shell. Same pattern used in `hero_voice/main.rs`. ### 4. Declare `PATH_ROOT` in each daemon's `service.toml` When daemons are started via `lab service <name> --start` (instead of via the CLI orchestrator), the env block in `service.toml` is what gets forwarded into the spawned process. Added: ```toml [[env]] var = "PATH_ROOT" default = "~/hero" desc = "Hero install root..." ``` to `mycelium_server`, `mycelium_admin`, `mycelium_server_msg`, and `mycelium_server_private`. Without this, those daemons panic on startup under `lab service` supervision with `PATH_VAR is not set`. ### 5. Bump `herolib_core` pin in `Cargo.lock` `cargo update -p herolib_core` — moves the pin from `3ff281d8` to `33b5a3fb`. The new pin includes a fallback in `herolib_core` that derives `PATH_VAR`, `PATH_BUILD`, and `PATH_CODE` from `PATH_ROOT` when they aren't set explicitly. Without this update, even with `PATH_ROOT` correctly threaded through (changes 3 + 4 above), daemons still panic on missing `PATH_VAR`. With the update, setting just `PATH_ROOT` is enough. ## What I verified - `cargo build --workspace --release` — works on a clean checkout. Before this PR it fails at the workspace manifest step. - `lab build --release --install` — 5/5 binaries built and installed. - `mycelium_admin` started cleanly and responded to: - `GET /health` → `{"service":"mycelium","status":"ok","version":"0.7.5"}` - `GET /.well-known/heroservice.json` → canonical JSON - Confirmed the spawned daemon's env contains `PATH_ROOT=...` (i.e. change 3 is actually working end-to-end). - `mycelium_server` started, bound its UDS socket, loaded state, created the router — then hit `Address already in use (os error 98)` on TCP 9651 because my workstation already runs a legacy `/usr/local/bin/mycelium` daemon on those ports. That's a workstation issue, not a code issue, and a clean reviewer box should make it past the bind. ## Tests - 31 unit tests pass across all crates except `mycelium_sdk` and `mycelium_e2e`. - `mycelium_e2e/tests/three_node_linux.rs` (4 tests) hit the same TCP 9651 conflict as above. Should pass on a box without the legacy daemon running. - `mycelium_sdk` lib test compile fails on Rust 2024 marking `std::env::set_var`/`remove_var` as `unsafe`: - `crates/mycelium_sdk/src/lib.rs:79,82` — `git blame` shows both lines were authored in commit `161f06ef` on 2026-04-18, **before** this PR. Latent since the workspace adopted edition 2024. Trivial fix (wrap the test body in `unsafe { ... }`), but I'm leaving it out of this PR to keep the scope tight. Happy to fold it in if you prefer. Before this PR, `cargo test --workspace` couldn't compile at all because of the broken path dep in change 1, so these test-side issues weren't visible.
Reaches the 35/35 target for the hero_proc#102 workspace D-10 sweep. Pre-existing
build break + 3 latent gaps surface and are closed in one commit.

Fixes
-----

1. `crates/mycelium_admin/Cargo.toml`
   - hero_admin_lib: path dep `../../../hero_website_framework/...` was broken on
     any checkout where geomind_code/ and lhumina_code/ aren't peers. Flipped to
     the canonical git dep used by hero_voice / hero_planner (origin tip
     branch=development). Unblocks `cargo build --workspace` on a clean clone.
   - herolib_core: now uses `{ workspace = true }` like the other 4 crates,
     instead of a standalone git ref that drifted independently.

2. `crates/mycelium_cli/src/self_register.rs` (Lesson #19)
   Adds `forward_env_if_set` for `PATH_ROOT/PATH_VAR/PATH_BUILD/PATH_CODE/HERO_SOCKET_DIR`
   on both spawned ActionSpecs (mycelium_server + mycelium_admin). hero_proc spawns
   daemons with a clean env, so the daemon's `herolib_core::base` path-resolution
   chain must be threaded explicitly. Same pattern as hero_voice/main.rs:75–92.

3. `crates/mycelium_{server,admin,server_msg,server_private}/service.toml`
   Added `[[env]] PATH_ROOT default="~/hero"` block. Required by the
   `lab service <bin> --start` spawn path: lab forwards the [[env]] block into
   the spawned action's env, satisfying `herolib_core::base::paths::path_root()`
   at daemon startup (Lesson #17, from s107 hero_foundry onward).

4. `Cargo.lock` — `cargo update -p herolib_core` (3ff281d8 → 33b5a3fb)
   The pinned version (3ff281d8) is **before** hero_lib commit `30a0b34e` which
   added the `PATH_VAR/PATH_BUILD/PATH_CODE` derivation fallback from `PATH_ROOT`.
   Without this update, daemons panic at `paths.rs:46` with
   `PATH_VAR is not set — re-install your environment` even when `PATH_ROOT` is
   correctly injected via the [[env]] block, because path_var() did not yet have
   the fallback. New pin (33b5a3fb) is the workspace-wide cascade head (= s124
   D-11 closure across hero_lib/hero_rpc).

D-10 acceptance (hero_proc#102)
-------------------------------

1. service.toml valid for all 5 crates (mycelium_server, mycelium_admin,
   mycelium_cli, mycelium_server_msg, mycelium_server_private) — canonical
   [service] + [[binaries]] + [[binaries.sockets]] (path + protocol) + valid
   `category` enum (network / ui / tool) + `[[env]] PATH_ROOT default="~/hero"`
   on the 4 daemons.
2. `service_base!()` macro applied in all 5 main.rs (verified pre-existing in
   `9905e48 refactor: migrate socket/state path resolution to herolib_core::base
   helpers`); `validate_service_toml` + `handle_info_flag` + (daemons)
   `print_startup_banner` + `prepare_sockets` triad confirmed.
3. `lab build --release --install --policy-mode warn` — 5/5 built clean.
4. `lab infocheck` — 5 crates clean / 0 findings.
5. Smoke validation:
   - mycelium_admin lab service smoke: 2/2 ✓
     (rpc + admin.sock /health 200 + /.well-known/heroservice.json 200)
   - mycelium_admin /proc/<pid>/environ confirms PATH_ROOT=/home/pctwo/hero
     threaded into the lab-spawned daemon — Lesson #19 verified end-to-end.
   - mycelium_server lab service smoke: daemon advances past PATH_VAR resolution,
     binds rpc.sock at `~/hero/var/sockets/mycelium/rpc.sock`, loads state, creates
     Router successfully, then fails with `Address already in use (os error 98)` on
     the TCP underlay port 9651 due to a workstation-side legacy
     `/usr/local/bin/mycelium` daemon (root-owned, ppid 1) occupying ports
     8989/8990/9651. This is a workstation-environmental conflict, not a code
     regression — the reviewer's clean box should pass smoke 4/4.

cargo test --workspace --release
--------------------------------

- 31 tests passed across all crates except mycelium_sdk and mycelium_e2e.
- 4 mycelium_e2e tests (three_node_linux) fail with the same TCP-port collision
  as mycelium_server above: spawned mycelium_server children cannot bind 9651
  because of the legacy system daemon. Reproduced in isolation with explicit
  MYCELIUM_STATE_DIR + HERO_SOCKET_DIR — daemon binds rpc.sock, loads state, then
  panics on `Address already in use`. Environmental, will pass on clean box.
- 1 mycelium_sdk lib test compile failure (NOT introduced by this commit):
  `crates/mycelium_sdk/src/lib.rs:79,82` — `std::env::set_var/remove_var` are
  marked unsafe under Rust 2024 (E0133). `git blame` shows both lines authored by
  @kristof5 in commit `161f06ef` on 2026-04-18, latent on `development_crate_layout`
  since the workspace adopted edition 2024. Wrap-in-unsafe block is the trivial
  fix; out of D-10 scope (separate test-only cleanup).

Branch policy
-------------

PR target is `development_crate_layout` per mycelium_network#46 (current default
dev branch on this repo, NOT `development` like the lhumina_code/* repos).
mik-tf changed title from chore(d10): hero_proc#102 D-10 closure — env forwarding, env block, broken dep, herolib_core cascade to Fix fresh-checkout build + daemon startup under hero_proc supervision 2026-05-19 18:04:46 +00:00
mik-tf merged commit 9abc843c2f into development_crate_layout 2026-05-19 18:05:19 +00:00
Sign in to join this conversation.
No reviewers
No labels
Urgent
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
geomind_code/mycelium_network!48
No description provided.