CLI: migrate to clap; add wizen, compose-runner, run subcommands - #86
Merged
Conversation
The composition/execution half of the CLI's charter (#13) plus #85's wizen productization, in one move because all three need the same dependency step change (the CLI now embeds wasmtime). clap 4 derive replaces the hand-rolled parser: lock/fold/aggregate/ emit/pins keep their flags, semantics, and verdict exit codes; usage errors now exit 2 with clap's messages (previously 1 via bail). pins keeps its check-vs-bump split (args_conflicts_with_subcommands + subcommand_negates_reqs); every -o gains a --output long form. wizen (alias wizer): wizer pre-initialization as a first-class subcommand (#85). The mechanism moves into component-test-runner as wizen/wizen_with (feature `wizer`), mirroring Runner::new/with_data so SUT-importing suites reuse the linker setup they already have — instantiation is eager, so the shipped driver alone cannot wizen them. The wizer-preinit bin is subsumed and deleted. The docs carry the non-negotiable caveats: the snapshot freezes what init observed (env, entropy, clocks), and the wizened artifact must be used everywhere downstream. compose-runner: the examples/compose topology as a library (wac-graph 0.10) — one shared provider instance feeding the suite's test-context and the runner core's factory/test-context, which is exactly what wac plug cannot express. Inputs classify by exports: bare suites get the provider; bundles (tests + test-context + factory re-exported) skip it; partial bundles and already-composed components are rejected by name. Defaults are size-optimized `embed`-profile builds of runner-cli and provider committed under crates/component-test-cli/embedded/ (118KB + 68KB), overridable via --runner/--provider; regenerate with `just embed-update`. Freshness is gated behaviorally — verify-cli diffs their output against the Path-2 goldens; a byte-compare gate would violate #44's no-cross-environment-reproducibility rule. run: compose-runner + execution in one step. A minimal wasmtime embedding equivalent to `wasmtime run -W component-model-async -S p3`: WASI p2 (suite/provider std imports) + p3 (the runner core's stdout and run entry point), Command::instantiate_async + run_concurrent, I32Exit downcast, exit code from the guest. Env is explicit like wasmtime run's; --jsonl sets COMPONENT_TEST_JSONL=1 for the wire format. verify-cli joins `just all` (so CI gates it): compose-runner's output under the wasmtime CLI, run's human + JSONL legs against the existing Path-2 goldens byte-for-byte, and wizen legs proving finding #22 stays true through the productized path — the wizened sample suite passes lock --check, reproduces the host-embed golden, and composes + runs identically. New wasm-gated integration tests cover the same from cargo (`just test-wasm`). Verified: just check, just all (full matrix incl. verify-cli), just test-wasm; manual legs for bundle input, pre-composed input, wizer alias, overrides, and rejection messages. Also verified along the way: a wizened suite composes and runs under wac-graph composition — wizer output stays a plain component (the "nested components" limit applies to wizer inputs, not outputs).
This was referenced Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the CLI half of #85 (plus the
compose/runitems from #13's charter).What
lock/fold/aggregate/emit/pinskeep their flags, semantics, and verdict exit codes. Usage errors now exit 2 with clap's messages (previously 1 viabail); duplicate scalar flags now error instead of last-wins. Every-ogains a--outputlong form.wizen(aliaswizer): Productize wizer pre-initialization: library entry point, setup action, discoverability #85's subcommand, subsuming the deletedwizer-preinitbin. The mechanism lands as library entry points in component-test-runner —wizen::wizen/wizen::wizen_with(featurewizer), mirroringRunner::new/with_dataso SUT-importing suites reuse their existing linker setup (Productize wizer pre-initialization: library entry point, setup action, discoverability #85's library checkbox). Docs carry the required caveats: the snapshot freezes what init observed (env/entropy/clocks); run the wizened artifact everywhere downstream.compose-runner: the examples/compose topology as a library (wac-graph 0.10), one shared provider instance — whatwac plugcannot express. Inputs classify by exports: bare suite → embedded reference provider; bundle (tests+test-context+factory) → provider skipped; partial bundles and already-composed inputs rejected by name. Embedded defaults are size-optimizedembed-profile builds of runner-cli (118KB) + provider (68KB) committed undercrates/component-test-cli/embedded/, overridable via--runner/--provider;just embed-updateregenerates.run: compose-runner + execution — a minimal wasmtime embedding equivalent towasmtime run -W component-model-async -S p3(WASI p2+p3,Command+run_concurrent,I32Exitdowncast, guest exit code;--jsonlsets the wire format). Accepts suites, bundles, or pre-composed components.Verification
just check,just all(full matrix),just test-wasm— all green.all, hence CI): compose-runner's output under the wasmtime CLI,runhuman + JSONL against the existing Path-2 goldens byte-for-byte, and wizen legs (lock--checkon the wizened artifact, host-embed golden, compose+run of the wizened artifact) — finding Runner execution-policy guidance #22 stays true through the productized path.#85 checkboxes covered
wizen_withfor SUT-importing suitescomponent-test wizensubcommand (subsumes the bin)cases_per_instancedocs, README scope list, sample-suite README "Large suites" section, findings driver lineNot covered here (still open in #85):
actions/setupwiring, the runner execution-policy doc, the wasm-opt post-pass spike, the #25 close-out comment.Follow-ups surfaced in review (non-blocking, happy to file)
compose.rs: explicit rejection for the context-without-factory partial-bundle shape(addressed in this PR).run.rs: document stdin/argv divergence from(addressed in this PR).wasmtime runembed-updatereminders are the mitigation.