diff --git a/scripts/ci/contextual_orchestrator_review_sidecar.sh b/scripts/ci/contextual_orchestrator_review_sidecar.sh index 965e6b4876..e88bd8d3bc 100755 --- a/scripts/ci/contextual_orchestrator_review_sidecar.sh +++ b/scripts/ci/contextual_orchestrator_review_sidecar.sh @@ -118,6 +118,23 @@ import faulthandler # Fatal startup diagnostics contain stack locations, never frame locals. faulthandler.enable() +import hashlib +import importlib.util +from pathlib import Path +import sys +import sysconfig + +# Fixed runtime artifacts only; never print environment values or file contents. +for kind, path in ( + ("python", Path(sys.executable)), + ("asyncio", Path(importlib.util.find_spec("_asyncio").origin)), + ("libpython", Path(sys.base_prefix) / "lib" / sysconfig.get_config_var("LDLIBRARY")), +): + if path.is_file(): + with path.open("rb") as artifact: + digest = hashlib.file_digest(artifact, "sha256").hexdigest() + print(f"[contextual-orchestrator-sidecar] runtime_identity kind={kind} sha256={digest}", flush=True) + import contextlib import http.client import io diff --git a/tests/test_contextual_orchestrator_review_sidecar_contract.py b/tests/test_contextual_orchestrator_review_sidecar_contract.py index 3db35662d1..de185bd1a5 100644 --- a/tests/test_contextual_orchestrator_review_sidecar_contract.py +++ b/tests/test_contextual_orchestrator_review_sidecar_contract.py @@ -14,6 +14,8 @@ import os from pathlib import Path import runpy +import re +import sys import subprocess from types import SimpleNamespace @@ -607,3 +609,22 @@ def test_sidecar_uses_lock_compatible_isolated_python() -> None: assert 'python-version: "3.12"' in workflow[setup:call] assert 'update-environment: false' in workflow[setup:call] assert 'SIDECAR_PYTHON: ${{ steps.sidecar_python.outputs.python-path }}' in workflow[setup:call] + + +def test_runtime_identity_logs_only_fixed_artifact_hashes() -> None: + """Runtime diagnostics must not copy inherited credential values or paths.""" + source = _read(SIDECAR).split("import faulthandler\n", 1)[1].split("import contextlib\n", 1)[0] + result = subprocess.run( + [sys.executable, "-c", "import faulthandler\n" + source], + env={**os.environ, "OPENAI_API_KEY": "runtime-diagnostic-private-marker"}, + capture_output=True, + text=True, + check=True, + ) + lines = result.stdout.splitlines() + assert len(lines) >= 2 + assert all(re.fullmatch( + r"\[contextual-orchestrator-sidecar\] runtime_identity " + r"kind=(python|asyncio|libpython) sha256=[0-9a-f]{64}", line + ) for line in lines) + assert "runtime-diagnostic-private-marker" not in result.stdout + result.stderr