#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later """Inactive Phase-1.0X transport orchestration with injected adapters only. This module has no socket, DNS, CLI, target address, byte-command formatter or live prompt detector. It implements local exclusive evidence and orchestrates synthetic adapter boundaries under an injected monotonic clock. """ from __future__ import annotations from dataclasses import dataclass import hashlib import json import os from pathlib import Path from typing import Any, Protocol from phase10v_shsrv_collector_model import CollectorError, OfflineCollector from phase10w_shsrv_client_policy import ( COLLECTOR_SHA256, SessionPlan, ) POLICY_SHA256 = \ "747d23c88f2722e8e8846599c3ac1dae3826eb3fca881caaad36b251f30f3592" MAX_BOUNDARY_CHUNKS = 64 class SessionFailure(RuntimeError): """Generic failure that never embeds adapter data or target values.""" class EvidenceFailure(RuntimeError): """Generic exclusive-evidence failure.""" class MonotonicClock(Protocol): def monotonic(self) -> float: ... class InjectedSessionAdapter(Protocol): def open_once(self, plan: SessionPlan, remaining_seconds: float) -> None: ... def receive_boundary( self, boundary: str, remaining_seconds: float, ) -> list[bytes]: ... def send_command_token( self, command: str, exact_path: str | None, remaining_seconds: float, ) -> None: ... def close_once(self) -> None: ... @dataclass(frozen=True) class EvidenceRecord: path: Path size: int sha256: str @dataclass(frozen=True) class SessionOutcome: receipt: EvidenceRecord output: EvidenceRecord classification: str exact_identity: bool class ExclusiveEvidenceStore: """Write local JSON once with O_EXCL; never overwrite or clean up.""" def __init__(self, root: Path) -> None: self.root = root @staticmethod def _encode(record: dict[str, Any]) -> bytes: return (json.dumps( record, sort_keys=True, separators=(",", ":"), ensure_ascii=True, ) + "\n").encode("ascii") def _create(self, filename: str, record: dict[str, Any]) -> EvidenceRecord: try: self.root.mkdir(parents=True, exist_ok=True) path = self.root / filename payload = self._encode(record) except (OSError, TypeError, ValueError) as error: raise EvidenceFailure("exclusive evidence preparation failed") from error flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL if hasattr(os, "O_BINARY"): flags |= os.O_BINARY descriptor = -1 close_failure: OSError | None = None try: descriptor = os.open(path, flags, 0o600) offset = 0 while offset < len(payload): written = os.write(descriptor, payload[offset:]) if written <= 0: raise OSError("short local evidence write") offset += written os.fsync(descriptor) except OSError as error: raise EvidenceFailure("exclusive evidence creation failed") from error finally: if descriptor >= 0: try: os.close(descriptor) except OSError as error: close_failure = error if close_failure is not None: raise EvidenceFailure("exclusive evidence close failed") from close_failure try: reopened = path.read_bytes() except OSError as error: raise EvidenceFailure("exclusive evidence reopen failed") from error if reopened != payload: raise EvidenceFailure("exclusive evidence reopen mismatch") return EvidenceRecord( path=path, size=len(reopened), sha256=hashlib.sha256(reopened).hexdigest(), ) def create_consumed_receipt( self, plan: SessionPlan, monotonic_value: float, ) -> EvidenceRecord: return self._create(f"{plan.run_id}.consumed.json", { "schema_version": 1, "status": "CONSUMED_BEFORE_ADAPTER_OPEN", "run_id": plan.run_id, "policy_sha256": POLICY_SHA256, "collector_sha256": COLLECTOR_SHA256, "window": plan.window, "deadline_seconds": plan.deadline_seconds, "created_monotonic": monotonic_value, "target_retained": False, "retry_allowed": False, }) def create_sanitized_output( self, plan: SessionPlan, receipt: EvidenceRecord, sanitized: dict[str, Any], ) -> EvidenceRecord: return self._create(f"{plan.run_id}.sanitized.json", { "schema_version": 1, "status": "SANITIZED_OUTPUT_COMPLETE", "run_id": plan.run_id, "receipt_sha256": receipt.sha256, "raw_transcript_persisted": False, "result": sanitized, }) def _remaining(clock: MonotonicClock, deadline: float) -> float: remaining = deadline - clock.monotonic() if remaining <= 0: raise SessionFailure("session deadline reached") return remaining def _feed_boundary( collector: OfflineCollector, chunks: list[bytes], ) -> None: if not isinstance(chunks, list) or len(chunks) > MAX_BOUNDARY_CHUNKS: raise SessionFailure("adapter boundary is invalid") try: for chunk in chunks: collector.feed(chunk) except CollectorError as error: raise SessionFailure("collector rejected adapter input") from error def run_injected_session( plan: SessionPlan, adapter: InjectedSessionAdapter, clock: MonotonicClock, evidence: ExclusiveEvidenceStore, ) -> SessionOutcome: """Run one injected session; never retries and never performs live I/O.""" start = clock.monotonic() deadline = start + plan.deadline_seconds receipt = evidence.create_consumed_receipt(plan, start) collector = OfflineCollector() open_attempted = False sanitized: dict[str, Any] | None = None primary_failure: SessionFailure | None = None try: open_attempted = True adapter.open_once(plan, _remaining(clock, deadline)) chunks = adapter.receive_boundary( "INITIAL_PROMPT", _remaining(clock, deadline)) _feed_boundary(collector, chunks) for command in plan.commands: adapter.send_command_token( command, plan.exact_literal_path, _remaining(clock, deadline)) chunks = adapter.receive_boundary( f"AFTER_{command.upper()}", _remaining(clock, deadline)) _feed_boundary(collector, chunks) _remaining(clock, deadline) expected_paths = ( {plan.exact_literal_path} if plan.exact_literal_path is not None else set() ) sanitized = collector.finalize(expected_paths) except Exception: # noqa: BLE001 - injected adapter boundary # Adapter exceptions are deliberately normalized; raw messages never # become evidence or user output. primary_failure = SessionFailure("injected session failed") finally: if open_attempted: try: adapter.close_once() except Exception: # noqa: BLE001 - injected adapter if primary_failure is None: primary_failure = SessionFailure("injected session close failed") if primary_failure is not None: raise primary_failure from None if sanitized is None: raise SessionFailure("sanitized result is missing") try: output = evidence.create_sanitized_output(plan, receipt, sanitized) except EvidenceFailure as error: raise SessionFailure("sanitized output creation failed") from error return SessionOutcome( receipt=receipt, output=output, classification=str(sanitized["classification"]), exact_identity=bool(sanitized["exact_identity"]), )