Move catalog/openrpc.json out of src/ to a top-level spec location #73

Closed
opened 2026-05-19 16:47:00 +00:00 by timur · 2 comments
Owner

Problem

The scaffolder emits the OpenRPC spec at crates/<name>/src/<domain>/openrpc.json — buried inside the core lib's src/. That's a poor home: it's not Rust source, it's the contract every SDK target consumes.

Suggested

Move it to one of:

  • sdk/openrpc.json (alongside the language SDKs — most natural since every SDK target generates from this spec)
  • spec/openrpc.json (dedicated top-level dir)
  • Workspace-root openrpc.json (simplest)

Propose one in a comment before implementing. My lean: sdk/openrpc.json since it's the upstream input to the language-specific SDK packages and they'll all reference it.

What to do

  • Pick the location.
  • Update OschemaBuildConfig / generator to emit there.
  • Update the embedded path in _admin's <hero-api-docs> integration (currently includes the file via build-time path).
  • Update hero_service_scaffold.md skill.
  • Regenerate hero_service template repo to match.

Acceptance

  • Fresh scaffold emits openrpc.json at the chosen location.
  • <hero-api-docs> in scaffolded _admin still resolves and renders correctly.
  • No openrpc.json left under crates/<name>/src/.
## Problem The scaffolder emits the OpenRPC spec at [`crates/<name>/src/<domain>/openrpc.json`](https://forge.ourworld.tf/lhumina_code/hero_service/src/branch/development/crates/hero_service/src/catalog/openrpc.json) — buried inside the core lib's `src/`. That's a poor home: it's not Rust source, it's the contract every SDK target consumes. ## Suggested Move it to one of: - `sdk/openrpc.json` (alongside the language SDKs — most natural since every SDK target generates from this spec) - `spec/openrpc.json` (dedicated top-level dir) - Workspace-root `openrpc.json` (simplest) Propose one in a comment before implementing. My lean: `sdk/openrpc.json` since it's the upstream input to the language-specific SDK packages and they'll all reference it. ## What to do - Pick the location. - Update `OschemaBuildConfig` / generator to emit there. - Update the embedded path in `_admin`'s `<hero-api-docs>` integration (currently includes the file via build-time path). - Update `hero_service_scaffold.md` skill. - Regenerate `hero_service` template repo to match. ## Acceptance - Fresh scaffold emits `openrpc.json` at the chosen location. - `<hero-api-docs>` in scaffolded `_admin` still resolves and renders correctly. - No `openrpc.json` left under `crates/<name>/src/`.
Author
Owner

Location locked: docs/openrpc.json (top-level).

Note: this is the API contract, distinct from the per-schema doc trees that were dropped in #71docs/openrpc.json is consumed by every SDK target + the <hero-api-docs> admin widget, so it belongs in a discoverable top-level location, not under src/. The docs/schemas/ dir from #71 stays gone; docs/ just contains this one canonical file (plus whatever a contributor adds — README, ADRs, etc.).

Action items for the implementing agent:

  • Update OschemaBuildConfig / generator to emit at docs/openrpc.json (workspace root).
  • Update the <hero-api-docs> build-time include path in scaffolded _admin main.rs.
  • Update hero_service_scaffold.md skill in hero_skills so the documented layout matches.
  • Regenerate the hero_service template repo + example/recipe_server so they reflect the new path.
Location locked: **`docs/openrpc.json`** (top-level). Note: this is the API contract, distinct from the per-schema doc trees that were dropped in #71 — `docs/openrpc.json` is consumed by every SDK target + the `<hero-api-docs>` admin widget, so it belongs in a discoverable top-level location, not under `src/`. The `docs/schemas/` dir from #71 stays gone; `docs/` just contains this one canonical file (plus whatever a contributor adds — README, ADRs, etc.). Action items for the implementing agent: - Update `OschemaBuildConfig` / generator to emit at `docs/openrpc.json` (workspace root). - Update the `<hero-api-docs>` build-time include path in scaffolded `_admin` `main.rs`. - Update `hero_service_scaffold.md` skill in `hero_skills` so the documented layout matches. - Regenerate the `hero_service` template repo + `example/recipe_server` so they reflect the new path.
Author
Owner

