| Actual State |
Runtime health and activity of a service (healthy/degraded/crashed). Published to Redis by each service via the SilvaService heartbeat: SET silvasonic:status:<id> with TTL (current snapshot) + PUBLISH silvasonic:status (live updates). Web-Interface uses the Read+Subscribe Pattern. Not persisted in the database. See ADR-0017, ADR-0019. |
| Auto-Enrollment |
Feature where the Controller automatically enrolls a newly detected USB device if it has an exact Match Criteria hit (score 100 = USB Vendor+Product ID). Controlled by the auto_enrollment flag in system_config (key system). Default: true. Can be changed at runtime via the Web-Interface — the Controller reads this setting every reconciliation cycle (no restart required). See Controller README §Profile Matching. |
| Consumer Principle |
Any service consuming data it did not create MUST mount that data read-only (e.g. BirdNET and BatDetect mount Recorder data as read-only). Protects source data from software faults. |
| Data Capture Integrity |
The paramount design principle: any operation that risks the continuity of sound recording is forbidden. All architectural decisions are subordinate to this rule. |
| Data Retention Policy |
Rules enforced by the Janitor for deleting old local files based on disk usage thresholds. Recordings are only deleted after confirmed upload. |
| Desired State |
The intended operational mode of a service, stored in the system_services table (enabled, status). Set by admin or Web-Interface. Not to be confused with Actual State. See ADR-0017. |
| Device Binding |
Persistent identification of a physical microphone via a Stable Device ID. Devices with USB serial numbers are identified as {vendor_id}-{product_id}-{serial} (globally unique). Devices without serials use {vendor_id}-{product_id}-port{bus_path} (stable per USB port). The Stable Device ID is stored as devices.name (PK) and determines Recorder name, workspace path, and Redis instance ID. Re-plugging a microphone re-activates the same Recorder. See Controller README §Device Identity. |
| Device Enabled Flag |
Boolean flag on the devices table (enabled, default true). When set to false, the Controller immediately stops the Recorder for this Device regardless of Enrollment Status. Acts as an emergency stop. |
| DeviceScanner |
Controller component that performs a full scan of all ALSA sound cards via /proc/asound/cards, correlates each with its USB parent via sysfs, and synchronizes the result with the devices table. Runs every reconciliation cycle (1 s interval) as the primary USB detection mechanism. See Controller README §USB Detection. |
| Domain-Driven Workspace Isolation |
Each service owns exactly one top-level directory in the Workspace matching its service name. No shared folders for persistent state. Enforces the Single Writer principle. |
| Dual Stream Architecture |
Recording strategy producing two simultaneous outputs per microphone: Raw (native sample rate) and Processed (48 kHz). Ensures hardware independence for downstream consumers. |
| Enrollment Status |
The state of a Device in its registration lifecycle: pending (new/unassigned), enrolled (assigned a Microphone Profile, eligible for recording), ignored (suppressed — Controller will never start a Recorder for this Device). Tracked in the devices table. |
| Factory Reset |
Deletion of all content within the Workspace path. The directory structure is immediately reconstructible by re-running the init script. |
| Filesystem Polling |
Communication pattern where the Processor watches the Recorder's workspace directories for new audio files, then indexes them into the database. See Messaging Patterns. |
| Heartbeat |
Periodic status message published by each service to Redis via the SilvaService base class (interval: see DEFAULT_HEARTBEAT_INTERVAL_S in heartbeat.py). Contains service name, instance ID, health status, activity, and optional metadata. Fire-and-forget — failures are silently caught. See ADR-0019. |
| Immutable Container |
A service that receives all configuration at launch time and never modifies its own state. All Tier 2 services plus the Processor (Tier 1) are immutable. The Recorder has no DB access; other immutable services may access the database. See ADR-0019. |
| Live Log Stream |
Real-time container log feed published via PUBLISH silvasonic:logs (Redis). The Controller reads Podman container stdout (structlog JSON) and forwards it to Redis. The Web-Interface subscribes and displays logs via SSE + Alpine.js auto-scroll. Fire-and-forget — if no subscriber is connected, logs are simply not displayed. See ADR-0022. |
| Live Stream |
(Planned) Real-time audio stream in Opus format, sent from a Recorder to the Icecast server (one mount point per microphone). Enables live monitoring of the soundscape via the Web-Interface without accessing stored recordings. Best-effort: does not compromise Data Capture Integrity. |
| Match Criteria |
Structured data within a Microphone Profile that defines how to match a USB device to that profile. Contains usb_vendor_id, usb_product_id (primary, stable), and alsa_name_contains (secondary, case-insensitive substring). Stored in the profile's config JSONB column under audio.match. Replaces the legacy match_pattern text field. See Microphone Profiles. |
| Mount Point |
(Planned) An Icecast endpoint path (e.g. /mic-ultramic.opus) representing one audio source. Each Recorder pushes to its own mount point; the Web-Interface selects which mount point to listen to. |
| OOM Killer |
Linux kernel mechanism that terminates processes when physical memory is exhausted. Silvasonic mitigates this via oom_score_adj and container memory limits (ADR-0020). |
OOM Score Adjust (oom_score_adj) |
Linux kernel parameter (-1000 to +1000) that biases the OOM Killer's target selection. Lower values = less likely to be killed. The Recorder uses -999 (maximum protection); analysis workers use +500 (expendable). See ADR-0020. |
| Opus |
(Planned) Lossy audio codec optimized for low-latency, high-quality streaming. Used exclusively for the live audio stream (Recorder → Icecast). Not used for archival — Raw and Processed recordings remain WAV/FLAC. |
Processed Artifact (file_processed) |
The standardized 48 kHz version of an audio recording, derived from the raw stream. Used as input for analysis (BirdNET, BatDetect), visualization, and consumption. Local format: WAV. |
| Profile Injection |
The mechanism by which the Controller injects Microphone Profile configuration into Recorder containers via environment variables at creation time. Applies exclusively to the Controller ↔ Recorder relationship. |
| QoS (Quality of Service) |
Tiered resource priority scheme ensuring critical services (Recorder) are never starved by optional services (BirdNET, BatDetect). Implemented via oom_score_adj and resource limits (ADR-0020). |
| Quadlet |
Podman-native systemd unit files (.container, .volume, .network) used for production deployment. Ensures automatic restart after power loss without compose. |
Raw Artifact (file_raw) |
The bit-perfect copy of the audio stream at the hardware's native sample rate. Preserved strictly for archival and scientific purposes; never modified. Local format: WAV. Cloud format: FLAC. |
| Read+Subscribe Pattern |
Two-step pattern used by the Web-Interface to display service status: (1) read all silvasonic:status:* keys for initial state, (2) subscribe to silvasonic:status for live updates. Solves the Pub/Sub "missed heartbeat" problem. See Messaging Patterns. |
| Reconcile-Nudge |
A simple PUBLISH silvasonic:nudge "reconcile" signal sent by the Web-Interface after a DB write to wake the Controller immediately instead of waiting for its reconciliation timer. Not a command — just a wake-up signal. If lost, the timer catches up. See Messaging Patterns. |
| Reconciliation |
The Controller's periodic process of comparing desired vs. actual Tier 2 container state and correcting drift (adopting orphans, restarting missing containers). Interval: see DEFAULT_RECONCILE_INTERVAL_S in reconciler.py. |
| Repository |
The immutable code directory (SILVASONIC_REPO_PATH) containing source code, scripts, and configuration templates. Containers have read-only access in production. |
| Resource Limits |
Podman container constraints (--memory, --cpus) enforced via Linux cgroups v2. Prevents any single container from exhausting host resources. See ADR-0020. |
| ServiceContext |
Shared infrastructure primitive used directly by HTTP/FastAPI services via lifespans. |
| SilvaService |
Base class (silvasonic.core.service.SilvaService) providing the canonical lifecycle for background worker services and immutable containers: logging, health server, Redis connection, heartbeat, signal handling. See ADR-0019. |
| Soundscape |
The complete acoustic environment captured by the system — from low-frequency avian vocalizations to ultrasonic bat echolocation calls. Not limited to a single species or frequency band. |
| State Reconciliation Pattern |
Declarative control pattern inspired by Kubernetes Operators. The Web-Interface writes desired state to DB, sends a Reconcile-Nudge, and the Controller reconciles. The Controller has no imperative API — it is a pure Listener + Actor. See ADR-0017. |
| Store & Forward |
Architecture pattern where recordings are written to local NVMe first. Synchronization to remote storage happens opportunistically — the station never depends on network connectivity. |
| Tier 1 (Infrastructure) |
Services managed by Podman Compose (dev) or Quadlets (prod). Always running. Includes Database, Controller, Gateway, Icecast, Processor, Web-Interface, Redis, Tailscale. |
| Tier 2 (Application) |
Services managed dynamically by the Controller at runtime. All Tier 2 containers are immutable. Includes Recorder, Uploader, BirdNET, BatDetect, Weather. |
| Worker Pull |
Orchestration pattern where analysis workers (BirdNET, BatDetect) independently poll the recordings table for unprocessed files, claiming work atomically via SELECT … FOR UPDATE SKIP LOCKED. See ADR-0018. |
| Workspace |
The mutable state directory (SILVASONIC_WORKSPACE_PATH) where all runtime data (recordings, configs, service state) is persisted. Strictly separated from the immutable code repository. |