feat(services): add service_biz.nu #89

Merged
mahmoud merged 1 commit from development_service_biz into development 2026-04-19 21:05:45 +00:00
Owner

Summary

Adds tools/modules/services/service_biz.nu, a lifecycle module for the hero_biz service (server + UI) with install | start | stop | status subcommands. Mirrors the Rust build_service_definition() at hero_biz/crates/hero_biz/src/main.rs:93-179. Three patterns new to the family, all called out in the module header.

Changes

  • tools/modules/services/service_biz.nu — new module (~388 lines). Registers hero_biz (server) and hero_biz_ui as hero_proc actions plus the hero_biz service.
  • tools/modules/services/mod.nu — add export use service_biz.nu.

--root optional on every command; user-level default.

Patterns new to the family (all in the module header)

  1. Server action name = hero_biz, NOT hero_biz_server. First service where the server action drops the _server suffix. Source of truth is the Rust build_service_definition() at main.rs:103.

  2. TOML misleading. hero_zero/services/hero_biz.toml declares only [server] but the CLI's self_start() registers both hero_biz and hero_biz_ui. The nu module is the authoritative record.

  3. Multi-dep preflight. TOML depends_on = ["hero_osis_identity", "hero_proxy_ui"]. svx_check_osis_identity warns (does not fail) on missing identity socket. hero_proxy_ui gets no preflight — grep confirms no code path in hero_biz/ reads from a proxy_ui socket; UIs are surfaced through hero_router's socket discovery as a deployment-level concern, not a boot-time dep.

Env wiring

UI action env (verbatim from TOML [env] block, UI-only consumers):

  • RUST_LOG=info
  • BASE_PATH=/hero_biz/ui
  • HERO0_BASE_URL=http://127.0.0.1:6666/hero_osis/ui

Server action env: RUST_LOG=info only. The Rust source sets nothing else on the server action — BASE_PATH and HERO0_BASE_URL are read only by hero_biz_ui (verified via grep: crates/hero_biz_ui/src/web/server.rs:89, .../hero0/mod.rs:93, .../services/mod.rs:36,50; zero hits in crates/hero_biz/).

The HERO0_BASE_URL brittleness (hardcoded 127.0.0.1:6666 loopback TCP) is documented in the module header as a future follow-up once service_osis.nu lands and exposes a discovery path.

Health policy divergences

Mirrored from Rust, not prior nu conventions:

  • Server health: start_period_ms: 5000 (prior services used 3000).
  • UI health: interval_ms: 2000 (prior UI actions used 3000).
  • UI stop_timeout_ms: 5000 (book/whiteboard used 5000 too; consistent).

Test Results

