Skip to content

[FEATURE] Database-Backed Configuration System with Versioning #35

@scottchronicity

Description

@scottchronicity

Context

Orpheus currently lives in a single orpheus.yaml file. That works for one station, but it doesn't support per-environment overrides, runtime tuning without restarts, or configuration versioning. Implement a layered configuration system:

  1. Base: orpheus.yaml (checked into git)
  2. Overrides: Database-stored settings (runtime-tunable)
  3. Final: Environment variables (deployment-specific, highest priority)

This enables a future multi-station deployment where each station has a base config with local overrides.

Architecturally Significant Requirements (ASRs)

Interface (Contract):

  • ConfigStore class with methods:
    • get(key: str, default: Any = None) -> Any — layered lookup (env → DB → YAML).
    • set(key: str, value: Any, author: str = "system") -> ConfigVersion — write to DB layer with version tracking.
    • history(key: str, limit: int = 10) -> List[ConfigVersion] — audit trail.
    • subscribe(key_pattern: str, callback: Callable) -> None — hot-reload notification.
  • ConfigVersion dataclass: {"key": str, "value": Any, "author": str, "changed_at": str, "version": int}.
  • Backward compatibility: OrpheusConfig.get_instance() delegates to ConfigStore internally.

Implementation (Internal Logic):

  • Layered resolver: check env vars first, then SQLite config_overrides table, then YAML file.
  • SQLite schema: config_versions table with key, value_json, author, changed_at, version (auto-increment per key).
  • MQTT publication to orpheus/system/config_changed with key and new value on every set() call.

Architectural Constraints

  • Must be backward-compatible with existing OrpheusConfig.get_instance() usage.
  • Database schema must version every configuration change (who changed what, when).
  • Must not require a migration for existing deployments — if no DB config exists, fall back to YAML.
  • Configuration changes must be publishable to MQTT so agents can hot-reload without restart.
  • Must be Python 3.9 compatible.

Acceptance Criteria

Feature: Database-Backed Configuration System

  Scenario: Layered config lookup (env > DB > YAML)
    Given orpheus.yaml sets "audio.volume" to 0.5
    And the DB override sets "audio.volume" to 0.7
    When config.get("audio.volume") is called
    Then the returned value is 0.7

  Scenario: Environment variable takes highest priority
    Given orpheus.yaml sets "audio.volume" to 0.5
    And the DB override sets "audio.volume" to 0.7
    And ORPHEUS_AUDIO_VOLUME env var is set to 0.3
    When config.get("audio.volume") is called
    Then the returned value is 0.3

  Scenario: Config change triggers MQTT notification
    Given an agent subscribes to "orpheus/system/config_changed"
    When config.set("audio.volume", 0.8, author="admin") is called
    Then the agent receives an MQTT message with key "audio.volume" and value 0.8
    And a new version record is created in the config_versions table

  Scenario: Backward compatibility with existing code
    Given existing code calls OrpheusConfig.get_instance()
    When the ConfigStore is initialized
    Then OrpheusConfig.get_instance() still works identically
    And no code changes are required in existing agents

Definition of Done

  • ConfigStore class in orpheus-common implementing the layered lookup (YAML → DB → env).
  • SQLite schema for versioned configuration storage.
  • MQTT notification on config change so agents can subscribe and reload.
  • Migration guide documenting upgrade path for existing deployments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C4: ComponentInternal logical boundaries (Classifiers, Managers)component: commonplatform/orpheus-commondomain: configConfiguration management and versioningtype: featureNew functionality

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions