Verify methods-only oschema path — full scaffold + SDK + OpenRPC stack works without rootobjects #131

Closed
opened 2026-05-22 13:24:19 +00:00 by timur · 1 comment
Owner

Goal

Verify the entire hero_rpc service scaffolding + end-to-end OpenRPC stack works for oschemas that declare only service blocks, no [rootobject] types. This is the prerequisite for the legacy-service migration (see meta hero_skills#262 closeout and the sister issue in this repo).

Why

Today, every example in examples/ (recipe_server, walkthrough_demo, petstore_*, hero_food) and every test fixture has at least one rootobject. There is no canary exercising the methods-only path.

A methods-only oschema is the natural shape for services like hero_indexer, hero_aibroker, hero_browser, etc. — which expose API surface but do not own storage. The migration of those services to oschema-driven codegen is gated on this path being verified end-to-end.

What I observe from the code (audit)

The bones are there but untested end-to-end:

  • Parser (crates/generator/src/schemas/oschema.rs): service blocks are first-class top-level constructs, parallel to type definitions. No rootobject required.
  • SDK trait emitter (crates/generator/src/build/emit/rust_rpc2.rs:281): walks rootobjects and services independently. With zero rootobjects it emits service methods only.
  • Server emitter (crates/generator/src/rust/rust_rpc.rs:130): if root_objects.is_empty() { return Ok(output); } — CRUD trait short-circuits cleanly. Service-method handlers come from a separate pass.
  • OpenRPC emitter (crates/generator/src/schemas/openrpc.rs): both CRUD and service-block methods merged into the spec.
  • Scaffolder (crates/generator/src/build/scaffold.rs:1787): test crate handles empty rootobjects (no [[test]] entries). Admin + web crates iterate &[RootObjectInfo] — with zero, emit empty index pages (degenerate but not fatal).

Likely failure modes (to be confirmed)

  • Admin crate that does not compile because UI templates assume at least one rootobject for the dashboard sidebar.
  • Test crate that scaffolds but has no generated tests (Cargo accepts this, but tooling like lab infocheck may not).
  • examples subcrate emission (still not generated per meta #262) — may be missing for the methods-only path too.
  • E2E test codegen path (crates/generator/src/generate/e2e.rs:129) — guarded on services.is_empty() but may emit a degenerate <svc>_e2e.rs that fails to link.
  • Python / Rhai / JS SDK emitters — same independent-pass shape but unverified.

Acceptance criteria

  • A new examples/methods_only/ workspace under hero_rpc/examples/ with an .oschema declaring only a service block (suggestion: a Hello { greet(name: str) -> str; echo(message: str) -> str } style toy service). No rootobjects.
  • Full scaffold + codegen produces: server crate, SDK crate, admin crate (acceptable to emit a placeholder dashboard saying "no rootobjects in this service"), web crate (same), tests crate, OpenRPC spec, all SDK targets (Rust, Python, Rhai, JS).
  • cargo build --workspace clean on the new example.
  • cargo test --workspace runs and passes (at minimum: a hand-written E2E test calling greet(...) end-to-end through the SDK trait).
  • A new CI test or generator-level integration test that re-runs codegen on examples/methods_only and diffs the output against a committed snapshot.

Out of scope

  • Migrating any actual existing service (hero_indexer, etc.) — that lands in the sister migration issue.
  • Refactoring the admin/web template engine — emitting an acceptable degenerate page is enough.
  • Meta closeout: hero_skills#262
  • Sister issue (migration): see hero_rpc issue filed alongside this one.
## Goal Verify the **entire** hero_rpc service scaffolding + end-to-end OpenRPC stack works for oschemas that declare **only `service` blocks, no `[rootobject]` types**. This is the prerequisite for the legacy-service migration (see meta hero_skills#262 closeout and the sister issue in this repo). ## Why Today, every example in `examples/` (`recipe_server`, `walkthrough_demo`, `petstore_*`, `hero_food`) and every test fixture has at least one rootobject. There is **no canary** exercising the methods-only path. A methods-only oschema is the natural shape for services like `hero_indexer`, `hero_aibroker`, `hero_browser`, etc. — which expose API surface but do not own storage. The migration of those services to oschema-driven codegen is gated on this path being verified end-to-end. ## What I observe from the code (audit) The bones are there but untested end-to-end: - **Parser** (`crates/generator/src/schemas/oschema.rs`): `service` blocks are first-class top-level constructs, parallel to type definitions. No rootobject required. - **SDK trait emitter** (`crates/generator/src/build/emit/rust_rpc2.rs:281`): walks rootobjects and services independently. With zero rootobjects it emits service methods only. - **Server emitter** (`crates/generator/src/rust/rust_rpc.rs:130`): `if root_objects.is_empty() { return Ok(output); }` — CRUD trait short-circuits cleanly. Service-method handlers come from a separate pass. - **OpenRPC emitter** (`crates/generator/src/schemas/openrpc.rs`): both CRUD and service-block methods merged into the spec. - **Scaffolder** (`crates/generator/src/build/scaffold.rs:1787`): test crate handles empty rootobjects (no `[[test]]` entries). Admin + web crates iterate `&[RootObjectInfo]` — with zero, emit empty index pages (degenerate but not fatal). ## Likely failure modes (to be confirmed) - Admin crate that does not compile because UI templates assume at least one rootobject for the dashboard sidebar. - Test crate that scaffolds but has no generated tests (Cargo accepts this, but tooling like `lab infocheck` may not). - `examples` subcrate emission (still not generated per meta #262) — may be missing for the methods-only path too. - E2E test codegen path (`crates/generator/src/generate/e2e.rs:129`) — guarded on `services.is_empty()` but may emit a degenerate `<svc>_e2e.rs` that fails to link. - Python / Rhai / JS SDK emitters — same independent-pass shape but unverified. ## Acceptance criteria - A new `examples/methods_only/` workspace under `hero_rpc/examples/` with an `.oschema` declaring **only** a `service` block (suggestion: a `Hello { greet(name: str) -> str; echo(message: str) -> str }` style toy service). No rootobjects. - Full scaffold + codegen produces: server crate, SDK crate, admin crate (acceptable to emit a placeholder dashboard saying "no rootobjects in this service"), web crate (same), tests crate, OpenRPC spec, all SDK targets (Rust, Python, Rhai, JS). - `cargo build --workspace` clean on the new example. - `cargo test --workspace` runs and passes (at minimum: a hand-written E2E test calling `greet(...)` end-to-end through the SDK trait). - A new CI test or generator-level integration test that re-runs codegen on `examples/methods_only` and diffs the output against a committed snapshot. ## Out of scope - Migrating any actual existing service (`hero_indexer`, etc.) — that lands in the sister migration issue. - Refactoring the admin/web template engine — emitting an acceptable degenerate page is enough. ## Links - Meta closeout: [hero_skills#262](https://forge.ourworld.tf/lhumina_code/hero_skills/issues/262) - Sister issue (migration): see hero_rpc issue filed alongside this one.
Author
Owner

Closed by hero_rpc#134 (squash sha 2b2aeb6). The methods-only oschema path is verified end-to-end — hero_service's greeter (methods-only) + extended catalog service-block methods exercise codegen + SDK + OpenRPC + E2E test emission cleanly. Forge auto-close didn't trigger; flipping manually.

Closed by hero_rpc#134 (squash sha `2b2aeb6`). The methods-only oschema path is verified end-to-end — `hero_service`'s greeter (methods-only) + extended catalog service-block methods exercise codegen + SDK + OpenRPC + E2E test emission cleanly. Forge auto-close didn't trigger; flipping manually.
timur closed this issue 2026-05-25 09:46:10 +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_rpc#131
No description provided.