Coverage for lintro / ai / audit.py: 100%

13 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-04-03 18:53 +0000

1"""AI modification audit log.""" 

2 

3from __future__ import annotations 

4 

5import json 

6import time 

7from pathlib import Path 

8from typing import TYPE_CHECKING 

9 

10if TYPE_CHECKING: 

11 from lintro.ai.models import AIFixSuggestion 

12 

13AUDIT_DIR = ".lintro-cache/ai" 

14AUDIT_FILE = "audit.json" 

15 

16 

17def write_audit_log( 

18 workspace_root: Path, 

19 applied: list[AIFixSuggestion], 

20 rejected_count: int, 

21 total_cost: float, 

22) -> None: 

23 """Write an audit log summarising the AI fix run. 

24 

25 Args: 

26 workspace_root: Project root directory. 

27 applied: List of applied fix suggestions. 

28 rejected_count: Number of rejected suggestions. 

29 total_cost: Cumulative cost in USD. 

30 """ 

31 entries = [ 

32 { 

33 "file": s.file, 

34 "line": s.line, 

35 "code": s.code, 

36 "tool": s.tool_name, 

37 "action": "applied", 

38 "confidence": s.confidence, 

39 "risk_level": s.risk_level, 

40 "cost": s.cost_estimate, 

41 } 

42 for s in applied 

43 ] 

44 audit = { 

45 "timestamp": time.time(), 

46 "applied_count": len(applied), 

47 "rejected_count": rejected_count, 

48 "total_cost_usd": round(total_cost, 6), 

49 "entries": entries, 

50 } 

51 audit_dir = workspace_root / AUDIT_DIR 

52 audit_dir.mkdir(parents=True, exist_ok=True) 

53 (audit_dir / AUDIT_FILE).write_text( 

54 json.dumps(audit, indent=2), 

55 encoding="utf-8", 

56 )