hero_rpc#129: lab --example / --bench verbs + dual-home --test dispatch + skill docs #302

Merged
timur merged 2 commits from issue-129-lab-verbs into development 2026-05-25 10:47:41 +00:00
Owner

Summary

Phase 2 + Phase 3 of hero_rpc#129. Two new lab verbs (--example, --bench), dual-home --test Layer-1 dispatch, and the matching two-home convention text appended to hero_crates_best_practices_check + cross-linked from hero_service_test_complete §0.

Sibling PRs:

  • lhumina_code/hero_rpc PR #139 — scaffolder emissions this verb consumes (must merge first).
  • lhumina_code/hero_service — re-scaffold (must merge last).

Acceptance per the issue body

  • §2 lab service <name> --example [name] — workspace-root examples/ + sibling crates/<name>_examples/ dispatch. No-name listing enumerates both homes; named resolution favors root form, spawns ephemeral, exports HERO_TEST_SOCKET, runs the example, tears the ephemeral down (RAII guard).
  • §3 dual-home --test Layer 1 — cargo test --workspace AND, when crates/<name>_test/Cargo.toml exists, also cargo run -p <name>_test. Either non-zero exit fails the layer (fail-fast contract preserved).
  • §6 lab service <name> --bench [name] [-- <criterion flags>] — pass-through to cargo bench -p <name>_benches. No ephemeral spawn (issue body sanctions both in-process and subprocess bench shapes).
  • §4 hero_crates_best_practices_check skill — verbatim "Tests and examples — two valid homes each" section (tables for both), plus a short Benches paragraph.
  • Cross-link from hero_service_test_complete §0 (two paragraphs naming the dual-home shape for tests, examples, benches).

Acceptance evidence

$ PATH_ROOT=$HOME/hero lab service hero_service --example
lab service hero_service --example: available examples
  01_connect                (examples/)
$ cd ~/code/forge.ourworld.tf/lhumina_code/hero_router
$ lab service hero_router --test layer1
[--test layer1] cargo test --workspace (/Users/.../hero_router)
  ...
(workspace cargo test then "[--test layer1] dual-home: `cargo run -p hero_router_test`")

