refactor: ADR 001 — crate topology, OSIS defat, unified server, SDK UI #26

Open
timur wants to merge 8 commits from refactor/adr-001-crate-topology into development
Owner

Summary

Implements ADR 001 (new): defat hero_rpc_osis to pure storage + traits, move transport concerns to hero_rpc_server, and add the hero_rpc_ui SDK dashboard crate. Six focused commits, each builds cleanly.

Commits

  1. docs: ADRs 001/002/003 and PRD 000 (Hero SDK vision). Deletes the earlier ADR 001 draft.
  2. feat(ui): new hero_rpc_ui crate — Axum dashboard with schema.parse/generate, project.scaffold, ai.chat, ai.models, rpc.discover JSON-RPC methods. Backend complete; SPA tracked in #24.
  3. refactor(osis): defat OSIS — delete 3,500-line AxumRpcServer, Redis client, remote index, Rhai codegen, AI mock generator, and 3 basic examples. Drop redis/deadpool-redis/herolib_ai/axum/tower/tower-http/hyper. OSIS becomes pure storage + handler traits.
  4. refactor(server): unified dispatch keyed by (context_name, type_name), new request_headers.rs for header→RequestContext parsing (moved out of OSIS), per-instance socket_dir/data_dir overrides alongside env/default cascade, title field + effective_title(), delete legacy core_server.rs / domain_server.rs.
  5. feat(generator): recognize [index] and [rootobject] comment markers as equivalent to parser-level annotations; emit as x- OpenRPC extensions.
  6. example(recipe_server): regenerate .set handlers for dual-mode data/obj params; drop rpc feature from hero_rpc_osis dep.

Supersedes

  • PR #23 (defat_osis_rpc, rpc-core feature gating). This PR deletes the legacy code instead of gating it — same goal, simpler endpoint.
  • PR #20 (configurable socket and data paths, Phase 1). This PR implements the same cascade plus the broader topology work.

Both will be closed as superseded once this merges.

Closes / references

  • Closes #22 (defat hero_rpc_osis)
  • Answers #13 (hero_sdk + hero_core rethinking) via ADRs + PRD
  • Implements #24 (SDK UI tracking — backend only; SPA is follow-up)
  • Does not address #4 (typed error codes) or #25 (generator REST aliases) — separate work

Test plan

  • cargo check --workspace passes on this branch
  • cargo check --workspace passes on hero_osis with a temporary [patch."…hero_rpc.git"] pointing at this branch, once the one-line hero_osis_seed change (remove AI-backed generate subcommand) is applied
  • CI passes on the PR
  • Downstream services (hero_books, hero_voice, hero_logic, hero_biz) verified — tracked separately

Downstream breakage

hero_osis's hero_osis_seed --generate subcommand uses the AI-backed mock generator from OSIS. That's gone. Companion PR on hero_osis strips the subcommand; --seed keeps working.

🤖 Generated with Claude Code

