The module registry is the immutable runtime representation of all known modules. It is populated from a ModuleSource at boot and provides lookups, enabled/disabled checks, and the entry point for pull-based collection.
ModuleRegistry
ModuleRegistry is a final readonly class populated during bootstrap. It receives its data from whichever ModuleSource implementation the panel's mode selects. Once populated, it is immutable for the lifetime of the request.
Instance lifecycle
In production mode, the registry is built once at worker boot from CachedModuleSource and shared across all requests the worker handles. In debug mode, a fresh registry is built from LiveModuleSource on every request so that changes to module code are picked up immediately. The registry class itself is the same in both cases; the bootstrap/DI layer decides whether to reuse or reconstruct.
Lookups
- Manifest by ident
- Registrar metadata by ident
- List all manifests
- List all idents
- Check whether a module is enabled, disabled, or present
Enabled modules
The list of enabled modules comes from the ModulesEnabled config, which is populated by the config system from the filenames in modules-enabled/*.toml. The registry uses this list to determine which modules participate in the lifecycle and collection. Modules present in the source but not in the enabled list are tracked as disabled.
If a module appears in the enabled list but has no corresponding manifest from the source, the registry logs a warning and skips it.
Collection
The registry owns the collect(CollectorHandler $handler, ?PanelContext $context) method. When a component needs data from modules, it passes a CollectorHandler to this method. The registry iterates all enabled modules, checks their registrar metadata for matching #[Collect] methods, and drives the create/process/finalise flow. See the Engine: Collectors issue for the full collection mechanics.
Error handling
- Missing cache file or source data: clear error with actionable message (e.g. "run discovery" or "check module installation")
- Enabled module not found in source: warning logged, module skipped
- Manifest or registrar lookup for unknown ident: exception
Tasks
The module registry is the immutable runtime representation of all known modules. It is populated from a
ModuleSourceat boot and provides lookups, enabled/disabled checks, and the entry point for pull-based collection.ModuleRegistry
ModuleRegistryis a final readonly class populated during bootstrap. It receives its data from whicheverModuleSourceimplementation the panel's mode selects. Once populated, it is immutable for the lifetime of the request.Instance lifecycle
In production mode, the registry is built once at worker boot from
CachedModuleSourceand shared across all requests the worker handles. In debug mode, a fresh registry is built fromLiveModuleSourceon every request so that changes to module code are picked up immediately. The registry class itself is the same in both cases; the bootstrap/DI layer decides whether to reuse or reconstruct.Lookups
Enabled modules
The list of enabled modules comes from the
ModulesEnabledconfig, which is populated by the config system from the filenames inmodules-enabled/*.toml. The registry uses this list to determine which modules participate in the lifecycle and collection. Modules present in the source but not in the enabled list are tracked as disabled.If a module appears in the enabled list but has no corresponding manifest from the source, the registry logs a warning and skips it.
Collection
The registry owns the
collect(CollectorHandler $handler, ?PanelContext $context)method. When a component needs data from modules, it passes aCollectorHandlerto this method. The registry iterates all enabled modules, checks their registrar metadata for matching#[Collect]methods, and drives the create/process/finalise flow. See theEngine: Collectorsissue for the full collection mechanics.Error handling
Tasks
ModuleRegistryfinal readonly classModuleSourceModulesEnabledcollect(CollectorHandler $handler, ?PanelContext $context)ModuleSource