# ALPINE Rust SDK Reference
This document covers the ALPINE Rust SDK surface area and common usage patterns.
It is intended for application developers who want a safe, explicit flow from
discovery to control and streaming.
## Goals
- Keep discovery, trust, handshake, and streaming explicit.
- Make unsafe actions opt-in and visible.
- Surface actionable diagnostics for operators and integrators.
## Core lifecycle (typical app)
1. Configure trust (attesters bundle + root pubkey).
2. Discover devices (runner or client).
3. Verify trust and capabilities.
4. Handshake and establish a session.
5. Control, stream, and monitor device state.
6. Close session explicitly when done.
## Environment and quickstart checks
The SDK does not auto-load env vars, but these are commonly used by apps/CLIs:
- `ALPINE_ATTESTERS_URL`
- `ALPINE_ROOT_PUBKEY_B64`
Use `QuickstartChecklist` to validate inputs and UDP reachability:
```rust
use alpine_protocol_sdk::{QuickstartChecklist, TrustConfig};
let trust = TrustConfig::new("https://example.com/attesters/latest")
.with_root_pubkey([0u8; 32]);
let checklist = QuickstartChecklist::run(Some(&trust));
println!("{}", checklist.summary());
```
Use `NetworkHealthReport::probe()` to inspect multicast/broadcast readiness.
## Discovery
### Runner (recommended)
The discovery runner handles unicast, broadcast, cached targets, and optional
subnet scans with clear diagnostics.
```rust
use alpine_protocol_sdk::{DiscoveryRunOptions, run_discovery_with_options};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
let mut opts = DiscoveryRunOptions::defaults_for_lan();
let outcome = run_discovery_with_options(
SocketAddr::new(IpAddr::V4(Ipv4Addr::BROADCAST), 19455),
opts,
).await?;
```
Use `DiscoveryRunOptions::defaults_for_lab()` to disable multicast and prefer
cached targets in lab environments.
Use `run_discovery_with_options_report` to get a `DiscoveryRunReport` with
per-attempt diagnostics and `summary()` hints.
### Dry run
`discovery_dry_run()` shows which NICs and targets would be used without sending
packets. Use `print_table()` for easy human inspection.
### Selection policy
`DeviceSelectionPolicy` enforces allowlist/denylist by device_id, model_id, and
manufacturer_id.
```rust
use alpine_protocol_sdk::DeviceSelectionPolicy;
let policy = DeviceSelectionPolicy {
allow_models: vec!["ALPINE-MK2".to_string()],
deny_device_ids: vec!["deadbeef".to_string()],
..Default::default()
};
policy.enforce(&outcome)?;
```
## Trust and identity
Use the trust bundle to verify device identity attestations. The main helpers are:
- `TrustConfig`, `TrustView`
- `load_or_fetch_trust_view`, `load_cached_trust_view`
- `enforce_trust_policy` with `TrustPolicy`
`TrustPolicy::RequireAttestation` is an alias for strict enforcement.
`DiscoveryOutcome::trust_state()` gives a structured `DeviceTrustState`.
`DiscoveryOutcome::require_trusted()` fails fast with explicit errors.
### Trust bundle pinning
Use `TrustConfig::with_pinned_bundle_issued_at` and
`with_pinned_bundle_signer_kid` to prevent silent trust-root upgrades.
## Handshake and session
Once discovery is complete, call `AlpineClient::connect` or
`AlpineClient::connect_checked`.
`connect_checked` validates that requested capabilities are supported by the
discovered device before handshake.
```rust
use alpine_protocol_sdk::{AlpineClient, DiscoveryOutcome};
use alpine_protocol_rs::crypto::identity::NodeCredentials;
let credentials = NodeCredentials::load("path/to/credentials")?;
let requested = outcome.reply.capabilities.clone();
let client = AlpineClient::connect_checked(outcome, requested, credentials).await?;
```
Use `HandshakeReport` and `TraceTimeline` for a full, timestamped handshake trace.
## Control APIs
### Standard vs vendor status
- `status()` and `status_vendor()` use a vendor command payload.
- `get_status()` uses `ControlOp::GetStatus` and errors with `StatusMismatchError`
if the device only supports vendor status.
### Control options
Use `ControlOptions` to set timeouts and retries. `defaults_for_ui()` sets a
short timeout and a single retry.
```rust
use alpine_protocol_sdk::{ControlCommand, ControlOptions};
let reply = client.control_with_options(ControlCommand::Ping, ControlOptions::defaults_for_ui()).await?;
```
### Dangerous commands
Use `DangerousControlCommand` for firmware update/reboot/identity reset.
Require `ControlOptions::allow_dangerous(true)`.
### Vendor extension registry
Register vendor command strings to avoid magic ops:
```rust
use alpine_protocol_sdk::VendorExtensionRegistry;
let mut registry = VendorExtensionRegistry::new();
registry.register("vendor:custom");
client.set_vendor_extension_registry(registry);
```
## Streaming
Call `start_stream` with a `StreamProfile` and keep the returned `config_id`.
Use `CapabilitiesSummary::validate_profile()` to preflight profiles for the
device capabilities.
Use `send_frame` to deliver channel updates. Streaming is refused if the device
or session capabilities do not allow it.
## SafeClient
`SafeClient` wraps an `AlpineClient` and enforces a probe before control/stream.
```rust
use alpine_protocol_sdk::{SafeClient, SafeClientOptions};
let safe = SafeClient::from_client(client, trust_state, SafeClientOptions::default()).await?;
```
Use `SafeClientOptions::require_trusted(true)` to refuse untrusted devices.
Use `SafeClient::from_discovery()` to wire trust state from discovery without
auto-connecting.
## Typestate clients
`UntrustedClient`, `TrustedClient`, and `ActiveSession` enforce phase ordering
at compile time. Sensitive operations require trusted state.
## Observability and diagnostics
- `AlpineSdkError::user_hint()` gives user-facing hints.
- `AlpineSdkError::internal_cause()` keeps engineer detail.
- `DiscoveryRunReport::summary()` provides actionable hints.
- `ProbeResult::to_ui_badge()` gives severity and color tokens.
- `TraceTimeline` and `HandshakeReport` record ordered steps and timings.
- `SessionGuard` tracks idle time; use `with_idle_reason()` to annotate expiry.
## Capability matching
Use `CapabilitiesSummary` for early validation of formats/channel counts.
Choose strict vs lenient modes with `CapabilityMatchMode`.
Use `CapabilityDeprecationRegistry` to surface deprecation warnings.
## Mode presets
`ClientMode::Ui`, `ClientMode::Automation`, and `ClientMode::Test` configure
default timeouts, retries, and logging verbosity.
## Quarantine mode
Identity anomalies (same IP, different pubkey) mark a device as quarantined.
Quarantined devices are observe-only until cleared via `clear_quarantine`.
## Bad-device simulator
`BadDeviceSimulator` provides a local UDP harness for testing discovery failures
and malformed packets.
## Logging
Use `init_pretty_logging()` or `init_json_logging()` to initialize `tracing`.
## Common examples
### UI app flow (discover, trust, probe)
```rust
use alpine_protocol_sdk::{
DiscoveryRunOptions, run_discovery_with_options_report,
SafeClient, SafeClientOptions, TrustPolicy, enforce_trust_policy
};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
let report = run_discovery_with_options_report(
SocketAddr::new(IpAddr::V4(Ipv4Addr::BROADCAST), 19455),
DiscoveryRunOptions::defaults_for_lan(),
).await;
let outcome = report.result?;
enforce_trust_policy(outcome.trust_state(), TrustPolicy::RequireAttestation)?;
let client = /* connect explicitly */;
let safe = SafeClient::from_discovery(client, &outcome, SafeClientOptions::default()).await?;
let badge = safe.last_probe().to_ui_badge(safe.trust_state());
```
### Automation flow (strict capabilities)
```rust
use alpine_protocol_sdk::{CapabilitiesSummary, CapabilityMatchMode};
let summary = CapabilitiesSummary::from(&outcome.reply.capabilities);
summary.validate_stream_with_mode(channel_format, channel_count, CapabilityMatchMode::Strict)?;
```
### Lab diagnostics flow
```rust
use alpine_protocol_sdk::{DiscoveryRunOptions, discovery_dry_run};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
let opts = DiscoveryRunOptions::defaults_for_lab();
let dry_run = discovery_dry_run(
SocketAddr::new(IpAddr::V4(Ipv4Addr::BROADCAST), 19455),
opts,
)?;
println!("{}", dry_run.print_table());
```
## Error handling conventions
- Use `AlpineSdkError::with_context` to attach device_id/ip/port consistently.
- Treat `StatusMismatchError` as a signal to use vendor status helpers.
- Respect `Quarantined` errors by downgrading to observe-only.
## Files and modules
- `discovery`: discovery runner, diagnostics, and selection policy.
- `trust`: attesters bundle handling and trust policy enforcement.
- `handshake`: handshake report and trace timeline.
- `session`: `AlpineClient`, control APIs, streaming, and `SafeClient`.
- `capabilities`: preflight helpers and deprecation warnings.
- `typestate`: compile-time ordering and trust gating.
- `preflight`: human-readable preflight summaries.
- `network_health`: UDP readiness probes.
- `quickstart`: env/trust/UDP readiness checklist.
- `vendor`: vendor extension registry.
- `simulator`: bad-device simulator for tests.
- `logging`: JSON/pretty logging init.