hero_rpc#124: MultiDomainBuilder + subprocess-driver tests + Layer 2-4 nu skeletons #126

Merged
timur merged 1 commit from issue-124-lifecycle-alignment into development 2026-05-22 13:09:18 +00:00
Owner

Closes part 1/3 of hero_rpc#124 (lifecycle alignment). Two sibling PRs follow: hero_skills (lab --ephemeral / --json / --pid / --test) and hero_service (template re-validation).

What this PR does

  1. MultiDomainBuilder (internal to hero_rpc_osis) — fluent assembly of one RpcModule from N OSIS domain handlers. Typestate (Production / Ephemeral) so .spawn() returns the right shape per mode. run / run_for_test become thin compat wrappers — no consumer breakage.
  2. Scaffolder main.rs template — collapses the per-domain register_methods ladder into a MultiDomainBuilder::production() chain. One .with_domain::<…>(…) line per .oschema domain.
  3. Scaffolder tests/src/lib.rs template — subprocess-driver shape: Command::new("lab") for spin-up, lab --stop --pid in Drop. No hero_rpc_osis, no jsonrpsee, no <name>_server direct dep. The running lab knows about new domains via service.toml, so adding an .oschema requires zero edits to this file.
  4. Scaffolder Layer 2-4 nushell skeletonstests/smoke.nu, tests/api_integration.nu, tests/e2e_<flow>.nu. Each accepts --socket <path> (or HERO_TEST_SOCKET env), uses curl --unix-socket for the UDS HTTP path. Smoke covers the four mandatory endpoints; api_integration walks one rootobject CRUD over the wire.
  5. README + docs/testing.md — scaffolded README points contributors at one verb (lab service <name> --test). docs/testing.md walks the five-layer pyramid with what each layer catches.
  6. Pre-existing clippy fixes — 7 warnings on development were blocking cargo clippy --workspace -- -D warnings (doc-list-indent, useless format!, collapsible if-let). Folded in so this PR lands under the CI gate.

Three commits, structured for review:

  • 98c2ce3 — MultiDomainBuilder extraction
  • 05e1a0b — subprocess-driver tests + nu skeletons + scaffolder regen
  • 33e8d60 — README + docs/testing.md + clippy fixes

Headline diff stats (hero_recipes_server template)

File Before (origin/development) After Delta
main.rs 121 lines 84 lines -37 (-31%)
tests/src/lib.rs 51 lines 109 lines +58

The tests/src/lib.rs line count went up — the subprocess shape needs error handling around Command::output, JSON parsing, a Drop impl, and a typed client connection that the previous in-process version got for free from run_for_test. The win isn't line count; it's drift-free: tests/src/lib.rs is now byte-identical across reruns regardless of how many .oschema domains exist. The old shape needed a hand-edit to the register_methods ladder for every new domain.

Main.rs collapses by 30% and the per-domain cfg(feature) block is now a single line per domain.

