Migrate hero_logic onto hero_rpc2 (hero_rpc#90 Phase 3a) #47

Merged
timur merged 1 commit from issue-90-phase3-hero-logic into main 2026-05-20 23:32:28 +00:00
Owner

Most-complex OSIS service in the org migrated off OServer onto hero_rpc2. Smoke transcript in the commit body; here's the short version:

Surface Result
GET /health {status: ok, service: hero_logic, version: 0.1.0}
GET /.well-known/heroservice.json canonical shape, protocol=openrpc, socket=rpc
GET /openrpc.json 19 methods, title LogicService — matches docs/openrpc.json
POST /rpc rpc.health {status: ok, trusted: true}
POST /rpc workflow.list 15+ seeded workflow SIDs
POST /rpc logicservice.flow_library_search 3 hits
Built-in flow seed created service_agent cleanly, no -32601 warnings
lab infocheck 3 crates clean, 0 findings

Two framework gaps surfaced + closed before this PR opened

  • hero_rpc PR #99OpenRpcDocument::from_value (the same gap hero_service hit; merged).
  • hero_rpc PR #100rpc2_adapter lowercases service-method wire names. The seed code (and all existing OSIS clients) sends logicservice.example_upsert lowercase, but the adapter was registering the PascalCase LogicService.example_upsert from the openrpc spec verbatim. jsonrpsee does case-sensitive method match, so every seed call hit -32601. OServer used to lowercase before dispatch; the adapter now does the same at registration time. New test pins it.

Sibling-module preservation via @server-feature: marker (hero_rpc#93)

engine, seed, services, tracing_layer each carry the //! @server-feature: marker now. The build.rs's old lib.rs post-write override is gone — generator auto-discovery handles it. Confirmed by regen + diff: pub mod engine; pub mod seed; pub mod services; pub mod tracing_layer; reappear automatically.

Compat shim retained

hero_logic_sdk/src/local_client.rs still uses hero_rpc_derive::openrpc_client! (the legacy macro). It works against the new hero_rpc2 transport because both speak POST /rpc JSON-RPC over the same UDS. A small openrpc-title patch in build.rs ("LogicService - logic""LogicService") keeps the macro-derived identifiers stable across the colon-fix from #94. Both retirements are follow-up cleanups; not blocking #90.

local_client.rs users (hero_logic, hero_logic_admin)

Build clean — these still go through the legacy openrpc_client! macro which works fine over hero_rpc2's POST /rpc.

Most-complex OSIS service in the org migrated off OServer onto hero_rpc2. Smoke transcript in the commit body; here's the short version: | Surface | Result | |---|---| | `GET /health` | `{status: ok, service: hero_logic, version: 0.1.0}` | | `GET /.well-known/heroservice.json` | canonical shape, `protocol=openrpc`, `socket=rpc` | | `GET /openrpc.json` | **19 methods**, title `LogicService` — matches `docs/openrpc.json` | | `POST /rpc rpc.health` | `{status: ok, trusted: true}` | | `POST /rpc workflow.list` | 15+ seeded workflow SIDs | | `POST /rpc logicservice.flow_library_search` | 3 hits | | Built-in flow seed | created `service_agent` cleanly, **no -32601 warnings** | | `lab infocheck` | 3 crates clean, 0 findings | ### Two framework gaps surfaced + closed before this PR opened - [hero_rpc PR #99](https://forge.ourworld.tf/lhumina_code/hero_rpc/pulls/99) — `OpenRpcDocument::from_value` (the same gap hero_service hit; merged). - [hero_rpc PR #100](https://forge.ourworld.tf/lhumina_code/hero_rpc/pulls/100) — `rpc2_adapter` lowercases service-method wire names. The seed code (and all existing OSIS clients) sends `logicservice.example_upsert` lowercase, but the adapter was registering the PascalCase `LogicService.example_upsert` from the openrpc spec verbatim. jsonrpsee does case-sensitive method match, so every seed call hit `-32601`. OServer used to lowercase before dispatch; the adapter now does the same at registration time. New test pins it. ### Sibling-module preservation via `@server-feature:` marker (hero_rpc#93) `engine`, `seed`, `services`, `tracing_layer` each carry the `//! @server-feature:` marker now. The build.rs's old `lib.rs` post-write override is **gone** — generator auto-discovery handles it. Confirmed by regen + diff: `pub mod engine; pub mod seed; pub mod services; pub mod tracing_layer;` reappear automatically. ### Compat shim retained `hero_logic_sdk/src/local_client.rs` still uses `hero_rpc_derive::openrpc_client!` (the legacy macro). It works against the new hero_rpc2 transport because both speak `POST /rpc` JSON-RPC over the same UDS. A small openrpc-title patch in build.rs (`"LogicService - logic"` → `"LogicService"`) keeps the macro-derived identifiers stable across the colon-fix from #94. Both retirements are follow-up cleanups; not blocking #90. ### `local_client.rs` users (hero_logic, hero_logic_admin) Build clean — these still go through the legacy openrpc_client! macro which works fine over hero_rpc2's `POST /rpc`.
OServer is gone in hero_rpc#90 Phase 1; this PR moves hero_logic — the
most complex OSIS service in the org (19 hand-written logicservice
methods, 4 hand-written sibling modules, Python flow execution
engine) — onto the new path. Mirrors the recipe_server + hero_service
templates from earlier phases.

What changed
============

crates/hero_logic_server/src/main.rs (rewritten)
- Replaces OServer::run_cli with explicit lifecycle dispatch
  (--start / --stop / --info), prepare_sockets +
  print_startup_banner, jsonrpsee::RpcModule built via
  rpc2_adapter::register_methods, hero_rpc2::ServerBuilder driving
  the UDS HTTP transport.
- Embedded docs/openrpc.json piped through
  OpenRpcDocument::from_value + with_discover so GET /openrpc.json +
  rpc.discover return the canonical 19-method spec.
- Header lift configured for X-Hero-Context / X-Hero-Claims /
  X-Forwarded-Prefix (rpc2_adapter projects them into
  RequestContext).
- Built-in flow seeding moved inline post-bind — same self-loopback
  shape OServer used.
- Logger + Python tracing SDK staging + SIGINT/SIGTERM handler all
  preserved.

crates/hero_logic_server/src/{engine,seed.rs,services,tracing_layer.rs}
- All four pre-existing hand-written sibling modules carry the new
  `//! @server-feature:` marker (hero_rpc#93) so generator auto-
  discovery preserves them in `lib.rs` across regens.

crates/hero_logic_types/build.rs
- Dropped the entire post-write `lib.rs` override hack — replaced by
  @server-feature marker auto-discovery.
- Dropped the inject-servers-block patch — generator now emits it
  natively (#94).
- Kept a tiny title patch: `"LogicService - logic"` →
  `"LogicService"` so the legacy `openrpc_client!` macro derives
  `LogicServiceClient` rather than `LogicServiceLogicClient`. (The
  macro stays in `local_client.rs` until a follow-up retires it.)

crates/hero_logic_server/Cargo.toml
- hero_rpc_server → hero_rpc2 (uds-http / client / discover) +
  jsonrpsee.
- hero_rpc_osis pulls the `rpc` feature so the rpc2_adapter is in
  scope.

crates/hero_logic_sdk/{Cargo.toml,src/logic/}
- Added hero_rpc2 + jsonrpsee deps so the new
  `#[rpc(server, client)]` trait emitter in `src/logic.rs` compiles
  (the macro emits `::jsonrpsee::…` paths that need the crate in the
  consumer manifest).
- Deleted the legacy `src/logic/{mod,osis_client_generated,types}.rs`
  directory — replaced by the codegen-emitted `src/logic.rs` rpc2
  trait file. `local_client.rs` + `python_source.rs` stay as
  hand-written extras (preserved by SDK auto-discovery).

Workspace Cargo.toml
- hero_rpc_server workspace dep removed; hero_rpc2 added.
- hero_rpc_client / hero_rpc_openrpc / hero_rpc_derive kept (still
  needed by local_client.rs's openrpc_client! macro until follow-up).

Smoke results
=============
PATH_ROOT=$HOME/hero HERO_SOCKET_DIR=/tmp/hero_logic_smoke \
  ./target/debug/hero_logic_server

GET /health
  {service: hero_logic, status: ok, version: 0.1.0}
GET /.well-known/heroservice.json
  {protocol: openrpc, name: hero_logic, title: "Hero Logic", socket: rpc}
GET /openrpc.json
  19 methods, title "LogicService" — matches docs/openrpc.json
rpc.health  → {status: ok, trusted: true}
workflow.list  → ["025f","02di","02ca", … ]  (15+ seeded workflows)
logicservice.flow_library_search {query: "agent", limit: 3}
  → ["025f","035z","01wc"]
seed: created 'service_agent' workflow=038d version=038e  (built-in seed
       completes cleanly — no -32601 Method-not-found warnings, which
       was the failure mode that surfaced the lowercase wire-name bug
       in the rpc2_adapter — fixed in hero_rpc#100)

lab infocheck  → 3 crates clean, 0 findings.

Depends on hero_rpc PRs #99 (`OpenRpcDocument::from_value`) and #100
(`rpc2_adapter` lowercases service-method wire names). Both merged
before this PR opened.
timur merged commit f4ec6e4ab3 into main 2026-05-20 23:32:28 +00:00
Sign in to join this conversation.
No reviewers
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/hero_logic!47
No description provided.