## Summary Implements ADR 001 (new): defat `hero_rpc_osis` to pure storage + traits, move transport concerns to `hero_rpc_server`, and add the `hero_rpc_ui` SDK dashboard crate. Six focused commits, each builds cleanly. ## Commits 1. **docs:** ADRs 001/002/003 and PRD 000 (Hero SDK vision). Deletes the earlier ADR 001 draft. 2. **feat(ui):** new `hero_rpc_ui` crate — Axum dashboard with `schema.parse/generate`, `project.scaffold`, `ai.chat`, `ai.models`, `rpc.discover` JSON-RPC methods. Backend complete; SPA tracked in #24. 3. **refactor(osis):** defat OSIS — delete 3,500-line `AxumRpcServer`, Redis client, remote index, Rhai codegen, AI mock generator, and 3 basic examples. Drop redis/deadpool-redis/herolib_ai/axum/tower/tower-http/hyper. OSIS becomes pure storage + handler traits. 4. **refactor(server):** unified dispatch keyed by `(context_name, type_name)`, new `request_headers.rs` for header→RequestContext parsing (moved out of OSIS), per-instance socket_dir/data_dir overrides alongside env/default cascade, title field + effective_title(), delete legacy `core_server.rs` / `domain_server.rs`. 5. **feat(generator):** recognize `[index]` and `[rootobject]` comment markers as equivalent to parser-level annotations; emit as `x-` OpenRPC extensions. 6. **example(recipe_server):** regenerate `.set` handlers for dual-mode `data`/`obj` params; drop `rpc` feature from hero_rpc_osis dep. ## Supersedes - **PR #23** (defat_osis_rpc, rpc-core feature gating). This PR deletes the legacy code instead of gating it — same goal, simpler endpoint. - **PR #20** (configurable socket and data paths, Phase 1). This PR implements the same cascade plus the broader topology work. Both will be closed as superseded once this merges. ## Closes / references - Closes #22 (defat hero_rpc_osis) - Answers #13 (hero_sdk + hero_core rethinking) via ADRs + PRD - Implements #24 (SDK UI tracking — backend only; SPA is follow-up) - Does not address #4 (typed error codes) or #25 (generator REST aliases) — separate work ## Test plan - [x] `cargo check --workspace` passes on this branch - [x] `cargo check --workspace` passes on `hero_osis` with a temporary `[patch."…hero_rpc.git"]` pointing at this branch, once the one-line `hero_osis_seed` change (remove AI-backed `generate` subcommand) is applied - [ ] CI passes on the PR - [ ] Downstream services (hero_books, hero_voice, hero_logic, hero_biz) verified — tracked separately ## Downstream breakage `hero_osis`'s `hero_osis_seed --generate` subcommand uses the AI-backed mock generator from OSIS. That's gone. Companion PR on hero_osis strips the subcommand; `--seed` keeps working. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
- ADR 001: crate topology (10 single-responsibility crates), path
  cascade (instance override > env var > default), socket alignment
  with hero_sockets canonical. Supersedes earlier configurable-paths
  ADR draft (deleted).
- ADR 002: adopt vendored hero_rpc2 as the SDK's RPC crate
  (jsonrpsee 0.26 over UDS + OpenRPC discovery). Three-wave migration.
- ADR 003: nu-script service lifecycle (scripts/nu_service.nu) sourcing
  shared helpers from hero_skills; retires bespoke Makefiles.
- PRD 000: Hero SDK vision — canonical toolkit for building Hero
  services. Four audiences, four non-goals.

Answers issue #13 (hero_sdk + hero_core rethinking).
New crate providing the Hero RPC SDK developer dashboard: schema
workbench, project scaffolder, AI assistant, and SDK docs browser.

- Axum router + Askama templates + embedded static assets
- JSON-RPC 2.0 dispatcher at POST /rpc with methods:
  schema.parse, schema.generate, project.scaffold, ai.chat,
  ai.models, rpc.discover
- Calls hero_rpc_oschema + hero_rpc_generator as libraries, not RPC
- Optional AI feature via herolib_ai (DeepSeekV3 default)
- Binds to $HERO_SOCKET_DIR/hero_rpc/ui.sock per hero_sockets conv.
- SPA templates are skeleton; frontend implementation tracked in
  hero_rpc issue #24.

Implements the dashboard crate from ADR 001 and PRD 000.
OSIS is now pure storage plus handler traits. Everything transport,
Redis, AI, and remote-index related has moved out of this crate.

Removed:
- rpc/server.rs — the 3,500-line AxumRpcServer (superseded by OServer
  in hero_rpc_server)
- rpc/client.rs — Redis-based RPC client
- rpc/unix_server.rs — legacy UnixRpcServer
- rpc/dispatch.rs — legacy dispatch
- rpc/context.rs — legacy RpcContext
- rpc/request_context.rs — axum-coupled from_headers moved to the
  server crate (crates/server/src/server/request_headers.rs)
- index/ — RemoteIndex client (superseded by in-process indexing)
- rhai.rs — Rhai codegen (moved to hero_rpc_generator)
- seed/generator.rs — 600-line AI-backed mock data generator
- examples/basic/{4,5,6}_*.rs — demos for removed APIs

Dependency impact (from Cargo.toml):
- redis, deadpool-redis — gone (were only used by the legacy server)
- herolib_ai — gone (only used by seed/generator.rs)
- axum, tower, tower-http, hyper — gone (legacy server transport)

What remains in osis/src/rpc/:
- handler.rs (OsisAppRpcHandler, OsisDomainInit)
- jsonrpc.rs, request_context.rs (pure struct), lifecycle.rs,
  protocol.rs, error.rs, debug.rs, dispatch traits
- server.rs — now just trait definitions

Closes #22. Supersedes PR #23's "rpc-core feature" approach —
instead of gating the legacy code, we delete it.

