feat(runtime): enforce governed mutation boundaries

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a06ba0-10aa-7ea0-b20a-4f3fac39efe9
This commit is contained in:
tegwick 2026-09-04 11:25:07 +02:00
parent e3c6124e22
commit 20e6f381f6
28 changed files with 1068 additions and 154 deletions

View file

@ -1,7 +1,8 @@
"""Write per-run records into the target repo's `.kaizen/metrics` tree.
"""Write per-run metrics to compatibility or durable external storage.
Follows kaizen-agentic ADR-004 conventions so the optimization loop can
observe harness-run agents:
Legacy grant-absent runs retain the kaizen-agentic ADR-004 repository layout.
Accepted grant runs use private external state and a projection descriptor so
metrics cannot dirty the validated checkout.
.kaizen/metrics/<agent>/
executions.jsonl # append-only
@ -10,7 +11,11 @@ observe harness-run agents:
from __future__ import annotations
import fcntl
import hashlib
import json
import os
import uuid
from dataclasses import asdict, dataclass, field
from datetime import datetime, timezone
from pathlib import Path
@ -46,6 +51,20 @@ def metrics_dir(project_root: Path, agent: str) -> Path:
return Path(project_root) / ".kaizen" / "metrics" / agent
def external_metrics_dir(
project_root: Path | str,
agent: str,
*,
state_dir: Path | None = None,
) -> Path:
"""Return the private durable metrics directory for a granted run."""
root = Path(project_root).expanduser().resolve()
base = state_dir.expanduser().resolve() if state_dir else _state_dir()
repo_id = hashlib.sha256(str(root).encode("utf-8")).hexdigest()[:32]
agent_id = hashlib.sha256(str(agent).encode("utf-8")).hexdigest()[:32]
return base / "execution-metrics" / repo_id / agent_id
def _utc_now() -> str:
return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace(
"+00:00", "Z"
@ -133,18 +152,17 @@ def record_execution(
directory = metrics_dir(root, agent)
directory.mkdir(parents=True, exist_ok=True)
record = ExecutionRecord(
timestamp=_utc_now(),
agent=agent,
record = _execution_record(
root,
agent,
success=success,
execution_time_s=float(execution_time_s),
session_id=session_id,
metadata=metadata or {},
repo=root.name,
execution_time_s=execution_time_s,
tokens=tokens,
committed=committed,
head_after=head_after,
reason=reason,
metadata=metadata,
session_id=session_id,
)
executions_path = directory / "executions.jsonl"
@ -158,3 +176,189 @@ def record_execution(
encoding="utf-8",
)
return executions_path
def record_external_execution(
project_root: Path | str,
agent: str,
*,
success: bool,
execution_time_s: float = 0.0,
tokens: int | None = None,
committed: bool | None = None,
head_after: str | None = None,
reason: str | None = None,
metadata: dict[str, Any] | None = None,
session_id: str | None = None,
state_dir: Path | None = None,
) -> Path:
"""Durably record granted-run metrics without dirtying the target checkout."""
root = Path(project_root).expanduser().resolve()
projection_target = _projection_target(agent)
directory = external_metrics_dir(root, agent, state_dir=state_dir)
_ensure_private_directory(directory)
lock_path = directory / ".lock"
lock_fd = os.open(lock_path, os.O_RDWR | os.O_CREAT, 0o600)
try:
os.fchmod(lock_fd, 0o600)
fcntl.flock(lock_fd, fcntl.LOCK_EX)
record = _execution_record(
root,
agent,
success=success,
execution_time_s=execution_time_s,
tokens=tokens,
committed=committed,
head_after=head_after,
reason=reason,
metadata=metadata,
session_id=session_id,
)
executions_path = directory / "executions.jsonl"
existing = (
executions_path.read_text(encoding="utf-8")
if executions_path.exists()
else ""
)
if existing and not existing.endswith("\n"):
raise OSError("external metrics ledger has an incomplete record")
records = _load_external_executions(executions_path) if existing else []
already_recorded = session_id is not None and any(
item.get("session_id") == session_id for item in records
)
if not already_recorded:
record_line = record.to_json_line()
_atomic_write_text(executions_path, existing + record_line + "\n")
records.append(json.loads(record_line))
_atomic_write_text(
directory / "summary.json",
json.dumps(regenerate_summary(agent, records), indent=2, sort_keys=True)
+ "\n",
)
repo_id = directory.parent.name
_atomic_write_text(
directory / "projection.json",
json.dumps(
{
"agent": agent,
"repository_id": repo_id,
"repository_name": root.name,
"target_relative_directory": projection_target,
},
indent=2,
sort_keys=True,
)
+ "\n",
)
_fsync_directory(directory)
return executions_path
finally:
try:
fcntl.flock(lock_fd, fcntl.LOCK_UN)
finally:
os.close(lock_fd)
def _projection_target(agent: str) -> str:
"""Return a checkout-relative projection target for a safe agent identity."""
if (
not agent
or agent in {".", ".."}
or "/" in agent
or "\\" in agent
or "\x00" in agent
or len(agent) > 200
):
raise OSError("agent identity cannot form a safe metrics projection")
return f".kaizen/metrics/{agent}"
def _execution_record(
root: Path,
agent: str,
*,
success: bool,
execution_time_s: float,
tokens: int | None,
committed: bool | None,
head_after: str | None,
reason: str | None,
metadata: dict[str, Any] | None,
session_id: str | None,
) -> ExecutionRecord:
return ExecutionRecord(
timestamp=_utc_now(),
agent=agent,
success=success,
execution_time_s=float(execution_time_s),
session_id=session_id,
metadata=metadata or {},
repo=root.name,
tokens=tokens,
committed=committed,
head_after=head_after,
reason=reason,
)
def _load_external_executions(path: Path) -> list[dict[str, Any]]:
records: list[dict[str, Any]] = []
for line in path.read_text(encoding="utf-8").splitlines():
try:
value = json.loads(line)
except json.JSONDecodeError as exc:
raise OSError("external metrics ledger contains invalid JSON") from exc
if not isinstance(value, dict):
raise OSError("external metrics ledger contains a non-object record")
records.append(value)
return records
def _state_dir() -> Path:
explicit = os.environ.get("REIN_AHARNESS_STATE_DIR", "").strip()
if explicit:
return Path(explicit).expanduser().resolve()
xdg = os.environ.get("XDG_STATE_HOME", "").strip()
if xdg:
return (Path(xdg).expanduser() / "rein-aharness").resolve()
return (Path.home() / ".local" / "state" / "rein-aharness").resolve()
def _ensure_private_directory(path: Path) -> None:
path.mkdir(parents=True, exist_ok=True)
current = path
while current.name and current != current.parent:
os.chmod(current, 0o700)
if current.name == "execution-metrics":
break
current = current.parent
def _atomic_write_text(path: Path, value: str) -> None:
temporary = path.parent / f".{path.name}.{uuid.uuid4().hex}.tmp"
fd = os.open(temporary, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
try:
with os.fdopen(fd, "w", encoding="utf-8") as handle:
fd = -1
handle.write(value)
handle.flush()
os.fsync(handle.fileno())
os.replace(temporary, path)
os.chmod(path, 0o600)
_fsync_directory(path.parent)
except BaseException:
if fd >= 0:
os.close(fd)
try:
temporary.unlink()
except FileNotFoundError:
pass
raise
def _fsync_directory(path: Path) -> None:
fd = os.open(path, os.O_RDONLY)
try:
os.fsync(fd)
finally:
os.close(fd)