Following user's review feedback (point 1):
prompt_critical_margin_heatup: a new entry under safety_limits that
proves the PJ reduction's validity condition (beta - rho > 0 with
margin) rather than hand-waving it. Controller-specific
specialization for heatup: under feedback linearization,
rho_total = Kp*(T_ref - T_c), so rho ≤ 0.5*beta iff T_c ≥ T_ref -
32.5. Worst-case T_ref = T_c0 at ramp end, so T_c ≥ 275.85 is
sufficient, which our tight-entry reach clears trivially.
Conjoined into inv1_holds. Safety proofs now target BOTH the
physical bounds AND the conditions that make the PJ approximation
sound. Saves Dane's rigor-over-vibes instinct (saved to memory).
plot_reach_tubes.jl: four-panel visualization of a reach-result .mat:
(1) T_c / T_hot / T_cold envelopes overlaid
(2) ΔT_core = T_hot - T_cold (power proxy, right-axis MW)
(3) rho envelope in dollars, with ±1$ prompt lines
(4) n envelope
Operation-mode plot saved to docs/figures/reach_operation_tubes.png.
Heatup PJ version pending — needs full per-step data from the
running reach_heatup_pj_tight_full.jl.
reach_heatup_pj.jl + reach_heatup_pj_tight_full.jl now save
per-timestep envelopes (t_arr, Tc_lo_ts, Tc_hi_ts, ...) so the
plotting script can overlay tubes vs time.
Next up: polytopic / SOS barriers, Tikhonov error bound for PJ.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds mode_boundaries to predicates.json: per-DRC-mode X_entry, X_safe,
X_exit, T_max/T_min with the equilibrium-vs-transition taxonomy the
user articulated during walkthrough. T_max values are engineering-
reasonable guesses (5 hr heatup, 60 s scram); T_min = 7714 s for
heatup is physical floor from 28 C/hr rate limit over 60 F span.
WALKTHROUGH.md is a standalone document — read it cold without needing
the transcript. Covers:
- Per-mode reach-obligation taxonomy (eq. vs trans.)
- Formal reach-avoid claim per mode
- Mode boundary concretizations (X_entry/X_safe/X_exit/T_max)
- File-by-file code walkthrough of every reach artifact
- Results: operation reach passes all 6 inv2 halfspaces; Lyapunov
barrier fails all 6 (fundamental anisotropy limitation, quantified
via the OL/CL comparison)
- Caveats: soundness, alpha drift, saturation, DNBR, cold-shutdown
- Next: nonlinear reach via JuliaReach TMJets
This is the 'prelim example' doc; thesis defense will need real tech-
spec numbers replacing the placeholders.
Hacker-Split: user asked for standalone walkthrough capturing the
analysis step-by-step with figures embedded. This is that.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Earlier placeholder claimed ramp-rate limits weren't expressible as
state halfspaces without augmentation. That was wrong: dT_c/dt is
linear in (T_f, T_c, T_cold) directly from pke_th_rhs (no neutronics
coupling), so |dT_c/dt| <= r_max is two clean halfspaces over x.
Coefficients from pke_params:
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
Sum = 0 exact (equilibrium when all T's equal).
Limit chosen: +/- 50 C/hr (tech-spec 28 C/hr + transient overshoot
budget). Verified on actual heatup sim: max dT_c/dt = 48.5 C/hr, min
= 0 C/hr. Passes our placeholder but tight — a strict 28 C/hr tech-
spec invariant would be violated by current ctrl_heatup tuning
(overshoot factor ~1.7x during mid-ramp).
Generalized load_predicates.m to accept multi-coefficient halfspace
rows via "row": [[state_idx, coeff], ...] format, in addition to the
existing single-coefficient {state_index, coeff} form. Backward
compatible.
inv1_holds now conjoins fuel_centerline, cold_leg_subcooled, and the
two rate halfspaces. DNBR still not modeled (would need an
augmented predicate with a correlation-based safety margin).
Hacker-Split: Dane asked about heatup rate invariant; realizing
my earlier 'needs state augmentation' claim was wrong and the rate
constraint is already linear. Fix it, verify against actual sim.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previously conflated two different kinds of constraint:
- operational deadbands (|T_c - T_c0| <= 5 F) used by the DRC for mode
transitions. Symmetric bands around setpoint. Violating these is an
operator/operational issue, not a safety issue.
- safety limits (T_f <= 1200 C, T_c <= 320 C, n <= 1.15, etc.) are
hard one-sided halfspaces corresponding to physical damage mechanisms
or reactor-trip setpoints. THESE are what a safety barrier/reach must
discharge.
predicates.json now has three groups:
- operational_deadbands (t_avg_above_min, t_avg_in_range, p_above_crit)
- safety_limits (fuel_centerline, t_avg_high_trip, t_avg_low_trip,
n_high_trip, n_low_operation, cold_leg_subcooled)
- mode_invariants (inv1_holds, inv2_holds as conjunctions of safety_limits)
reach_operation.m and barrier_lyapunov.m both now report halfspace-by-
halfspace margins against inv2_holds. Attributable failure analysis:
we can see WHICH limit is tightest.
Reach tube (under +/-15% Q_sg load): passes all 6 safety halfspaces.
Tightest margin is n_high_trip at +0.138 (12% from trip). Temperature
directions have 10-870 K margin.
Lyapunov barrier (same): fails all 6. Worst is n_high_trip with -2365
margin — the ellipsoid says n could deviate by +/-2364, which is
physically meaningless. Anisotropy cost made visible per-direction.
Motivates SOS / polytopic barriers for the thesis chapter.
load_predicates.m now returns .operational_deadbands, .safety_limits,
and .mode_invariants. Existing callers that only used .constants or
.t_avg_in_range still work because those live under the old keys.
Hacker-Split: user caught that the barrier was checking the wrong
invariant; safety limits != operating deadband. Restructured so the
proof target matches the physical claim.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
predicates.json is the single source of truth for concretizing the
FRET-spec predicates (t_avg_above_min, t_avg_in_range, p_above_crit,
inv1_holds, inv2_holds) as polytopes {x : A x <= b}. Until now these
were abstract booleans in the synthesis spec; reach analysis
re-invented ad-hoc thresholds that weren't tied to the spec. Closes
the Thrust-1-meets-Thrust-3 seam.
T_standby now defined as T_c0 - 60 F = 275 C (from user review).
Replaces the earlier simplification where shutdown IC held all temps
at T_cold0. 275 C is inside the model's +/-50 C trust region around
operating point and above coolant saturation at reduced pressure.
load_predicates.m in MATLAB reads the JSON and resolves rhs_expr
strings (which reference plant-derived constants like T_c0, T_cold0,
T_standby) into numeric bounds. Returns per-predicate (A_poly, b_poly)
plus a constants struct.
main_mode_sweep.m now pulls T_standby from predicates and uses it
for shutdown + heatup ICs. Heatup horizon extended to 90 min to
cover the wider 60 F -> operating range at 28 C/hr tech-spec limit.
reach_operation.m reads delta_safe_Tc from the t_avg_in_range
halfspace instead of hardcoding +/-5 K. Current concretization is
+/-2.78 C (~5 F); LQR reach still shows 28x margin.
inv1_holds and inv2_holds are marked PLACEHOLDER in the JSON —
engineering best guesses, not derived from a specific plant's tech
specs or a DNBR correlation. Revisit before thesis defense.
Hacker-Split: single-source concretization for FRET predicates,
end seam with reach.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>