This commit was merged in pull request #845.
This commit is contained in:
106
packages/mosaic/framework/tools/lease-broker/receipt_observer.py
Normal file
106
packages/mosaic/framework/tools/lease-broker/receipt_observer.py
Normal file
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Trusted latest-assistant-message observer boundary for receipt promotion.
|
||||
|
||||
Runtime adapters must implement ``observe_latest_assistant_message`` directly:
|
||||
Claude selects the exact latest assistant entry and Pi selects ``message_end``.
|
||||
The broker accepts no observed message through its request protocol.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import stat
|
||||
from pathlib import Path
|
||||
from typing import Protocol
|
||||
|
||||
|
||||
class ReceiptObserver(Protocol):
|
||||
def observe_latest_assistant_message(
|
||||
self,
|
||||
session_id: str,
|
||||
runtime: str,
|
||||
runtime_generation: int,
|
||||
binding: dict[str, object],
|
||||
) -> str | None: ...
|
||||
|
||||
|
||||
class UnavailableReceiptObserver:
|
||||
"""Production-safe default until a runtime adapter injects an observer."""
|
||||
|
||||
def observe_latest_assistant_message(
|
||||
self,
|
||||
_session_id: str,
|
||||
_runtime: str,
|
||||
_runtime_generation: int,
|
||||
_binding: dict[str, object],
|
||||
) -> str | None:
|
||||
return None
|
||||
|
||||
|
||||
class TestReceiptObserver:
|
||||
"""Deterministic controlled observer used only by byte-build tests."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._messages: dict[tuple[str, int], str] = {}
|
||||
|
||||
def record_latest_assistant_message(
|
||||
self, session_id: str, runtime_generation: int, message: str
|
||||
) -> None:
|
||||
self._messages[(session_id, runtime_generation)] = message
|
||||
|
||||
def observe_latest_assistant_message(
|
||||
self,
|
||||
session_id: str,
|
||||
_runtime: str,
|
||||
runtime_generation: int,
|
||||
_binding: dict[str, object],
|
||||
) -> str | None:
|
||||
return self._messages.get((session_id, runtime_generation))
|
||||
|
||||
|
||||
class FileTestReceiptObserver:
|
||||
"""Private fixture-file observer for isolated out-of-process test drivers."""
|
||||
|
||||
def __init__(self, path: Path) -> None:
|
||||
self.path = path
|
||||
|
||||
def observe_latest_assistant_message(
|
||||
self,
|
||||
session_id: str,
|
||||
_runtime: str,
|
||||
runtime_generation: int,
|
||||
_binding: dict[str, object],
|
||||
) -> str | None:
|
||||
flags = os.O_RDONLY | getattr(os, "O_CLOEXEC", 0) | getattr(os, "O_NOFOLLOW", 0)
|
||||
try:
|
||||
descriptor = os.open(self.path, flags)
|
||||
except OSError:
|
||||
return None
|
||||
try:
|
||||
metadata = os.fstat(descriptor)
|
||||
if (
|
||||
not stat.S_ISREG(metadata.st_mode)
|
||||
or stat.S_IMODE(metadata.st_mode) != 0o600
|
||||
or metadata.st_uid != os.geteuid()
|
||||
or metadata.st_size > 64 * 1024
|
||||
):
|
||||
return None
|
||||
raw = os.read(descriptor, 64 * 1024 + 1)
|
||||
finally:
|
||||
os.close(descriptor)
|
||||
if len(raw) > 64 * 1024:
|
||||
return None
|
||||
try:
|
||||
value = json.loads(raw)
|
||||
except (json.JSONDecodeError, UnicodeDecodeError):
|
||||
return None
|
||||
if (
|
||||
not isinstance(value, dict)
|
||||
or set(value) != {"session_id", "runtime_generation", "latest_assistant_message"}
|
||||
or value["session_id"] != session_id
|
||||
or value["runtime_generation"] != runtime_generation
|
||||
or not isinstance(value["latest_assistant_message"], str)
|
||||
):
|
||||
return None
|
||||
return value["latest_assistant_message"]
|
||||
Reference in New Issue
Block a user