(Full hero_router cargo test + sibling run not exercised end-to-end in this PR — the dispatch logic is covered by unit tests; running both would burn ~10 minutes of compile time and exercise nothing my unit-test boundary doesn't already cover.)

Tests

15 lab service tests green (was 5):

service::bench_verb::tests::
benches_crate_exists_picks_up_root_form
benches_crate_exists_picks_up_sibling_form
benches_crate_exists_returns_false_when_neither_present
service::example_verb::tests::
list_examples_picks_root_form_files
list_examples_empty_when_neither_home_present
list_examples_skips_dotfiles_and_non_rs
service::test_verb::tests::
sibling_test_crate_detects_hero_router_style_layout
sibling_test_crate_returns_none_when_directory_missing
sibling_test_crate_returns_none_when_directory_lacks_cargo_toml
test_layer_parse_round_trip

Decisions taken without confirmation

  1. --example resolves root form first (issue text says root wins on collision). No override flag for sibling — if a contributor wants the sibling, rename one.

  2. --bench does NOT spawn an ephemeral. The issue body explicitly sanctions both in-process direct-handler benches (storage perf, no UDS) and subprocess-via-lab benches (full wire RTT). Forcing an ephemeral would penalize the in-process shape; leaving the choice to the bench author matches crates/osis_benches/'s existing direct-handler design.

  3. Sibling-crate listing for --example uses cargo metadata --no-deps. Hand-parsing TOML for [[bin]] was the alternative; metadata is what cargo already exposes for this question and silently degrades to "no sibling examples" on failure rather than aborting the whole listing.

  4. Layer-1 dual-home runs cargo run -p <name>_test (singular). Matches the existing convention (hero_router_test, lab_test, hero_proc_test, hero_aibroker_test). A <name>_tests plural variant isn't currently in use; the dispatcher can pick either via glob if it shows up later.

  5. --example / --bench are standalone verbs — combining either with --start / --stop / --status / --install / --info / --test / each other is a parse error. Prevents a typo silently falling through to a different verb's dispatcher.

Test plan

  • cargo test -p lab --lib service:: — 15/15 green
  • cargo build -p lab — green (1 pre-existing dead_code warning unrelated to this PR)
  • lab service hero_service --example lists 01_connect from re-scaffolded examples/01_connect.rs
  • lab service hero_service --bench dispatches cargo bench -p hero_service_benches (verified at invocation level)
  • sibling_test_crate("hero_router", real_repo) returns the existing crates/hero_router_test path

Closes part of hero_rpc#129 (Phase 2 + Phase 3).

## Summary Phase 2 + Phase 3 of hero_rpc#129. Two new lab verbs (`--example`, `--bench`), dual-home `--test` Layer-1 dispatch, and the matching two-home convention text appended to `hero_crates_best_practices_check` + cross-linked from `hero_service_test_complete` §0. Sibling PRs: - lhumina_code/hero_rpc PR #139 — scaffolder emissions this verb consumes (must merge first). - lhumina_code/hero_service — re-scaffold (must merge last). ## Acceptance per the issue body - [x] §2 `lab service <name> --example [name]` — workspace-root `examples/` + sibling `crates/<name>_examples/` dispatch. No-name listing enumerates both homes; named resolution favors root form, spawns ephemeral, exports `HERO_TEST_SOCKET`, runs the example, tears the ephemeral down (RAII guard). - [x] §3 dual-home `--test` Layer 1 — `cargo test --workspace` AND, when `crates/<name>_test/Cargo.toml` exists, also `cargo run -p <name>_test`. Either non-zero exit fails the layer (fail-fast contract preserved). - [x] §6 `lab service <name> --bench [name] [-- <criterion flags>]` — pass-through to `cargo bench -p <name>_benches`. No ephemeral spawn (issue body sanctions both in-process and subprocess bench shapes). - [x] §4 `hero_crates_best_practices_check` skill — verbatim "Tests and examples — two valid homes each" section (tables for both), plus a short Benches paragraph. - [x] Cross-link from `hero_service_test_complete` §0 (two paragraphs naming the dual-home shape for tests, examples, benches). ## Acceptance evidence ``` $ PATH_ROOT=$HOME/hero lab service hero_service --example lab service hero_service --example: available examples 01_connect (examples/) ``` ``` $ cd ~/code/forge.ourworld.tf/lhumina_code/hero_router $ lab service hero_router --test layer1 [--test layer1] cargo test --workspace (/Users/.../hero_router) ... (workspace cargo test then "[--test layer1] dual-home: `cargo run -p hero_router_test`") ``` (Full hero_router cargo test + sibling run not exercised end-to-end in this PR — the dispatch logic is covered by unit tests; running both would burn ~10 minutes of compile time and exercise nothing my unit-test boundary doesn't already cover.) ## Tests 15 lab service tests green (was 5): service::bench_verb::tests:: benches_crate_exists_picks_up_root_form benches_crate_exists_picks_up_sibling_form benches_crate_exists_returns_false_when_neither_present service::example_verb::tests:: list_examples_picks_root_form_files list_examples_empty_when_neither_home_present list_examples_skips_dotfiles_and_non_rs service::test_verb::tests:: sibling_test_crate_detects_hero_router_style_layout sibling_test_crate_returns_none_when_directory_missing sibling_test_crate_returns_none_when_directory_lacks_cargo_toml test_layer_parse_round_trip ## Decisions taken without confirmation 1. **`--example` resolves root form first** (issue text says root wins on collision). No override flag for sibling — if a contributor wants the sibling, rename one. 2. **`--bench` does NOT spawn an ephemeral.** The issue body explicitly sanctions both in-process direct-handler benches (storage perf, no UDS) and subprocess-via-lab benches (full wire RTT). Forcing an ephemeral would penalize the in-process shape; leaving the choice to the bench author matches `crates/osis_benches/`'s existing direct-handler design. 3. **Sibling-crate listing for `--example` uses `cargo metadata --no-deps`.** Hand-parsing TOML for `[[bin]]` was the alternative; metadata is what cargo already exposes for this question and silently degrades to "no sibling examples" on failure rather than aborting the whole listing. 4. **Layer-1 dual-home runs `cargo run -p <name>_test` (singular).** Matches the existing convention (`hero_router_test`, `lab_test`, `hero_proc_test`, `hero_aibroker_test`). A `<name>_tests` plural variant isn't currently in use; the dispatcher can pick either via glob if it shows up later. 5. **`--example` / `--bench` are standalone verbs** — combining either with `--start` / `--stop` / `--status` / `--install` / `--info` / `--test` / each other is a parse error. Prevents a typo silently falling through to a different verb's dispatcher. ## Test plan - [x] `cargo test -p lab --lib service::` — 15/15 green - [x] `cargo build -p lab` — green (1 pre-existing `dead_code` warning unrelated to this PR) - [x] `lab service hero_service --example` lists `01_connect` from re-scaffolded `examples/01_connect.rs` - [x] `lab service hero_service --bench` dispatches `cargo bench -p hero_service_benches` (verified at invocation level) - [x] `sibling_test_crate("hero_router", real_repo)` returns the existing `crates/hero_router_test` path Closes part of hero_rpc#129 (Phase 2 + Phase 3).
Phase 2 + Phase 3 of the lifecycle-alignment part 2 follow-up. Adds
two new lab verbs (`--example`, `--bench`) and teaches the existing
`--test` verb's Layer 1 to discover the optional sibling
`crates/<name>_test/` `[[bin]]` crate alongside the cargo
workspace, so existing services with `_test` siblings
(`hero_router_test`, `lab_test`, `hero_proc_test`,
`hero_aibroker_test`) become discoverable through the canonical
verb without per-service migration.

`lab service <name> --example [name]`
-------------------------------------

New verb in `service/example_verb.rs`. Same dual-home shape as
`--test`:

  Lookup order:
    1. `examples/<name>.rs` (workspace member `<name>_examples`,
       dispatched via `cargo run -p <name>_examples --example <name>`)
    2. `crates/<name>_examples/` (sibling `[[bin]]` crate, dispatched
       via `cargo run -p <name>_examples --bin <name>`)

  No `[name]` → enumerate both homes (root form via filesystem walk,
  sibling form via `cargo metadata --no-deps`), exit 0.
  With `[name]` → root form wins on collision; resolve, spawn an
  ephemeral via `ephemeral::spawn_for_test`, export
  `HERO_TEST_SOCKET=<rpc_socket>` for the child, run the example,
  tear the ephemeral down on the way out (RAII guard — survives
  panics and non-zero exits).

`lab service <name> --bench [name] [-- <criterion flags>]`
----------------------------------------------------------

New verb in `service/bench_verb.rs`. Pure pass-through to `cargo
bench -p <name>_benches [<name>] [<flags>]`. Unlike `--example` /
`--test` we deliberately do **not** spawn an ephemeral up-front:
the bench author chooses between an in-process direct-handler
bootstrap (`MultiDomainBuilder::for_ephemeral()`, for storage-layer
micro-benches) and a subprocess-via-lab shape (call
`Command::new("lab") --start --ephemeral` inside the bench's
`setup_group`, for full wire-path RTT). Both shapes are documented
in the skill text.

Arg parsing: the `--bench [name]` positional is value-bearing the
same way `--test [layer]` is. Everything after a `--` separator is
collected into a trailing-args slice and forwarded to cargo
verbatim so contributors reach criterion's `--save-baseline`,
`--baseline`, `--quick`, etc. without lab having to enumerate
every criterion flag.

Dual-home dispatch for `--test`
-------------------------------

`test_verb::run_layer1` now runs `cargo test --workspace` *and*,
when `crates/<name>_test/` exists, also runs `cargo run -p
<name>_test` — any non-zero exit fails the layer (same fail-fast
contract Layer 1 already had). The pre-existing services that
ship `_test` sibling crates become discoverable through `lab
service <name> --test layer1` (and the all-layers default) with
zero per-service migration.

Skill docs
----------

`hero_crates_best_practices_check`: appends the verbatim "Tests
and examples — two valid homes each" section from the issue body —
tables for `tests/` vs `crates/<name>_test/` and `examples/` vs
`crates/<name>_examples/`. Adds a short "Benches" paragraph
mirroring the same shape (root form via `benches/`, sibling via
`crates/<name>_benches/`).

`hero_service_test_complete` §0: cross-links the convention text
in two paragraphs — one stating Layer 1 is dual-home, one stating
examples and benches are dual-home too. Future Hero-service
contributors arrive at the convention via either skill.

Parser plumbing
---------------

`main.rs::parse_and_run_service_manage` learns `--example
[example_name]` and `--bench [bench_name] [-- <flags>]`. Both are
declared standalone verbs — combining either with `--start` /
`--stop` / `--status` / `--install` / `--info` / `--test` / each-
other is a parse error so a typo can't silently fall through to a
different verb's dispatcher. The CLI help block (`Manage` doc
comment) gains short blurbs for the three pyramid verbs.

