Why Voice Stub Implementations Don't Require Per-Call #[cfg] Attributes in OpenHuman
The OpenHuman voice module uses a facade-plus-stub pattern that provides identical public symbols regardless of feature flags, eliminating the need for scattered per-call #[cfg] guards throughout the codebase.
The OpenHuman codebase avoids littering conditional compilation attributes across call sites by implementing a sophisticated architectural pattern for optional features. By combining an always-on facade with a feature-gated stub, the voice domain maintains API stability whether the feature is enabled or disabled. This design centralizes conditional logic at the module boundary rather than forcing developers to wrap every voice-related invocation in #[cfg] checks.
Understanding the Facade-Plus-Stub Architecture
Always-On Facade Module
The voice subsystem entry point at src/openhuman/voice/mod.rs declares the module unconditionally using pub mod voice;. This facade compiles in every build configuration, providing a stable import path and guaranteeing that dependent code never encounters "unresolved import" errors due to missing feature flags.
Feature-Gated Real Implementations
Actual voice functionality—including speech recognition, streaming, and audio toolkit operations—resides in sub-modules annotated with #[cfg(feature = "voice")]. When this feature is enabled, these modules provide working implementations for components like server, audio_toolkit, streaming, and dictation_listener.
Automatic Stub Substitution
When the voice feature is disabled, the compiler selects src/openhuman/voice/stub.rs instead (annotated with #[cfg(not(feature = "voice"))]). This stub re-exports the exact same public API surface as the real implementation, including functions like server, dictation_listener, streaming, reply_speech, cloud_transcribe, cli, create_stt_provider, effective_stt_provider, and publish_ptt_transcript_committed. The stub bodies return None, no-ops, or descriptive "voice disabled" errors depending on the expected return type.
Why Callers Don't Need Per-Call #[cfg]
Because the stub presents an identical interface to the real implementation, any code importing openhuman::voice::* compiles successfully regardless of the build configuration. The compiler resolves symbols against the facade, and the build system links either the real implementation or the stub based entirely on the feature flag state.
According to the architecture documentation in AGENTS.md (lines 784-788):
"
pub mod voice;is always compiled as a facade: the real submodules are#[cfg(feature = "voice")], and a#[cfg(not(feature = "voice"))] mod stub;(src/openhuman/voice/stub.rs) re‑exposes the same public surface that always‑on / other‑gated callers use … Callers therefore do not need per‑call#[cfg]. When voice is off: the voice/audio controllers are unregistered … andopenhuman voicereturns a voice disabled error."
This architectural decision ensures that conditional compilation concerns remain encapsulated within the voice module itself.
Practical Code Examples
The following Rust snippets compile and execute identically whether the voice feature is enabled or disabled:
use openhuman::voice;
// Query the current speech-to-text provider configuration
let provider = voice::effective_stt_provider();
// When feature is disabled: returns None (stub behavior)
// When feature is enabled: returns Option<Provider> with actual configuration
use openhuman::voice;
// Attempt to initialize the dictation listener
match voice::dictation_listener::start() {
Ok(handle) => println!("Voice recognition active"),
Err(e) => eprintln!("Voice unavailable: {}", e), // Stub returns disabled-error
}
Neither example requires #[cfg(feature = "voice")] guards because effective_stt_provider and dictation_listener exist in the symbol table via either the real implementation at src/openhuman/voice/dictation_listener.rs or the stub at src/openhuman/voice/stub.rs.
Key Implementation Files
src/openhuman/voice/mod.rs— The unconditional facade module that is always compiledsrc/openhuman/voice/stub.rs— Stub implementation providing no-op versions of all public functions when#[cfg(not(feature = "voice"))]src/openhuman/voice/*.rs— Real implementations compiled only when#[cfg(feature = "voice")]is activeAGENTS.md(lines 784-788) — Architecture documentation describing the facade-stub pattern rationale
Summary
- The facade-plus-stub pattern eliminates the need for per-call conditional compilation in the OpenHuman voice domain.
src/openhuman/voice/mod.rscompiles unconditionally, providing a stable import target for all callers.src/openhuman/voice/stub.rsautomatically substitutes no-op implementations when thevoicefeature is disabled, maintaining API surface compatibility.- Callers import
openhuman::voicewithout#[cfg]guards because the public interface remains identical across both build configurations. - This design centralizes conditional compilation logic at the module boundary rather than scattering it across hundreds of potential call sites.
Frequently Asked Questions
What happens when I call voice functions with the feature disabled?
The stub implementation returns appropriate default values—typically None for optional return types or a descriptive "voice disabled" error for operations requiring active functionality. Your code compiles and executes normally, but voice-dependent operations gracefully degrade or return empty results rather than causing linker errors.
Does the stub increase binary size when voice is enabled?
No. When #[cfg(feature = "voice")] is active, the real voice modules compile instead of the stub. The stub file is excluded from the build entirely via its negative cfg attribute, resulting in zero runtime overhead or binary bloat when the feature is enabled.
Can I apply this pattern to other optional features in OpenHuman?
Yes. The architecture notes in AGENTS.md indicate this facade-stub approach is the recommended pattern for optional feature gates throughout the codebase. Any domain can implement an unconditional facade with feature-protected real modules and a complementary stub module to avoid per-call cfg complexity.
How do I know which functions the stub provides?
The stub at src/openhuman/voice/stub.rs explicitly re-exports all public symbols that the real implementation provides, including server, streaming, cloud_transcribe, and provider management functions. Reviewing this file reveals the complete API contract guaranteed to callers regardless of feature state.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →