"""Owned native Codex stdio adapter; inert until explicitly launched by an owner. Only a trusted in-process root adapter may install Binding objects. There is no HTTP bind/RPC endpoint, tenant inference, or activated SSE subscription. appendSpeech acceptance is not proof of audible speech or history persistence. """ from __future__ import annotations import hmac import hashlib import json import queue import secrets import subprocess import sys import threading import time from dataclasses import dataclass from pathlib import Path from http.server import BaseHTTPRequestHandler, HTTPServer from typing import BinaryIO, TypedDict, Callable @dataclass(frozen=True) class WatchReceipt: """INTERNAL adapter contract, not a claim about backend wire field names. Backend resolver authenticates an opaque handle using the member credential against a trusted, configured Omni endpoint. Backend secret stays server-side. The resolver must verify tenant, source request thread and history together. No URL or identity supplied by a notice is trusted as subscription authority. """ opaque_handle: str tenant_id: str bekci_session_id: str history_revision: str thread_id: str expires_at: float @dataclass(frozen=True) class RequestCorrelation: """Captured by the owned HTTP bridge from the actual incoming request. Must be captured before metadata arrives, not reconstructed from its body. generation is the mux epoch observed at request capture, never the latest tab. """ connection_id: str thread_id: str generation: int class WatchReceiptAdapter: """One consumer; root chooses transport/decoder after backend agreement. decode extracts only the opaque handle from bekci.watch SSE data or the nonstream _bekci_watch value. resolve performs authenticated backend lookup. Missing agreement is fail-closed, not fabricated ready metadata. """ def __init__(self, mux, *, decode: Callable[[object], str] | None = None, resolve: Callable[[str], WatchReceipt] | None = None): self.mux, self.decode, self.resolve = mux, decode, resolve self._accepted = {} def capture(self, headers: dict, body: dict) -> RequestCorrelation | None: normalized = {k.lower(): v for k, v in headers.items()} values = [normalized.get('session-id'), normalized.get('thread-id'), body.get('prompt_cache_key')] if not all(isinstance(v, str) and v for v in values) or len(set(values)) != 1: return None snap = self.mux.snapshot() state = snap['threads'].get(values[0], {}) if snap['closed'] or not state.get('active'): return None return RequestCorrelation(snap['connection_id'], values[0], state['generation']) def accept(self, transport: str, payload: object, correlation: RequestCorrelation | None) -> str: if transport not in ('bekci.watch', '_bekci_watch'): return 'unsupported_metadata_transport' if self.decode is None or self.resolve is None: return 'backend_contract_not_established' if correlation is None or correlation.connection_id != self.mux.connection_id: return 'request_correlation_missing' try: handle = self.decode(payload) if not isinstance(handle, str) or not 1 <= len(handle) <= 4096: return 'invalid_receipt' receipt = self.resolve(handle) except Exception: return 'receipt_verification_failed' # never expose credential-bearing exception text if not isinstance(receipt, WatchReceipt) or receipt.opaque_handle != handle: return 'invalid_receipt' if (receipt.thread_id != correlation.thread_id or type(receipt.expires_at) not in (int, float) or not time.time() < receipt.expires_at <= time.time() + 3600 or not all(isinstance(v, str) and 0 < len(v) <= 256 for v in (receipt.tenant_id, receipt.bekci_session_id, receipt.history_revision, receipt.thread_id))): return 'receipt_mismatch_or_expired' binding = Binding(receipt.tenant_id, receipt.bekci_session_id, receipt.history_revision, correlation.connection_id, receipt.thread_id, correlation.generation) previous = self._accepted.get(handle) if previous is not None and previous != (receipt, binding): return 'receipt_replay_mismatch' if previous is None and len(self._accepted) >= 4096: return 'capacity_exhausted' if not self.mux.bind(binding): return 'stale_generation' self._accepted[handle] = (receipt, binding) return 'bound' def notice(self, handle: str, notice: Notice) -> dict: accepted = self._accepted.get(handle) if accepted is None: return {'status': 'binding_not_established'} receipt, binding = accepted if time.time() >= receipt.expires_at: return {'status': 'receipt_expired'} expected = dict(tenant_id=binding.tenant_id, bekci_session_id=binding.bekci_session_id, history_revision=binding.history_revision, thread_id=binding.thread_id, connection_id=binding.connection_id, expected_generation=binding.generation) if not isinstance(notice, dict) or any(notice.get(k) != v for k, v in expected.items()): return {'status': 'binding_mismatch'} return self.mux.submit(notice) def verified_original(path: str, expected_sha256: str) -> str: """Owner-pinned absolute original; no PATH/override discovery or extra engine.""" candidate = Path(path) if not candidate.is_absolute() or not candidate.is_file() or candidate.resolve() == Path(__file__).resolve(): raise ValueError('original executable must be an explicitly pinned absolute file') if len(expected_sha256) != 64: raise ValueError('original executable hash required') with candidate.open('rb') as stream: actual = hashlib.file_digest(stream, 'sha256').hexdigest() if not hmac.compare_digest(actual, expected_sha256.lower()): raise ValueError('original executable hash mismatch') return str(candidate.resolve()) def stdio_invocation(args: list[str]) -> bool: """Installed Desktop tc()/Ks() grammar, preserving every original argument.""" seen, i = False, 0 while i < len(args): arg = args[i] if arg in ('-c', '--config') and i + 1 < len(args): i += 2 continue if arg == 'app-server' and not seen: seen = True elif seen and arg in ('--stdio', '--analytics-default-enabled'): pass elif seen and arg == '--listen' and args[i+1:i+2] == ['stdio://']: i += 1 else: return False i += 1 return seen def launch_original(path: str, expected_sha256: str, args: list[str], *, attach: Callable[[WatchReceiptAdapter], None] | None = None) -> int: """Source launcher entry for a future normal bridge module copy. No activation/config mutation. Unknown invocation grammar passes native stdio directly. Owner callback wires only this consumer after backend agreement. No second engine, binary patch, token file or discovery of current UI tab. """ original = verified_original(path, expected_sha256) observer = stdio_invocation(args) mux = NativeSpeechMux([original, *args], observer=observer) if observer and attach is not None: try: attach(WatchReceiptAdapter(mux)) except Exception: # Optional adapter failure cannot take down native stdio. Invalidate # any partial setup so no correction can escape a failed attachment. mux._disabled = True mux._bindings.clear() return mux.run() class Notice(TypedDict): notice_id: str tenant_id: str bekci_session_id: str history_revision: str connection_id: str thread_id: str expected_generation: int issued_at: float expires_at: float text: str @dataclass(frozen=True) class Binding: """Local scope labels (legacy field names), NOT literal server identity claims. Trusted owner attests this opaque receipt scope belongs to this native epoch. Install only from independently verified mapping, NEVER from notice fields. Rebind explicitly for a new history revision or realtime generation. """ tenant_id: str bekci_session_id: str history_revision: str connection_id: str thread_id: str generation: int def _object(raw: bytes) -> dict: try: value = json.loads(raw) return value if isinstance(value, dict) else {} except (ValueError, UnicodeError): return {} def _id(value): return (type(value), value) if type(value) in (str, int) else None class NativeSpeechMux: """One original process, bounded FIFO, one writer in each direction. argv is the original executable plus its original arguments. observer=True must only be selected for a verified stdio app-server invocation. The CLI deliberately recognizes only the exact ['app-server'] invocation; all other invocations inherit the original stdio directly. No environment/cwd rewrite. """ def __init__(self, argv: list[str], *, observer: bool = False): self.argv = list(argv) self.observer = observer self.connection_id = secrets.token_hex(24) self._prefix = 'bekci-speech-' + secrets.token_hex(24) + ':' self._token = secrets.token_urlsafe(32) self._lock = threading.RLock() self._queue = queue.Queue(maxsize=32) self._ended = threading.Event() self._eof = False self._disabled = False self._threads = {} self._starts = set() self._bindings = {} self._receipts = {} self._pending = {} self._counter = 0 self._server = None self._process = None def snapshot(self) -> dict: with self._lock: return {'connection_id': self.connection_id, 'binding_status': 'established' if self._bindings else 'binding_not_established', 'threads': {k: dict(v) for k, v in self._threads.items()}, 'closed': self._eof or self._ended.is_set(), 'injection_disabled': self._disabled} def bind(self, binding: Binding) -> bool: """Trusted local API only. No untrusted endpoint can invoke this.""" with self._lock: st = self._threads.get(binding.thread_id, {}) if (binding.connection_id != self.connection_id or not st.get('active') or st.get('generation') != binding.generation or self._eof or self._ended.is_set()): return False self._bindings[(binding.tenant_id, binding.bekci_session_id)] = binding return True def _invalidate(self, thread): if not isinstance(thread, str): return if thread in self._threads: self._threads[thread]['active'] = False self._bindings = {k: b for k, b in self._bindings.items() if b.thread_id != thread} def _observe_client(self, obj): with self._lock: rid = _id(obj.get('id')) # Responses to server requests may legitimately reuse our ID. if 'method' in obj and isinstance(obj.get('id'), str) and obj['id'].startswith(self._prefix): self._disabled = True self._pending.pop(obj['id'], None) if obj.get('method') in ('thread/start', 'thread/resume', 'thread/fork') and rid: if len(self._starts) < 4096: self._starts.add(rid) else: self._disabled = True if obj.get('method') in ('thread/realtime/stop', 'thread/realtime/start', 'thread/unsubscribe'): params = obj.get('params') if isinstance(params, dict): self._invalidate(params.get('threadId')) def _observe_server(self, obj) -> bool: with self._lock: rid = obj.get('id') response = 'method' not in obj and (('result' in obj) != ('error' in obj)) if response and isinstance(rid, str) and rid in self._pending: key = self._pending.pop(rid) self._receipts[key]['status'] = 'rpc_error' if 'error' in obj else 'rpc_accepted' return True if response and _id(rid) in self._starts: self._starts.discard(_id(rid)) result = obj.get('result') thread = result.get('thread', {}) if isinstance(result, dict) else {} tid = thread.get('id') if isinstance(thread, dict) else None if isinstance(tid, str): self._threads.setdefault(tid, {'generation': 0, 'active': False, 'realtime_session_id': None}) params = obj.get('params') if not isinstance(params, dict) or 'id' in obj: return False tid = params.get('threadId') if not isinstance(tid, str): return False method = obj.get('method') if method == 'thread/realtime/started': self._invalidate(tid) previous = self._threads.get(tid, {}).get('generation', 0) self._threads[tid] = {'generation': previous + 1, 'active': True, 'realtime_session_id': params.get('realtimeSessionId')} elif method in ('thread/realtime/closed', 'thread/realtime/error'): self._invalidate(tid) return False def _validate(self, notice): if not isinstance(notice, dict) or set(notice) != set(Notice.__annotations__): return 'invalid_schema' for key in Notice.__annotations__: if key not in ('expected_generation', 'issued_at', 'expires_at'): if not isinstance(notice[key], str) or not notice[key].strip() or len(notice[key]) > (8000 if key == 'text' else 256): return 'invalid_schema' if type(notice['expected_generation']) is not int or notice['expected_generation'] < 1: return 'invalid_schema' if any(type(notice[k]) not in (int, float) for k in ('issued_at', 'expires_at')): return 'invalid_schema' now = time.time() if not (now - 60 <= notice['issued_at'] <= now + 2 and now < notice['expires_at'] <= notice['issued_at'] + 60): return 'expired_or_invalid_ttl' if self._eof or self._ended.is_set(): return 'closed' if self._disabled or not self.observer: return 'injection_disabled' binding = self._bindings.get((notice['tenant_id'], notice['bekci_session_id'])) if binding is None: return 'binding_not_established' if binding != Binding(notice['tenant_id'], notice['bekci_session_id'], notice['history_revision'], notice['connection_id'], notice['thread_id'], notice['expected_generation']): return 'binding_mismatch' st = self._threads.get(binding.thread_id, {}) if not st.get('active') or st.get('generation') != binding.generation: return 'stale_generation' return None def submit(self, notice: Notice) -> dict: with self._lock: error = self._validate(notice) if error: return {'status': error} key = (notice['tenant_id'], notice['bekci_session_id'], notice['notice_id']) if key in self._receipts: return dict(self._receipts[key]) # Never evict dedupe during this process lifetime or retry uncertain sends. if len(self._receipts) >= 4096: return {'status': 'capacity_exhausted'} receipt = {'status': 'queued'} self._receipts[key] = receipt try: self._queue.put_nowait(('notice', (dict(notice), key))) except queue.Full: del self._receipts[key] return {'status': 'busy'} return dict(receipt) def start_inlet(self) -> tuple[str, str]: """Return loopback URL and secret to trusted owner IN MEMORY; never log. One bounded request at a time; 2s timeout applies only to inlet HTTP reads, never the original engine. Owner must arrange private credential delivery. """ if not self.observer or self._server is not None: raise ValueError('inlet requires an unused app-server observer') mux = self class Handler(BaseHTTPRequestHandler): def log_message(self, *args): pass def setup(self): super().setup() self.connection.settimeout(2) def do_POST(self): try: auth = self.headers.get('Authorization', '') if not hmac.compare_digest(auth.encode(), ('Bearer ' + mux._token).encode()): self.send_error(401) return if self.headers.get('Origin') or self.headers.get('Transfer-Encoding'): self.send_error(400) return lengths = self.headers.get_all('Content-Length', []) if len(lengths) != 1 or not lengths[0].isdigit() or not 0 < int(lengths[0]) <= 65536: self.send_error(400) return raw = self.rfile.read(int(lengths[0])) if len(raw) != int(lengths[0]): self.send_error(400) return if self.path == '/notice': result = mux.submit(_object(raw)) elif self.path == '/status' and _object(raw) == {}: result = mux.snapshot() else: self.send_error(404) return body = json.dumps(result).encode() self.send_response(200) self.send_header('Content-Type', 'application/json') self.send_header('Content-Length', str(len(body))) self.end_headers() self.wfile.write(body) except (OSError, ValueError): return self._server = HTTPServer(('127.0.0.1', 0), Handler) threading.Thread(target=self._server.serve_forever, daemon=True).start() return f'http://127.0.0.1:{self._server.server_port}', self._token def _put(self, item): while not self._ended.is_set(): try: self._queue.put(item, timeout=.1) return True except queue.Full: pass return False def run(self, source: BinaryIO | None = None, target: BinaryIO | None = None) -> int: if not self.observer: return subprocess.call(self.argv) # exact inherited stdin/stdout/stderr/env/cwd source = source if source is not None else sys.stdin.buffer target = target if target is not None else sys.stdout.buffer process = self._process = subprocess.Popen(self.argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE) def read_client(): fragment = False while not self._ended.is_set(): raw = source.readline(65536) if not raw: with self._lock: self._eof = True self._put(('eof', None)) return complete = raw.endswith(b'\n') if not fragment and complete: self._observe_client(_object(raw)) elif not complete: # Oversized records still forward byte-for-byte, but cannot be # safely observed. Fail closed for injection for this connection. with self._lock: self._disabled = True fragment = not complete if not self._put(('raw', raw)): return def send_notice(value): notice, key = value with self._lock: error = self._validate(notice) if error: self._receipts[key]['status'] = error return self._counter += 1 rid = self._prefix + str(self._counter) self._pending[rid] = key self._receipts[key]['status'] = 'sent_unknown' raw = json.dumps({'id': rid, 'method': 'thread/realtime/appendSpeech', 'params': {'threadId': notice['thread_id'], 'text': notice['text']}}, ensure_ascii=True).encode() + b'\n' # No lock during blocking pipe I/O: observer must drain server output. # Protocol has no server-side generation precondition; this race remains. process.stdin.write(raw) process.stdin.flush() def write_server(): partial = False try: while not self._ended.is_set(): try: kind, value = self._queue.get(timeout=.1) except queue.Empty: continue if kind == 'eof': return if kind == 'notice': if partial: # An oversized frame has disabled injection; reject now. with self._lock: self._receipts[value[1]]['status'] = 'injection_disabled' else: send_notice(value) else: # Re-apply lifecycle invalidation at the actual write boundary # too: a prior server start may have arrived while queued. if not partial and value.endswith(b'\n'): obj = _object(value) if obj.get('method') in ('thread/realtime/start', 'thread/realtime/stop'): params = obj.get('params') if isinstance(params, dict): with self._lock: self._invalidate(params.get('threadId')) process.stdin.write(value) process.stdin.flush() partial = not value.endswith(b'\n') except (OSError, ValueError): pass finally: try: process.stdin.close() except OSError: pass reader = threading.Thread(target=read_client, daemon=True) writer = threading.Thread(target=write_server, daemon=True) reader.start() writer.start() fragment = False try: while True: raw = process.stdout.readline(65536) if not raw: break complete = raw.endswith(b'\n') consumed = not fragment and complete and self._observe_server(_object(raw)) if not complete: with self._lock: self._disabled = True fragment = not complete if not consumed: target.write(raw) target.flush() finally: self._ended.set() process.stdout.close() with self._lock: self._bindings.clear() for st in self._threads.values(): st['active'] = False for receipt in self._receipts.values(): if receipt['status'] == 'queued': receipt['status'] = 'closed' if self._server: self._server.shutdown() self._server.server_close() return process.wait() # no deadline on legitimate native work def main() -> int: # Future launcher must pin/verify the original executable, never resolve the # override recursively. No CODEX_CLI_PATH configuration is performed here. if len(sys.argv) >= 5 and sys.argv[1] == '--pinned-original' and sys.argv[4] == '--': try: return launch_original(sys.argv[2], sys.argv[3], sys.argv[5:]) except ValueError: print('original executable verification failed', file=sys.stderr) return 2 if len(sys.argv) < 3 or sys.argv[2] != '--': print('usage: native_speech_mux.py --pinned-original ORIGINAL_EXECUTABLE SHA256 -- ORIGINAL_ARGS...', file=sys.stderr) return 2 argv = [sys.argv[1], *sys.argv[3:]] return NativeSpeechMux(argv, observer=argv[1:] == ['app-server']).run() if __name__ == '__main__': raise SystemExit(main())