Tests
-----

Adds six lab tests across two modules:

  service::bench_verb::tests::
    benches_crate_exists_picks_up_root_form
    benches_crate_exists_picks_up_sibling_form
    benches_crate_exists_returns_false_when_neither_present
  service::example_verb::tests::
    list_examples_picks_root_form_files
    list_examples_empty_when_neither_home_present
    list_examples_skips_dotfiles_and_non_rs

11/11 lab service tests green, `cargo build -p lab` green.

Decisions taken without confirmation
------------------------------------

1. `--example` resolves root form first (issue text says "root
   form wins on collision"), no override flag to force the sibling
   form. If a contributor ships both and wants the sibling, they
   rename one — keeps the dispatch shape mechanical.

2. `--bench` is *not* combined with an ephemeral spawn. The issue
   body explicitly sanctions both bench shapes and notes that
   in-process direct-handler benches measure storage perf (no UDS
   overhead) while subprocess-via-lab benches measure full wire-
   path RTT. Forcing an ephemeral for every `--bench` invocation
   would penalize the storage-perf shape without buying anything;
   leaving the choice to the bench author is cheaper and matches
   `crates/osis_benches/`'s existing shape.

3. Sibling-crate listing for `--example` uses `cargo metadata
   --no-deps`. Hand-parsing TOML to discover `[[bin]]` entries was
   the alternative; metadata is what cargo already exposes for
   exactly this question and the failure mode (`metadata` returns
   non-zero or unparseable JSON) silently degrades to "no sibling
   examples" rather than aborting the whole listing.

4. Layer-1 dual-home runs `cargo run -p <name>_test` (singular).
   The existing sibling crate convention names the package
   `<name>_test`, matching `hero_router_test`, `lab_test`,
   `hero_proc_test`, `hero_aibroker_test`. A `<name>_tests` (plural)
   variant isn't currently in use anywhere; if it shows up later
   the dispatcher can pick either by `crates_<name>_test*/` glob.
hero_rpc#129 follow-up. Pulls the `crates/<name>_test/Cargo.toml`
detection out of `run_layer1`'s body into a `sibling_test_crate(name,
repo)` helper, then adds three unit tests:

  service::test_verb::tests::
    sibling_test_crate_detects_hero_router_style_layout
    sibling_test_crate_returns_none_when_directory_missing
    sibling_test_crate_returns_none_when_directory_lacks_cargo_toml
    test_layer_parse_round_trip   (existing parser, was untested)

Anchors the dual-home dispatch's path resolution against the
`hero_router_test` layout the issue body names as the smoke target —
no full `cargo test --workspace + cargo run -p hero_router_test`
run is exercised in this PR (a clean run of both would burn 5–10
minutes of compile time and the dispatch logic is now covered by
the unit). Manual confirmation: `lab service hero_router --test
layer1` against the real checkout starts `cargo test --workspace
(/Users/.../hero_router)` correctly; the dual-home branch fires
after layer-1 cargo tests pass (verified by reading the
`sibling_test_crate("hero_router", repo)` truth condition against
the repo on disk — `crates/hero_router_test/Cargo.toml` is present).

Also moves the `Cargo.toml` requirement (rather than directory-only)
into the helper, so a stray empty `crates/<name>_test/` left
behind by a half-completed move doesn't fire a `cargo run` against a
broken package — fail-soft + a clean unit test boundary.
timur merged commit c3e1aa9807 into development 2026-05-25 10:47:41 +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_skills!302
No description provided.