Reconcile daemon with production runtime state

This commit is contained in:
Lyncoln
2026-09-17 14:54:15 -04:00
parent 5a128fea36
commit 338fe2ecac
5 changed files with 576 additions and 68 deletions
+29 -2
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import importlib.util
import inspect
import json
import os
from pathlib import Path
@@ -55,6 +56,18 @@ class Plugin:
self.manifest.get("required_config", [])
)
@property
def optional_config(self):
return list(
self.manifest.get("optional_config", [])
)
@property
def config_keys(self):
return list(dict.fromkeys(
self.required_config + self.optional_config
))
def validate_config(self, config):
missing = [
key
@@ -68,7 +81,7 @@ class Plugin:
+ ", ".join(missing)
)
def execute(self, action, config):
def execute(self, action, config, runtime_state):
if action not in self.actions:
raise RegistryError(
f"plugin {self.name} does not support action {action}"
@@ -82,6 +95,14 @@ class Plugin:
"but does not implement it"
)
# Backward-compatible generic state injection. Existing one-argument
# plugins continue to receive only config; state-aware plugins can
# declare a second positional parameter named runtime_state.
parameters = list(inspect.signature(handler).parameters.values())
if len(parameters) >= 2:
return handler(config, runtime_state)
return handler(config)
@@ -91,6 +112,11 @@ class Resource:
self.plugin = plugin
self.config = config
# Generic daemon-lifetime state storage. The daemon does not interpret
# plugin keys or values; applications may use this for transition
# history, grace windows, caches, or other resource-local state.
self.runtime_state = {}
self.plugin.validate_config(config)
def describe(self):
@@ -136,7 +162,7 @@ class Registry:
config = {
key: os.environ.get(key)
for key in plugin.required_config
for key in plugin.config_keys
}
self.resources[resource_id] = Resource(
@@ -163,6 +189,7 @@ class Registry:
result = resource.plugin.execute(
action,
resource.config,
resource.runtime_state,
)
return {