System Architecture¶
This page describes the runtime architecture of Lyndrix Core and how the main subsystems interact during startup and normal operation.
Architectural style¶
Lyndrix Core is an event-driven platform runtime.
Core services do not rely on a single monolithic startup function. Instead, they subscribe to well-defined bus topics, react when prerequisites become available, and emit new events when their own responsibilities are complete.
This design keeps components loosely coupled and makes plugin integration easier.
Main building blocks¶
Application shell¶
app/main.pyapp/ui/*
Responsibilities:
- create the FastAPI and NiceGUI runtime
- wire middleware and UI routes
- emit startup events such as
system:started - host the maintenance and boot-related UI behavior
Event bus¶
app/core/bus.py
Responsibilities:
- topic-based event delivery
- support for sync and async handlers
- tracked background tasks with centralized error logging
- selective payload redaction or summarization for noisy and sensitive topics
Configuration¶
app/config.py
Responsibilities:
- load environment-backed settings
- provide derived values such as
DATABASE_URL - parse plugin desired-state configuration
- support environment,
.env, and Vault-based configuration lookups
Core components¶
app/core/components/*
Responsibilities:
- Vault bootstrap and secret readiness
- database initialization and reconnect handling
- IAM bootstrap and provider-chain activation
- boot orchestration and module loading
- plugin lifecycle and marketplace sync
- UI features such as dashboard, settings, and notifications
Simplified boot sequence¶
The startup flow is roughly:
- the application emits
system:started - the Vault component checks initialization and seal state
- once Vault is ready, it emits
vault:opened - the database component reacts to
vault:openedand starts connecting - once the database is ready, it emits
db:connected - the auth component initializes IAM and emits
iam:ready - the boot component reacts to
iam:ready, changes the boot phase, and triggers module loading - module discovery loads core modules and plugins
- once startup succeeds, Lyndrix emits
system:boot_complete
If a critical phase fails, Lyndrix can move into system:maintenance_mode.
Boot phases¶
The Boot component maintains an explicit state machine:
waiting_coreloading_modulesreadyfailed
The current phase is published through system:boot_phase, allowing the UI to reflect progress and failures.
Plugin architecture¶
The plugin system is split across two main layers.
ModuleManager¶
Key responsibilities:
- discover built-in core components and user plugins
- import
entrypoint.pyfiles - validate manifests
- create
ModuleContextobjects - restore plugin activation state from the database
- enforce dependency-aware activation
- handle reload, unload, enable, and disable flows
PluginService¶
Key responsibilities:
- download plugin archives from GitHub
- resolve version tags
- validate archive extraction paths
- install plugin dependencies into
vendor/ - perform staging-based install and upgrade operations
- manage marketplace metadata and collection sync
Authentication architecture¶
The authentication subsystem includes:
- local username/password login
- optional LDAP authentication
- optional OIDC login
- a provider registry that preserves runtime order
- plugin-registered providers through
auth:register_provider
The auth subsystem emits iam:ready when the schema, bootstrap users, and provider chain are ready.
Data ownership¶
Lyndrix uses multiple persistence layers for different concerns:
- MariaDB for relational platform state such as users, groups, and plugin activation data
- Vault for secrets and secure runtime configuration
- local storage paths for logs, plugin data, temporary runtime data, and encrypted Vault bootstrap material
Event-driven integration¶
The event bus is the contract between components.
Examples:
- Vault signals readiness to Database
- Database signals readiness to Auth
- Auth signals readiness to Boot
- PluginService signals file changes to ModuleManager
- Git sync status feeds plugin marketplace refresh behavior
- Notifications expose a normalized outbound event stream
For a full topic reference, see core-components/events.md.
UI-facing architecture¶
The UI is not a separate backend service. Instead, it is part of the same application process and reacts to shared runtime state.
Examples:
- boot state can be reflected in the UI via
system:boot_phase - dashboard widgets can be contributed by plugins
- settings and login views are owned by dedicated core components
- maintenance mode can be activated by backend components and surfaced in the frontend
Source map¶
Helpful files for architecture work:
app/main.pyapp/config.pyapp/core/bus.pyapp/core/services.pyapp/core/components/boot/logic/boot_service.pyapp/core/components/vault/logic/vault_service.pyapp/core/components/database/logic/db_service.pyapp/core/components/auth/logic/auth_service.pyapp/core/components/plugins/logic/manager.pyapp/core/components/plugins/logic/plugin_service.py