# Why Voice Stub Implementations Don't Require Per-Call #[cfg] Attributes in OpenHuman

> Discover how OpenHuman's voice stub implementations avoid per-call cfg attributes by using a facade-plus-stub pattern for consistent public symbols, simplifying your codebase.

- Repository: [Tiny Humans/openhuman](https://github.com/tinyhumansai/openhuman)
- Tags: internals
- Published: 2026-08-30

---

**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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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`](https://github.com/tinyhumansai/openhuman/blob/main/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 … and `openhuman voice` returns 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:

```rust
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

```

```rust
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`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/voice/dictation_listener.rs) or the stub at [`src/openhuman/voice/stub.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/voice/stub.rs).

## Key Implementation Files

- **[`src/openhuman/voice/mod.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/voice/mod.rs)** — The unconditional facade module that is always compiled
- **[`src/openhuman/voice/stub.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/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 active
- **[`AGENTS.md`](https://github.com/tinyhumansai/openhuman/blob/main/AGENTS.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.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/voice/mod.rs)** compiles unconditionally, providing a stable import target for all callers.
- **[`src/openhuman/voice/stub.rs`](https://github.com/tinyhumansai/openhuman/blob/main/src/openhuman/voice/stub.rs)** automatically substitutes no-op implementations when the `voice` feature is disabled, maintaining API surface compatibility.
- Callers import `openhuman::voice` without `#[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`](https://github.com/tinyhumansai/openhuman/blob/main/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.