Coverage for node / src / stigmem_node / plugins / lifecycle.py: 84%
32 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-06-18 05:34 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-06-18 05:34 +0000
1"""Installed plugin registration lifecycle."""
3from __future__ import annotations
5import logging
7from stigmem_node.settings import settings
9from .discovery import DiscoveredPlugin, discover_plugin_manifests, resolve_plugin_dependencies
10from .registry import HookRegistry, get_registry
11from .signing import (
12 PluginSignatureVerifier,
13 allow_unsigned_development_override,
14 require_verified_signature,
15)
17logger = logging.getLogger("stigmem.plugins.lifecycle")
20def register_discovered_plugins(
21 *,
22 registry: HookRegistry | None = None,
23 freeze: bool = True,
24 signing_required: bool | None = None,
25 signature_verifier: PluginSignatureVerifier = require_verified_signature,
26) -> tuple[DiscoveredPlugin, ...]:
27 """Discover, dependency-order, and register installed plugin packages.
29 This function is intentionally startup-only. It mutates the supplied registry
30 during application initialization and freezes it by default so later runtime
31 hot unload/reload paths are not introduced by PR 4-INF.2.
32 """
34 target = registry or get_registry()
35 require_signatures = (
36 settings.plugin_signing_required if signing_required is None else signing_required
37 )
38 if not settings.plugin_auto_discovery_enabled: 38 ↛ 39line 38 didn't jump to line 39 because the condition on line 38 was never true
39 logger.info("installed plugin auto-discovery disabled")
40 if freeze:
41 target.freeze()
42 return ()
44 discovered = discover_plugin_manifests()
45 ordered = resolve_plugin_dependencies(
46 discovered,
47 registered_plugins=target.registered_plugins(),
48 )
49 for plugin in ordered:
50 if require_signatures:
51 signing_info = signature_verifier(plugin)
52 else:
53 signing_info = allow_unsigned_development_override(plugin)
54 logger.warning(
55 "SECURITY WARNING: unsigned plugin %r loaded because "
56 "STIGMEM_PLUGIN_SIGNING_REQUIRED=false; do not use this setting in production",
57 plugin.manifest.name,
58 )
59 signing_identity = signing_info.signing_identity
60 signing_metadata = signing_info.audit_metadata()
61 target.register_plugin(
62 plugin.manifest,
63 discovery_source=_discovery_source(plugin),
64 signing_identity=signing_identity,
65 signing_metadata=signing_metadata,
66 )
67 if freeze:
68 target.freeze()
69 if ordered:
70 logger.info(
71 "registered installed plugins: %s",
72 ", ".join(plugin.manifest.name for plugin in ordered),
73 )
74 return ordered
77def _discovery_source(plugin: DiscoveredPlugin) -> dict[str, str | None]:
78 return {
79 "type": "python_entry_point",
80 "entry_point_name": plugin.entry_point_name,
81 "entry_point_value": plugin.entry_point_value,
82 "distribution": plugin.distribution,
83 }