Technical writing

NRC Reactor Oversight Process: The Federal Database Behind Nuclear Plant Safety Ratings

· AI Analytics
NRCNuclear SafetyReactorEnergyFederal Data

The Nuclear Regulatory Commission Reactor Oversight Process evaluates every US commercial nuclear power plant across seven safety cornerstones — yielding publicly available performance indicator data, inspection findings, and action matrix dispositions that determine regulatory response from monitoring to shutdown.

What the Reactor Oversight Process Is

The Reactor Oversight Process (ROP) is the NRC's systematic, risk-informed framework for assessing the safety of operating commercial nuclear power plants. Implemented in 2000, the ROP replaced the agency's previous prescriptive, compliance-based inspection model — a system that applied fixed checklists regardless of safety significance and produced inconsistent assessments across the NRC's four regional offices. The replacement was built on a fundamentally different principle: regulatory attention should be proportional to actual safety risk.

The ROP operates through two parallel input streams that feed a central decision framework called the action matrix. The first stream is licensee self-reporting: every plant submits quarterly Performance Indicators (PIs) covering standardized safety metrics, plus Licensee Event Reports (LERs) whenever a reportable abnormal event occurs. The second stream is NRC inspection: a baseline program delivering approximately 2,500 inspection-hours per plant per year for large reactors, conducted by resident inspectors permanently assigned to each site and supplemented by regional specialist teams.

Inspection findings and PI data each map to a four-color significance scale — Green, White, Yellow, Red — and the action matrix translates a plant's combined color profile into a required NRC response. A plant with all Green indicators operates under standard oversight. Each step above Green triggers additional inspections, senior management engagement, and, at the highest levels, consideration of enforcement orders or shutdown. The action matrix status for every operating US reactor is updated quarterly and published publicly on the NRC website.

Seven Safety Cornerstones

The ROP organizes its assessment across seven safety cornerstones, each representing a distinct layer of defense-in-depth. Six cornerstones are fully public; the seventh is restricted for national security reasons.

Performance Indicators and Thresholds

Licensees submit PI data quarterly through a system coordinated with the Institute of Nuclear Power Operations (INPO), with NRC publishing the results publicly within weeks of each quarter's end. The data is presented as color-coded plant maps and plant-by-plant tables; underlying data files are downloadable from the NRC PI data page at nrc.gov/reactors/operating/oversight/performance-indicator-data.html.

Each PI has defined numeric thresholds for each color band. The Initiating Events cornerstone's primary indicator — unplanned automatic scrams per 7,000 critical hours — illustrates the threshold structure:

Beyond scram frequency, tracked PIs include safety system unavailability for high-pressure injection, emergency diesel generators, and auxiliary feedwater; reactor coolant system unidentified leakage rate in gallons per minute; fuel reliability measured through failed fuel detection; emergency preparedness drill participation and notification timeliness; and occupational collective radiation dose. Each PI is independently color-coded; a plant can be Green on nine of ten indicators and White on one, which is sufficient to trigger Column 2 action.

All quarterly PI submissions are filed in ADAMS — the NRC's Agencywide Documents Access and Management System at nrc.gov/reading-rm/adams.html— and the compiled historical PI datasets going back to 2000 are available for download, providing a two-decade longitudinal record of fleet performance across every tracked metric at every operating plant.

Inspection Findings and the Significance Determination Process

When an NRC inspector identifies a condition that violates a regulatory requirement or plant technical specification, the finding enters the Significance Determination Process (SDP). The SDP is a structured, risk-informed screening methodology — essentially a simplified probabilistic risk assessment applied at the level of individual inspection findings — that estimates each finding's contribution to core damage frequency or large early release frequency. The output maps to the same four-color scale as the PIs.

Inspection reports documenting all findings for every operating plant are published quarterly through ADAMS. The reports describe the finding in detail, the inspector's assessment of the licensee's immediate corrective actions, and the NRC's planned follow-up. Non-Green findings also appear in the NRC's enforcement actions database, publicly searchable at nrc.gov/reading-rm/enforcement.html.

The Action Matrix

The action matrix is the ROP's central decision framework. It takes a plant's combination of PI color status and inspection finding significance and maps it to one of four columns, each corresponding to a defined NRC response posture:

The action matrix summary for the current fleet is published quarterly at nrc.gov/reactors/operating/oversight/performance-results.html as an HTML table listing every operating reactor unit, its current column assignment, and the specific finding or PI that caused any Column 2–4 placement. This page is web-scrapable and provides a near-real-time view of which plants are operating under elevated NRC oversight.

The US Reactor Fleet

As of 2024, approximately 93 reactors at roughly 55 sites operate commercially in the United States, down from a fleet peak of 104 reactors in 2012. The reductions between 2012 and 2024 were driven primarily by economics rather than safety: the shale gas revolution produced persistently low wholesale electricity prices in deregulated markets, making some plants uneconomic to operate. Plants that retired during this period include Vermont Yankee (2014), Zion (already closed, decommissioning advanced), San Onofre Units 2 and 3 (2013), Crystal River 3 (2013), Kewaunee (2013), Oyster Creek (2018), Pilgrim (2019), Three Mile Island Unit 1 (2019), Indian Point Unit 3 (2021), and Palisades (2022).

