feat: use telemetry in guardrails

This commit is contained in:
2026-06-02 16:44:36 +01:00
parent 2fcc822394
commit 6eef97582d
6 changed files with 160 additions and 10 deletions
+66 -2
View File
@@ -5,6 +5,8 @@ from datetime import datetime, timedelta
import re
from pathlib import Path
from .telemetry import read_events
def _read_safe(root: Path, relative: str) -> str | None:
"""Read a file if it exists, otherwise return None."""
@@ -95,6 +97,66 @@ def check_repeated_commands(root: Path) -> dict:
}
def check_repeated_commands_telemetry(root: Path) -> dict:
"""Detect repeated commands from telemetry events.
Reads structured session-log.jsonl to find command targets
that have been issued more than 3 times. Falls back gracefully
when the telemetry log is absent.
Returns a dict with keys: status, details.
"""
events = read_events(root)
if not events:
return {"status": "ok", "details": "No telemetry data available."}
command_events = [e for e in events if e.event_type == "command"]
if not command_events:
return {"status": "ok", "details": "No command events found in telemetry."}
counts = Counter(e.target for e in command_events)
repeated = {target: count for target, count in counts.items() if count > 3}
if not repeated:
return {"status": "ok", "details": "No significantly repeated commands detected in telemetry."}
items = ", ".join(f"{t} ({c}x)" for t, c in list(repeated.items())[:5])
return {
"status": "warning",
"details": f"Repeated commands: {items}",
}
def check_repeated_reads_telemetry(root: Path) -> dict:
"""Detect repeated file reads from telemetry events.
Reads structured session-log.jsonl to find read/read_file target events
that have been issued more than 3 times. Falls back gracefully
when the telemetry log is absent.
Returns a dict with keys: status, details.
"""
events = read_events(root)
if not events:
return {"status": "ok", "details": "No telemetry data available."}
read_events_list = [e for e in events if e.event_type in ("read", "read_file")]
if not read_events_list:
return {"status": "ok", "details": "No file read events found in telemetry."}
counts = Counter(e.target for e in read_events_list)
repeated = {target: count for target, count in counts.items() if count > 3}
if not repeated:
return {"status": "ok", "details": "No significantly repeated file reads detected in telemetry."}
items = ", ".join(f"{t} ({c}x)" for t, c in list(repeated.items())[:5])
return {
"status": "warning",
"details": f"Repeated file reads: {items}",
}
def check_no_recent_file_changes(root: Path) -> dict:
"""Flag if project files have not been modified in a long time (> 48 h).
@@ -185,8 +247,10 @@ def check_run_log_updated(root: Path) -> dict:
def run_all_guardrails(root: Path) -> dict:
"""Run all guardrail checks and return combined results."""
checks = {
"Repeated reads": check_repeated_reads(root),
"Repeated commands": check_repeated_commands(root),
"Repeated reads (heuristics)": check_repeated_reads(root),
"Repeated commands (RUN_LOG)": check_repeated_commands(root),
"Repeated commands (telemetry)": check_repeated_commands_telemetry(root),
"Repeated file reads (telemetry)": check_repeated_reads_telemetry(root),
"No recent file changes": check_no_recent_file_changes(root),
"No test run recorded": check_no_test_run_recorded(root),
"Run log updated": check_run_log_updated(root),