Implement lifecycle workspace publication and audit delivery
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a10780-6d41-7952-9718-dfbc1f41236f
This commit is contained in:
parent
ee472acc87
commit
5fec7de4cb
21 changed files with 1022 additions and 78 deletions
|
|
@ -36,9 +36,10 @@ def token_file(path):
|
|||
|
||||
class AuditPump:
|
||||
"""One process, bounded batches, 30s ticks; never drops a failed record."""
|
||||
def __init__(self, store, sink, *, clock=time.time, intake_worker=None):
|
||||
def __init__(self, store, sink, *, clock=time.time, intake_worker=None, lifecycle_delivery=False):
|
||||
self.store, self.worker, self.clock = store, OutboxWorker(store, sink), clock
|
||||
self.intake_worker = intake_worker
|
||||
self.lifecycle_delivery = lifecycle_delivery
|
||||
self._stop = threading.Event()
|
||||
self._thread = None
|
||||
self._lock = threading.Lock()
|
||||
|
|
@ -57,10 +58,15 @@ class AuditPump:
|
|||
try:
|
||||
if self.intake_worker:
|
||||
self.intake_worker.run_once(limit=10)
|
||||
self.store.queue_heartbeats(include_posed=self.intake_worker is not None)
|
||||
if self.lifecycle_delivery:
|
||||
self.store.stage_lifecycle_audit()
|
||||
self.store.queue_heartbeats(include_posed=self.intake_worker is not None,
|
||||
include_lifecycle=self.lifecycle_delivery)
|
||||
result = self.worker.run_once(limit=10)
|
||||
if self.intake_worker:
|
||||
self.store.settle_intake_audit()
|
||||
if self.lifecycle_delivery:
|
||||
self.store.settle_lifecycle_audit()
|
||||
now = self.clock()
|
||||
if now - self._last_reconciled >= 300:
|
||||
stamp = lambda t: datetime.fromtimestamp(t, timezone.utc).isoformat(timespec="microseconds")
|
||||
|
|
@ -112,6 +118,7 @@ class AuditPump:
|
|||
class Runtime:
|
||||
controller: ReviewController
|
||||
pump: AuditPump
|
||||
lifecycle: object | None = None
|
||||
|
||||
@classmethod
|
||||
def from_file(cls, filename):
|
||||
|
|
@ -122,11 +129,14 @@ class Runtime:
|
|||
or info.st_size > 16384):
|
||||
raise ValueError("runtime configuration must be an owned private 0600 file")
|
||||
data = json.loads(path.read_text())
|
||||
if ((set(data) - {"ordinary_approval_ids", "intake_delivery"}) != {"schema", "evidence_db", "policy", "approval_origin", "audit"}
|
||||
if ((set(data) - {"ordinary_approval_ids", "intake_delivery", "lifecycle_policy", "lifecycle_delivery"}) != {"schema", "evidence_db", "policy", "approval_origin", "audit"}
|
||||
or data["schema"] != "informed-decision.review-runtime.v1"
|
||||
or set(data["policy"]) != {"origin", "package", "version", "package_digest", "caller_token_file"}
|
||||
or set(data["audit"]) != {"origin", "sender_token_file"}):
|
||||
raise ValueError("invalid review runtime configuration")
|
||||
lifecycle_delivery = data.get("lifecycle_delivery", False)
|
||||
if type(lifecycle_delivery) is not bool:
|
||||
raise ValueError("invalid lifecycle delivery setting")
|
||||
ordinary = ordinary_review_ids(data.get("ordinary_approval_ids", []))
|
||||
if not Path(data["evidence_db"]).is_absolute():
|
||||
raise ValueError("absolute evidence database path required")
|
||||
|
|
@ -145,6 +155,17 @@ class Runtime:
|
|||
if not isinstance(delivery, dict) or set(delivery) != {'hub_origin'}:
|
||||
raise ValueError('invalid intake delivery configuration')
|
||||
hub = HubDelivery(delivery['hub_origin'])
|
||||
lifecycle_policy = None
|
||||
if "lifecycle_policy" in data:
|
||||
configuration = data["lifecycle_policy"]
|
||||
if (not isinstance(configuration, dict)
|
||||
or set(configuration) != {"origin", "package", "version", "package_digest", "caller_token_file"}):
|
||||
raise ValueError("invalid lifecycle policy configuration")
|
||||
if configuration["package"] == policy["package"]:
|
||||
raise ValueError("lifecycle policy must have a separate admission package")
|
||||
lifecycle_policy = PolicyClient(configuration["origin"], token_file(configuration["caller_token_file"]),
|
||||
package=configuration["package"], version=configuration["version"],
|
||||
package_digest=configuration["package_digest"], allow_internal_http=True)
|
||||
store = Store(data["evidence_db"])
|
||||
controller = ReviewController(store, client, lambda session: ApprovalHTTPClient(
|
||||
approval_origin, session, allow_internal_http=True, ordinary_approval_ids=tuple(ordinary)))
|
||||
|
|
@ -153,4 +174,10 @@ class Runtime:
|
|||
from .intake_delivery import IntakeDeliveryWorker
|
||||
worker = IntakeDeliveryWorker(store, audit=sink, notify=hub.notify,
|
||||
hub_transport=hub.resolution, hub_base_url=hub.origin)
|
||||
return cls(controller, AuditPump(store, sink, intake_worker=worker))
|
||||
lifecycle = None
|
||||
if lifecycle_policy is not None:
|
||||
from .lifecycle import LifecycleRepository
|
||||
from .lifecycle_service import LifecycleService
|
||||
lifecycle = LifecycleService(LifecycleRepository(store), lifecycle_policy)
|
||||
return cls(controller, AuditPump(store, sink, intake_worker=worker,
|
||||
lifecycle_delivery=lifecycle_delivery), lifecycle)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue