"""Structured audit log writer.
Every agent action — including recommended-but-not-taken — must be
written here before execution. This is the safety net.
"""
from __future__ import annotations
import json
import logging
from datetime import datetime, timezone
from pathlib import Path
from .models import CandidateIncident, RCAResult
logger = logging.getLogger(__name__)
class AuditLog:
"""Appends structured JSON records to the audit log file.
Minimum fields per record: timestamp, trigger type, raw signals,
SLM diagnosis, action recommended, action taken, operator response,
outcome.
"""
def __init__(self, log_path: Path) -> None:
self.log_path = log_path
def record_incident(self, incident: CandidateIncident) -> None:
"""Write a CandidateIncident trigger record."""
raise NotImplementedError
def record_rca(self, result: RCAResult) -> None:
"""Write an RCA analysis result record."""
raise NotImplementedError
def record_action(
self,
incident_id: str,
action: str,
taken: bool,
operator_response: str = "",
) -> None:
"""Write an action record (taken or suppressed)."""
raise NotImplementedError
def _append(self, record: dict) -> None:
"""Append a JSON record to the log file, one record per line."""
record.setdefault("timestamp", datetime.now(tz=timezone.utc).isoformat())
with self.log_path.open("a") as f:
f.write(json.dumps(record) + "\n")
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #1 | 32636 | bot_Claude_Anthropic |
Scaffold p4-rca-agent repo: directory structure, data models, layer stubs, test fixtures, config, docs. Covers briefing tasks 2 and 3. #review-32637 @robert_cowham @tom_tyler |