Acceptance (this PR's slice)

Full issue acceptance lands across all three PRs; this PR delivers:

  • MultiDomainBuilder::production() + MultiDomainBuilder::for_ephemeral() in hero_rpc_osis::rpc::bootstrap, with with_domain<App> chained registration. Internal to hero_rpc_osis — no public-crate surface added.
  • run_for_test<A> kept as compat wrapper so existing osis_benches keeps building.
  • Scaffolded crates/<name>_server/src/main.rs uses MultiDomainBuilder::production() — no inline register_methods ladder.
  • Scaffolded tests/src/lib.rs is the subprocess-driver shape — no hero_rpc_osis import, no MultiDomainBuilder mention, no per-domain cfg(feature) block.
  • Adding a new .oschema domain requires zero edits to tests/src/lib.rs. main.rs only sees a new .with_domain::<…>(…) line after re-scaffolding (verified by regenerating examples/recipe_server end-to-end).
  • Scaffolder emits Layer 2-4 nushell skeletons under tests/ with the canonical --socket / HERO_TEST_SOCKET shape.
  • tests/Cargo.toml drops hero_rpc_osis, jsonrpsee, and the <name>_server path dep — only hero_rpc2 (client), <name>_sdk, serde_json, anyhow, tokio remain.
  • cargo test --workspace --lib --bins clean (excluding the pre-existing hero_rpc_osis_benches breakage — see Follow-ups).
  • cargo clippy --workspace -- -D warnings clean (excluding the same pre-existing bench breakage).
  • cargo fmt --all -- --check clean.
  • 24 generator-scaffold tests pass, including two new ones that pin the subprocess shape (test_scaffold_tests_lib_rs_is_subprocess_driver, test_scaffold_tests_cargo_toml_drops_bootstrap_deps) and one that pins the nu skeletons (test_scaffold_emits_nushell_skeletons).

Deferred to PR2 (hero_skills):

  • lab service <name> --start --ephemeral --json (the verb the new tests/src/lib.rs shells out to).
  • lab service <name> --stop --pid <pid> flag.
  • lab service <name> --test [layer] verb (the README + docs/testing.md reference this ahead of its merge — clean ordering per the issue's squash-merge plan).
  • hero_service_test_complete skill doc update.

Deferred to PR3 (hero_service):

  • Template re-validation, including the orphan-check (pgrep -f hero_service_server empty after lab --test).

Decisions taken without confirmation

  1. for_testfor_ephemeral rename. The final issue framing uses "ephemeral" everywhere; the builder constructor matches.
  2. tests/src/lib.rs and <server>/src/main.rs switched to write_managed (overwrite-on-rerun). write_preserved (the previous default for both files) made the issue's acceptance criterion — "zero hand-edits after re-scaffolding" — impossible to meet. Other scaffolder-emitted files stay preserve-once. New ScaffoldResult::files_updated field reports which files were managed.
  3. curl --unix-socket inside the nu scripts, not nushell's native http get (which is TCP-only). The hero_service_test_complete skill calls out curl as the established escape hatch for the UDS case.
  4. examples/recipe_server regenerated via the new templates. The example workspace is excluded from the top-level workspace, so hero_rpc CI runs cargo check on it but not the integration tests — the subprocess shape compiles cleanly without lab installed.
  5. Pre-existing clippy fixes folded in. Three warnings on development (doc-list-indent in scaffold.rs + rust_osis.rs, format! literals in js_struct.rs, collapsible if-let in js_struct.rs) were blocking the CI gate; fixed in this PR so reviewers don't have to deal with stale red.

Follow-ups not done here

  • osis_benches subprocess shape (Phase F in the issue). Pending lab --ephemeral landing in hero_skills PR2; today's benches still call run_for_test directly via the compat wrapper.
  • Pre-existing hero_rpc_osis_benches missing generated/mod.rs — broken on development already (codegen half-merged from PR #125). Out of scope for #124; should be a follow-up bug.
  • hero_service_test_complete / tests_pyramid skill updates — land in the hero_skills PR alongside the lab --test verb.

Test plan

  • cargo test --workspace --lib --bins --exclude hero_rpc_osis_benches green (446 tests).
  • cargo clippy --workspace --exclude hero_rpc_osis_benches -- -D warnings green.
  • cargo fmt --all -- --check green.
  • cargo check --tests --manifest-path examples/recipe_server/Cargo.toml green (subprocess-shape generated tests compile cleanly without lab installed).
  • Re-running the scaffolder against examples/recipe_server produces a byte-identical tests/src/lib.rs on subsequent runs.
  • End-to-end cargo test -p hero_recipes_tests — requires hero_skills PR2's lab --ephemeral to be live. Will verify as part of the hero_service PR3 acceptance.
Closes part 1/3 of hero_rpc#124 (lifecycle alignment). Two sibling PRs follow: hero_skills (`lab --ephemeral` / `--json` / `--pid` / `--test`) and hero_service (template re-validation). ## What this PR does 1. **`MultiDomainBuilder` (internal to `hero_rpc_osis`)** — fluent assembly of one `RpcModule` from N OSIS domain handlers. Typestate (`Production` / `Ephemeral`) so `.spawn()` returns the right shape per mode. `run` / `run_for_test` become thin compat wrappers — no consumer breakage. 2. **Scaffolder `main.rs` template** — collapses the per-domain `register_methods` ladder into a `MultiDomainBuilder::production()` chain. One `.with_domain::<…>(…)` line per `.oschema` domain. 3. **Scaffolder `tests/src/lib.rs` template** — subprocess-driver shape: `Command::new("lab")` for spin-up, `lab --stop --pid` in `Drop`. No `hero_rpc_osis`, no `jsonrpsee`, no `<name>_server` direct dep. The running lab knows about new domains via `service.toml`, so adding an `.oschema` requires zero edits to this file. 4. **Scaffolder Layer 2-4 nushell skeletons** — `tests/smoke.nu`, `tests/api_integration.nu`, `tests/e2e_<flow>.nu`. Each accepts `--socket <path>` (or `HERO_TEST_SOCKET` env), uses `curl --unix-socket` for the UDS HTTP path. Smoke covers the four mandatory endpoints; api_integration walks one rootobject CRUD over the wire. 5. **README + `docs/testing.md`** — scaffolded README points contributors at one verb (`lab service <name> --test`). `docs/testing.md` walks the five-layer pyramid with what each layer catches. 6. **Pre-existing clippy fixes** — 7 warnings on `development` were blocking `cargo clippy --workspace -- -D warnings` (doc-list-indent, useless `format!`, collapsible if-let). Folded in so this PR lands under the CI gate. Three commits, structured for review: - `98c2ce3` — MultiDomainBuilder extraction - `05e1a0b` — subprocess-driver tests + nu skeletons + scaffolder regen - `33e8d60` — README + docs/testing.md + clippy fixes ## Headline diff stats (hero_recipes_server template) | File | Before (origin/development) | After | Delta | |---|---|---|---| | `main.rs` | 121 lines | 84 lines | **-37 (-31%)** | | `tests/src/lib.rs` | 51 lines | 109 lines | +58 | The `tests/src/lib.rs` line count went *up* — the subprocess shape needs error handling around `Command::output`, JSON parsing, a `Drop` impl, and a typed client connection that the previous in-process version got for free from `run_for_test`. The win isn't line count; it's **drift-free**: tests/src/lib.rs is now byte-identical across reruns regardless of how many `.oschema` domains exist. The old shape needed a hand-edit to the `register_methods` ladder for every new domain. Main.rs collapses by 30% and the per-domain `cfg(feature)` block is now a single line per domain. ## Acceptance (this PR's slice) Full issue acceptance lands across all three PRs; this PR delivers: - [x] `MultiDomainBuilder::production()` + `MultiDomainBuilder::for_ephemeral()` in `hero_rpc_osis::rpc::bootstrap`, with `with_domain<App>` chained registration. Internal to `hero_rpc_osis` — no public-crate surface added. - [x] `run_for_test<A>` kept as compat wrapper so existing `osis_benches` keeps building. - [x] Scaffolded `crates/<name>_server/src/main.rs` uses `MultiDomainBuilder::production()` — no inline `register_methods` ladder. - [x] Scaffolded `tests/src/lib.rs` is the subprocess-driver shape — no `hero_rpc_osis` import, no `MultiDomainBuilder` mention, no per-domain `cfg(feature)` block. - [x] Adding a new `.oschema` domain requires zero edits to `tests/src/lib.rs`. `main.rs` only sees a new `.with_domain::<…>(…)` line after re-scaffolding (verified by regenerating `examples/recipe_server` end-to-end). - [x] Scaffolder emits Layer 2-4 nushell skeletons under `tests/` with the canonical `--socket` / `HERO_TEST_SOCKET` shape. - [x] `tests/Cargo.toml` drops `hero_rpc_osis`, `jsonrpsee`, and the `<name>_server` path dep — only `hero_rpc2` (client), `<name>_sdk`, `serde_json`, `anyhow`, `tokio` remain. - [x] `cargo test --workspace --lib --bins` clean (excluding the pre-existing `hero_rpc_osis_benches` breakage — see Follow-ups). - [x] `cargo clippy --workspace -- -D warnings` clean (excluding the same pre-existing bench breakage). - [x] `cargo fmt --all -- --check` clean. - [x] 24 generator-scaffold tests pass, including two new ones that pin the subprocess shape (`test_scaffold_tests_lib_rs_is_subprocess_driver`, `test_scaffold_tests_cargo_toml_drops_bootstrap_deps`) and one that pins the nu skeletons (`test_scaffold_emits_nushell_skeletons`). Deferred to PR2 (hero_skills): - `lab service <name> --start --ephemeral --json` (the verb the new `tests/src/lib.rs` shells out to). - `lab service <name> --stop --pid <pid>` flag. - `lab service <name> --test [layer]` verb (the README + docs/testing.md reference this ahead of its merge — clean ordering per the issue's squash-merge plan). - `hero_service_test_complete` skill doc update. Deferred to PR3 (hero_service): - Template re-validation, including the orphan-check (`pgrep -f hero_service_server` empty after `lab --test`). ## Decisions taken without confirmation 1. **`for_test` → `for_ephemeral` rename.** The final issue framing uses "ephemeral" everywhere; the builder constructor matches. 2. **`tests/src/lib.rs` and `<server>/src/main.rs` switched to `write_managed` (overwrite-on-rerun).** `write_preserved` (the previous default for both files) made the issue's acceptance criterion — "zero hand-edits after re-scaffolding" — impossible to meet. Other scaffolder-emitted files stay preserve-once. New `ScaffoldResult::files_updated` field reports which files were managed. 3. **`curl --unix-socket` inside the nu scripts**, not nushell's native `http get` (which is TCP-only). The `hero_service_test_complete` skill calls out `curl` as the established escape hatch for the UDS case. 4. **`examples/recipe_server` regenerated via the new templates.** The example workspace is `exclude`d from the top-level workspace, so hero_rpc CI runs `cargo check` on it but not the integration tests — the subprocess shape compiles cleanly without `lab` installed. 5. **Pre-existing clippy fixes folded in.** Three warnings on `development` (doc-list-indent in `scaffold.rs` + `rust_osis.rs`, `format!` literals in `js_struct.rs`, collapsible if-let in `js_struct.rs`) were blocking the CI gate; fixed in this PR so reviewers don't have to deal with stale red. ## Follow-ups not done here - **`osis_benches` subprocess shape** (Phase F in the issue). Pending `lab --ephemeral` landing in hero_skills PR2; today's benches still call `run_for_test` directly via the compat wrapper. - **Pre-existing `hero_rpc_osis_benches` missing `generated/mod.rs`** — broken on `development` already (codegen half-merged from PR #125). Out of scope for #124; should be a follow-up bug. - **`hero_service_test_complete` / `tests_pyramid` skill updates** — land in the hero_skills PR alongside the `lab --test` verb. ## Test plan - [x] `cargo test --workspace --lib --bins --exclude hero_rpc_osis_benches` green (446 tests). - [x] `cargo clippy --workspace --exclude hero_rpc_osis_benches -- -D warnings` green. - [x] `cargo fmt --all -- --check` green. - [x] `cargo check --tests --manifest-path examples/recipe_server/Cargo.toml` green (subprocess-shape generated tests compile cleanly without `lab` installed). - [x] Re-running the scaffolder against `examples/recipe_server` produces a byte-identical `tests/src/lib.rs` on subsequent runs. - [ ] **End-to-end `cargo test -p hero_recipes_tests`** — requires hero_skills PR2's `lab --ephemeral` to be live. Will verify as part of the hero_service PR3 acceptance.
Add a fluent builder in `hero_rpc_osis::rpc::bootstrap` that collapses the
`RpcModule::new(())` → per-domain `register_methods(...)` → `serve_http(...)`
ladder into one chained call. Typestate (`Production` / `Test`) keeps the
two return shapes (`RunningServer` vs `(RunningServer, TempDir)`) without a
runtime mode enum.

`run` and `run_for_test` become thin wrappers over the builder for
backward compat — every existing single-domain consumer (recipe_server
example, generated SDK tests) stays untouched.
Rewrite the scaffolder's `tests/src/lib.rs` template as a subprocess
driver around `lab service <name> --start --ephemeral --json`:

  - `ServiceHandle` holds the connected `hero_rpc2::Client` and the
    lab-reported pid; `Drop` shells out to `lab --stop --pid` so a
    panic / failure / early-return can't leak the child.
  - `spin_up_service()` is byte-identical across reruns — adding a
    new `.oschema` requires zero edits to the file. The running lab
    picks up the new domain through `service.toml`.
  - `tests/Cargo.toml` drops `hero_rpc_osis`, `jsonrpsee`, and the
    `<name>_server` path dep — the subprocess shape only needs the
    `hero_rpc2` client, `serde_json`, `anyhow`, `tokio`.

Generated `<entity>_e2e.rs` updated to the new ServiceHandle shape
(no `TempDir` second-tuple, no `svc.shutdown().await`).

Also emit Layer 2-4 nushell skeletons under `tests/`:

  - `smoke.nu`   — `/health`, `/openrpc.json`, `/.well-known/heroservice.json`,
                    `rpc.discover` over the UDS socket via `curl --unix-socket`.
  - `api_integration.nu` — first-rootobject CRUD cycle over HTTP.
  - `e2e_<flow>.nu`      — multi-step user-journey skeleton.

Each script accepts `--socket <path>` and falls back to
`HERO_TEST_SOCKET` so the same file works under `lab --test` and
under a hand-run `lab service --start --ephemeral`.

Rename `MultiDomainBuilder::for_test()` → `for_ephemeral()` and
`Test` marker → `Ephemeral` so the builder's name matches the lab
flag every consumer reaches for.

Regenerate `examples/recipe_server` so the example tracks the new
templates. The example workspace is excluded from the top-level
`cargo test --workspace`, so hero_rpc CI doesn't require lab to be
installed — only `cargo check` runs on the example, which the
subprocess shape compiles cleanly under.
hero_rpc#124: scaffold testing.md + README pointing at lab --test
Some checks failed
Test / test (push) Failing after 1m37s
Test / test (pull_request) Failing after 1m13s
33e8d602c0
Scaffolded README's "Tests" section collapses to one verb — `lab
service <name> --test [layer]` — and points contributors at the new
`docs/testing.md` walkthrough for the per-layer details. The verb
lives in hero_skills (lands in the sibling hero_skills PR); the
scaffolder template references it ahead of that PR so a `cargo run
hero_rpc_generator --name …` against `development` produces a
README that's correct as soon as both PRs land.

docs/testing.md walks the five layers (cargo → smoke.nu →
api_integration.nu → e2e_*.nu → hero_browser MCP), each with what
it catches and when to author at that level, plus the ad-hoc
`lab service <name> --start --ephemeral --json` recipe.

Also fix 7 pre-existing clippy errors that block `cargo clippy
--workspace -- -D warnings` on development:

  - 4× doc-list-without-indentation (scaffold.rs + rust_osis.rs).
  - 2× useless `format!` on literal strings (js_struct.rs).
  - 1× collapsible nested `if let` (js_struct.rs).

These are cosmetic warnings on existing code, not introduced by
#124. Folded in here so the PR can land cleanly under the CI
clippy gate.

Regenerate examples/recipe_server with the new README + docs/testing.md.
timur force-pushed issue-124-lifecycle-alignment from 33e8d602c0
Some checks failed
Test / test (push) Failing after 1m37s
Test / test (pull_request) Failing after 1m13s
to 2b7096c5bc
Some checks failed
Test / test (push) Failing after 2m13s
Test / test (pull_request) Failing after 2m32s
2026-05-22 11:13:34 +00:00
Compare
hero_rpc#124: recipe example is a build script, not a checked-in tree
Some checks failed
Test / test (pull_request) Failing after 2m9s
Test / test (push) Failing after 2m15s
b1afe114cb
The previous layout checked the scaffolded `examples/recipe_server/`
tree directly into git — 60+ files, almost all of which are pure
scaffolder output. Two problems: drift (the tree silently went stale
whenever the scaffolder template changed) and signal-to-noise (the
~340 lines of hand-written content that actually teach the recipes
domain got buried in scaffolder boilerplate).

Replace that with a build script. The example is now the *act* of
building a working recipes service:

  examples/recipe_example/
  ├── build.sh             ← runs scaffolder → injects hand-code → cargo build
  ├── README.md            ← explains the pattern
  ├── schemas/recipes/recipes.oschema
  └── inject/              ← the ~340 lines a contributor would normally hand-write
      ├── crates/hero_recipes/src/recipes/types.rs                          (16 lines)
      ├── crates/hero_recipes_server/src/recipes/rpc.rs                     (180 lines — service methods)
      └── crates/hero_recipes_server/src/recipes/tests_error_category.rs    (102 lines)

`examples/recipe_server/` becomes the output of running `build.sh`
— gitignored, regenerated from scratch on each invocation. Re-running
guarantees the example tracks the current scaffolder; there is no
stale-checked-in version to drift against.

Two side notes:

- The previous `examples/recipe_server/sdk/rust/tests/seed_smoke.rs`
  imported `hero_recipes_server::recipes::OsisRecipes` from inside
  the SDK crate, which the scaffolder-emitted Cargo.toml doesn't
  permit (no `_server` dev-dep). Dropped — the new workspace-root
  `tests/` crate (hero_rpc#124 subprocess-driver shape) covers the
  SDK ↔ server end-to-end path the smoke test was checking.
- `build.sh` injects a `[patch."https://forge.ourworld.tf/lhumina_code/hero_rpc.git"]`
  section pointing at the in-tree `crates/*` so the example exercises
  the *working tree*, not whatever commit happens to be pinned on
  origin/development. Without it, the example always lags by a PR.
- `cargo build` runs in three staged passes (`-p hero_recipes`,
  `-p hero_recipes_server`, `--workspace`) to side-step a
  reproducible cargo first-build race in workspace mode where the
  `hero_recipes_server` bin can't see its own sibling lib (same
  package name) under fresh `target/`. Staged building warms the
  per-package lib→bin sequencing.
Author
Owner

Pushed a follow-up commit + rebased onto current development (picks up PR #127 / @index integration):

  • b1afe11 — recipe example is a build script, not a checked-in tree. Replaces 60+ checked-in scaffolder-output files under examples/recipe_server/ with a 3-step build script at examples/recipe_example/build.sh: writes schemas → runs scaffolder → injects ~340 lines of hand-written content (service-method impls, custom type impls, a domain test). Output is gitignored. Eliminates the scaffolder ↔ checked-in-example drift exactly. Net file delta: 60+ files deleted, 8 added under examples/recipe_example/.

  • Rebased onto origin/development so PR #127s @index integration + osis_benches expansion are now in the base. The bench compile now passes locally (was the pre-existing breakage I called out in the original PR description — no longer a follow-up).

One small reframe on run_for_test: it stays. The osis_benches harness is the server (no separate _server binary to subprocess-spawn), so the Phase F “migrate benches to subprocess” framing doesnt fit. run_for_test is the legit in-process variant of lab --ephemeral for that case — same code path under the hood now that its a thin wrapper over MultiDomainBuilder::for_ephemeral().

Summary of branch state: 4 commits (MultiDomainBuilder → subprocess scaffolder + nu skeletons → README/testing.md → example-as-build-script), cargo test --workspace --lib --bins clean, cargo clippy --workspace -- -D warnings clean.

Pushed a follow-up commit + rebased onto current `development` (picks up PR #127 / @index integration): - **`b1afe11` — recipe example is a build script, not a checked-in tree.** Replaces 60+ checked-in scaffolder-output files under `examples/recipe_server/` with a 3-step build script at `examples/recipe_example/build.sh`: writes schemas → runs scaffolder → injects ~340 lines of hand-written content (service-method impls, custom type impls, a domain test). Output is gitignored. Eliminates the scaffolder ↔ checked-in-example drift exactly. Net file delta: 60+ files deleted, 8 added under `examples/recipe_example/`. - **Rebased onto origin/development** so PR #127s @index integration + osis_benches expansion are now in the base. The bench compile now passes locally (was the pre-existing breakage I called out in the original PR description — no longer a follow-up). One small reframe on `run_for_test`: it stays. The osis_benches harness *is* the server (no separate `_server` binary to subprocess-spawn), so the Phase F “migrate benches to subprocess” framing doesnt fit. `run_for_test` is the legit in-process variant of `lab --ephemeral` for that case — same code path under the hood now that its a thin wrapper over `MultiDomainBuilder::for_ephemeral()`. Summary of branch state: 4 commits (MultiDomainBuilder → subprocess scaffolder + nu skeletons → README/testing.md → example-as-build-script), `cargo test --workspace --lib --bins` clean, `cargo clippy --workspace -- -D warnings` clean.
hero_rpc#124: delete run_for_test; lab --ephemeral is the only spawn
Some checks failed
Test / test (pull_request) Failing after 2m46s
Test / test (push) Failing after 2m47s
58dfe821ad
Reframe + cleanup pass. `MultiDomainBuilder::for_ephemeral()` is the
single internal-to-hero_rpc_osis primitive for spawning an OSIS
service against a tempdir; `lab service <name> --start --ephemeral`
is the only external entry point that consumers should reach for.
The legacy single-domain `run_for_test<A>` wrapper is gone.

Three changes:

1. `crates/osis/src/rpc/bootstrap.rs` — delete `run_for_test`. Drop
   the `bootstrap::run_for_test` re-export from `rpc/mod.rs`. The
   module docs reframe `MultiDomainBuilder` as the single bootstrap
   primitive shared between production `main.rs` and lab's ephemeral
   spawn path; there is no separate "in-process variant for tests".

2. `crates/osis_benches/benches/index_perf.rs` — drop the old
   `ServerFixture { _running: RunningServer, ... }` shape. The bench
   harness never actually called the server during timed sections
   (every measurement is a direct `Arc<OsisBench>` method call); the
   server was cosmetic. The bench now constructs `OsisBench` against
   a fresh tempdir via `OsisDomainInit::create` directly — no server
   in the loop, no tokio runtime needed in the bench groups.

3. Codegen-emitted `#![allow(clippy::clone_on_copy,
   clippy::needless_borrows_for_generic_args)]` at the generated
   barrel level (`generated/mod.rs` in both the types side via
   `generate/rust_types.rs` and the server side via
   `generate/rust_server.rs`) plus inside the `types.rs` wrapper
   that `include!()`s `generated/types.rs`. Codegen emits `.clone()`
   on Copy enum/primitive fields when building OTOML payloads — the
   redundancy is intentional so the emitter doesn't special-case Copy
   vs non-Copy. The allow keeps `cargo clippy -- -D warnings` green
   on every scaffolded service.

Also touch up docs (BENCH_RESULTS.md, ADR-0002,
generator/src/build/tests_emit.rs, osis Cargo.toml feature comment)
so no stale `run_for_test` reference remains in the tree, and fix a
pre-existing `doc_lazy_continuation` clippy error in
`rust_struct.rs::generate_find_params` that surfaced once the
generator lib started building cleanly under `--workspace`.
Author
Owner

Pushed 58dfe82run_for_test is fully gone. Reframe: MultiDomainBuilder::for_ephemeral() is the only in-tree primitive, and lab service <name> --start --ephemeral is the only external entry point consumers should reach for.

What changed:

  1. Deleted bootstrap::run_for_test. Bench was the last caller. The bench was never actually using the server during timed sections (direct Arc<OsisBench> calls all the way down) — the server was cosmetic. Bench now constructs OsisBench against a fresh tempdir via OsisDomainInit::create directly. No server in the loop, no tokio runtime needed in the bench groups.
  2. Module docs reframed to say: there is no separate "in-process variant for tests". MultiDomainBuilder is the one primitive; production main.rs and lab --ephemeral both go through it; benches use OsisBench::create directly when they only need storage access.
  3. Codegen-emitted #![allow(clippy::clone_on_copy, ...)] at the generated barrel + types-wrapper level so cargo clippy -- -D warnings stays green after the bench unblocks (codegen emits .clone() on Copy types intentionally; the lint was masked previously by the pre-existing bench breakage).

cargo test --workspace --lib --bins + cargo clippy --workspace -- -D warnings both green.

Pushed `58dfe82` — `run_for_test` is fully gone. Reframe: `MultiDomainBuilder::for_ephemeral()` is the only in-tree primitive, and `lab service <name> --start --ephemeral` is the only external entry point consumers should reach for. What changed: 1. **Deleted `bootstrap::run_for_test`**. Bench was the last caller. The bench was never actually using the server during timed sections (direct `Arc<OsisBench>` calls all the way down) — the server was cosmetic. Bench now constructs `OsisBench` against a fresh tempdir via `OsisDomainInit::create` directly. No server in the loop, no tokio runtime needed in the bench groups. 2. **Module docs reframed** to say: there is no separate "in-process variant for tests". MultiDomainBuilder is the one primitive; production main.rs and lab --ephemeral both go through it; benches use OsisBench::create directly when they only need storage access. 3. **Codegen-emitted `#![allow(clippy::clone_on_copy, ...)]`** at the generated barrel + types-wrapper level so `cargo clippy -- -D warnings` stays green after the bench unblocks (codegen emits .clone() on Copy types intentionally; the lint was masked previously by the pre-existing bench breakage). `cargo test --workspace --lib --bins` + `cargo clippy --workspace -- -D warnings` both green.
timur force-pushed issue-124-lifecycle-alignment from 58dfe821ad
Some checks failed
Test / test (pull_request) Failing after 2m46s
Test / test (push) Failing after 2m47s
to 5e72817184
Some checks failed
Test / test (pull_request) Failing after 3m2s
Test / test (push) Failing after 3m6s
2026-05-22 13:08:58 +00:00
Compare
timur merged commit c3cb7c2b4f into development 2026-05-22 13:09:18 +00:00
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!126
No description provided.