Lifecycle alignment, part 2 — examples, dual-home tests, benches-at-root, --bench #129
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_rpc#129
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Lifecycle alignment, part 2 — examples, dual-home tests, benches-at-root,
--benchSibling follow-up to hero_rpc#124. The three PRs that close #124
(hero_rpc#126 + hero_skills#285 + hero_service#8) deliver the core
of the alignment:
MultiDomainBuilder, thelab --ephemeral/--json/--pid/--testsurface, the subprocess-drivertests/src/lib.rs, and the Layer 2–4 nushell skeletons.This issue picks up the items we agreed on in conversation after
the agent's last issue refresh. None block #124; all belong with
the same alignment story.
Scope
1.
examples/scaffolded at workspace rootCargo's standard
examples/directory was dropped from theper-service template by hero_rpc#116 and never replaced. The
scaffolder should emit one starter file:
Regen-once: byte-identical on every re-scaffold, never overwritten
after first emit.
2.
lab service <name> --example [name]New verb in
hero_skills/crates/labparalleling the existing--test [layer]shape. Dispatch:name→ list every example from both sources, exit 0.nameresolution: rootexamples/<name>wins on collision; sibling crate is fallback.--examplespawns its own--start --ephemeral, runs the example withHERO_TEST_SOCKET=<path>(or by parsing the JSON envelope itself — the example chooses), then--stop --pid <N>.3. Two-home dispatch for
--testlab service <name> --test [layer](landed in hero_skills#285) currently runs thetests/crate only. Extend it:Existing
_testsibling crates (hero_router_test,lab_test,hero_proc_test,hero_aibroker_test) become discoverable through the canonical verb without any per-service migration.4.
hero_crates_best_practices_checkskill — two-home convention textAdd the following section to the skill so the two homes for tests
and examples are documented canonically:
5.
benches/at workspace root (consumer services)Per the per-service layout:
tests/andbenches/mirrored atroot. The scaffolder should emit
benches/as a workspace membercrate that shares
spin_up_servicefromtests/:benches/is opt-in at first — emit onlybenches/Cargo.tomlandbenches/src/lib.rsskeleton on initial scaffold. Each.rsbenchfile is hand-authored thereafter.
6.
lab service <name> --bench [name]Implementation:
cargo bench -p <name>_benches [<flags>]under thehood. Mirrors the
--testverb's pass-through shape.Sanction both bench shapes in the skill:
shape): measures pure OSIS storage perf, no UDS overhead. Use for
storage-layer micro-benches.
setup_groupcallsCommand::new("lab") --start --ephemeral, runs through thehero_rpc2::Clientwire path. Use when you want to measure thefull wire RTT.
Both are legitimate; the bench author picks based on what they're
measuring. Document this in
docs/testing.md.7.
serial_testdev-dep in scaffoldedtests/Cargo.tomlAdd
serial_test = "3"(or current) to dev-deps so contributorswho write env-mutating tests don't have to amend Cargo.toml first.
~50 KB compile cost, only paid when cargo test runs.
8.
hero_rpc/crates/osis_benches/→hero_rpc/benches/(optional)For symmetry with the consumer-service layout, move
crates/osis_benches/tobenches/at hero_rpc root. Keep itsinternal-bootstrap shape (no
labsubprocess — hero_rpc is thelibrary that defines
MultiDomainBuilder, calling lab from itwould be circular).
This is cosmetic-only. Skip if it materially complicates the diff.
Out of scope
_testsibling crates intotests/. They stay where they are;--testdispatch discovers them._examplessibling crates intoexamples/(onlylab_test/src/examples/exists; not worth touching).--benchto hero_proc / hero_router / etc. existing services. Per-service follow-up driven by each owner.Acceptance
lab service hero_service --examplelists01_connect;lab service hero_service --example 01_connectruns it green against an auto-spawned ephemeral.lab service hero_service --benchruns the scaffolded criterion benches.examples/01_connect.rsexists, is byte-identical across re-scaffolds, runs green.benches/Cargo.toml+benches/src/lib.rsskeleton exist; adding a starterbenches/index_perf.rsand runninglab --bench index_perfworks end-to-end.lab service hero_router --testdiscovers AND runscrates/hero_router_testalongsidetests/. Same for any other existing_testsibling.hero_crates_best_practices_checkskill includes the two-home convention text.tests/Cargo.tomlin the scaffolded template includesserial_testunder[dev-dependencies].lab service hero_service --teststill runs all 5 layers green.Related
_examplesplaceholders (and never replaced them — this issue does).hero_skills/claude/skills_tocheck/hero_crates_best_practices_check— gets the convention update.hero_skills/claude/skills_tocheck/tests_pyramid— unchanged, layered under--test.Closed by three squash-merges into
development:examples/,benches/,serial_testdev-dep) +osis_benchesrename tobenches/.--example/--benchverbs + dual-home--testLayer-1 dispatch + skill docs (hero_crates_best_practices_check+hero_service_test_complete§0).Acceptance recap
examples/01_connect.rsscaffolded at workspace root (regen-once); byte-identical across re-scaffolds.lab service <name> --example [name]— dual-home dispatch (examples/always +crates/<name>_examples/fallback). No-name listing enumerates both homes.lab service <name> --testLayer 1 is dual-home — runscargo test --workspaceandcargo run -p <name>_testwhencrates/<name>_test/Cargo.tomlexists.hero_crates_best_practices_checkskill carries the verbatim "Tests and examples — two valid homes each" section. Cross-linked fromhero_service_test_complete§0.benches/workspace member emitted with re-export of<name>_tests::*for sharedspin_up_service.lab service <name> --bench [name] [-- <criterion flags>]— pass-through tocargo bench -p <name>_benches. Both bench shapes (in-process direct-handler vs subprocess-via-lab) sanctioned in the skill text.serial_test = "3"under[dev-dependencies]in scaffoldedtests/Cargo.toml.crates/osis_benches/→benches/move. Crate keepshero_rpc_osis_benchespackage name; in-process bootstrap shape preserved (hero_rpc is the library that definesMultiDomainBuilder, calling lab from it would be circular).Decisions taken without confirmation
examples/is a real workspace member (<name>_examplespackage with[[example]]entries pointing at the root.rsfiles) rather than a bare directory at workspace root. Cargo can only run examples that belong to a package; the wrapper is the smallest change that letscargo run -p <name>_examples --example <foo>work, which is what the lab--exampleverb dispatches through.benches/emission gated ongenerate_tests— the starter shape re-exports<name>_tests::spin_up_serviceand that dep would dangle withouttests/.--benchdoes not spawn an ephemeral up-front. 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 RTT. Forcing an ephemeral would penalize the storage-perf shape without buying anything.Layer-1 dual-home runs
cargo run -p <name>_test(singular, matching the existinghero_router_test/lab_test/hero_proc_test/hero_aibroker_testconvention). The check looks forcrates/<name>_test/Cargo.tomlrather than the directory alone, so a stray empty dir from a half-completed move doesn't fire a broken cargo run.The new
--no-examples/--no-benchesflags are surfaced on the standalonehero_rpc_generatorbinary only — a grep acrosshero_skills/crates/lab/src/turned up no scaffold invocation, so wiring them into a lab subcommand would be a future change rather than part of this PR series.hero_skills #302 includes a
chore(fmt)commit bundled into the same PR rather than a separate dev-branch cleanup — dev's CI was failing on the same drift across six files, and splitting the work would have blocked this PR on a chore PR that nobody was going to prioritize.Smoke-test evidence
Unit tests cover the dispatch logic in all three new modules (
bench_verb,example_verb,test_verb::sibling_test_crate). A full end-to-endlab service hero_router --test layer1run (cargo test --workspace + cargo run -p hero_router_test) was not exercised in this PR series — the dispatch is unit-tested and the manuallab service hero_router --test layer1invocation startscargo test --workspaceagainst the correct repo path. Closing.