feat(service_manager v2): code-not-data per-service Rust modules (closes #90) #92

Closed
mik-tf wants to merge 3 commits from development_mik_service_manager_v2 into development
Owner

Closes #90.

Supersedes #91, which built a ServiceDefinition schema + interpreter — Kristof flagged that as too rigid (see #90 comment 30721). v2 implements his preferred design: each service is Rust code that uses hero_proc_sdk plus shared helpers directly. Same model as the existing nu modules under hero_skills, in Rust.

Comprehensive handoff at #90 comment 30802 — read that first if continuing this work.

Architecture

Third UDS under $HERO_SOCKET_DIR/hero_router/:

hero_router/
├── rpc.sock        ← existing: router.* JSON-RPC
├── ui.sock         ← existing: admin dashboard
└── service.sock    ← service.* JSON-RPC (new)

HeroService trait — minimal:

  • Identity: name / forge_loc / description / binaries
  • Required: install / start / stop
  • Defaulted: restart / health / status / verify / delete / upgrade

Each services/<name>.rs is a self-contained Rust module that calls hero_proc_sdk::ServiceBuilder + ActionBuilder directly, plus shared helpers from service_manager::lib. No schema, no interpreter.

Coverage — 33 services

Aligned to hero_skills@371138f convention (_ui_admin):

hero_agent, hero_aibroker, hero_biz, hero_books, hero_browser,
hero_claude, hero_code, code_indexer, hero_codescalers, hero_collab,
hero_compute, hero_db, hero_editor, hero_embedder, hero_foundry,
hero_indexer, hero_livekit, hero_logic, hero_mail, hero_matrixchat,
hero_office, hero_os, hero_osis, hero_planner, hero_proxy,
hero_router, hero_runner_rhai, hero_shrimp, hero_slides, hero_voice,
hero_wallet, hero_whiteboard, mycelium

Documented exclusions (in services/mod.rs): hero_proc (circular), hero_onlyoffice (Docker — tracked at #98), hero_do (installer-only), service_core.nu (empty meta).

Workspace gate

  • cargo fmt --check
  • cargo clippy -p hero_router --all-targets -- -D warnings
  • cargo build -p hero_router --release
  • cargo test -p hero_router119 tests (9 dispatcher e2e + 5 lib unit + 105 pre-existing)
  • All 105 pre-existing tests still pass — no regressions to existing hero_router features

Operational verification

  • hero_db v0.3.2 walked through full lifecycle (install → start → health 200 OK → stop) — see #90 comment 30763
  • ⚠️ The convention alignment (commit 92a947a) means --mode download will now fail for services whose published releases still ship _ui asset names. Source-build path works regardless.

Follow-up issues filed

# Topic
#93 LiveKit auto-bootstrap
#94 ONNX Runtime auto-install
#95 Cascade --split mother variant
#96 Multi-instance suffix support
#97 BindStrategy::Mycelium engine support
#98 Docker-action support
#99 FromHeroProcSecret resolver (low priority)
#100 Admin UI dashboard pane
#101 Per-service translation accuracy audit
#102 Deletion plan execution

Test plan

  • Compile + clippy + tests green
  • CLI surface (hero_router service --help) lists all 13 ops
  • hero_db v0.3.2 end-to-end smoke (pre-alignment commit)
  • Re-smoke each service after upstream releases ship _admin assets — tracked in #101
  • Heroci validation per feedback_no_direct_push_except_hero_demo.md — needs explicit go-ahead

Signed-off-by: mik-tf

Closes https://forge.ourworld.tf/lhumina_code/hero_router/issues/90. Supersedes [#91](https://forge.ourworld.tf/lhumina_code/hero_router/pulls/91), which built a `ServiceDefinition` schema + interpreter — Kristof flagged that as too rigid (see [#90 comment 30721](https://forge.ourworld.tf/lhumina_code/hero_router/issues/90#issuecomment-30721)). v2 implements his preferred design: each service is **Rust code** that uses `hero_proc_sdk` plus shared helpers directly. Same model as the existing nu modules under `hero_skills`, in Rust. **Comprehensive handoff at [#90 comment 30802](https://forge.ourworld.tf/lhumina_code/hero_router/issues/90#issuecomment-30802)** — read that first if continuing this work. ## Architecture Third UDS under `$HERO_SOCKET_DIR/hero_router/`: ``` hero_router/ ├── rpc.sock ← existing: router.* JSON-RPC ├── ui.sock ← existing: admin dashboard └── service.sock ← service.* JSON-RPC (new) ``` `HeroService` trait — minimal: - Identity: `name` / `forge_loc` / `description` / `binaries` - Required: `install` / `start` / `stop` - Defaulted: `restart` / `health` / `status` / `verify` / `delete` / `upgrade` Each `services/<name>.rs` is a self-contained Rust module that calls `hero_proc_sdk::ServiceBuilder` + `ActionBuilder` directly, plus shared helpers from `service_manager::lib`. No schema, no interpreter. ## Coverage — 33 services Aligned to [hero_skills@371138f](https://forge.ourworld.tf/lhumina_code/hero_skills/commit/371138f2d6ffc50803310db09282785bc8a439e5) convention (`_ui` → `_admin`): ``` hero_agent, hero_aibroker, hero_biz, hero_books, hero_browser, hero_claude, hero_code, code_indexer, hero_codescalers, hero_collab, hero_compute, hero_db, hero_editor, hero_embedder, hero_foundry, hero_indexer, hero_livekit, hero_logic, hero_mail, hero_matrixchat, hero_office, hero_os, hero_osis, hero_planner, hero_proxy, hero_router, hero_runner_rhai, hero_shrimp, hero_slides, hero_voice, hero_wallet, hero_whiteboard, mycelium ``` Documented exclusions (in `services/mod.rs`): `hero_proc` (circular), `hero_onlyoffice` (Docker — tracked at #98), `hero_do` (installer-only), `service_core.nu` (empty meta). ## Workspace gate - `cargo fmt --check` ✅ - `cargo clippy -p hero_router --all-targets -- -D warnings` ✅ - `cargo build -p hero_router --release` ✅ - `cargo test -p hero_router` — **119 tests** (9 dispatcher e2e + 5 lib unit + 105 pre-existing) ✅ - All 105 pre-existing tests still pass — no regressions to existing hero_router features ## Operational verification - ✅ `hero_db v0.3.2` walked through full lifecycle (install → start → health 200 OK → stop) — see [#90 comment 30763](https://forge.ourworld.tf/lhumina_code/hero_router/issues/90#issuecomment-30763) - ⚠️ The convention alignment (commit `92a947a`) means `--mode download` will now fail for services whose published releases still ship `_ui` asset names. Source-build path works regardless. ## Follow-up issues filed | # | Topic | |---|---| | [#93](https://forge.ourworld.tf/lhumina_code/hero_router/issues/93) | LiveKit auto-bootstrap | | [#94](https://forge.ourworld.tf/lhumina_code/hero_router/issues/94) | ONNX Runtime auto-install | | [#95](https://forge.ourworld.tf/lhumina_code/hero_router/issues/95) | Cascade `--split` mother variant | | [#96](https://forge.ourworld.tf/lhumina_code/hero_router/issues/96) | Multi-instance suffix support | | [#97](https://forge.ourworld.tf/lhumina_code/hero_router/issues/97) | `BindStrategy::Mycelium` engine support | | [#98](https://forge.ourworld.tf/lhumina_code/hero_router/issues/98) | Docker-action support | | [#99](https://forge.ourworld.tf/lhumina_code/hero_router/issues/99) | `FromHeroProcSecret` resolver (low priority) | | [#100](https://forge.ourworld.tf/lhumina_code/hero_router/issues/100) | Admin UI dashboard pane | | [#101](https://forge.ourworld.tf/lhumina_code/hero_router/issues/101) | Per-service translation accuracy audit | | [#102](https://forge.ourworld.tf/lhumina_code/hero_router/issues/102) | Deletion plan execution | ## Test plan - [x] Compile + clippy + tests green - [x] CLI surface (`hero_router service --help`) lists all 13 ops - [x] `hero_db v0.3.2` end-to-end smoke (pre-alignment commit) - [ ] Re-smoke each service after upstream releases ship `_admin` assets — tracked in #101 - [ ] Heroci validation per `feedback_no_direct_push_except_hero_demo.md` — needs explicit go-ahead Signed-off-by: mik-tf
feat(service_manager): code-not-data per-service Rust modules (closes #90)
All checks were successful
Build & Test / check (pull_request) Successful in 2m28s
23a8bcb542
Implements Kristof's redirection on
#90 — each Hero
service is Rust code that uses hero_proc_sdk + service_manager::lib
helpers directly, no schema or interpreter. Same model as the existing
nu modules under hero_skills, in Rust.

Architecture:

- service.sock (third UDS alongside rpc.sock / ui.sock) serves the
  service.* JSON-RPC namespace + own OpenRPC document.
- HeroService trait (service.rs) — minimal: name/forge_loc/description/
  binaries identity + install/start/stop required + restart/health/
  status/verify/delete/upgrade defaulted. Each service overrides only
  the methods that need quirks.
- service_manager::lib — Rust port of nu lib.nu primitives
  (install_download / install_source / place_binary / verify_elf /
  verify_fresh / probe_uds / hp_start_service / hp_stop_service / etc.)
- services/common.rs — build_server_action / build_ui_action helpers
  that collapse the standard "server+ui pair" boilerplate to ~30 lines
  per service.
- services/<name>.rs × 33 — each is a self-contained module that
  composes lib + ActionBuilder + ServiceBuilder however it needs.

Coverage (33 services), with documented exceptions:
- hero_proc — circular (manager is a hero_proc client)
- hero_onlyoffice — Docker; engine doesn't issue docker run yet
- hero_do — installer-only, no daemon
- service_core.nu — empty meta-module

CLI surface unchanged: hero_router service <op> wraps the JSON-RPC
dispatcher; same code path as the agent.

Workspace gate green: cargo fmt --check + clippy -D warnings + release
build + 119 tests (9 dispatcher e2e + 5 lib unit + 105 pre-existing).

What survives from the (closed) PR #91:
- service.sock + JSON-RPC dispatcher + Axum router (rpc.rs)
- ops_log ring buffer
- error enum + JSON-RPC error codes
- OpenRPC spec (static/service_manager.openrpc.json)
- Documentation (docs/service_manager/{README,migration,removal}.md)
- main.rs third-socket bind + service CLI subcommand
- CLAUDE.md third-socket entry

What's new in v2:
- HeroService trait (replaces ServiceDefinition struct + 7 enums)
- service_manager::lib (consolidated helpers, replaces
  build.rs + install.rs + lifecycle.rs + health.rs split)
- 33 per-service Rust modules (each is code, not a struct literal)
- common.rs helpers for the standard server+ui shape

Operationally unverified — issue #90 closing checklist still requires
live hero_proc smoke + heroci validation + per-service translation
audit. Tracked in #90.

Signed-off-by: mik-tf
fix(service_manager): hero_db socket paths match v0.3.2 runtime behaviour
All checks were successful
Build & Test / check (pull_request) Successful in 2m25s
5a904a3129
Local smoke (issue #90 comment 30763) found that hero_db v0.3.2 binds
sockets directly under \$HERO_SOCKET_DIR/ with flat naming
(hero_db_server.sock / hero_db_resp.sock / hero_db_ui.sock), NOT under
a per-service subdirectory like hero_db/rpc.sock as the upstream nu
module's kill_other listed.

After the fix:
  - install hero_db --mode download -> v0.3.2 fetched + ELF-verified
  - start hero_db                    -> sockets bound, supervisor running
  - health hero_db                   -> 200 OK, body shows v0.3.2
  - stop hero_db                     -> clean exit

This is exactly the kind of bug the v2 code-not-data design makes
trivial to fix — just edit the Rust function body, no schema extension.

Signed-off-by: mik-tf
align(service_manager): _ui → _admin per hero_skills@371138f convention
All checks were successful
Build & Test / check (pull_request) Successful in 3m11s
92a947add5
Upstream hero_skills did a sweeping rename:
  371138f2

Mirror it in v2 service ports — _ui binaries / actions / sockets all
become _admin. Affected files: every per-service module that had a
"_ui" admin action (29 of 33).

Special cases:
  - hero_collab — server + web (was _ui, but canonical is _web — reverted my
    smoke-driven misfix).
  - hero_shrimp — server + web + admin (3 actions per canonical, was 2).
  - hero_planner — server (bare) + admin + web (3 actions).
  - hero_db — reverted the flat-socket convention I introduced last commit;
    canonical uses subdir convention (hero_db/admin.sock).
  - hero_mail — hero_mail_cli renamed to hero_mail; _ui → _admin.
  - hero_books — deduped binaries list (the rename collapses _ui and the
    pre-existing _admin dev binary into one).
  - hero_router — keeps its OWN ui.sock (admin dashboard socket). Not a
    rename target; refers to hero_router itself, not a managed service.
  - hero_code — keeps _web (no _admin in canonical).

Note: published Forgejo releases for some services still ship the
pre-rename _ui asset names (e.g. hero_db v0.3.2). Download path will fail
for those services until upstream cuts new releases with the renamed
assets. Source build path works regardless.

Workspace gate green: cargo fmt --check + clippy -D warnings + release
build + 119 tests still pass.

Signed-off-by: mik-tf
despiegk closed this pull request 2026-05-08 05:06:09 +00:00
All checks were successful
Build & Test / check (pull_request) Successful in 3m11s

Pull request closed

Sign in to join this conversation.
No reviewers
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_router!92
No description provided.