Implementation up on branch issue-73-openrpc-location. Commit 24d8b25 covers everything in scope for this repo:

  • OschemaBuildConfig gains a workspace_dir setting. The builder auto-detects the workspace root by walking up from CARGO_MANIFEST_DIR for a Cargo.toml with [workspace]; explicit override is available for non-standard layouts (and unit tests, which fall back to the manifest dir).
  • Generator gets a matching workspace_dir field. write_openrpc_json now writes a single <workspace>/docs/openrpc.json instead of per-domain copies under src/{domain}/. rust_types no longer emits the in-tree spec at all — rust_server is the single emission point.
  • rust_server computes the include_str! path from the server file's directory to <workspace>/docs/openrpc.json so the prior hardcoded include_str!("openrpc.json") / include_str!("../core/openrpc.json") layout fix-ups go away. Same path-computation works for nested layout, server_crate_dir, and flat in-tree alike.
  • Scaffolded _admin/main.rs template now embeds the canonical spec at build time (include_str!("../../../docs/openrpc.json")) and serves it on /openrpc.json so <hero-api-docs spec-url="/openrpc.json"> resolves out of the box.
  • example/recipe_server regenerated: docs/openrpc.json is the single canonical file; both crates/hero_recipes/src/recipes/openrpc.json and crates/hero_recipes_server/src/recipes/openrpc.json are gone; the hero_recipes_admin include_str! now points at the new path.

All 125 generator tests + downstream workspace tests pass; both the hero_rpc workspace and example/recipe_server workspace build clean (generated osis_server_generated.rs now uses include_str!("../../../../docs/openrpc.json") from crates/hero_recipes_server/src/recipes/).

Known limitation (noted in commit message): the generator runs per-domain and overwrites the same docs/openrpc.json each call — last-domain-wins for multi-domain services. Both recipe_server and the hero_service template are single-domain so it's a non-issue for the acceptance criteria, but merging multi-domain specs into one canonical file is a follow-up worth filing.

Out of scope (separate PRs in their own repos):

  • hero_skills/hero_service_scaffold.md — needs the documented layout updated to match.
  • hero_service template repo — needs to be regenerated by the updated scaffolder and the resulting docs/openrpc.json + admin include_str path committed.
Implementation up on branch [`issue-73-openrpc-location`](https://forge.ourworld.tf/lhumina_code/hero_rpc/src/branch/issue-73-openrpc-location). Commit 24d8b25 covers everything in scope for this repo: - `OschemaBuildConfig` gains a `workspace_dir` setting. The builder auto-detects the workspace root by walking up from `CARGO_MANIFEST_DIR` for a `Cargo.toml` with `[workspace]`; explicit override is available for non-standard layouts (and unit tests, which fall back to the manifest dir). - `Generator` gets a matching `workspace_dir` field. `write_openrpc_json` now writes a single `<workspace>/docs/openrpc.json` instead of per-domain copies under `src/{domain}/`. `rust_types` no longer emits the in-tree spec at all — `rust_server` is the single emission point. - `rust_server` computes the `include_str!` path from the server file's directory to `<workspace>/docs/openrpc.json` so the prior hardcoded `include_str!("openrpc.json")` / `include_str!("../core/openrpc.json")` layout fix-ups go away. Same path-computation works for nested layout, `server_crate_dir`, and flat in-tree alike. - Scaffolded `_admin/main.rs` template now embeds the canonical spec at build time (`include_str!("../../../docs/openrpc.json")`) and serves it on `/openrpc.json` so `<hero-api-docs spec-url="/openrpc.json">` resolves out of the box. - `example/recipe_server` regenerated: `docs/openrpc.json` is the single canonical file; both `crates/hero_recipes/src/recipes/openrpc.json` and `crates/hero_recipes_server/src/recipes/openrpc.json` are gone; the `hero_recipes_admin` `include_str!` now points at the new path. All 125 generator tests + downstream workspace tests pass; both the `hero_rpc` workspace and `example/recipe_server` workspace build clean (generated `osis_server_generated.rs` now uses `include_str!("../../../../docs/openrpc.json")` from `crates/hero_recipes_server/src/recipes/`). **Known limitation (noted in commit message):** the generator runs per-domain and overwrites the same `docs/openrpc.json` each call — last-domain-wins for multi-domain services. Both `recipe_server` and the `hero_service` template are single-domain so it's a non-issue for the acceptance criteria, but merging multi-domain specs into one canonical file is a follow-up worth filing. **Out of scope (separate PRs in their own repos):** - `hero_skills/hero_service_scaffold.md` — needs the documented layout updated to match. - `hero_service` template repo — needs to be regenerated by the updated scaffolder and the resulting `docs/openrpc.json` + admin include_str path committed.
timur closed this issue 2026-05-20 06:52:31 +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#73
No description provided.