Downstream services (hero_osis, hero_books, hero_voice, hero_logic,
hero_biz) get faster compiles and smaller binaries. No API changes
at the handler-trait level.
Shape the server crate to match ADR 001:

- config.rs: per-instance socket_dir/data_dir overrides alongside
  existing env/default cascade; add title field + effective_title();
  rpc_socket/ui_socket/service_socket_dir become instance methods
  that use self.name. Legacy deprecated core_socket/domain_socket
  helpers removed — per-service directory pattern is canonical.
- request_headers.rs (new): parse X-Hero-Context, X-Hero-Claims,
  X-Forwarded-Prefix into a RequestContext in the server crate
  (was previously in osis). Keeps transport concerns out of OSIS.
- unified_server.rs: type-erased dispatch map keyed by
  (context_name, type_name). Context names are strings and dispatch
  strips the domain prefix.
- registry.rs, server.rs, spawn.rs, mod.rs: align with the above.
- core_server.rs / domain_server.rs: deleted (legacy per-domain socket
  model, superseded by the unified server).
- service/lifecycle.rs: minor cleanup.

Supersedes PR #20 (same path cascade plus the broader topology and
header-parsing work).
OSchema authors currently write indexing hints as inline comment
markers (`# [index]`, `# [rootobject]`). The generator now treats
these as equivalent to parser-level annotations:

- json_schema: field comments containing `[index]` → `x-index: true`
  extension; marker stripped from the emitted description.
- openrpc: type comments containing `[rootobject]` → `x-rootobject:
  true`; marker stripped from description.

Keeps the human-facing description clean while keeping the marker
machine-detectable. No schema changes required downstream.
example(recipe_server): accept JSON data in set handlers + drop rpc feature
Some checks failed
Test / test (pull_request) Failing after 56s
e29d389700
- Regenerate .set handlers to accept either `data` (JSON object or
  string) or `obj` (legacy OTOML string). JSON is the preferred path.
- Refresh openrpc.json to match.
- Drop the `rpc` feature from the example's hero_rpc_osis dep
  (no longer needed after the OSIS defat).
- Update Cargo.lock for the reduced dependency set.
fix(service): restore inputs: None on JobCreateInput
Some checks failed
Test / test (pull_request) Failing after 49s
fe13522855
Lost in the server refactor rebase onto development — development
had already added this in 784b411 to match hero_proc_sdk's new
input field. Building against current hero_proc_sdk required it.
fix(dev): bump hero_proc_sdk + fix test missing hero_context_name
All checks were successful
Test / test (pull_request) Successful in 1m4s
afbb5ec61b
Two small drifts on development that broke the build:

1. Cargo.lock pinned hero_proc_sdk at 8e7e985 — before the `inputs`
   field was added to `JobCreateInput`. Commit 784b411 introduced
   `inputs: None` in `crates/service/src/lifecycle.rs:290`, but the
   lockfile was never bumped, so cargo resolved the old sha and the
   field didn't exist: E0560 "struct JobCreateInput has no field
   named 'inputs'". Running `cargo update -p hero_proc_sdk` bumps
   to e847693 (latest dev tip).

2. `test_serde_roundtrip` in request_context.rs constructs
   `RequestContext` struct-literal-style but was never updated when
   commit 7d14133 added the `hero_context_name: Option<String>`
   field — E0063 "missing field hero_context_name". Add it (None).

After both fixes:
- `cargo check --workspace` green
- `cargo check --workspace --tests` green
- `cargo test --workspace --lib` — 266 passed, 0 failed, 1 ignored
All checks were successful
Test / test (pull_request) Successful in 1m4s
This pull request has changes conflicting with the target branch.
  • Cargo.lock
  • example/recipe_server/src/recipes/server/osis_server_generated.rs
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin refactor/adr-001-crate-topology:refactor/adr-001-crate-topology
git switch refactor/adr-001-crate-topology

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch development
git merge --no-ff refactor/adr-001-crate-topology
git switch refactor/adr-001-crate-topology
git rebase development
git switch development
git merge --ff-only refactor/adr-001-crate-topology
git switch refactor/adr-001-crate-topology
git rebase development
git switch development
git merge --no-ff refactor/adr-001-crate-topology
git switch development
git merge --squash refactor/adr-001-crate-topology
git switch development
git merge --ff-only refactor/adr-001-crate-topology
git switch development
git merge refactor/adr-001-crate-topology
git push origin development
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_rpc!26
No description provided.