End-to-end smoke test on the Hetzner box (under flock to serialize with the parallel agent's voice test). 13/15 PASS. 2 FAIL are upstream placeholder-backend issues, not module bugs.

# Assertion Result
1a–1c hero_proc-down error paths PASS
2a service_proc start --root healthy PASS
2b service_biz install --root produced 2 binaries PASS
2c service_biz start --reset --root — osis_identity preflight fired, both actions registered, summary shows base path + hero0 url PASS
2d rpc.sock is a live socket FAIL (upstream) — hero_biz backend is a placeholder
2e ui.sock is a live socket PASS
2f curl --unix-socket rpc.sock accepts HTTP FAIL (upstream) — no server to talk to
2g curl --unix-socket ui.sock accepts HTTP PASS
2h status returns {name: hero_biz, state: running, restarts: 0} PASS
2i-A UI action env BASE_PATH = /hero_biz/ui PASS (verified via proc action get hero_biz_ui --root)
2i-B UI action env HERO0_BASE_URL set PASS
2j Server action registered as name hero_biz (no _server suffix) PASS
2k Idempotent start prints "already running" PASS
2l 15 s observation — no new restarts, state held running PASS
2m stop unregisters cleanly PASS
2n Post-stop status returns service 'hero_biz' not found PASS

Notes on the 2d / 2f FAILs

hero_biz's run_server() at crates/hero_biz/src/main.rs:183-207 is explicitly a placeholder:

tracing::info!("hero_biz backend — placeholder (not yet implemented)");
tokio::signal::ctrl_c().await?;

The server process runs and waits for ctrl_c but never binds rpc.sock — it only creates the parent directory and removes any stale socket file. The module is correct: the action spec matches the Rust build_service_definition() exactly, including the socket path. When the hero_biz backend is implemented upstream, the RPC side will light up automatically without any change here. Out of scope for this PR.

Full per-step output on issue #86.

## Summary Adds `tools/modules/services/service_biz.nu`, a lifecycle module for the `hero_biz` service (server + UI) with `install | start | stop | status` subcommands. Mirrors the Rust `build_service_definition()` at `hero_biz/crates/hero_biz/src/main.rs:93-179`. Three patterns new to the family, all called out in the module header. ## Related - Closes #86 - Part of #75 ## Changes - `tools/modules/services/service_biz.nu` — new module (~388 lines). Registers `hero_biz` (server) and `hero_biz_ui` as hero_proc actions plus the `hero_biz` service. - `tools/modules/services/mod.nu` — add `export use service_biz.nu`. `--root` optional on every command; user-level default. ### Patterns new to the family (all in the module header) 1. **Server action name = `hero_biz`, NOT `hero_biz_server`.** First service where the server action drops the `_server` suffix. Source of truth is the Rust `build_service_definition()` at `main.rs:103`. 2. **TOML misleading.** `hero_zero/services/hero_biz.toml` declares only `[server]` but the CLI's `self_start()` registers both `hero_biz` and `hero_biz_ui`. The nu module is the authoritative record. 3. **Multi-dep preflight.** TOML `depends_on = ["hero_osis_identity", "hero_proxy_ui"]`. `svx_check_osis_identity` warns (does not fail) on missing identity socket. `hero_proxy_ui` gets no preflight — grep confirms no code path in `hero_biz/` reads from a proxy_ui socket; UIs are surfaced through hero_router's socket discovery as a deployment-level concern, not a boot-time dep. ### Env wiring UI action env (verbatim from TOML `[env]` block, UI-only consumers): - `RUST_LOG=info` - `BASE_PATH=/hero_biz/ui` - `HERO0_BASE_URL=http://127.0.0.1:6666/hero_osis/ui` Server action env: `RUST_LOG=info` only. The Rust source sets nothing else on the server action — `BASE_PATH` and `HERO0_BASE_URL` are read only by `hero_biz_ui` (verified via grep: `crates/hero_biz_ui/src/web/server.rs:89`, `.../hero0/mod.rs:93`, `.../services/mod.rs:36,50`; zero hits in `crates/hero_biz/`). The `HERO0_BASE_URL` brittleness (hardcoded `127.0.0.1:6666` loopback TCP) is documented in the module header as a future follow-up once `service_osis.nu` lands and exposes a discovery path. ## Health policy divergences Mirrored from Rust, not prior nu conventions: - Server health: `start_period_ms: 5000` (prior services used 3000). - UI health: `interval_ms: 2000` (prior UI actions used 3000). - UI `stop_timeout_ms: 5000` (book/whiteboard used 5000 too; consistent). ## Test Results End-to-end smoke test on the Hetzner box (under `flock` to serialize with the parallel agent's voice test). 13/15 PASS. 2 FAIL are **upstream placeholder-backend issues**, not module bugs. | # | Assertion | Result | |---|---|---| | 1a–1c | hero_proc-down error paths | PASS | | 2a | `service_proc start --root` healthy | PASS | | 2b | `service_biz install --root` produced 2 binaries | PASS | | 2c | `service_biz start --reset --root` — osis_identity preflight fired, both actions registered, summary shows `base path` + `hero0 url` | PASS | | 2d | `rpc.sock` is a live socket | **FAIL (upstream)** — hero_biz backend is a placeholder | | 2e | `ui.sock` is a live socket | PASS | | 2f | `curl --unix-socket rpc.sock` accepts HTTP | **FAIL (upstream)** — no server to talk to | | 2g | `curl --unix-socket ui.sock` accepts HTTP | PASS | | 2h | `status` returns `{name: hero_biz, state: running, restarts: 0}` | PASS | | 2i-A | UI action env `BASE_PATH = /hero_biz/ui` | PASS (verified via `proc action get hero_biz_ui --root`) | | 2i-B | UI action env `HERO0_BASE_URL` set | PASS | | 2j | Server action registered as name `hero_biz` (no `_server` suffix) | PASS | | 2k | Idempotent `start` prints "already running" | PASS | | 2l | 15 s observation — no new restarts, state held `running` | PASS | | 2m | `stop` unregisters cleanly | PASS | | 2n | Post-stop `status` returns `service 'hero_biz' not found` | PASS | ### Notes on the 2d / 2f FAILs `hero_biz`'s `run_server()` at `crates/hero_biz/src/main.rs:183-207` is explicitly a placeholder: ```rust tracing::info!("hero_biz backend — placeholder (not yet implemented)"); tokio::signal::ctrl_c().await?; ``` The server process runs and waits for ctrl_c but **never binds `rpc.sock`** — it only creates the parent directory and removes any stale socket file. The module is correct: the action spec matches the Rust `build_service_definition()` exactly, including the socket path. When the hero_biz backend is implemented upstream, the RPC side will light up automatically without any change here. Out of scope for this PR. Full per-step output on issue #86.
Add a service_biz module that provides install | start | stop | status
lifecycle commands for hero_biz (hero_biz + hero_biz_ui) through
hero_proc. Mirrors the Rust build_service_definition() at
hero_biz/crates/hero_biz/src/main.rs:93-179.

Three patterns new to the family, documented in the module:

- Server action name is hero_biz, NOT hero_biz_server. First service
  where the server action drops the _server suffix. Source of truth is
  the Rust build_service_definition at main.rs:103.

- TOML misleading: hero_zero/services/hero_biz.toml declares only
  [server] but the CLI's self_start() registers BOTH hero_biz and
  hero_biz_ui. The nu module is the authoritative record of this.

- Multi-dep preflight: TOML depends_on lists hero_osis_identity +
  hero_proxy_ui. svx_check_osis_identity warns (does not fail) when
  the identity socket is absent; hero_proxy_ui gets no preflight
  because no code path in hero_biz reads from a proxy_ui socket.

UI action env wires BASE_PATH=/hero_biz/ui and HERO0_BASE_URL=
http://127.0.0.1:6666/hero_osis/ui verbatim from the TOML — both
are UI-only (grep confirms zero reads in crates/hero_biz/). Server
action env stays on RUST_LOG only, matching the Rust source.

HERO0_BASE_URL brittleness (hardcoded loopback TCP) is documented in
the module header as a future follow-up once service_osis.nu lands.

#86
#75
mahmoud merged commit fb108281c2 into development 2026-04-19 21:05:45 +00:00
mahmoud deleted branch development_service_biz 2026-04-19 21:05:50 +00:00
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_skills!89
No description provided.