OServer::run_cli ignores service.toml socket paths — falls back to defaults #69

Closed
opened 2026-05-19 15:30:38 +00:00 by timur · 1 comment
Owner

Context

Discovered by the #261 agent while bootstrapping hero_service.

The generated _server main.rs calls OServer::run_cli(lifecycle, ...) which is supposed to honor the socket path declared in the embedded service.toml. In practice it falls back to the default-derived path (HERO_SOCKET_DIR / service_name / rpc.sock), ignoring any custom path specified under [[binaries.sockets]].

For the standard case the result is fine (because the default matches the convention), but a service that legitimately needs a non-default socket path can't get it.

What to do

  • Trace OServer::run_cli socket resolution in hero_rpc/crates/server/.
  • Make it read the service.toml socket entry first and only fall back to the default if not set.
  • Add a test fixture with a non-default socket path and verify the server binds at the declared path.

Acceptance

  • Generated services with custom path in [[binaries.sockets]] bind at the declared path.
  • Default-case behaviour unchanged.
## Context Discovered by the [#261 agent](https://forge.ourworld.tf/lhumina_code/hero_skills/issues/261#issuecomment-34264) while bootstrapping `hero_service`. The generated `_server` `main.rs` calls `OServer::run_cli(lifecycle, ...)` which is supposed to honor the socket path declared in the embedded `service.toml`. In practice it falls back to the default-derived path (HERO_SOCKET_DIR / service_name / rpc.sock), ignoring any custom `path` specified under `[[binaries.sockets]]`. For the standard case the result is fine (because the default matches the convention), but a service that legitimately needs a non-default socket path can't get it. ## What to do - Trace `OServer::run_cli` socket resolution in `hero_rpc/crates/server/`. - Make it read the `service.toml` socket entry first and only fall back to the default if not set. - Add a test fixture with a non-default socket path and verify the server binds at the declared path. ## Acceptance - Generated services with custom `path` in `[[binaries.sockets]]` bind at the declared path. - Default-case behaviour unchanged. ## Related - [hero_skills#261](https://forge.ourworld.tf/lhumina_code/hero_skills/issues/261). - Parent META: [hero_skills#262](https://forge.ourworld.tf/lhumina_code/hero_skills/issues/262).
Author
Owner

Fix on issue-69-oserver-socket-paths

Three commits (compare):

  1. fix(server)8617118 — core fix.
  2. test(server)17687b6 — integration test in crates/server/tests/run_cli_socket_path.rs.
  3. chore(example)564c4de — opt the recipe_server example into the new resolution.

Root cause

OServer::run_cli constructed an OServerConfig only with the lifecycle's service_name and bound at config.rpc_socket(&config.name)$HERO_SOCKET_DIR/<service_name>/rpc.sock. It never read service.toml, so a binary like petstore_server declaring path = "hero_petstore/rpc.sock" was silently bound at petstore_server/rpc.sock instead.

print_info_json had the same bug — the --info JSON descriptor reported the default path, not the declared one.

Fix

  • New HeroLifecycle::service_toml(toml_str) builder — attach the embedded manifest to the lifecycle.
  • New OServerConfig::rpc_socket_relative(rel) builder — override the rpc socket path.
  • OServer::run_cli now parses the attached service.toml, finds the rpc socket entry (SockType::Rpc) for the matching binary, and propagates path as the override. Falls back gracefully when no manifest is attached or no rpc socket is declared.
  • print_info_json uses the same resolution.
  • Resolution is fully unit-tested in crates/server/src/server/server.rs and end-to-end in the new integration test.

Acceptance

  • Generated services with custom path in [[binaries.sockets]] bind at the declared path (validated by rpc_socket_path_resolution::Case 1, plus a live rpc.health request).
  • Default-case behaviour unchanged (validated by rpc_socket_path_resolution::Case 2).
  • All existing tests pass (cargo test -p hero_rpc_server -p hero_lifecycle: 21 + 8 + 1 + doctests, all green).
### Fix on `issue-69-oserver-socket-paths` Three commits ([compare](https://forge.ourworld.tf/lhumina_code/hero_rpc/compare/development...issue-69-oserver-socket-paths)): 1. **`fix(server)`** — `8617118` — core fix. 2. **`test(server)`** — `17687b6` — integration test in `crates/server/tests/run_cli_socket_path.rs`. 3. **`chore(example)`** — `564c4de` — opt the `recipe_server` example into the new resolution. ### Root cause `OServer::run_cli` constructed an `OServerConfig` only with the lifecycle's `service_name` and bound at `config.rpc_socket(&config.name)` → `$HERO_SOCKET_DIR/<service_name>/rpc.sock`. It never read `service.toml`, so a binary like `petstore_server` declaring `path = "hero_petstore/rpc.sock"` was silently bound at `petstore_server/rpc.sock` instead. `print_info_json` had the same bug — the `--info` JSON descriptor reported the default path, not the declared one. ### Fix - New `HeroLifecycle::service_toml(toml_str)` builder — attach the embedded manifest to the lifecycle. - New `OServerConfig::rpc_socket_relative(rel)` builder — override the rpc socket path. - `OServer::run_cli` now parses the attached `service.toml`, finds the rpc socket entry (`SockType::Rpc`) for the matching binary, and propagates `path` as the override. Falls back gracefully when no manifest is attached or no rpc socket is declared. - `print_info_json` uses the same resolution. - Resolution is fully unit-tested in `crates/server/src/server/server.rs` and end-to-end in the new integration test. ### Acceptance - ✅ Generated services with custom `path` in `[[binaries.sockets]]` bind at the declared path (validated by `rpc_socket_path_resolution::Case 1`, plus a live `rpc.health` request). - ✅ Default-case behaviour unchanged (validated by `rpc_socket_path_resolution::Case 2`). - ✅ All existing tests pass (`cargo test -p hero_rpc_server -p hero_lifecycle`: 21 + 8 + 1 + doctests, all green).
timur closed this issue 2026-05-20 05:55:09 +00:00
Sign in to join this conversation.
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
lhumina_code/hero_blueprint#69
No description provided.