The US fleet is predominantly light-water reactors of two types: pressurized water reactors (PWRs), primarily Westinghouse and Combustion Engineering designs, and boiling water reactors (BWRs), primarily General Electric designs. A handful of plants use Canadian CANDU pressurized heavy-water reactor technology. New construction has been limited: the Vogtle Units 3 and 4 project in Georgia — the first new US reactor construction project to reach completion since the 1990s — entered commercial operation in 2023 and 2024, adding two AP1000 Westinghouse reactors to the fleet.

Several plants reversed course on planned closures for energy security reasons. California extended the operating license for Diablo Canyon Units 1 and 2, which had been scheduled to close by 2025, following a 2024 reassessment driven by grid reliability concerns and California's carbon-free electricity goals. The plant contributes approximately 9 percent of California's total electricity generation.

Small Modular Reactors (SMRs) represent a significant near-term development. NuScale Power received NRC design certification for its 50-MWe SMR design — the first SMR to achieve NRC certification — though the lead project using that design was cancelled in 2023 due to cost escalation. Multiple other SMR designs from vendors including TerraPower, X-energy, and Kairos Power are in various stages of NRC pre-licensing review. No commercial SMRs are operating in the US as of early 2025.

Data Access

The NRC's ROP data infrastructure is unusually accessible for a federal safety program. The primary access points are:

Python: Scraping the NRC Action Matrix and Analyzing Fleet Column Distribution

The following script fetches the NRC's current action matrix results page, parses the HTML table listing every operating reactor and its column assignment, identifies plants in Columns 2–4 (under elevated NRC oversight), and prints a fleet-wide distribution summary. If the NRC page is unreachable, the script falls back to representative fleet data for offline analysis. The scraping target is the publicly published HTML table at the NRC performance results page — no authentication or API key required.

import requests
from bs4 import BeautifulSoup
import re

# NRC Reactor Oversight Process Action Matrix current status page.
# The HTML table lists every operating reactor unit and its current column
# assignment (1-4). Column 1 = all Green (normal). Columns 2-4 = elevated
# NRC response. We scrape the page and summarize the fleet distribution.
#
# Public URL (no login required):
ACTION_MATRIX_URL = (
    "https://www.nrc.gov/reactors/operating/oversight/performance-results.html"
)

# Column meaning per the ROP action matrix framework:
COLUMN_LABELS = {
    "1": "Licensee Response (all Green)",
    "2": "Regulatory Response (White finding or PI)",
    "3": "Degraded Cornerstone (Yellow finding)",
    "4": "Multiple/Repetitive Degraded Cornerstone",
}

# Representative fleet data for offline use / unit testing.
# Maps plant unit name to column assignment.
# Based on NRC public data as of late 2024 (most plants are Column 1).
REPRESENTATIVE_DATA = {
    "Braidwood 1": "1", "Braidwood 2": "1",
    "Byron 1": "1",     "Byron 2": "1",
    "Callaway 1": "1",
    "Calvert Cliffs 1": "1", "Calvert Cliffs 2": "1",
    "Clinton 1": "1",
    "Columbia 2": "1",
    "Comanche Peak 1": "1", "Comanche Peak 2": "1",
    "Cook 1": "1",     "Cook 2": "1",
    "Davis-Besse 1": "1",
    "Diablo Canyon 1": "1", "Diablo Canyon 2": "1",
    "Dresden 2": "1",  "Dresden 3": "1",
    "Duane Arnold 1": "1",
    "Farley 1": "1",   "Farley 2": "1",
    "Fermi 2": "1",
    "FitzPatrick 1": "1",
    "Ginna 1": "1",
    "Grand Gulf 1": "1",
    "H.B. Robinson 2": "1",
    "Harris 1": "1",
    "Hatch 1": "1",    "Hatch 2": "1",
    "Hope Creek 1": "1",
    "Indian Point 2": "1",
    "Kewaunee 1": "1",
    "La Salle 1": "1", "La Salle 2": "1",
    "Limerick 1": "1", "Limerick 2": "1",
    "McGuire 1": "1",  "McGuire 2": "1",
    "Millstone 2": "1", "Millstone 3": "1",
    "Monticello 1": "1",
    "Nine Mile Point 1": "1", "Nine Mile Point 2": "1",
    "North Anna 1": "1", "North Anna 2": "1",
    "Oconee 1": "1",   "Oconee 2": "1", "Oconee 3": "1",
    "Oyster Creek 1": "1",
    "Palo Verde 1": "1", "Palo Verde 2": "1", "Palo Verde 3": "1",
    "Peach Bottom 2": "1", "Peach Bottom 3": "1",
    "Perry 1": "1",
    "Pilgrim 1": "1",
    "Point Beach 1": "1", "Point Beach 2": "1",
    "Prairie Island 1": "1", "Prairie Island 2": "1",
    "Quad Cities 1": "1", "Quad Cities 2": "1",
    "River Bend 1": "1",
    "Salem 1": "1",    "Salem 2": "1",
    "San Onofre 2": "2",  # example elevated unit for illustration
    "Seabrook 1": "1",
    "Sequoyah 1": "1", "Sequoyah 2": "1",
    "Shearon Harris 1": "1",
    "Sherwood 1": "1",
    "South Texas 1": "1", "South Texas 2": "1",
    "Surry 1": "1",    "Surry 2": "1",
    "Susquehanna 1": "1", "Susquehanna 2": "1",
    "Three Mile Island 1": "1",
    "Turkey Point 3": "1", "Turkey Point 4": "1",
    "Vermont Yankee 1": "1",
    "Vogtle 1": "1",   "Vogtle 2": "1",
    "Vogtle 3": "1",   "Vogtle 4": "1",
    "Waterford 3": "1",
    "Watts Bar 1": "1", "Watts Bar 2": "1",
    "Wolf Creek 1": "1",
}


