# SR analysis

## Authority and scope

This directory is the frozen symbolic-regression evidence package for the LegacyCelerisLab fluidic pinball. The active scientific scope is Kármán-cloak and Illusion PPO data collection, symbolic discovery/refit, closed-loop CFD validation, sampled duration/generalization extensions, term deletion/scaling, and canonical publication export. The disturbance-free `steady` scene remains only as the calibration used to interpret the Kármán rear constant.

The authoritative evidence index is `results/README.md`; execution details are in `PIPELINE.md`. Material under `archive/` is historical, excluded, or non-authoritative.

## Three-stage workflow

1. `stage_1_infer.py`: collect immutable, run-scoped Legacy PPO trajectories for trained Kármán and Illusion scenes.
2. `stage_2_fit.py`: perform broad per-case discovery, within-objective joint discovery, and fixed-topology all-data coefficient refit.
3. `stage_3_validate.py`: deploy PPO, symbolic, uncontrolled, or constant policies in serial Legacy CFD and evaluate the exact legacy DTW contract.

The acceptance chain is data and wiring checks → offline discovery/Pareto diagnostics → frozen topology and coefficient refit → finite closed-loop CFD → 200-step acceptance → 400-step duration and sampled unseen-condition checks → term deletion/scaling. Offline R² helps discover structure; it does not accept a controller. Averages never override a non-finite or prematurely terminated case.

## Scientific contracts

- **Solver/model/norm:** Stage 1 and Stage 3 use LegacyCelerisLab and the frozen legacy PPO models. Runtime PPO observations use the scene's frozen `data/karman/**/norm.json` or `data/illusion/**/norm.json`; PPO inference defaults to CPU while PyCUDA owns the CFD GPU.
- **Native order:** bodies/actions are `front, upper, lower`; forces are front, upper, lower with `(x,y)` components; sensors are upper, centre, lower with `(u_x,u_y)` components. `checks/order_contract.py` is the runtime gate.
- **Causal alignment:** Stage 2 uses `causal_post_state_to_next_action`: recorded post-state `i` predicts action `i+1`. Warm-up and lag construction are trajectory-local and splits do not cross trajectories.
- **Action units:** formulas output `alpha = omega/U0`. PPO normalized actions are decoded with the scene scale and bias before fitting; Stage 3 converts formula outputs back to `omega` for CFD.
- **Mapped-shared deployment:** the canonical architecture is `alpha_F=(h_F(x)-h_F(Gx))/2`, `alpha_U=h_R(x)`, `alpha_L=-h_R(Gx)`. This imposes exact reflection symmetry; it is not a claim that PPO training was equivariant. Three independent heads are diagnostic only.
- **Metric:** `legacy_dtw_v1_abs_n_unclipped`, reported as `legacy_reference_cycle_vs_last_recorded_cycle`, is the exact acceptance metric. Its fitted circular lag is part of the historical comparison algorithm, not a physical delay.
- **Names:** Kármán scene `re_code` uses reference length `2D`, so `Re_D=re_code/2`. Illusion labels such as `1L` are historical: the stored `target_diameter` value is passed to `add_cylinder` as a radius and must not be silently relabelled as a physical diameter.

## Current claim and evidence chain

Accepted training data are `data/runs/article-joint-data-karman-20260718` (Re-code 50/100/200/400) and `data/runs/article-joint-data-illusion-20260718` (0.75L/1L/1.5L). Formula discovery, refits, accepted and rejected CFD, 400-step duration, sampled unseen points, deletion/scaling, steady calibration, and plotting are retained under `results/runs/article-*` and `results/runs/article2-*` because their manifests and parent paths are provenance dependencies.

The Kármán evidence supports a controller dominated by persistent rear counter-rotation, with secondary rear-lift feedback and weak tested front feedback. The steady sweep calibrates the rear constant's magnitude; it is not a third fitting objective. The Illusion result is a finite symmetric numerical family, but its terms are partly replaceable and it does not establish explicit target tracking. Neither result proves global symbolic optimality, causal flow mechanism, universal high-Re behavior, or distribution-wide generalization; Article2 supports only the explicitly sampled conditions.

## Active package map

- Root: `configs.py`, the three stages, this README, and `PIPELINE.md`.
- `checks/`: order and policy-replay gates.
- `utils/`: active data, feature, symmetry, metric, formula, CFD, and provenance contracts.
- `tools/`: canonical plotting/export tools (`prepare_plotting_data.py`, `telemetry_to_csv.py`, both SR plotting modules, and `export_flow_comparison.py`).
- `tests/`: CPU contract tests.
- `data/`: frozen Kármán/Illusion norms, steady calibration data, and the two accepted article data runs.
- `results/`: the evidence index and provenance-dependent `article-*`/`article2-*` families.
- `archive/`: excluded experiments, diagnostics, old run families, superseded flat surfaces, and historical code/docs. Archive paths may be non-executable.

## Verification

From the repository root:

```bash
PYTHONPATH=src conda run -n sr_env python -m pytest src/SR_analysis/tests -q
python3 -m compileall -q src/SR_analysis/configs.py src/SR_analysis/stage_1_infer.py src/SR_analysis/stage_2_fit.py src/SR_analysis/stage_3_validate.py src/SR_analysis/utils src/SR_analysis/checks src/SR_analysis/tools
git diff --check -- src/SR_analysis
```

No GPU CFD is part of this verification.
