{
  "_comment": [
    "Concretization of the FRET-spec predicates AND the hard safety limits.",
    "Two categories kept distinct:",
    "  - operational_deadbands: soft bands around setpoint used by the DRC for",
    "    mode transitions (t_avg_in_range etc.).  Violating these does not",
    "    cause damage, it just triggers a mode change or operator action.",
    "  - safety_limits: hard one-sided halfspaces corresponding to physical",
    "    damage mechanisms or reactor-trip setpoints.  Barrier certificates",
    "    and reach-set safety checks should target THESE, not the deadbands.",
    "",
    "The FRET-spec invariants inv1_holds, inv2_holds are concretized as the",
    "conjunction of relevant safety_limits for each mode."
  ],
  "_units": {
    "temperatures": "degrees Celsius (SI, internal model units)",
    "n": "normalized power, 1.0 = full power"
  },
  "references": {
    "T_c0": "308.35 C — full-power avg coolant (from pke_params.m)",
    "T_f0": "328.35 C — full-power fuel",
    "T_cold0": "290.0 C — full-power cold leg",
    "T_standby": "275.02 C — hot standby T_avg, defined as T_c0 - 33.33 C (= T_c0 - 60 F)"
  },
  "derived": {
    "T_standby_offset_F": -60.0,
    "T_standby_offset_C": -33.333333333,
    "t_avg_in_range_halfwidth_F": 5.0,
    "t_avg_in_range_halfwidth_C": 2.777777,
    "t_avg_above_min_margin_F": 10.0,
    "t_avg_above_min_margin_C": 5.555555,
    "p_above_crit_threshold_n": 1.0e-4,
    "T_fuel_limit_C": 1200.0,
    "T_c_high_trip_C": 320.0,
    "n_high_trip": 1.15,
    "T_cold_subcooling_margin_C": 15.0
  },

  "operational_deadbands": {
    "_comment": "Soft bands. Used by the DRC for mode switching, not for safety proofs.",
    "t_avg_above_min": {
      "meaning": "Coolant warmed above cold-start threshold — shutdown may transition to heatup.",
      "concretization": "T_c >= T_standby + 5.556 C (hot-standby + 10 F buffer)",
      "halfspaces": [
        { "state_index": 9, "coeff": -1.0, "rhs_expr": "-(T_standby + 5.556)" }
      ]
    },
    "t_avg_in_range": {
      "meaning": "Average coolant in tight operating band — used for heatup->operation transition.",
      "concretization": "|T_c - T_c0| <= 2.778 C (~5 F deadband)",
      "halfspaces": [
        { "state_index": 9, "coeff":  1.0, "rhs_expr": "T_c0 + 2.778" },
        { "state_index": 9, "coeff": -1.0, "rhs_expr": "-(T_c0 - 2.778)" }
      ]
    },
    "p_above_crit": {
      "meaning": "Reactor power in the 'power range' instrumentation regime.",
      "concretization": "n >= 1e-4",
      "halfspaces": [
        { "state_index": 1, "coeff": -1.0, "rhs_expr": "-1.0e-4" }
      ]
    }
  },

  "safety_limits": {
    "_comment": [
      "Hard one-sided halfspaces. Exceeding any of these is damage or trip.",
      "All are asymmetric — the plant is not equally vulnerable on both sides",
      "of the setpoint.  Values are representative of a 2-loop Westinghouse-",
      "class PWR; calibrate to specific plant tech specs before defense."
    ],
    "fuel_centerline": {
      "meaning": "Fuel centerline temperature below design limit to prevent UO2 melt.",
      "concretization": "T_f <= 1200 C (conservative; actual melt ~2800 C)",
      "halfspaces": [
        { "state_index": 8, "coeff": 1.0, "rhs_expr": "1200.0" }
      ]
    },
    "t_avg_high_trip": {
      "meaning": "High-T_avg reactor trip. Typical PWR: ~612-616 F = 322-324 C.",
      "concretization": "T_c <= 320 C (conservative)",
      "halfspaces": [
        { "state_index": 9, "coeff": 1.0, "rhs_expr": "320.0" }
      ]
    },
    "t_avg_low_trip": {
      "meaning": "Low-T_avg reactor trip.  Typical PWR: ~540 F = 282 C.",
      "concretization": "T_c >= 280 C",
      "halfspaces": [
        { "state_index": 9, "coeff": -1.0, "rhs_expr": "-280.0" }
      ]
    },
    "n_high_trip": {
      "meaning": "High-flux reactor trip.  Typical PWR: 118%% of rated.",
      "concretization": "n <= 1.15",
      "halfspaces": [
        { "state_index": 1, "coeff": 1.0, "rhs_expr": "1.15" }
      ]
    },
    "n_low_operation": {
      "meaning": "Operation mode is only valid at power (avoids intermediate-range instrumentation).",
      "concretization": "n >= 0.15 (15%% of rated)",
      "halfspaces": [
        { "state_index": 1, "coeff": -1.0, "rhs_expr": "-0.15" }
      ]
    },
    "cold_leg_subcooled": {
      "meaning": "Cold leg stays subcooled with margin against loss-of-pressure events.",
      "concretization": "T_cold <= T_cold0 + 15 (roughly saturation margin at operating pressure)",
      "halfspaces": [
        { "state_index": 10, "coeff": 1.0, "rhs_expr": "T_cold0 + 15.0" }
      ]
    },
    "heatup_rate_upper": {
      "meaning": "Coolant heatup rate does not exceed tech-spec limit + overshoot margin.",
      "concretization": "dT_c/dt = a_f*T_f + a_c*T_c + a_cold*T_cold <= 0.01389 C/s (50 C/hr; tech-spec 28 C/hr + transient overshoot budget)",
      "_derivation": "dT_c/dt is linear in (T_f, T_c, T_cold) from pke_th_rhs.m: a_f=hA/(M_c*c_c)=+0.4587/s, a_c=-(hA+2*W*c_c)/(M_c*c_c)=-0.9587/s, a_cold=2*W*c_c/(M_c*c_c)=+0.5000/s. Coefficients sum to zero by construction (equilibrium when all T's equal).",
      "halfspaces": [
        { "row": [[8, 0.4587], [9, -0.9587], [10, 0.5000]], "rhs_expr": "0.01389" }
      ]
    },
    "heatup_rate_lower": {
      "meaning": "Coolant cooldown rate during heatup doesn't exceed -50 C/hr (flag runaway cooldown).",
      "halfspaces": [
        { "row": [[8, -0.4587], [9, 0.9587], [10, -0.5000]], "rhs_expr": "0.01389" }
      ]
    },
    "prompt_critical_margin_heatup": {
      "meaning": "Total reactivity stays safely below prompt-critical; keeps the prompt-jump PJ reduction valid. Per-mode specialization: for heatup with feedback linearization, rho_total = Kp*(T_ref(t) - T_c). Requiring rho <= 0.5*beta gives T_c >= T_ref - (beta - 0.5*beta)/Kp = T_ref - 32.5. Since T_ref increases monotonically from T_standby up to T_c0, the worst case is at the ramp end: T_c >= T_c0 - 32.5 = 275.85 C. Approximate as a constant halfspace with the worst-case T_ref.",
      "concretization": "T_c >= 275.85 (ensures rho <= 0.5*beta under heatup FL controller)",
      "halfspaces": [
        { "state_index": 9, "coeff": -1.0, "rhs_expr": "-275.85" }
      ],
      "_note": "This is a controller-specific specialization. If the controller or its gain change, recompute. For LQR operation and constant-u scram the margin is trivially satisfied (much larger)."
    }
  },

  "mode_invariants": {
    "_comment": [
      "Per-DRC-mode invariants: conjunctions of relevant safety_limits.",
      "This is the target of per-mode reach and barrier analysis."
    ],
    "inv1_holds": {
      "meaning": "Heatup mode safety envelope.",
      "conjunction_of": [
        "fuel_centerline",
        "cold_leg_subcooled",
        "heatup_rate_upper",
        "heatup_rate_lower",
        "prompt_critical_margin_heatup"
      ],
      "_note": "dT_c/dt is linear in (T_f, T_c, T_cold), so ramp-rate halfspace has 3 nonzero coefficients per row. prompt_critical_margin_heatup proves the PJ reduction's validity condition (beta - rho > 0 with margin) as part of the safety obligation rather than as an unverified premise. DNBR not modeled — would need an augmented correlation-based predicate."
    },
    "inv2_holds": {
      "meaning": "Operation mode safety envelope.",
      "conjunction_of": [
        "fuel_centerline",
        "t_avg_high_trip",
        "t_avg_low_trip",
        "n_high_trip",
        "n_low_operation",
        "cold_leg_subcooled"
      ]
    }
  },

  "mode_boundaries": {
    "_comment": [
      "Per-DRC-mode entry/exit sets and time budgets.  Two kinds of modes:",
      "  equilibrium: operation, shutdown.  Obligation is forever-invariance.",
      "  transition:  heatup, scram.     Obligation is reach-avoid — reach",
      "               X_exit within [T_min, T_max] while maintaining X_safe.",
      "",
      "T_max values are demo-reasonable guesses, not tech-spec calibrated.",
      "T_min where given is a physical lower bound from rate limits (heatup",
      "at 28 C/hr implies >= 60F/28 = 2.14 hr minimum for the 60F span)."
    ],

    "q_shutdown": {
      "kind": "equilibrium",
      "obligation": "stay within X_safe forever; transition out only when X_exit becomes true",
      "X_entry_description": "initial DRC state OR post-scram cooled-down state — reasonable hot-standby conditions",
      "X_entry_polytope": {
        "n_range":      [1.0e-7, 1.0e-4],
        "T_f_range_C":  [270.0, 280.0],
        "T_c_range_C":  [270.0, 280.0],
        "T_cold_range_C": [270.0, 280.0]
      },
      "X_safe_predicate": "inv_shutdown_holds (TBD — conservative: stay near T_standby with n subcritical)",
      "X_exit_predicate": "t_avg_above_min (operator has warmed coolant above threshold)",
      "T_max_seconds": null,
      "T_min_seconds": null
    },

    "q_heatup": {
      "kind": "transition",
      "obligation": "from X_entry, reach X_exit within [T_min, T_max], maintain inv1_holds throughout",
      "X_entry_description": "post-t_avg_above_min: operator has warmed coolant, n pulled toward criticality",
      "X_entry_polytope": {
        "n_range":      [5.0e-4, 5.0e-3],
        "T_f_range_C":  [275.0, 295.0],
        "T_c_range_C":  [281.0, 295.0],
        "T_cold_range_C": [270.0, 281.0]
      },
      "X_safe_predicate": "inv1_holds",
      "X_exit_predicate": "t_avg_in_range AND p_above_crit AND inv1_holds",
      "T_max_seconds": 18000,
      "T_min_seconds": 7714,
      "_T_max_rationale": "5 hr. Tech-spec limit 28 C/hr; 60 F = 33.3 C span; nominal 1.19 hr, allow 4x margin for transient overshoot + settling.",
      "_T_min_rationale": "2 hr 8.6 min. Physical floor: heatup faster than 28 C/hr violates the rate invariant. 60 F / 28 C/hr = 33.3 / 28 = 1.189 hr at tech-spec max; add 30% margin for non-uniform ramp = 2.14 hr."
    },

    "q_operation": {
      "kind": "equilibrium",
      "obligation": "stay in X_safe forever under bounded Q_sg",
      "X_entry_description": "X_exit(heatup)",
      "X_entry_polytope_ref": "q_heatup.X_exit_predicate",
      "X_safe_predicate": "inv2_holds",
      "X_exit_predicate": "NOT inv2_holds (trigger scram) OR q_operation stays indefinitely",
      "disturbance": {
        "variable": "Q_sg",
        "range_fraction_of_P0": [0.85, 1.00],
        "_rationale": "Grid load-follow envelope. Could be tightened to 0.95-1.00 for steady-state or widened to 0.70-1.00 for aggressive load following."
      },
      "T_max_seconds": null,
      "T_min_seconds": null
    },

    "q_scram": {
      "kind": "transition",
      "obligation": "from any trip-triggering state, drive reactor to safely-subcritical within T_max",
      "X_entry_description": "any state where inv1_holds or inv2_holds fails during heatup/operation",
      "X_entry_polytope": "union of (X_operation - inv2_holds-satisfying) and (X_heatup - inv1_holds-satisfying) — for demo, take x_op",
      "X_safe_predicate": "n is monotonically non-increasing (n'(t) <= 0); T stays bounded",
      "X_exit_predicate": "n <= 1e-4 AND T_f <= T_f0 + 50 C",
      "T_max_seconds": 60,
      "T_min_seconds": null,
      "_T_max_rationale": "60 s. NRC requirement typically few seconds to subcritical; 60 s is generous for our lumped model with idealized rod-insertion. Real plants: rods free-fall in ~2-3 s."
    }
  },

  "_placeholder_warning": [
    "Numerical values in safety_limits are representative (2-loop Westinghouse-",
    "class PWR tech-spec ranges) but NOT calibrated to a specific plant.",
    "Calibrate against a real plant's tech specs before defense."
  ]
}