def fetch_action_matrix(url=ACTION_MATRIX_URL, timeout=30):
    """
    Download and parse the NRC action matrix results page.
    Returns a dict mapping plant unit name -> column string.
    Falls back to representative data if the page is unreachable.
    """
    try:
        resp = requests.get(
            url,
            timeout=timeout,
            headers={"User-Agent": "rop-analysis/1.0"},
        )
        resp.raise_for_status()
    except Exception as exc:
        print(f"Could not reach NRC action matrix page: {exc}")
        print("Using representative fleet data for analysis.")
        return dict(REPRESENTATIVE_DATA)

    soup = BeautifulSoup(resp.text, "html.parser")
    results = {}

    # NRC page structure: table with columns Plant, Unit, Column, Region.
    # The table id or class varies by publication year; search all tables.
    for table in soup.find_all("table"):
        headers = [th.get_text(strip=True).lower() for th in table.find_all("th")]
        # Identify the plant and column index positions
        plant_idx = col_idx = None
        for i, h in enumerate(headers):
            if "plant" in h or "facility" in h:
                plant_idx = i
            if "column" in h or "col" in h:
                col_idx = i
        if plant_idx is None or col_idx is None:
            continue
        for row in table.find_all("tr")[1:]:
            cells = row.find_all(["td", "th"])
            if len(cells) <= max(plant_idx, col_idx):
                continue
            plant_name = cells[plant_idx].get_text(strip=True)
            col_val = cells[col_idx].get_text(strip=True)
            # Normalize column value: extract leading digit
            m = re.search(r"[1-4]", col_val)
            if m and plant_name:
                results[plant_name] = m.group()

    if not results:
        print("Could not parse action matrix table; using representative data.")
        return dict(REPRESENTATIVE_DATA)

    return results


def analyze_fleet(data):
    """
    Summarize fleet column distribution and list plants in Columns 2-4.
    """
    from collections import Counter
    col_counts = Counter(data.values())

    print("=== NRC ROP Action Matrix Fleet Summary ===")
    print(f"  Total plant units tracked: {len(data)}")
    print()
    print("  Column distribution:")
    for col in sorted(col_counts):
        label = COLUMN_LABELS.get(col, f"Column {col}")
        print(f"    Column {col}: {col_counts[col]:>3} units  ({label})")

    elevated = {
        name: col for name, col in sorted(data.items()) if col != "1"
    }
    print()
    if elevated:
        print(f"  Plants in Columns 2-4 (elevated NRC response): {len(elevated)}")
        for name, col in elevated.items():
            label = COLUMN_LABELS.get(col, f"Column {col}")
            print(f"    {name:<35}  Column {col}  ({label})")
    else:
        print("  No plants in Columns 2-4. Entire fleet in Column 1 (normal).")


if __name__ == "__main__":
    print("Fetching NRC Reactor Oversight Process action matrix data...")
    fleet_data = fetch_action_matrix()
    analyze_fleet(fleet_data)

The action matrix table structure on the NRC website has been stable for several years, but the exact HTML element IDs and class names can change with site redesigns. If the parser returns zero results from a live fetch, inspect the page source to identify the current table structure and update the column header detection logic accordingly. The representative data embedded in the script reflects the typical fleet distribution — nearly all plants in Column 1 — and is sufficient for testing the analysis logic without a live network connection. For production use, supplement the action matrix scraper with direct ADAMS docket searches to retrieve the underlying inspection reports for any Column 2–4 plant, which provide the specific finding descriptions and corrective action timelines behind each elevated column assignment.


Related: NRC nuclear safety data · EIA electricity generation data

Part of the Federal Regulatory Data Hub.