PWR-HYBRID-3/claude_memory/2026-04-20-21-overnight-session-summary.md
Dane Sabo 2bbb1871cc refactor: scripts subdivision + TOML configs + results/ split + presentation outline
Architecture restructure from morning review:

1. code/scripts/ subdivided into sim/, reach/, barrier/, plot/.
   Easier nav; `barrier/` is the natural place for SOS scale-up scripts.
2. Heatup PJ reach variants consolidated behind TOML configs.
   reach_heatup_pj.jl now takes `--config path/to/config.toml`;
   configs/heatup/baseline.toml (wide entry, from predicates.json) and
   configs/heatup/tight.toml (narrow entry, reproduces all-6-halfspaces
   discharged result). Old reach_heatup_pj_tight.jl and
   reach_heatup_pj_tight_full.jl deleted (superseded).
3. Reach output .mat files moved from reachability/ to results/.
   reachability/ now = specs + docs; results/ = ephemeral outputs
   (gitignored *.mat). README added.
4. OVERNIGHT_NOTES.md archived to claude_memory/2026-04-20-21-overnight-
   session-summary.md (date range in the filename makes the history clearer).

All include() / Pkg.activate() paths in scripts updated for the new
depth. Smoke tests pass (reach_operation.jl generates its .mat in
the new results/ location; sim_sanity.jl matches MATLAB).

Presentation outline for the 20-min prelim talk landed in
presentations/prelim-presentation/outline.md. 14-slide assertion-
evidence format targeting OT-informed cybersecurity audience. Each
slide: one declarative assertion + one figure. Outline includes
which figures already exist and which need to be created, timing
checkpoints, cybersecurity angle to emphasize, and Q&A prep.

New config configs/heatup/with_steam_dump.toml + its companion
scripts/reach/reach_heatup_pj_sd.jl (12-state RHS with Q_sg as an
augmented bounded parameter x[10] and time as x[11]). Kicks off
point 3 from morning review.

Next up: scram X_entry expansion (morning point 2) — LOCA scenario
+ union of mode reach envelopes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 20:24:48 -04:00

