Compliance Monitor
The Compliance Monitor tracks regulatory deadlines, detects rule changes, monitors production data for violations, and computes risk scores for wells across an operator’s portfolio. It queries the knowledge graph service for entity data and applies domain-specific compliance logic.
Overview
Oil and gas operators must track dozens of regulatory deadlines, production allowables, and evolving rules. The compliance monitor provides four capabilities:
- Deadline tracking — Scans permits, flaring authorizations, and filing deadlines for approaching or expired dates, categorizing alerts as critical, warning, or informational
- Production monitoring — Checks well production data against allowable limits, flags gas-oil ratio (GOR) anomalies, identifies zero-production active wells, and detects unauthorized flaring
- Rule change detection — Maps recent statewide and field-specific rule changes to affected wells and operations
- Risk scoring — Computes a 0-100 compliance risk score per well based on deadline proximity, active issues, violation history, and flaring exposure, then ranks the portfolio
The service also provides a portfolio dashboard endpoint that aggregates all four capabilities for a given operator.
Port & Language
| Property | Value |
|---|---|
| Port | 8006 |
| Language | Python 3.12 |
| Framework | FastAPI |
| Entry point | src/compliance/main.py |
Key Endpoints
| Method | Path | Description |
|---|---|---|
POST | /compliance/deadlines | Scan permits, authorizations, and filings for approaching deadlines. |
POST | /compliance/production | Check production data for allowable exceedances and anomalies. |
POST | /compliance/rule-changes | Detect rule changes affecting the given wells. |
POST | /compliance/risk-score | Risk-rank wells based on compliance factors. |
GET | /compliance/dashboard/{operator_id} | Full portfolio compliance dashboard for an operator. |
GET | /health | Health check. |
Architecture
Module Breakdown
src/compliance/
├── main.py # FastAPI app, endpoint definitions, dashboard aggregation
├── config.py # Settings from environment variables
├── deadlines.py # Deadline scanning logic
├── production.py # Production compliance checking
├── rule_changes.py # Rule change detection
└── risk_scoring.py # Risk scoring algorithmDeadline Tracking (deadlines.py)
The scan_deadlines function processes three types of items:
| Item Type | Checked Field | Alert Context |
|---|---|---|
| Permits | expiration_date | Permit type, permit number |
| Flaring authorizations | expiration_date | R-32 authorization number, renewal urgency |
| Filings | due_date or filed_date | Filing type, form number |
Alert thresholds (configurable):
| Threshold | Default | Alert Level |
|---|---|---|
| Expired (days < 0) | — | critical |
| Critical | 7 days | critical |
| Warning | 14 days | warning |
| Info | 30 days | info |
Alerts are sorted by days remaining (most urgent first). The response includes aggregate counts of critical and warning alerts.
Production Monitoring (production.py)
The check_production_compliance function evaluates each well against four checks:
| Check | Condition | Severity |
|---|---|---|
| Allowable exceedance | Oil production exceeds allowable by more than 5% | critical |
| GOR anomaly | Gas-oil ratio exceeds 2,000 MCF/BBL | warning |
| Zero production | Active well reporting zero oil and gas production | warning |
| Unauthorized flaring | Flaring volume > 0 without an active R-32 authorization | critical |
Rule Change Detection (rule_changes.py)
The service maintains a registry of recent rule changes (currently hardcoded; in production, this would be scraped from RRC). Each rule change is matched against wells based on:
- Well type match: Does the rule affect this well’s type (oil, gas)?
- Field match: Does the rule target a specific field? (If no field restriction, all wells match.)
Currently tracked rule changes:
| Rule Change | Effective Date | Impact |
|---|---|---|
| Rule 32 Amendment — Enhanced Flaring Reporting | 2025-06-01 | Electronic reporting of all flaring events within 24 hours |
| Spraberry Field Rule Amendment | 2025-03-01 | Updated density requirements for horizontal wells |
| EPA OOOOb/c Final Rule | 2024-12-06 | Comprehensive methane emission standards |
Risk Scoring (risk_scoring.py)
The score_well_risk function computes a 0-100 risk score across four weighted factors:
| Factor | Max Points | Scoring |
|---|---|---|
| Deadline proximity | 25 | 25 = expired, 20 = critical, 10 = warning, 0 = clear |
| Active issues | 25 | 8 points per production issue (capped at 25) |
| Violation history | 25 | 10 points per past violation (capped at 25) |
| Flaring exposure | 25 | 25 = exceeded auth, 15 = approaching (80%+), 5 = active |
Risk levels:
| Score Range | Level |
|---|---|
| 70-100 | HIGH |
| 40-69 | MEDIUM |
| 1-39 | LOW |
| 0 | MINIMAL |
The score_portfolio function scores all wells, sorts by risk (descending), and returns distribution statistics.
Portfolio Dashboard
The GET /compliance/dashboard/{operator_id} endpoint aggregates all four capabilities:
- Fetch data from the knowledge graph service via Cypher queries:
- Wells operated by the operator
- Permits associated with the operator
- Flaring authorizations on the operator’s leases
- Run all checks: deadlines, rule changes, production compliance, risk scoring
- Return summary with counts, alerts, and risk distribution
{
"operator_id": "op-permian-01",
"summary": {
"total_wells": 12,
"total_permits": 5,
"total_flaring_auths": 3,
"critical_alerts": 2,
"warning_alerts": 4,
"average_risk_score": 35.2
},
"deadlines": { ... },
"rule_changes": { ... },
"production": { ... },
"risk_scores": { ... }
}Dependencies
Python Packages
| Package | Version | Purpose |
|---|---|---|
fastapi | ^0.115 | Web framework |
uvicorn | ^0.34 | ASGI server |
asyncpg | ^0.29 | PostgreSQL async driver |
httpx | ^0.28 | HTTP client for knowledge graph queries |
aegis-shared | local | Shared models and DB helpers |
Service Dependencies
| Service | Protocol | Purpose |
|---|---|---|
| Knowledge Graph Service (8003) | HTTP | Cypher queries for operator wells, permits, authorizations |
Configuration
| Environment Variable | Default | Description |
|---|---|---|
COMPLIANCE_HOST | 0.0.0.0 | Bind address |
COMPLIANCE_PORT | 8006 | Bind port |
DATABASE_URL | postgresql://aegis:aegis_local@localhost:5432/aegis | PostgreSQL connection |
KNOWLEDGE_GRAPH_SERVICE_URL | http://localhost:8003 | Knowledge graph service URL |
DB_SCHEMA | ag_catalog | Database schema prefix |
Hardcoded thresholds (in config.py):
| Setting | Value | Description |
|---|---|---|
DEADLINE_CRITICAL_DAYS | 7 | Days before deadline triggers critical alert |
DEADLINE_WARNING_DAYS | 14 | Days before deadline triggers warning alert |
DEADLINE_INFO_DAYS | 30 | Days before deadline triggers info alert |
GOR_THRESHOLD | 2,000 MCF/BBL | Gas-oil ratio threshold for RRC review |
ALLOWABLE_TOLERANCE_PCT | 5% | Percentage over allowable before flagging |
Running Locally
cd services/compliance-monitor
poetry install
poetry run uvicorn compliance.main:app --reload --port 8006The compliance monitor depends on the knowledge graph service for the dashboard endpoint. The individual check endpoints (/compliance/deadlines, /compliance/production, etc.) accept data directly in the request body and do not require the knowledge graph service.