Audit Agent¶
The Audit Agent creates and executes reusable health check profiles against your network snapshot data. Design a check once, run it daily β get a structured Markdown report every time.
Feature Claims
| ID | Claim | Status |
|---|---|---|
| C-NE-32 | olav --agent audit "create BGP health check" guides profile creation |
πΆ Env-Blocked |
| C-NE-33 | olav --agent audit "run bgp-health audit" produces a Markdown health report |
πΆ Env-Blocked |
| C-NE-34 | Designer validates table and column names exist before writing SQL queries | β¬ Pending |
| C-NE-35 | analyze_thresholds provides P50/P90/P95 statistical recommendations |
πΆ Env-Blocked |
Architecture¶
The Audit workspace has two sub-agents and an orchestrator:
graph TD
User["olav --agent audit '...'"] --> Orch[Audit Orchestrator]
Orch -->|"create profile"| Designer[Designer Agent]
Orch -->|"run audit"| Auditor[Auditor Agent]
Designer -->|saves| Profile[profiles/*.md]
Auditor -->|reads| Profile
Auditor -->|outputs| Report[Markdown Report]
| Agent | Role |
|---|---|
| Designer | Create and modify audit profiles (SQL queries + thresholds) |
| Auditor | Execute profiles and render health reports |
Creating a Profile¶
The Designer guides you through:
- What to check β Which tables/views to query (e.g.,
v_bgp_neighbors_auto) - Schema validation β Designer verifies that tables and columns exist in DuckDB before writing any SQL
- SQL query β Parameterized queries with
:windowplaceholder for time range - Thresholds β Optional: use
analyze_thresholdsto get P50/P90/P95 recommendations from historical data - Save β Profile written as YAML frontmatter + Markdown to
profiles/<name>.md
Profile Format¶
---
name: bgp-health
version: 1
description: BGP session health check
schedule: daily
---
## Job: Down Neighbors
```sql
SELECT device_name, neighbor_ip, neighbor_as, state
FROM v_bgp_neighbors_auto
WHERE state != 'Established'
AND snapshot_id = (SELECT MAX(snapshot_id) FROM netops.parsed_outputs)
severity: high max_findings: 50
Execution is a two-phase Map-Reduce pipeline:
Phase 1: Map (map_engine)¶
- Loads the profile
- Executes each job's SQL query
- Collects results, respects
max_findings_per_job - Outputs segmented JSON (one section per job)
Phase 2: Render (render_report)¶
- LLM renders each finding section into human-readable Markdown
- Correlation Pass adds an Executive Summary across all sections
- Final output: complete Markdown health report
Example Report Output¶
# BGP Health Report β 2026-04-06
## Executive Summary
3 of 24 BGP sessions are not in Established state.
All affected sessions are on device R3 (AS 65003).
## Down Neighbors (severity: high)
| Device | Neighbor IP | Peer AS | State |
|--------|------------|---------|-------|
| R3 | 10.0.0.1 | 65001 | Active |
| R3 | 10.0.0.5 | 65002 | Idle |
| R3 | 10.0.0.9 | 65004 | Active |
### Analysis
All three sessions originate from R3. Possible causes:
- R3 management plane issue (all peers affected)
- ACL blocking TCP 179 on R3
- Physical link failure on R3 uplinks
Designer Tools¶
| Tool | Purpose |
|---|---|
database_introspection |
List tables and columns in DuckDB/LanceDB |
test_map_query |
Dry-run SQL with sample data (preview before saving) |
analyze_thresholds |
Statistical P50/P90/P95 for data-driven thresholds |
save_profile |
Validate YAML schema and write profile |
read_profile |
Load existing profile for editing |
append_jobs |
Add checks to existing profile without full rewrite |
Auditor Tools¶
| Tool | Purpose |
|---|---|
map_engine |
Execute all profile jobs, produce JSON results |
render_report |
LLM-render sections + correlation β Markdown report |