187 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Overnight session summary
## ⚠️ Remote push blocked
You asked me to push to remote for backup. The repo has **no configured
origin remote**, so I guessed `ssh://git@gitea.danesabo.com:1738/danesabo/pwr-hybrid-3-demo.git`
based on the submodule URLs. The harness blocked this as "agent-inferred
URL" exfiltration risk — correct call on its part.
To unblock, run one of:
```bash
git remote add origin ssh://git@gitea.danesabo.com:1738/danesabo/<ACTUAL-REPO-NAME>.git
git push -u origin main
```
or add `Bash(git remote add*)` + `Bash(git push*)` to
`.claude/settings.local.json` and let me retry.
All work is committed locally; no data lost.
---
**Date:** 2026-04-20 → 2026-04-21 (overnight autonomous session)
Read this first when you open the laptop. Full details in
`journal/journal.pdf` (newest entry: `2026-04-20-overnight-prompt-jump.tex`).
## Post-gym session additions (2026-04-21 afternoon)
Six more commits landed after you left for the gym. Headlines:
6. **PJ-validity halfspace added to predicates.** New
`prompt_critical_margin_heatup` row in `safety_limits`: requires
`T_c ≥ T_c0 - 32.5` to guarantee `ρ ≤ 0.5·β` under the heatup
feedback-lin controller. Conjoined into `inv1_holds`. Now the PJ
approximation's validity is *part of the safety obligation* the
reach proves, not an external premise. (Your point 1.)
7. **T_c + T_h + T_cold tube overlay plots.** Four-panel figures for
operation and heatup PJ: temperature tubes on one axis,
ΔT_core = T_h T_cold as power proxy (MW right-axis), ρ
envelope in dollars, n envelope. See
`docs/figures/reach_operation_tubes.png` and
`docs/figures/reach_heatup_pj_tubes.png`. (Your point 4.)
8. **Polytopic barrier check (naive):** fails as expected. Safety
polytope too big for LQR to contract from everywhere. Right tool
is Blanchini pre-image iteration; sketched in the script +
journal.
9. **SOS polynomial barrier: FIRST SUCCESS.** Degree-4 polynomial
`B(x1, x2)` certifies safety on the 2-state reduced operation
projection. CSDP returned OPTIMAL. Full coefficients in the
journal entry. `code/scripts/barrier_sos_2d.jl`. This is the
non-quadratic barrier the plant needs; quadratic Lyapunov can
never work due to anisotropy, polynomial-of-degree-4 can.
10. **Tikhonov bound derivation for PJ.** Wrote out the
singular-perturbation theorem application: puts the PKE in
slow-fast form, identifies `n_PJ(x)` as the quasi-steady
manifold, and shows error is `O(Λ) = O(10⁻⁴)` uniformly after
the boundary layer. Rigorous rate. The `prompt_critical_margin_heatup`
invariant is the validity hypothesis, which reach discharges.
Empirical 0.1% error and the bound are consistent. Remaining
gap: compute the problem-specific constant `C` numerically.
11. **Controller-ref mismatch found in heatup tube plots.** With
`X_entry` at `T_c ∈ [285, 291]` but controller ref starting at
`T_standby = 275`, the FL controller commands cooling (ρ stays
negative). Captured in journal as an apass for next session;
physics-grade fix is to parameterize `ref.T_start` from current
`T_c` at mode entry.
## TL;DR
1. **Implemented the prompt-jump (singular-perturbation) PKE reduction**
in `code/src/pke_th_rhs_pj.jl`. State drops 10 → 9 (n algebraic).
Validated against full 10-state: max 0.1% relative error on n, max
7 mK on temperatures over 50 minutes of heatup. See
`docs/figures/validate_pj_heatup.png`.
2. **Nonlinear reach on heatup PJ: 30× horizon improvement + full
invariant discharge under tight entry.**
- Before: full-state hit prompt-neutron stiffness wall at T=10s.
- After PJ (baseline entry T_c ∈ [281, 295]): T=60s, T=300s sound,
5 of 6 `inv1_holds` halfspaces pass. Low-T_avg trip violated
by tube (272.4 vs 280) due to entry width + over-approximation.
- **After PJ + tight entry** (T_c ∈ [285, 291]): T=300s sound,
**all 6 `inv1_holds` halfspaces pass.** T_c envelope stable at
[281.05, 291.0] — tube reached steady envelope and stopped
growing. First sound nonlinear reach-avoid proof for this plant.
- T=1800s+ runs out of 100k step budget even with PJ. Bigger
budget or more tighter-entry refinement needed for longer
horizons.
3. **Scram PJ reach — landed.** All three probe horizons (10, 30, 60 s)
clean, no step-budget truncation. n decays monotonically:
`[0.0347 → 0.0155 → 0.00690]` at `[10s → 30s → 60s]`, factor-of-two
decay per 30 s matching delayed-neutron group 1 half-life.
**BUT:** `X_exit(scram) = n ≤ 1e-4` isn't reached in 60 s
(real `n ~ 7e-3`). T_max vs plant-decay-rate mismatch, not a control
failure. Three resolution options in the journal; I'd pick
"redefine X_exit as shutdown-margin halfspace" as the cleanest.
4. **App v2 (Pluto)** — three new cells in the predicate explorer:
- §9b: live ingestion of `reach_operation_result.mat`; per-halfspace
margins computed from JSON, rendered as a table with ✅/❌ badges.
- §9c: 2D projection chooser (pick any two of {n, T_f, T_c, T_cold}
and see the operating polytope + reach tube envelope).
- §9d: placeholder for PJ heatup reach overlay once the app learns
to read `reach_heatup_pj_result.mat`.
5. **Journal:** now 32 pages, rebuilds cleanly via `latexmk -pdf` in
`journal/`. Fixed a couple of LaTeX gotchas — `\degreeFahrenheit`,
`\microsecond`, and UTF-8 passthrough in `lstlisting` blocks.
## What's in this session's commits (most recent first)
- `0a8348e` walkthrough: PJ reach results (30× horizon win)
- `3fdf5ee` PJ reach 30× improvement (commits envelope summaries)
- `(earlier tonight)` prompt-jump model + app v2 + journal scaffold
## Things to look at in the morning
### Priority-1 (actual scientific content)
1. **Pull up `journal/journal.pdf`.** 32 pages, all the deep stuff.
Most relevant entry: `2026-04-20-overnight-prompt-jump.tex`.
2. **Look at `docs/figures/validate_pj_heatup.png`** — the visual
evidence that PJ is a sound reduction for slow heatup.
3. **Pluto app:**
```bash
cd app && julia --project=. -e 'using Pluto; Pluto.run()'
# open predicate_explorer.jl
```
§9b should show live margins from the refreshed reach result.
4. **Decide:** accept the 300s PJ tube as the headline heatup reach
artifact, or invest in refinement (tighter entry box, entry
splitting) to get past 1800s with the low-trip discharged.
### Priority-2 (followup ideas)
- `code/scripts/reach_heatup_pj_tight.jl` exists (committed but not
run tonight). Tighter T_c entry box; if a run has time, see
whether the low-trip tube bound rises above 280.
- `code/scripts/reach_scram_pj.jl` — scram reach. Either already in
the commit log by morning, or still running.
- Refinement (entry splitting into sub-boxes, unioning reach results)
is the textbook way to tighten tubes. Haven't implemented.
- Saturation-as-hybrid-sub-mode — still the open item for heatup
soundness.
- Polytopic/SOS barrier — still the open item for analytic
certificate.
- Parametric α uncertainty — still the open item for robust reach.
### What NOT to forget
- The PJ reduction introduces a ≤0.1% error. It's documented and
bounded, but it's an approximation. "Sound w.r.t. PJ dynamics"
≠ "sound w.r.t. physical plant." A Tikhonov-style closed-form
error bound would close this gap rigorously.
- Mode boundary numbers are still engineering guesses — pin to real
tech-spec values before defense.
- `reach_heatup_pj_result.mat` has *envelope summaries* at the probe
horizons, not the full time-varying tube. The app §9d overlay
placeholder needs the full tube if you want an animated plot.
## Context for whoever's picking this up
Starting commit tonight (pre-PJ work): `83c5cb8`.
Current HEAD: `0a8348e` + whatever scram produced.
Clean working tree expected (commits are atomic per task).
MATLAB is gone. Everything is Julia. Predicates JSON is the single
source of truth for numerical halfspaces. Journal is the narrative
source of truth. `claude_memory/` has short pointers.
Was fun to work on. Go read the overnight entry, grab coffee, pick
the next lever. 🦎
---
*— Hacker-Split, overnight 2026-04-20 → 2026-04-21*