[nu-demo] hero_osis_ui stuck at 'Loading service spec...' — no /api/services route, per-domain discovery never completes #175

Closed
opened 2026-04-24 16:08:13 +00:00 by mik-tf · 1 comment
Owner

Symptom

Clicking the OSIS island in herodemo's dock loads the Hero OSIS Admin UI iframe but it hangs permanently on:

Loading service spec...

Left sidebar shows Types: Loading... also stuck.

Root cause

hero_osis_ui (the dashboard admin UI) was designed in the monolithic-hero_osis era to talk to a single OpenRPC endpoint that served ALL the types. In the nu-shell era, hero_osis is split into 17 per-domain servers (hero_osis_business, hero_osis_calendar, hero_osis_code, etc.) each with its own rpc.sock.

The admin UI's JS (dashboard.js) calls discoverRootTypes() + discoverServiceMethods() against what it expects is a single aggregator, but hero_osis_ui/src/lib.rs registers no /api/services route — only /health, /.well-known/heroservice.json, /api/stats, /config/env, /, static assets. No aggregation layer exists.

sockets/ on the VM clearly shows the per-domain split:

hero_osis
hero_osis_base
hero_osis_business
hero_osis_calendar
hero_osis_code
hero_osis_communication
hero_osis_files
hero_osis_finance
hero_osis_identity
hero_osis_job
hero_osis_ledger
hero_osis_media
hero_osis_network
hero_osis_projects
hero_osis_settings

Each per-domain socket works fine on its own (direct curl --unix-socket hero_osis_business/rpc.sock ... returns the business OpenRPC spec). But there's no /api/services endpoint that returns the union.

Fix proposals

1. Add an aggregation route to hero_osis_ui

/api/services returns [{name, description, openrpc_url, domain}] — one entry per per-domain socket. Can be built on-startup by scanning $HERO_SOCKET_DIR/hero_osis_*/rpc.sock and fetching each's .well-known/heroservice.json. Then dashboard.js switches to per-service spec fetches.

2. Consolidate under hero_router

hero_router already does POST /mcp/{service_name} for every service it discovers — same pattern could power /hero_osis/ui/api/services by proxying from hero_router's service cache. Less code in hero_osis_ui.

3. Ship per-domain admin UIs separately

Each hero_osis_<domain> service gets its own admin UI iframe (or tab within a parent shell). Lists of dialogs per domain are the most useful view anyway. Deprecate the single-page aggregator UI.

Demo workaround

None applied — admin UI stuck loading. Per-domain data IS accessible via the Business island (which DOES work and shows Persons/Companies/Contacts/Deals), and via the AI Assistant (which can call tools that hit the per-domain sockets). The Admin UI specifically is the blocker.

  • home#130 — hero_osis_ai domain not registered (sibling per-domain registration issue)
  • home#160 — consolidated demo state

Signed-off-by: mik-tf

## Symptom Clicking the OSIS island in herodemo's dock loads the Hero OSIS Admin UI iframe but it hangs permanently on: ``` Loading service spec... ``` Left sidebar shows `Types: Loading...` also stuck. ## Root cause `hero_osis_ui` (the dashboard admin UI) was designed in the monolithic-hero_osis era to talk to a single OpenRPC endpoint that served ALL the types. In the nu-shell era, hero_osis is split into 17 per-domain servers (hero_osis_business, hero_osis_calendar, hero_osis_code, etc.) each with its own `rpc.sock`. The admin UI's JS (`dashboard.js`) calls `discoverRootTypes()` + `discoverServiceMethods()` against what it expects is a single aggregator, but `hero_osis_ui/src/lib.rs` registers no `/api/services` route — only `/health`, `/.well-known/heroservice.json`, `/api/stats`, `/config/env`, `/`, static assets. No aggregation layer exists. `sockets/` on the VM clearly shows the per-domain split: ``` hero_osis hero_osis_base hero_osis_business hero_osis_calendar hero_osis_code hero_osis_communication hero_osis_files hero_osis_finance hero_osis_identity hero_osis_job hero_osis_ledger hero_osis_media hero_osis_network hero_osis_projects hero_osis_settings ``` Each per-domain socket works fine on its own (direct `curl --unix-socket hero_osis_business/rpc.sock ...` returns the business OpenRPC spec). But there's no `/api/services` endpoint that returns the union. ## Fix proposals ### 1. Add an aggregation route to hero_osis_ui `/api/services` returns `[{name, description, openrpc_url, domain}]` — one entry per per-domain socket. Can be built on-startup by scanning `$HERO_SOCKET_DIR/hero_osis_*/rpc.sock` and fetching each's `.well-known/heroservice.json`. Then `dashboard.js` switches to per-service spec fetches. ### 2. Consolidate under hero_router hero_router already does `POST /mcp/{service_name}` for every service it discovers — same pattern could power `/hero_osis/ui/api/services` by proxying from hero_router's service cache. Less code in hero_osis_ui. ### 3. Ship per-domain admin UIs separately Each `hero_osis_<domain>` service gets its own admin UI iframe (or tab within a parent shell). Lists of dialogs per domain are the most useful view anyway. Deprecate the single-page aggregator UI. ## Demo workaround None applied — admin UI stuck loading. Per-domain data IS accessible via the Business island (which DOES work and shows Persons/Companies/Contacts/Deals), and via the AI Assistant (which can call tools that hit the per-domain sockets). The Admin UI specifically is the blocker. ## Related - [home#130](https://forge.ourworld.tf/lhumina_code/home/issues/130) — hero_osis_ai domain not registered (sibling per-domain registration issue) - [home#160](https://forge.ourworld.tf/lhumina_code/home/issues/160) — consolidated demo state Signed-off-by: mik-tf
Author
Owner

Moved to hero_demo#35 — see lhumina_code/hero_demo#35

Moved to hero_demo#35 — see https://forge.ourworld.tf/lhumina_code/hero_demo/issues/35
Sign in to join this conversation.
No labels
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/home#175
No description provided.