diff --git a/src/SR_analysis/ASSET_STATUS.md b/src/SR_analysis/ASSET_STATUS.md new file mode 100644 index 0000000..13a4e68 --- /dev/null +++ b/src/SR_analysis/ASSET_STATUS.md @@ -0,0 +1,98 @@ +# SR asset-status ledger + +## Scope and preservation rule + +This ledger classifies the current `src/SR_analysis` tree without changing scientific artifacts. It separates execution authority, evidence authority, historical views, and external standardized acquisition. + +**No physical movement, renaming, deletion, or manifest rewriting is authorized now.** Kármán and Illusion are interleaved in active configuration, utilities, accepted data runs, `article-*`/`article2-*` provenance chains, and derived packages; many manifests and formula artifacts are path-bound. Moving only Illusion material would break or obscure provenance, while moving mixed packages would also displace active Kármán evidence. **“Illusion archive” therefore means a scientific view and claim downgrade, not a filesystem relocation.** Immutable evidence and paper drafts remain untouched. + +## Classification + +### 1. Active Stage 1–3 and configuration + +- **Assets:** `stage_1_infer.py`, `stage_2_fit.py`, `stage_3_validate.py`, `configs.py`. +- **Authority:** executable authority for the frozen Legacy route, subordinate to immutable run manifests for claims. +- **Purpose:** collect causally aligned PPO trajectories, discover/refit formulas, and run closed-loop Legacy CFD. The code still supports both Kármán and Illusion, plus the contextual `steady` scene. +- **Retain/archive-view policy:** retain in place as active infrastructure. The active scientific claim is Kármán; Illusion branches remain available for reproducibility and diagnosis but are viewed as historical/negative science unless new evidence reopens them. +- **Path/provenance risk:** high. Configuration names, scene IDs, norms, formula paths, action order, and parent hashes are embedded across data and manifests. Splitting by objective now risks changing execution semantics and invalidating lineage. +- **Reader entry:** start at `README.md`, then `PIPELINE.md`; use `CLAIMS.md` before interpreting an objective scientifically. + +### 2. Active checks, utilities, tools, and tests + +- **Assets:** `checks/`, `utils/`, `tools/`, `tests/`. +- **Authority:** contract and verification authority for order, causal alignment, symmetry, formula/provenance schemas, metrics, CFD wiring, exports, and CPU regression behavior. +- **Purpose:** enforce the shared Legacy execution contract and derive auditable tables/figures without refitting. +- **Retain/archive-view policy:** retain in place. Shared Illusion capability is not itself an active Illusion scientific claim. Archive only after dependency analysis and a replacement contract exists. +- **Path/provenance risk:** medium to high. These packages are mixed-objective and imported by stages, tests, and publication exporters; selective relocation can silently alter imports or generated identities. +- **Reader entry:** `PIPELINE.md` for when each component is used; `tests/` for executable contract examples. + +### 3. Flat data references + +- **Assets:** `data/karman/`, `data/illusion/`, and `data/steady/` outside `data/runs/`. +- **Authority:** frozen runtime-reference inputs (scene configs, norms, target harmonics, and retained reference results), not the sole authority for article claims. +- **Purpose:** provide Stage 1/3 scene contracts and normalization; Illusion harmonics also support target construction; steady supports contextual calibration. +- **Retain/archive-view policy:** retain in place and treat as reference surfaces. Do not infer acceptance merely because a flat result exists. Illusion references remain required by mixed runtime and external standardized-acquisition provenance even though the SR claim is downgraded. +- **Path/provenance risk:** high. External metadata and internal stages record exact paths/hashes; historical labels such as `target_diameter` have legacy semantics and must not be normalized by renaming. +- **Reader entry:** `README.md` scientific contracts, then the relevant scene directory; use accepted run roots below for article evidence. + +### 4. Immutable accepted data runs + +- **Assets:** `data/runs/article-joint-data-karman-20260718/` and `data/runs/article-joint-data-illusion-20260718/`. +- **Authority:** authoritative accepted Stage 1 trajectories for the 2026-07 article workflow, with scene manifests, hashes, norms, telemetry, and results. +- **Purpose:** supply the seven causally aligned training trajectories and exact policy-replay lineage used by discovery and frozen-topology refits. +- **Retain/archive-view policy:** immutable, retain in place. Kármán remains active evidence. Illusion is retained as historical input and negative-evidence provenance, not promoted by location to a current positive claim. +- **Path/provenance risk:** critical. Downstream formulas and summaries cite parent paths and hashes; moving or editing these roots can make the final formula readable while making lineage unverifiable. +- **Reader entry:** `results/README.md`, then `results/runs/article-joint-data-audit-20260718/data_inventory.json` and each scene manifest. + +### 5. Immutable `article-*` and `article2-*` results + +- **Assets:** all `results/runs/article-*` and `results/runs/article2-*` families, including discovery seeds, fixed-topology refits, accepted and rejected CFD, 200/400-step runs, sampled unseen cases, deletion/scaling, steady calibration, per-case diagnostics, and plotting/export packages. +- **Authority:** evidence authority for what was run and observed. `results/runs/article-joint-sr-final-20260718/evidence_manifest.json` is the compact lineage index; later standardized acquisition outside this directory can revise claim status without rewriting these artifacts. +- **Purpose:** preserve the auditable chain from discovery through closed-loop validation and publication derivation, including failures. +- **Retain/archive-view policy:** immutable, retain in place. Apply semantic views: Kármán current evidence; steady contextual evidence; Illusion historical/negative evidence; rejected topology B negative evidence. Do not rewrite manifests to reflect the newer claim interpretation. +- **Path/provenance risk:** critical. Families cross-reference absolute and repository-relative parents; plotting packages mix objectives; rejected telemetry is part of selection provenance. +- **Reader entry:** `results/README.md`, `results/runs/article-joint-sr-final-20260718/readable_summary.txt`, then `CLAIMS.md` for current status and limitations. + +### 6. Mixed packages + +- **Assets:** root stages/configuration; shared `checks/`, `utils/`, `tools/`, and `tests/`; accepted-data audits and final evidence manifests; `article2-generalization-summary-*`, `article2-timeseries-csv-*`, `article2-long-timeseries-csv-*`, `article2-percase-refit-summary-*`, `article2-sr-elements-*`, and `article2-plotting-package-*`. +- **Authority:** varies by package: manifests/raw telemetry are evidence; CSVs, summaries, and figures are derived views. +- **Purpose:** compare objectives under one contract and preserve shared derivation/provenance. +- **Retain/archive-view policy:** retain intact. Filter or index by claim status; do not split directories into Kármán and Illusion trees now. +- **Path/provenance risk:** critical because objective-level files share manifests, generators, tables, and parent paths. A physical “Illusion archive” would either duplicate evidence or damage Kármán lineage. +- **Reader entry:** `results/README.md`; then package-local README/manifest and `CLAIMS.md`. + +### 7. Existing archive categories + +- **Assets:** `archive/old/`, `archive/stage_docs/`, `archive/historical_docs/`, `archive/experiments/`, `archive/diagnostics/`, `archive/stage4/`, `archive/legacy_utils/`, `archive/data/`, `archive/results/`, and archived tests/tools. +- **Authority:** non-authoritative unless explicitly reconciled against current contracts and immutable evidence. +- **Purpose:** preserve superseded code and stage guides, excluded V5/Vortex work, diagnostics, malformed or non-mainline runs, superseded flat result surfaces, prior formulas/validations, and scientific history. +- **Retain/archive-view policy:** retain as historical material; restore a workflow from git history and its contemporaneous environment rather than moving individual files back. Existing archive location does not upgrade or downgrade current `article-*` evidence. +- **Path/provenance risk:** high. Archived imports and absolute paths may be stale; files may not execute in place; Legacy and V5 evidence must not be mixed. +- **Reader entry:** `archive/README.md`, followed by the category-specific document or manifest. + +### 8. Empty/nonexistent internal module + +- **Assets:** `internal/` exists but is empty; no importable `SR_analysis.internal` package is present because there is no `__init__.py` or implementation. +- **Authority:** none. +- **Purpose:** currently none; it is an empty placeholder, not hidden active infrastructure. +- **Retain/archive-view policy:** leave untouched in this documentation-only pass. Do not direct readers or code to it; future removal or implementation requires a separate authorized change. +- **Path/provenance risk:** low for evidence, but misleading if documented as functional. +- **Reader entry:** none; use `utils/`, `checks/`, or `tools/` according to function. + +### 9. Standardized Legacy acquisition outside `SR_analysis` + +- **Assets:** `src/drl_pinball/data/reproduction/legacy///` (the repository path is a symlink to external immutable storage), especially `illusion_1L/{sr,zero}/`; summaries include `src/drl_pinball/data/reproduction/sr_wake_l2_summary.{csv,json}` and plots under `src/drl_pinball/data/reproduction_plots_sr/legacy/`. +- **Authority:** current standardized long-window comparison authority for same-case target/SR/physical-zero roles. It is external corroborating or claim-revising evidence, not a replacement for the original article lineage. +- **Purpose:** compare policies under a common Legacy contract after 480 warm-up intervals and 160 retained post-step boundaries, with independently phased telemetry/fields and explicit physical-zero baselines. +- **Retain/archive-view policy:** retain outside `SR_analysis`; cite it from the claim ledger. Do not copy, move, or rewrite its products into the article trees. Its Illusion result is negative/diagnostic evidence; its Kármán products supplement the active claim. +- **Path/provenance risk:** critical. The repository path resolves to external storage, metadata records resolved paths and dirty Git state, and some campaign roles are absent. Cite stable repository-facing paths plus role metadata/hashes; never imply a complete Illusion matrix from the completed 1L comparison. +- **Reader entry:** role-local `metadata.json` and `dtw_summary.json`; then `src/drl_pinball/data/reproduction/sr_wake_l2_summary.json` and the legacy SR acquisition plots. + +## Reading order + +1. `CLAIMS.md` for current scientific status. +2. `README.md` and `PIPELINE.md` for contracts and execution. +3. `results/README.md` and the final evidence manifest for the immutable article chain. +4. Standardized Legacy role metadata/results for the later zero-baseline comparison. +5. `archive/README.md` only for historical or rejected paths. diff --git a/src/SR_analysis/CLAIMS.md b/src/SR_analysis/CLAIMS.md new file mode 100644 index 0000000..41eb473 --- /dev/null +++ b/src/SR_analysis/CLAIMS.md @@ -0,0 +1,142 @@ +# SR claim-status ledger + +## Reading rule + +This ledger states what the retained evidence currently supports. It does not modify immutable runs or paper drafts. All quoted similarities use the metric named at the evidence path; numbers from different protocols/windows must not be merged as if they were repeated trials. `re_code` uses the Legacy `2D` reference, so `Re_D=re_code/2`. + +Status vocabulary: + +- **Current:** supported as a present SR claim within the stated domain. +- **Contextual:** useful interpretation or calibration, not a separately fitted objective or mechanism proof. +- **Historical:** an observed result retained for provenance, but no longer an active positive scientific claim. +- **Withdrawn:** earlier wording is not supported by the combined evidence. +- **Rejected:** candidate failed an acceptance gate. +- **Diagnostic:** informative about fit, transfer, or failure, but not an accepted controller or general law. + +## Current Kármán claims + +### K1 — Reproducible sparse Legacy controller reduction — Current + +The frozen mapped-shared Kármán law is + +`alpha_F = odd(-0.381391 Cd_rear,a)`, +`alpha_U = 1.307782 Cl_rear,s - 3.431209`, +`alpha_L = -alpha_U(Gx)`. + +It was produced by causally aligned Stage 1 data, recurrent discovery, fixed-topology joint refit, and finite closed-loop Legacy CFD. Standard 200-step `legacy_dtw_v1_abs_n_unclipped` similarities for Re-code 50/100/200/400 are `0.9543, 0.9427, 0.8560, 0.7827`; 400-step values are `0.952178, 0.944339, 0.863850, 0.833365`. + +- **Evidence:** `results/runs/article-joint-sr-final-20260718/evidence_manifest.json`; `results/runs/article-L3-karman-20260718/`; `results/runs/article2-generalization-summary-20260720/`; `results/README.md`. +- **Limit:** this supports finite deployments at named cases and durations. It does not prove global symbolic optimality, asymptotic stability, universal Reynolds behavior, or statistical robustness. Re400 is materially weaker than lower-Re cases. + +### K2 — Persistent rear counter-rotation is the dominant tested element — Current + +The fitted rear constant has magnitude `3.431209 alpha`; deleting it causes the largest short-window degradation, while deleting rear-lift feedback causes moderate degradation and deleting the tested front drag-asymmetry term has weak effect. The standardized long-window Legacy campaign independently retained substantial Kármán action and same-case performance, including native DTW `0.952585, 0.942357, 0.860939, 0.835460` for Re-code 50/100/200/400. + +- **Evidence:** `results/runs/article2-plotting-package-20260721/tables/term_deletion.csv`; `results/runs/article-scaling-L1-v2-20260718/summary.json`; standardized products at `src/drl_pinball/data/reproduction/legacy/karman_re*/sr/`. +- **Limit:** deletion is a tested-window, parent-relative intervention. “Dominant” does not mean uniquely sufficient, globally necessary, or a causal flow mechanism. The front term's weak tested effect does not prove it is unnecessary in every regime or horizon. + +### K3 — Rear-lift feedback is secondary; front feedback is weak — Current + +Across the accepted law and tested deletions, `Cl_rear,s` modulates the persistent rear rotation, while the front `Cd_rear,a` term has smaller measured impact. Per-case coefficients vary non-monotonically; there is no supported clean low-/high-Re coefficient law. + +- **Evidence:** `results/runs/article2-percase-refit-summary-20260720/{coefficients.csv,interpretation.md}`; deletion table above. +- **Limit:** per-case refits are on PPO-visited trajectories and are not separately closed-loop accepted controllers. Coefficient variation does not establish parameter dependence. + +## Contextual steady evidence + +### S1 — Constant magnitude has a steady-flow correspondence — Contextual + +In disturbance-free steady deployment, the joint law's last-cycle rear actions are approximately `(-3.4306, +3.4318)`, matching the analytical constant magnitude `3.4312`. A discrete constant-rotation sweep peaks at magnitude `5` with similarity `0.987212`; the joint law gives `0.966494`. + +- **Evidence:** `results/runs/article2-steady-analysis-20260720/{steady_constant_correspondence.json,interpretation.md}` and associated steady run families. +- **Limit:** steady was not a third fitting objective. This is an order-of-magnitude/closed-loop correspondence, not direct momentum-balance equality, unique optimum, deficit-to-surface-speed conversion, or causal mechanism. The discrete sweep does not locate a continuous optimum. + +## Historical Illusion findings + +### I1 — A finite symmetric numerical family was found — Historical + +The retained mapped-shared Illusion formula is + +`alpha_F = odd(-1.826604 Cd_rear,a + 2.064493 Cl_F)`, +`alpha_U = 1.254440 Cd_rear,a - 1.528074 Cl_F`, +`alpha_L = -alpha_U(Gx)`. + +It completed the original 200-step training-scene validations with similarities `0.8749, 0.9217, 0.8306` for `0.75L, 1L, 1.5L`, and the original 400-step runs with `0.854379, 0.915609, 0.833587`. + +- **Evidence:** `results/runs/article-joint-sr-final-20260718/evidence_manifest.json`; `results/runs/article-L3-illusionA-20260718/`; Article2 duration/timeseries families. +- **Limit:** these are target-similarity observations under the original finite windows, not evidence of efficacy over physical zero. The family is retained as historical/negative evidence and is not an active Illusion SR controller claim. + +### I2 — Selected static formulas omit explicit target/error terms — Historical negative finding + +Target/error variables were available in discovery, but the selected low-complexity deployment formulas contain only measured force combinations. Every one-term deletion remained finite over the tested short windows, and per-case fits changed signs/emphasis; the joint law is an averaging compromise rather than a uniquely identified target-aware law. + +- **Evidence:** `results/runs/article2-sr-elements-20260720/sr_key_elements.md`; `results/runs/article2-percase-refit-summary-20260720/interpretation.md`; `results/runs/article2-plotting-package-20260721/tables/term_deletion.csv`. +- **Limit:** omission in static symbolic regression does not prove target information is absent from PPO behavior; lagged/dynamic information may be aliased. Stable short deletions do not prove terms are globally irrelevant. + +### I3 — Standardized long-window 1L comparison shows no meaningful zero-baseline benefit — Historical negative finding + +After the standardized Legacy protocol (`480` warm-up control intervals, `160` retained post-step boundaries), Illusion 1L SR and physical zero are effectively equal: native Legacy DTW is `0.9117016` versus `0.9119890`, and target-normalized DTW is `0.8940190` versus `0.8940537`. The downstream field summary likewise gives mean-field errors `0.189990` (SR) versus `0.189414` (zero), i.e. `eta_mean=-0.00304`; eight-phase errors are `0.264176` versus `0.261832`, `eta_phase8=-0.00895`. The accepted formula approaches near-zero actuation over the long window. + +- **Evidence:** `src/drl_pinball/data/reproduction/legacy/illusion_1L/{sr,zero}/dtw_summary.json`, role-local `metadata.json`, and `src/drl_pinball/data/reproduction/sr_wake_l2_summary.{csv,json}`. Reader-facing products are under `src/drl_pinball/data/reproduction_plots_sr/legacy/`. +- **Limit:** this is one standardized 1L realization and a geometry-guarded ROI diagnostic; it is not a complete multi-size statistical campaign. Roles are independently phased, phase slots are nearest snapshots rather than ensembles, no global phase minimization is used, and the field metric lacks a persisted solver-exact mask. It revises the active claim but does not erase the older finite-run observations. + +## Withdrawn unsupported claims + +The following claims are **withdrawn** unless new evidence directly establishes them: + +- Illusion SR explicitly tracks the requested target or explains the PPO target-matching mechanism. +- Illusion SR provides meaningful benefit over physical zero in the standardized long-window 1L comparison. +- The four-term Illusion law, or each of its terms, is uniquely necessary. +- Original Illusion 200/400-step target similarity alone establishes control efficacy. +- Sampled Illusion sizes establish a continuous size law, cross-size generalization, distribution-wide robustness, or uncertainty bounds. +- Kármán results establish universal high-Re behavior, one global coefficient law, or a unique/global symbolic optimum. +- Steady calibration proves direct momentum balance or a unique physical mechanism. +- DTW circular lag is a physical delay. +- Spatial correlation or formula-variable selection proves causal flow structures. + +These withdrawals are claim-status changes only. They do not authorize editing or relocating immutable evidence or paper drafts. + +## Rejected Illusion topology B + +### I-B — Alternative topology B — Rejected + +Topology B completed only the 40-step `0.75L` screen (`0.958889` similarity) but failed at `1L` and `1.5L` with `FloatingPointError: raw observation contains non-finite values`. It is rejected because every required case must remain finite and complete; a favorable offline fit or one-case rollout cannot override failures. + +- **Evidence:** `results/runs/article-L2-illusionB-20260718/` and the `rejected_candidate` records in `results/runs/article-joint-sr-final-20260718/evidence_manifest.json`. +- **Limit:** rejection demonstrates failure under the tested deployment contract. It does not prove all related topologies or dynamic target-aware controllers must fail. + +## Diagnostic per-case and unseen-condition results + +### D1 — Per-case fixed-topology refits — Diagnostic + +Kármán per-case refits do not show a monotonic Reynolds trend: rear constants have magnitudes `3.58, 4.18, 3.41, 2.55` at Re-code `50,100,200,400`, and other coefficients vary non-monotonically. Illusion per-case coefficients change signs and emphasis; rear-head R² is negative at `0.75L` (`-5.44`) and `1L` (`-11.25`), while `1.5L` emphasizes front lift. + +- **Evidence:** `results/runs/article2-percase-refit-summary-20260720/{coefficients.csv,interpretation.md}` and `results/runs/article-per-case-discovery-summary-20260718/summary.json`. +- **Limit:** these are offline diagnostics on PPO-visited states. They are not independently accepted controllers, do not define a Reynolds/size coefficient law, and negative R² is retained as insufficiency evidence. + +### D2 — Coefficient-frozen Kármán unseen points — Diagnostic support for pointwise transfer + +One 200-step realization at each named condition gives Re-code `25/70/150/300` similarities `0.988078, 0.954339, 0.907496, 0.835758`. + +- **Evidence:** `results/runs/article2-generalization-summary-20260720/{generalization.csv,summary.json}` and source run paths recorded there. +- **Limit:** these are individual interpolation/extrapolation samples, not a continuous Reynolds law, robustness distribution, confidence interval, or universal generalization claim. + +### D3 — Coefficient-frozen Illusion unseen points — Historical diagnostic only + +The original one-realization 200-step size samples `0.5L/0.6L/0.8L/1.2L/2L` gave `0.784055, 0.821103, 0.884573, 0.925530, 0.756880`. + +- **Evidence:** `results/runs/article2-generalization-summary-20260720/{generalization.csv,summary.json}` and recorded source runs. +- **Limit:** because the later standardized 1L comparison finds no meaningful benefit over physical zero, these target-similarity values are not evidence of active cross-size SR efficacy. They remain historical pointwise diagnostics with one realization each and no same-protocol zero-baseline matrix. + +## Authority precedence + +For current interpretation, use this order: + +1. immutable role/run telemetry and manifests for what occurred; +2. standardized same-case SR/physical-zero comparisons for efficacy claims; +3. accepted/rejected closed-loop CFD for controller selection; +4. frozen-topology, deletion, and sampled-extension diagnostics for bounded interpretations; +5. summaries/plots as reader views; +6. archived documents only as historical statements. + +Later evidence may downgrade a claim without altering the immutable artifact that originally supported it. In particular, **“Illusion archive” is a semantic view over retained mixed/path-bound evidence, not permission to move files.** diff --git a/src/SR_analysis/HANDOFF.md b/src/SR_analysis/HANDOFF.md new file mode 100644 index 0000000..f6d91f3 --- /dev/null +++ b/src/SR_analysis/HANDOFF.md @@ -0,0 +1,126 @@ +# SR handoff + +## Current state + +The active scientific scope is **Kármán/cloaking only**. The executable SR authority remains `stage_1_infer.py -> stage_2_fit.py -> stage_3_validate.py` on LegacyCelerisLab. `steady` is contextual calibration. Illusion SR is a retained historical/negative route: keep shared runtime capability and immutable evidence, but do not claim target tracking, cross-size generalization, term necessity, or mechanism. + +No paper draft is part of this documentation consolidation. Future manuscript edits must first reconcile their claim ledger with this scope. + +## Restart in five minutes + +1. Read `README.md` for active scope and non-claims. +2. Read `results/README.md` for source runs, while treating older Illusion-positive wording as historical until the index contains an explicit active/archive claim-status ledger. +3. Read `PIPELINE.md` before running code or CFD. +4. Read `HISTORY_AND_LESSONS.md` before reorganizing evidence or reviving an old route. +5. Inspect Git status and do not discard unrelated work. +6. Resolve storage mappings and inspect existing role/run destinations before choosing a new ID. +7. Recall Nowledge memories for the authoritative SR scope, evidence ladder, standardized acquisition, and Illusion long-horizon result. + +## Claim-status handoff + +### Active/supported + +- Reproducible Legacy Stage 1→2→3 Kármán policy-surrogate workflow. +- Exact mapped-shared deployment under `G`, described as imposed symmetry. +- Persistent rear counter-rotation as the dominant tested Kármán element, with secondary rear-lift feedback and weak tested front feedback over the declared deletion window. +- Finite closed-loop behavior and metric values only at their named conditions, windows, formulas, and realizations. + +### Contextual + +- Steady constant-rotation sweep and steady deployment calibrate the Kármán rear constant's magnitude. They are consistent with a deficit-compensation interpretation, not proof of momentum equality or causal flow mechanism. + +### Historical/negative + +- Illusion target/harmonics and deployment capability remain available for reproducibility. +- July Illusion formulas and finite Stage 3 records remain immutable history. +- Selected formulas omitted target/error despite target availability. +- August standardized long-window Illusion acquisition decayed near physical zero and showed no meaningful benefit over zero. +- Failed crossing-gate, incomplete campaign, rejected topology, and deletion records remain diagnostic evidence. + +### Unsupported without new evidence + +- Illusion SR target tracking or cross-size generalization. +- Universal Reynolds-number behavior, distribution-wide robustness, or uncertainty bounds. +- A unique/global optimal symbolic law or necessity of every retained term. +- Causal wake structures, momentum-balance equality, or a physical delay inferred from DTW alignment. + +## Evidence paths that must not be moved or rewritten + +- `src/SR_analysis/data/runs/article-joint-data-karman-20260718/` +- `src/SR_analysis/results/runs/article-joint-sr-final-20260718/` +- Kármán `article-discovery-*`, `article-joint-*`, `article-refit-*`, `article-L2-*`, `article-L3-*`, deletion/scaling, Article2 duration/generalization/steady, and plotting parents referenced by manifests. +- Existing Illusion `article-*`/`article2-*` inputs, formulas, validations, telemetry, summaries, and rejected runs, even though their scientific status is historical/negative. +- Standardized outputs resolved through the `src/drl_pinball/data/reproduction` storage mapping, including Target/PPO/SR/Zero roles and metadata. + +Do not rename these to make navigation prettier. Build semantic indexes around immutable paths. + +## Runtime and provenance checklist + +Before any new run: + +- Confirm the intended claim and minimum evidence needed. +- Inspect Git SHA/dirty state, active processes, GPU mapping, environment, destination existence, storage root, and free space. +- Use `sr_env` only for PySR; use `pycuda_3_10` for Legacy CFD/PPO, with `PYTHONNOUSERSITE=1` for standardized acquisition. +- Use physical GPU 2 by established convention; after `CUDA_VISIBLE_DEVICES=2`, pass logical device 0. Record actual mapping. +- Run one Legacy CFD/config compilation at a time. Separate GPUs do not protect shared generated solver files. +- Choose a unique run ID. Never use overwrite for scientific evidence. +- Bind model, norm, target/config, formula/deployment, alignment, metric/window, solver/build sources, Git/environment/GPU, and parent identities. +- Preserve failed telemetry and incomplete status. Never edit a manifest to promote a failed run. + +After any run: + +- Check row count, finiteness, action units/order, clocks, expected schemas, hashes, staging/scratch cleanup, and exact destination. +- For standardized periodic acquisition, require 480 warm-up + 160 retained boundaries, at least four accepted centre-`uy` rising crossings, phase-cycle output, eight fixed-phase single fields, complete-cycle mean fields, and separately named native/normalized DTW. +- Compare against the declared baseline, including physical zero when efficacy is the question. +- Update the claim-status ledger and durable Memory with bounded wording. + +## Phase review template + +```text +Phase and intended claim: +Files/runs touched: +Environment and GPU mapping: +Contracts checked (order, units, alignment, G, metric, phase): +Immutable parents/hashes checked: +No-clobber and failure retention checked: +Comparator and window stated: +Observed result: +Bounded interpretation: +Explicit non-claims: +New/updated claim-ledger entry: +Nowledge recall/update completed: +Undermind literature/mechanism check needed or completed: +Scope or provenance blocker: +``` + +A failed contract, provenance, no-clobber, or claim-status check stops the next phase. + +## Important historical plans + +These plans are context, not evidence: + +- `/home/frank14f/.cursor/plans/sr-analysis-restructure_082de010.plan.md` +- `/home/frank14f/.cursor/plans/可信sr全流程重建_ac521468.plan.md` +- `/home/frank14f/.cursor/plans/joint_sr_article_flow_4d153f90.plan.md` +- `/home/frank14f/.cursor/plans/sr_分析完善工作计划_e8744ad4.plan.md` +- `/home/frank14f/.cursor/plans/sr_final_consolidation_846e9c84.plan.md` +- `/home/frank14f/.cursor/plans/sr标准化采集_003a2c08.plan.md` +- `/home/frank14f/.cursor/plans/sr项目收尾整理_56371fda.plan.md` + +## Memory and literature rules + +Use Nowledge Mem as the external decision memory: recall near a restart or phase boundary, search before adding, update prior decisions when they are refined, and save only durable scope/contract/lesson/result summaries. Do not treat Memory text as scientific evidence; resolve claims to repository artifacts. Create a resumable handoff through the supported memory workflow only when explicitly requested. + +Use Undermind before writing literature positioning or upgrading a fluid-mechanics interpretation to mechanism language. Local SR term structure plus CFD similarity is not a substitute for spatial/causal evidence or literature support. + +## Manuscript handoff + +Before editing a paper draft later: + +1. Build or verify the active/archive claim-status ledger. +2. Replace Illusion-positive SR claims with the negative standardized result and preserve PPO/DRL capability as a separate statement. +3. Keep Kármán language bounded to a policy surrogate and tested closed-loop evidence. +4. Label steady as contextual calibration. +5. Cite every number by source path, metric, duration/window, comparator, and realization count. +6. Do not import modern V5 evidence into the Legacy SR chain. +7. Run a final evidence-parity and claim-discipline review before submission. diff --git a/src/SR_analysis/HISTORY_AND_LESSONS.md b/src/SR_analysis/HISTORY_AND_LESSONS.md new file mode 100644 index 0000000..6cd25c2 --- /dev/null +++ b/src/SR_analysis/HISTORY_AND_LESSONS.md @@ -0,0 +1,119 @@ +# SR history and lessons + +## Purpose + +This document records how the SR package reached its current Kármán/cloaking-only scope. It is not a second result authority. Numerical claims must resolve through immutable artifacts and the claim-status ledger expected from `results/README.md`. Historical plans describe intent at the time; they are not proof that every proposed run or interpretation remained valid. + +## Chronology + +### Early restructuring: make a readable pipeline + +The first consolidation separated active scripts from duplicated and historical material and promoted a staged workflow. It was useful organizationally, but some early narrative treated Illusion cross-size behavior and Vortex transfer too confidently and mixed “writer-ready” aspirations with evidence status. + +Plan: `/home/frank14f/.cursor/plans/sr-analysis-restructure_082de010.plan.md` + +Lesson: directory cleanliness and attractive figures do not establish scientific authority. A registry or summary is trustworthy only when each entry resolves to the correct solver, norm, trajectory, metric, and immutable artifact. + +### Trust rebuild: contracts before formulas + +The trust-rebuild phase froze native action/force/sensor order, causal state-to-next-action alignment, G semantics, Stage 1/Stage 3 parity, run-scoped outputs, and failure retention. It separated three-head diagnostics from mapped-shared deployment and established a closed-loop evidence ladder. + +Plan: `/home/frank14f/.cursor/plans/可信sr全流程重建_ac521468.plan.md` + +Lesson: symbolic controller discovery is closed-loop model selection, not ordinary regression. Offline R² can identify structure but cannot accept a controller. A one-step alignment error or action-order mismatch can produce a plausible yet wrong formula. + +### July article chain: Stage 1 → 2 → 3 + +The July workflow collected accepted PPO trajectories, performed per-case and within-objective discovery, froze recurring topology, refit coefficients, and used short then standard closed-loop Legacy CFD. It retained rejected Illusion topology telemetry and added deterministic deletion/scaling experiments. + +Plan: `/home/frank14f/.cursor/plans/joint_sr_article_flow_4d153f90.plan.md` + +The canonical July relationship is: + +```text +Stage 1: immutable PPO trajectories and replay gates + -> Stage 2: broad discovery, topology selection, frozen coefficient refit + -> Stage 3: static safety, short CFD, standard closed-loop DTW +``` + +Lesson: topology recurrence across seeds/cases is stronger than a lucky single fit; fixed-topology refit must not be confused with discovery; an average score cannot hide one non-finite or early-terminated case. + +### Article2 extension: duration, samples, deletion, steady context + +The next phase added 400-step duration runs, named unseen-condition samples, per-case diagnostics, CSV exports, deletion/scaling, and a steady constant-rotation sweep. + +Plan: `/home/frank14f/.cursor/plans/sr_分析完善工作计划_e8744ad4.plan.md` + +Lesson: each extension answers only one question. A longer finite run probes drift, not asymptotic stability. An unseen point is pointwise transfer, not a continuous parameter law. Deletion over one window is term-screening, not universal necessity. Steady calibrates magnitude; it does not prove a spatial or causal mechanism. + +### Conservative final consolidation + +A later pass unified terminology, preserved metric and provenance behavior, retained archived routes, and emphasized manuscript-level claim limits. + +Plan: `/home/frank14f/.cursor/plans/sr_final_consolidation_846e9c84.plan.md` + +Lesson: low-risk consolidation should preserve byte/path-bound evidence. “Cleaning” a run directory by moving or rewriting it can sever formula parents, hashes, manifests, plotting inputs, and external references. + +### August standardized Legacy acquisition + +The August work added an SR role to the mature standardized Legacy collector instead of building another CFD pipeline. + +Plan: `/home/frank14f/.cursor/plans/sr标准化采集_003a2c08.plan.md` + +`src/drl_pinball/legacy_test/acquire.py` uses a standardized periodic role contract: 480 warm-up intervals, 160 retained boundaries, same-run telemetry and fields, independent centre-`uy` phase, complete cycles, phase and mean fields, native plus normalized DTW, fail-closed crossing gates, staging, no-clobber publication, and provenance metadata. + +This route complements July rather than superseding it: + +- July Stage 1 data are the causally aligned policy-imitation inputs. +- July Stage 2 creates and freezes candidate formulas. +- July Stage 3 performs the original acceptance and extension runs. +- August acquisition reruns frozen Target/PPO/SR/Zero roles under a common long-window role protocol and exposes late-attractor behavior. + +The August evidence changed the Illusion interpretation. The fitting/runtime feature pool supplied the target, but selected formulas omitted target/error. In standardized Illusion 1L acquisition, action magnitude decayed toward physical zero after the long warm-up, native and normalized DTW were effectively equal to zero, and the mean field was nearly the zero role. The earlier target-similarity values lacked this long-window zero-efficacy gate. Illusion therefore remains shared runtime capability and preserved negative evidence, not an active SR result. + +Lesson: never “repair” a negative result by weakening warm-up, lowering the crossing threshold, changing action/U0 scaling without a demonstrated bug, or comparing only to target while omitting physical zero. + +### Current closeout + +The current consolidation narrows active claims to Kármán/cloaking, retains steady as context, preserves Illusion as historical/negative evidence, and does not edit paper drafts. + +Plan: `/home/frank14f/.cursor/plans/sr项目收尾整理_56371fda.plan.md` + +## Key mistakes not to repeat + +1. **Treating offline fit as control success.** High R² or low action RMSE does not guarantee stable closed-loop state visitation or target performance. +2. **Conflating target availability with target use.** Illusion target values existed in runtime/features; the selected formula omitted them. Availability is not evidence of tracking. +3. **Calling target similarity efficacy.** A controller must be compared under the relevant window to physical zero and other declared baselines. Similarity alone can hide an autonomous or near-zero attractor. +4. **Overstating sampled transfer.** Named Re/size deployments are samples, not universal laws, distributions, robustness estimates, or uncertainty analyses. +5. **Reading DTW lag physically.** The fitted circular shift belongs to a historical comparison algorithm; it is not a causal delay. +6. **Confusing imposed and learned symmetry.** Mapped-shared `G` deployment enforces symmetry; it does not prove PPO equivariance. +7. **Mixing plants.** LegacyCelerisLab article evidence and modern V5 CelerisLab evidence are separate chains and must not be pooled silently. +8. **Renaming evidence for aesthetics.** Parent paths, hashes, manifests, and external storage mappings can make an awkward run ID immutable. +9. **Overwriting failures.** Failed, rejected, partial, and crossing-gate runs are evidence. New attempts need new IDs. +10. **Parallel Legacy compilation/config mutation.** Separate GPU devices do not make concurrent shared `macros.h`/kernel compilation safe. Serialize initialization and CFD. +11. **Field recapture after phase selection.** Sensors and candidate fields must come from the same rollout; repeated initialization can change vortex phase. +12. **Letting old documentation outrank later evidence.** Older “accepted Illusion” or “generalization” language is historical after the standardized near-zero result. + +## Durable engineering rules + +- Protect before reorganizing: inventory paths, identities, consumers, and external mappings. +- Use one active implementation for each contract; archive alternatives rather than leaving parallel authoritative entry points. +- Admit data only after order, alignment, model/norm/target identity, replay, finiteness, and provenance gates. +- Keep Stage 2 splits trajectory-local and temporal; do not randomize correlated rows into misleading validation. +- Freeze topology before final coefficient refit and retain discovery parents. +- Use static safety and short CFD before spending on standard/long runs. +- Keep role outputs transactional and no-clobber; inspect staging/scratch cleanup. +- State metric, window, comparator, realization count, and evidence status beside every number. +- Separate observation (“metric/action changed”), interpretation (“consistent with deficit compensation”), and mechanism (“causes the wake change”). Current SR supports bounded observations and limited interpretation, not mechanism. + +## Phase self-review and external knowledge + +At every project phase: + +1. Recall the relevant Nowledge Memory before changing scope, contracts, claims, or run status. +2. Search existing memory before adding a new durable decision; update an existing memory when refining it rather than duplicating it. +3. Use Undermind when a statement depends on literature, prior art, or a fluid-mechanics mechanism. Record uncertainty; do not use literature to upgrade local numerical evidence. +4. Review scope, contracts, immutable evidence, claim language, environment/GPU discipline, and whether a second pipeline was introduced. +5. Save a compact durable Memory update after a substantive decision or result. Create a resumable handoff only when explicitly requested. + +Current useful memory topics include the authoritative Kármán-only scope, the SR evidence ladder, the standardized Legacy acquisition decision, and the Illusion long-horizon collapse. Memory is context and decision support; repository artifacts remain the scientific evidence. diff --git a/src/SR_analysis/PIPELINE.md b/src/SR_analysis/PIPELINE.md index 7bbb722..d354cda 100644 --- a/src/SR_analysis/PIPELINE.md +++ b/src/SR_analysis/PIPELINE.md @@ -1,85 +1,141 @@ -# Frozen SR pipeline +# Frozen SR pipeline and standardized acquisition -## Authority +## Authority and scope -The only active route is: +The active scientific objective is Kármán/cloaking. The authoritative executable SR route remains: ```text stage_1_infer.py -> stage_2_fit.py -> stage_3_validate.py ``` -It covers Kármán and Illusion. The `steady` Stage 3/config scene is retained solely for the Article2 constant-rotation calibration used to interpret the Kármán rear constant. Current evidence is indexed by `results/README.md`; archived workflows are non-authoritative and may not execute. +`steady` is contextual calibration only. Illusion support is retained so frozen evidence and shared runtime contracts remain executable/auditable, but Illusion SR is a historical/negative route and must not be presented as target tracking, generalization, or mechanism. + +The August standardized collector at `src/drl_pinball/legacy_test/acquire.py` has a different role: it acquires comparable long-window Target/PPO/SR/Zero role artifacts under one Legacy contract. It validates what a frozen role does after standardized warm-up; it does not refit or replace the July Stage 1→2→3 chain. ## Preconditions and immutable contracts -Use LegacyCelerisLab, its frozen PPO model, and the scene's frozen norm. Keep native body/action order `front, upper, lower`, native force order `front_fx, front_fy, upper_fx, upper_fy, lower_fx, lower_fy`, and sensor order upper/centre/lower `(u_x,u_y)`. Run `checks/order_contract.py` after any solver/kernel change and `checks/policy_replay.py` before admitting data. +Use LegacyCelerisLab, frozen PPO models/norms, and immutable run-scoped outputs. Keep native body/action order `front, upper, lower`; force order `front_fx, front_fy, upper_fx, upper_fy, lower_fx, lower_fy`; sensor order upper/centre/lower `(u_x,u_y)`. Run `checks/order_contract.py` after solver/kernel changes and `checks/policy_replay.py` before admitting Stage 1 data. -The fit alignment is exactly `causal_post_state_to_next_action`: post-state `i` predicts decoded physical action `i+1`; no lag, derivative, split, or warm-up state crosses a trajectory boundary. Formula output is `alpha=omega/U0`. Canonical deployment is mapped-shared under reflection `G`: `alpha_F=(h_F(x)-h_F(Gx))/2`, `alpha_U=h_R(x)`, `alpha_L=-h_R(Gx)`. +The fitting alignment is exactly `causal_post_state_to_next_action`: recorded post-state `i` predicts decoded physical action `i+1`. Warm-up, lag construction, derivatives, and splits are trajectory-local. Formula output is `alpha=omega/U0`; Stage 3 converts it to physical `omega`. Canonical mapped-shared deployment under reflection `G` is -The validation metric is exactly `legacy_dtw_v1_abs_n_unclipped` / `legacy_reference_cycle_vs_last_recorded_cycle`: estimate lag from transverse sensor channel 1 using the historical target/reference windows, circularly shift the full target, compute absolute normalized unclipped DTW independently for six channels, then average. Lag is alignment metadata, not a physical delay. - -Interpret names literally: `Re_D=re_code/2` because the code Reynolds reference is `2D`; the Illusion `target_diameter` field is historically named but passed as the Legacy cylinder radius. - -## Stage 1 — collect accepted trajectories - -Environment: `pycuda_3_10`. CFD is serial. With physical GPU 2 masked, PyCUDA sees logical device 0; keep PPO inference on CPU. - -```bash -CUDA_VISIBLE_DEVICES=2 PYTHONPATH=src conda run -n pycuda_3_10 python src/SR_analysis/stage_1_infer.py --group karman_trained --run-id --device 0 --model-device cpu --steps 200 --norm-source existing -CUDA_VISIBLE_DEVICES=2 PYTHONPATH=src conda run -n pycuda_3_10 python src/SR_analysis/stage_1_infer.py --group illusion_trained --run-id --device 0 --model-device cpu --steps 200 --norm-source existing +```text +alpha_F=(h_F(x)-h_F(Gx))/2 +alpha_U=h_R(x) +alpha_L=-h_R(Gx) ``` -Outputs are immutable beneath `data/runs////` and include config, manifest, hashes, frozen norm, target, controlled telemetry, and result; Kármán also retains uncontrolled data and Illusion target harmonics. The canonical accepted roots are the two `article-joint-data-*-20260718` families. +The July validation metric is exactly `legacy_dtw_v1_abs_n_unclipped` / `legacy_reference_cycle_vs_last_recorded_cycle`: estimate the historical circular lag, shift the full target, compute absolute normalized unclipped DTW independently on six channels, then average. Its lag is comparison metadata, not a physical delay. -## Stage 2 — discover then refit +Interpret labels literally: `Re_D=re_code/2`; historical Illusion `target_diameter` is passed to the Legacy builder as a radius. -Environment: `sr_env`. Start broad with `raw_complete` and `symmetry`; for Illusion compare `actual_only`, `target_only`, `actual_plus_target`, and `actual_plus_error`. Run per-case searches with multiple seeds, then joint searches only within one objective. Keep contiguous train/validation/blind diagnostics and case/trajectory-equal weighting. +## July Stage 1 — immutable PPO trajectories + +Environment: `pycuda_3_10`. CFD is serial. When physical GPU 2 is masked, PyCUDA sees logical device 0; PPO inference stays on CPU. ```bash -PYTHONPATH=src conda run -n sr_env python src/SR_analysis/stage_2_fit.py --scenes karman_re50,karman_re100,karman_re200,karman_re400 --mode joint --run-id --data-root src/SR_analysis/data/runs/article-joint-data-karman-20260718 --feature-set symmetry --feature-profile actual_only --deployment-architecture mapped_shared --fit-augmentation G --fit-purpose discovery --seed 0 --niterations 40 --smoke +CUDA_VISIBLE_DEVICES=2 PYTHONPATH=src conda run -n pycuda_3_10 \ + python src/SR_analysis/stage_1_infer.py \ + --group karman_trained --run-id \ + --device 0 --model-device cpu --steps 200 --norm-source existing ``` -After topology recurs and survives diagnostics, freeze it and run `--fit-purpose fixed-topology-refit` with explicit front/rear topology expressions and discovery-parent paths. Only coefficients may change. Do not rewrite article parent paths or manifests. PySR score, Pareto complexity, blind R², and static safety are discovery evidence only. +Outputs live below `data/runs////` and bind config, manifest, hashes, norm, target, telemetry, and result. Never reuse a run ID. Existing `article-joint-data-*` paths are immutable dependencies, including mixed Kármán/Illusion historical evidence. -## Stage 3 — closed-loop acceptance +Admission gates: correct channel ledger, model/norm/target identity, finite telemetry, exact action decoding, causal alignment, policy replay, and complete provenance. A failed gate blocks Stage 2; it is not repaired by editing an artifact in place. -Environment: `pycuda_3_10`; run one CFD process at a time. Screen at 40 steps, then validate accepted candidates for 200 steps with a new immutable run ID. +## July Stage 2 — discovery, selection, frozen refit + +Environment: `sr_env`; no CFD process belongs in this environment. + +1. Search broad, non-duplicated feature families per case and across several seeds. +2. Use contiguous train/validation/blind blocks and case/trajectory-equal weighting. +3. Compare topology recurrence and deployment safety; offline R², RMSE, and Pareto score are diagnostics only. +4. Joint discovery is allowed only within one scientific objective and one compatible contract. +5. Once a topology is selected, freeze it and refit coefficients on all declared eligible data. Only coefficients may change; discovery parents and hashes remain fixed. + +For Kármán, compare the rear constant baseline, rear-lift feedback, and tested front feedback. Do not infer a spatial/causal mechanism from term appearance. For historical Illusion work, the feature/runtime system supplied target and error candidates, but selected formulas omitted them; that omission is central negative evidence, not proof that the target was unnecessary. + +## July Stage 3 — closed-loop acceptance + +Environment: `pycuda_3_10`; run one CFD process at a time. ```bash -CUDA_VISIBLE_DEVICES=2 PYTHONPATH=src conda run -n pycuda_3_10 python src/SR_analysis/stage_3_validate.py --group karman_re50,karman_re100,karman_re200,karman_re400 --mode pysr --formula-front --formula-rear --device 0 --steps 200 --run-id +CUDA_VISIBLE_DEVICES=2 PYTHONPATH=src conda run -n pycuda_3_10 \ + python src/SR_analysis/stage_3_validate.py \ + --group karman_re50,karman_re100,karman_re200,karman_re400 \ + --mode pysr --formula-front --formula-rear \ + --device 0 --steps 200 --run-id ``` -Reject any case that is non-finite, terminates early, violates action/order/schema contracts, or lacks required provenance. Retain rejected telemetry. Closed-loop stability and exact legacy DTW outrank offline fit. +Screen short candidates before standard validation. Reject a case that is non-finite, terminates early, violates action/order/schema contracts, or lacks provenance. Retain failed telemetry. Closed-loop stability and the declared task metric outrank action imitation or offline fit. An average never masks one failed case. -## Extensions and necessity tests +Extensions use frozen coefficients: longer duration, explicitly sampled unseen conditions, deterministic term deletion/scaling, and steady calibration. They support only their named samples and windows. A finite 400-step run is not asymptotic stability; a sampled unseen point is not a continuous law; deletion over one window is not universal necessity. -Use the frozen accepted coefficients for 400-step duration runs, pointwise unseen Kármán Re-code and Illusion size-label conditions, the disturbance-free `steady` constant-rotation sweep, and deterministic additive-term deletion/coefficient scaling (`0, 0.5, 0.75, 1, 1.25, 1.5`). These are sampled deployments, not a continuous parameter law or statistical robustness study. A term is important only if deletion causes repeatable closed-loop degradation; scale zero must agree with deletion and parent formulas remain immutable. +## August standardized Legacy role acquisition -## Publication exports +`src/drl_pinball/legacy_test/acquire.py` standardizes role comparison on the original solver. For periodic Kármán/Illusion roles it uses: + +- `480` warm-up control intervals, then `160` retained post-step boundaries; +- same-run telemetry and candidate physical `ux/uy` fields; +- independent role phase from smoothed centre-sensor `uy = sensors[:,3]`; +- rising zero crossings with a minimum-gap filter and a **fail-closed requirement of at least four accepted crossings**; +- complete half-open cycles, 32-bin phase-cycle summaries, eight nearest single snapshots at fixed phases, and a complete-cycle mean field; +- native historical reward DTW plus a separately named target-max-abs-normalized six-channel cycle DTW; +- transactional staging, exact-schema checks, scratch cleanup, and atomic publication. + +Typical commands are: ```bash -PYTHONPATH=src conda run -n sr_env python -m SR_analysis.tools.prepare_plotting_data --output-dir src/SR_analysis/results/runs/article2-plotting-package- -PYTHONPATH=src conda run -n sr_env python -m SR_analysis.tools.plot_sr_diagnostics -PYTHONPATH=src conda run -n sr_env python -m SR_analysis.tools.plot_sr_presentation +PYTHONNOUSERSITE=1 CUDA_VISIBLE_DEVICES=2 PYTHONPATH=src \ + conda run -n pycuda_3_10 python -m drl_pinball.legacy_test.acquire \ + karman_re100 --role sr --device-id 0 + +PYTHONNOUSERSITE=1 CUDA_VISIBLE_DEVICES=2 PYTHONPATH=src \ + conda run -n pycuda_3_10 python -m drl_pinball.legacy_test.acquire \ + karman_re100 --role zero --device-id 0 ``` -`telemetry_to_csv.py` exports Stage 1/3 trajectories and exact DTW-window diagnostics. `export_flow_comparison.py` defines the same-sample phase-matched field-comparison contract; generating flow fields requires separate serial GPU CFD and is not part of CPU verification. +Do not pass `--overwrite` for scientific production. If the destination exists, inspect it and choose a new role/run location; never destroy evidence. Formula/deployment hashes, alignment, initial action-history state, model/norm, generated target/config identities, Git state, environment, device mapping, and resolved output root belong in metadata. -## Acceptance hierarchy and claim limits +The standardized collector's native and normalized DTW answer different documented comparisons and must not be merged. A phase crossing failure invalidates publication of phase artifacts; do not lower the crossing threshold, shorten warm-up, or select flow fields by visual similarity to force completion. -1. Contract and provenance integrity. -2. Finite closed-loop completion for every required case. -3. Exact legacy DTW at standard duration. -4. Duration and explicitly sampled unseen-condition behavior. -5. Deletion/scaling evidence for term necessity. -6. Physical interpretation, stated as limited by the preceding evidence. +The standardized Illusion 1L result is a negative control on the prior interpretation: after warm-up the historical formula's action was near physical zero and its SR metrics/mean field were effectively the zero-role result. This does not invalidate shared Illusion runtime capability or immutable historical evidence, but it closes active claims of SR target tracking, cross-size generalization, and mechanism. -Supported: reproducible PPO-to-symbolic reduction; dominant Kármán rear counter-rotation with secondary rear-lift feedback; a finite symmetric Illusion numerical family; and pointwise Article2 extension at named samples. Unsupported: global/unique symbolic optimality, universal Re or size generalization, explicit Illusion target-tracking mechanism, necessity of every Illusion term, causal flow structures, or physical delay inferred from DTW lag. +## Run, provenance, storage, and GPU rules -## Exact CPU verification +- Use a unique descriptive run ID; record command, timestamp, Git SHA and dirty state, environment, visible and logical GPU identity, config, model/norm/target/formula identities, parents, and metric/window definitions. +- Results are no-clobber and append-only. Preserve successful, rejected, incomplete, and failed runs. Never edit a manifest to make a run appear complete. +- Keep original `article-*`/`article2-*` and standardized reproduction paths because manifests and hashes bind them. Add semantic indexes instead of renaming them. +- Verify the resolved storage root and free space before CFD; require staging and scratch to be cleaned after publication. +- PySR runs only in `sr_env`. Legacy CFD and PPO inference run only in `pycuda_3_10` with `PYTHONNOUSERSITE=1` where standardized acquisition requires it. +- At most one Legacy CFD/config compilation may mutate shared solver files at a time. Physical GPU 2 is the established default; after masking it, use logical device 0. Check existing processes before launch and record actual mapping. +- Never run paper drafting, unrelated cleanup, or a second CFD campaign as a side effect of verification. + +## Claim-status gate + +Before publishing a number, resolve it through `results/README.md` or its linked claim-status ledger. Record: claim, scene/role, source artifact, formula/hash, metric definition, duration/window, comparator, status, and limitation. If the ledger still labels Illusion accepted/generalized, the Kármán-only scope in `README.md` and `HANDOFF.md` takes precedence until the index is corrected. + +## Phase self-review + +At the end of every phase answer, in writing: + +1. **Scope:** Did this stay within Kármán active claims and preserve Illusion only as shared/historical evidence? +2. **Contracts:** Are order, units, alignment, G mapping, metric, phase, and action initialization unchanged? +3. **Evidence:** Are sources immutable, hash/parent paths intact, failures retained, and statuses honest? +4. **Execution:** Were environments and GPU serialization correct, with no overwrite or concurrent solver mutation? +5. **Claims:** Does every sentence distinguish observation, interpretation, and mechanism? Are window/sample limits explicit? +6. **Package:** Was a second pipeline, schema, metric, or authority accidentally introduced? + +Any failed answer stops promotion to the next phase. + +## Verification + +CPU checks for code work: ```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 ``` + +Documentation consolidation requires only diff/path/link inspection. Do not launch CFD merely to verify Markdown. diff --git a/src/SR_analysis/README.md b/src/SR_analysis/README.md index 8cd198b..09f070c 100644 --- a/src/SR_analysis/README.md +++ b/src/SR_analysis/README.md @@ -1,54 +1,92 @@ # SR analysis -## Authority and scope +## Five-minute navigation -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. +This directory is the symbolic-regression (SR) evidence package for the LegacyCelerisLab fluidic pinball. The **current scientific scope is Kármán/cloaking only**: a compact, symmetry-constrained surrogate of the frozen PPO policy, tested in closed-loop Legacy CFD. The disturbance-free `steady` scene is contextual calibration for the Kármán rear-rotation magnitude; it is not a fitting objective or an independent mechanism result. -The authoritative evidence index is `results/README.md`; execution details are in `PIPELINE.md`. Material under `archive/` is historical, excluded, or non-authoritative. +Read in this order: -## Three-stage workflow +1. This file for scope, claims, and the package map. +2. `results/README.md` for the evidence index and claim-status ledger. Until that index is rewritten as an active/archive ledger, treat any older Illusion “accepted” or “generalization” wording there as historical rather than current authority. +3. `PIPELINE.md` for executable contracts and reproduction rules. +4. `HISTORY_AND_LESSONS.md` for chronology, failed routes, and lessons. +5. `HANDOFF.md` before resuming experiments or manuscript work. -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 executable July route remains: -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 +```text +stage_1_infer.py -> stage_2_fit.py -> stage_3_validate.py ``` -No GPU CFD is part of this verification. +The August standardized role-acquisition route is separate in purpose: `src/drl_pinball/legacy_test/acquire.py` reruns frozen roles under a common long-window collection contract. It audits deployment behavior and produces comparable role artifacts; it does not replace Stage 1 discovery data, refit formulas, or silently promote a new scientific claim. + +## Current scientific position + +### Kármán/cloaking — active + +The canonical mapped-shared law is retained under the immutable `article-*` evidence chain. The evidence supports a bounded statement: persistent rear counter-rotation is the dominant tested element, rear-lift feedback is secondary, and the tested front feedback is weak over the deletion window. The steady sweep is consistent with the magnitude of the rear constant, but does not establish momentum balance, a causal wake mechanism, universal Reynolds-number behavior, or a unique symbolic law. + +Formula output is dimensionless `alpha = omega/U0`. The current architecture is + +```text +alpha_F = (h_F(x) - h_F(Gx))/2 +alpha_U = h_R(x) +alpha_L = -h_R(Gx) +``` + +This imposes exact reflection symmetry at deployment. It does not show that PPO training was equivariant. + +### Illusion SR — retained historical/negative route + +Illusion runtime support remains shared capability because Stage 1–3, target/harmonics handling, formula loading, provenance checks, and standardized acquisition still depend on it. Its immutable data, formulas, manifests, rejected runs, and standardized outputs must remain at their existing paths. + +Illusion is **not** an active SR scientific result. The runtime and fitting pool supplied target information, but the selected formulas omitted target/error terms. In the long standardized Legacy acquisition, the retained SR action decayed near physical zero and showed no meaningful benefit over the physical-zero role. Older finite 200/400-step target-similarity values therefore do not establish efficacy against zero. Do not claim Illusion target tracking, cross-size generalization, term necessity, or mechanism from this route. The Illusion PPO/DRL capability and the failed SR explanation are different claims. + +## Evidence and claim rules + +`results/README.md` is expected to provide, or link to, a claim-status ledger with at least these states: + +- **active/supported:** Kármán surrogate deployment and explicitly bounded term-ranking evidence; +- **contextual:** steady magnitude calibration; +- **historical:** July Illusion discovery/refit and finite short/medium closed-loop records; +- **negative/diagnostic:** standardized Illusion decay toward physical zero, failed crossings, rejected topology, and incomplete campaign roles; +- **unsupported:** target tracking, universal/general distribution claims, unique/global symbolic optimality, causal mechanism, momentum equality, and physical delay inferred from DTW lag. + +A numerical statement is not authoritative unless it resolves to an immutable artifact, manifest/hash chain, metric definition, duration/window, scene, role, and evidence status. Preserve rejected and failed telemetry. + +## Package map + +- `configs.py`, `stage_1_infer.py`, `stage_2_fit.py`, `stage_3_validate.py`: active July Stage 1→2→3 implementation. +- `checks/`: native order and policy-replay gates. +- `utils/`: data/alignment, feature, symmetry, formula, metric, CFD, and provenance contracts. +- `tools/`: derived export and plotting tools; these do not create acceptance evidence by themselves. +- `tests/`: CPU contract tests. +- `data/`: frozen inputs and accepted run-scoped acquisition artifacts. Existing paths are provenance dependencies. +- `results/`: immutable run families and their evidence index. Semantic status must be layered over run IDs; do not rename hash/parent-bound runs for readability. +- `archive/`: non-active experiments, superseded implementations, diagnostics, and historical material. Archived paths may not execute. +- `HISTORY_AND_LESSONS.md`: project chronology and mistakes not to repeat. +- `HANDOFF.md`: restart checklist, claim boundaries, and writing handoff. + +The standardized collector lives outside this directory at `src/drl_pinball/legacy_test/acquire.py`. Its role outputs normally resolve through the reproduction storage mapping; the resolved output root and source hashes belong in each artifact's metadata. + +## Non-negotiable contracts + +- Native body/action order: `front, upper, lower`. +- Force order: front, upper, lower, each `(x,y)`; sensors: upper, centre, lower, each `(u_x,u_y)`. +- Causal fitting alignment: recorded post-state `i` predicts action `i+1`; no warm-up, lag, split, or derivative state crosses a trajectory boundary. +- Runtime PPO uses the frozen scene norm; PyCUDA owns the CFD GPU and PPO inference remains on CPU. +- `re_code` uses reference length `2D`, so `Re_D = re_code/2`. +- Historical Illusion size labels are not to be silently reinterpreted: the stored `target_diameter` value is passed to the Legacy builder as a radius. +- The exact July acceptance metric is `legacy_dtw_v1_abs_n_unclipped` / `legacy_reference_cycle_vs_last_recorded_cycle`; fitted circular lag is alignment metadata, not physical delay. +- Runs are immutable and no-clobber. Never overwrite a successful, failed, or partial evidence directory; use a new run/role ID and retain the old record. + +## Verification and review + +Documentation-only checks require no CFD: + +```bash +git diff --check -- src/SR_analysis/README.md src/SR_analysis/PIPELINE.md src/SR_analysis/HISTORY_AND_LESSONS.md src/SR_analysis/HANDOFF.md +git diff -- src/SR_analysis/README.md src/SR_analysis/PIPELINE.md src/SR_analysis/HISTORY_AND_LESSONS.md src/SR_analysis/HANDOFF.md +``` + +For later code changes, run focused CPU tests before the full SR suite. GPU CFD is never part of a routine documentation verification. Each phase must end with a contract, evidence, claim, provenance, and scope self-review; details are in `HANDOFF.md`. diff --git a/src/SR_analysis/archive/README.md b/src/SR_analysis/archive/README.md index c97a7d8..c0cc964 100644 --- a/src/SR_analysis/archive/README.md +++ b/src/SR_analysis/archive/README.md @@ -1,12 +1,40 @@ # SR archive -Content below this directory is historical, excluded from the active mainline, or non-authoritative. It is preserved to retain scientific history, rejected paths, diagnostics, and prior contracts; it must not be used as current article evidence without an explicit reconciliation. +## Status and authority -Current evidence remains in: +Everything below this directory is historical, excluded, superseded, diagnostic, or otherwise non-authoritative. Current scope is defined by `../README.md`; current execution contracts by `../PIPELINE.md`; and current evidence status by `../results/README.md`. -- `../data/runs/article-joint-data-*` for accepted training trajectories; -- `../results/runs/article-*` and `../results/runs/article2-*` for discovery provenance, accepted/rejected CFD evidence, extensions, ablations, and publication outputs. +Archive documents may internally call a file, formula, workflow, result, or directory **active**, **current**, **canonical**, or the **source of truth**. That language records the document's own epoch only. It is historical and is not current authority. Do not quote an archived claim without reconciling it against the three current documents above and immutable current run provenance. -Archive categories include old code and stage guides, excluded V5 and Vortex work, diagnostic tools/results, superseded flat result surfaces, historical metadata/notes, and non-mainline data/run families. Archived files may retain historical absolute paths or imports and are not guaranteed to execute from their archived location. +Archived code may have stale imports, absolute paths, missing dependencies, or assumptions tied to an old tree. It is not guaranteed executable. Restore a historical workflow from its full contemporaneous git state and environment; do not move files out of the archive or rewrite scientific artifacts piecemeal. -To restore an archived workflow, use git history to recover the original tree and its contemporaneous environment and contracts. Do not move selected files back piecemeal or rewrite archived scientific artifacts merely to make them executable. +## Epochs and categories + +The archive preserves several overlapping epochs rather than one runnable package: + +- `old/`: earliest exploratory SINDy/PySR scripts, raw formulas, ad hoc validation, comparisons, shell drivers, legacy configuration, and old data. These predate the frozen three-stage contract. +- `stage_docs/` and `stage4/`: superseded stage guides and an analysis/visualization stage that is not part of the active `stage_1 -> stage_2 -> stage_3` route. +- `diagnostics/`, `tools/`, and `tests/`: one-off audit, symmetry, phase, round-one, and migration utilities/tests. They describe their historical campaigns, not current gates. +- `data/runs/` and `results/runs/`: pre-article round-one, trusted-baseline, parity, wiring, and other non-mainline run families. Their run-scoped layout may be immutable within its epoch, but the families are not current publication evidence. +- `results/formulas/`, `results/validations/`, and `results/figures/`: superseded flat outputs. Flat files lose or weaken run provenance and must not override current immutable `../results/runs/article-*` and `article2-*` families. +- `historical/` and `historical_docs/`: notes and reports whose interpretation and numerical claims may be stale. +- `experiments/v5/`, `data/v5/`, and `results/formulas_v5/`: modern/V5 bridge experiments, inputs, and formulas. V5 uses a different solver/normalization contract and must never be mixed with Legacy evidence. +- `data/vortex/` and Vortex formula/validation files: excluded Vortex/Lamb/Taylor investigations, not evidence for the current Kármán result. +- `legacy_utils/` and package marker files: compatibility remnants for archived scripts; they do not define an active internal API. + +There is no active `SR_analysis.internal` module. If an empty `internal/` directory is present in some checkout, it has no imports, exports, or supported API and must not be treated as an implementation layer. + +## Inputs, outputs, and compute + +Archived inputs include old flat scene data, norms, V5 datasets, Vortex datasets, and historical run trees. Archived outputs include formula JSON, validations, plots, reports, diagnostics, and candidate registries. Their paths and schemas belong to their original epoch. + +Most inspection and historical fitting/plotting artifacts are CPU-side. Archived closed-loop scripts, runtime diagnostics, and some V5/Legacy acquisition paths may require a CUDA GPU and their original environment. A GPU requirement does not confer authority, and successful execution does not promote an archived result. + +## Stale-claim ledger + +- **Old Illusion target tracking:** archived reports describe selected laws as direct drag/error or target tracking. Current accepted formulas omit target/error terms, and standardized long-window evidence does not support an active SR target-tracking claim. Illusion is retained as historical/negative evidence. +- **Continuous size regime:** archived interpolation language and ranges such as a working diameter interval are not a continuous law. Article2 tested isolated named sizes with frozen coefficients, generally one realization each; this supports pointwise observations only. +- **Universal cloak or Vortex mechanism:** archived statements about a universal cloaking law, a universal Illusion mechanism, or transfer to Vortex/Lamb/Taylor are withdrawn or unsupported. Vortex is excluded, and Kármán support is limited to tested Legacy conditions. +- **Old Kármán formula:** expressions such as `alpha_F = daF_dt - 14.952*mu*Cl_tot` with a constant rear head are superseded. The retained Legacy article law is the formula identified in `../results/README.md`; old per-Re, `mu`, derivative, V5, and flat formula files are not current authority. + +When an archived number conflicts with the current evidence index, preserve the archived file as history and record the discrepancy outside the artifact; do not silently edit the old evidence. diff --git a/src/SR_analysis/archive/illusion/ARCHIVE_METADATA.json b/src/SR_analysis/archive/illusion/ARCHIVE_METADATA.json new file mode 100644 index 0000000..23b1d52 --- /dev/null +++ b/src/SR_analysis/archive/illusion/ARCHIVE_METADATA.json @@ -0,0 +1,170 @@ +{ + "schema_version": "1.0.0", + "status": { + "route": "closed", + "scientific_status": "historical_negative", + "closure_date": "2026-08-08", + "view_type": "non_mutating_scientific_archive_view", + "active_scientific_scope": "karman_cloaking_only" + }, + "authority": { + "archive_view": "src/SR_analysis/archive/illusion/README.md", + "metadata": "src/SR_analysis/archive/illusion/ARCHIVE_METADATA.json", + "note": "This index assigns semantic status only; it does not supersede artifact manifests, hashes, parent links, or runtime contracts." + }, + "closure_reason": [ + "The Illusion runtime and fitting feature pool supplied target and error candidates.", + "The frozen selected Illusion formula omitted target and error terms.", + "Earlier short and 400-step target-similarity evidence lacked a matched long-window physical-zero efficacy gate.", + "Under standardized long-window Legacy acquisition, the frozen Illusion SR action decayed toward physical zero and its retained behavior and mean field matched the physical-zero role.", + "Therefore Illusion SR target-tracking, cross-size generalization, term-necessity, and mechanism claims are withdrawn." + ], + "preservation_policy": { + "mode": "index_in_place", + "immutable": true, + "no_move": true, + "no_copy": true, + "no_rename": true, + "no_rewrite": true, + "no_delete": true, + "no_clobber": true, + "new_evidence_policy": "Use a new immutable run or role identity; never alter an indexed artifact in place.", + "mixed_package_policy": "Mixed Karman/Illusion packages remain physically active and path-bound at their existing locations because active Karman tools, manifests, hashes, and publication parents depend on them. This archive view changes only the semantic status of their Illusion content." + }, + "immutable_paths": { + "accepted_data": { + "status": "historical_accepted_acquisition", + "paths": [ + "src/SR_analysis/data/runs/article-joint-data-illusion-20260718/" + ] + }, + "discovery_parent_refit": { + "status": "historical_discovery_and_frozen_refit", + "paths": [ + "src/SR_analysis/results/runs/article-discovery-illusion_*", + "src/SR_analysis/results/runs/article-joint-illusion-*", + "src/SR_analysis/results/runs/article-refit-illusion-topology-a-20260718/", + "src/SR_analysis/results/runs/article-refit-illusion-topology-b-20260718/", + "src/SR_analysis/results/runs/article-per-case-discovery-summary-20260718/" + ] + }, + "L2_L3": { + "status": "historical_finite_closed_loop_evidence", + "paths": [ + "src/SR_analysis/results/runs/article-L2-illusionA-20260718/", + "src/SR_analysis/results/runs/article-L3-illusionA-20260718/" + ] + }, + "topology_B_rejected": { + "status": "rejected_diagnostic", + "paths": [ + "src/SR_analysis/results/runs/article-L2-illusionB-20260718/", + "src/SR_analysis/results/runs/article-refit-illusion-topology-b-20260718/" + ] + }, + "ablations_scaling": { + "status": "historical_diagnostic", + "paths": [ + "src/SR_analysis/results/runs/article-ablation-formulas-v2-20260718/", + "src/SR_analysis/results/runs/article-ablation-L2-i_front0-20260718/", + "src/SR_analysis/results/runs/article-ablation-L2-i_front1-20260718/", + "src/SR_analysis/results/runs/article-ablation-L2-i_rear0-20260718/", + "src/SR_analysis/results/runs/article-ablation-L2-i_rear1-20260718/", + "src/SR_analysis/results/runs/article-scaling-L1-v2-20260718/" + ] + }, + "duration_generalization": { + "status": "historical_bounded_samples_not_active_generalization", + "paths": [ + "src/SR_analysis/results/runs/article2-long-illusion-20260720/", + "src/SR_analysis/results/runs/article2-long-timeseries-csv-20260720/", + "src/SR_analysis/results/runs/article2-timeseries-csv-20260720/", + "src/SR_analysis/results/runs/article2-generalization-summary-20260720/" + ] + }, + "standardized_negative_diagnostics": { + "status": "negative_diagnostic", + "paths": [ + "src/drl_pinball/data/reproduction/legacy/illusion_1L/target/", + "src/drl_pinball/data/reproduction/legacy/illusion_1L/controlled/", + "src/drl_pinball/data/reproduction/legacy/illusion_1L/sr/", + "src/drl_pinball/data/reproduction/legacy/illusion_1L/zero/", + "src/drl_pinball/data/reproduction_plots_sr/" + ], + "storage_note": "The repository reproduction path is a storage mapping. Role outputs remain physically located at the resolved path and are path-bound by their metadata and derived manifests." + }, + "mixed_packages": { + "status": "physically_active_path_bound_mixed_authority", + "physically_active": true, + "path_bound": true, + "illusion_content_status": "historical_or_negative", + "paths": [ + "src/SR_analysis/results/runs/article-joint-sr-final-20260718/", + "src/SR_analysis/results/runs/article-joint-data-audit-20260718/", + "src/SR_analysis/results/runs/article2-sr-elements-20260720/", + "src/SR_analysis/results/runs/article2-plotting-package-20260721/" + ], + "note": "Do not move or globally archive these directories: active Karman evidence and consumers still depend on their existing paths." + } + }, + "active_runtime_dependencies": { + "status": "shared_capability_not_active_illusion_claim", + "paths": [ + "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/checks/", + "src/SR_analysis/utils/", + "src/SR_analysis/data/illusion/", + "src/drl_pinball/legacy_test/acquire.py" + ], + "retained_functions": [ + "Legacy Illusion scene and target construction", + "frozen PPO model and normalization compatibility", + "target and harmonics handling", + "formula loading and mapped-shared deployment", + "policy replay and provenance checks", + "standardized Target, controlled-PPO, SR, and physical-Zero role acquisition" + ] + }, + "superseded_claims": [ + "Illusion SR explicitly tracks the supplied target.", + "Illusion SR demonstrates efficacy over physical zero.", + "Short or 400-step target similarity establishes long-window control efficacy.", + "Sampled Illusion sizes establish cross-size or distribution-wide generalization.", + "Every retained Illusion formula term is necessary.", + "The frozen Illusion formula identifies a causal physical mechanism.", + "The selected Illusion formula is unique or globally optimal." + ], + "current_allowed_claims": [ + "Illusion PPO/DRL is preserved as a target-matching demonstration under its documented Legacy contracts.", + "The shared runtime supports Illusion target, harmonics, PPO, formula, provenance, and standardized role handling.", + "July Illusion discovery, refit, finite accepted topology-A runs, rejected topology-B runs, ablations, scaling, duration, and sampled-condition records are preserved historical or diagnostic evidence.", + "The fitting and runtime feature pool supplied target information, while the frozen selected formula omitted target and error terms.", + "The standardized long-window Illusion 1L acquisition is negative evidence: the frozen SR action decayed toward physical zero and matched the physical-zero role under that protocol.", + "No active Illusion SR claim of target tracking, efficacy over zero, generalization, term necessity, or mechanism remains." + ], + "successor_authority_docs": [ + { + "path": "src/SR_analysis/README.md", + "role": "current scientific scope and claim authority" + }, + { + "path": "src/SR_analysis/PIPELINE.md", + "role": "executable Stage 1-3 and standardized acquisition contracts" + }, + { + "path": "src/SR_analysis/HANDOFF.md", + "role": "restart, preservation, and claim-status authority" + }, + { + "path": "src/SR_analysis/HISTORY_AND_LESSONS.md", + "role": "chronology and non-authoritative lessons" + }, + { + "path": "src/SR_analysis/results/README.md", + "role": "legacy evidence index; older Illusion-positive wording is historical where it conflicts with current scope authority" + } + ] +} diff --git a/src/SR_analysis/archive/illusion/README.md b/src/SR_analysis/archive/illusion/README.md new file mode 100644 index 0000000..7fb6d69 --- /dev/null +++ b/src/SR_analysis/archive/illusion/README.md @@ -0,0 +1,40 @@ +# Illusion SR archive view + +## Status and authority + +This directory is a **non-mutating scientific archive view** over evidence that remains at its original repository-relative paths. It does not contain copied evidence and does not change the authority, bytes, hashes, manifests, parent links, storage mappings, or executability of any indexed artifact. + +The Illusion symbolic-regression route was closed as an active scientific claim on **2026-08-08**. Current SR authority is `src/SR_analysis/README.md`, with executable and acquisition contracts in `src/SR_analysis/PIPELINE.md` and restart/claim guidance in `src/SR_analysis/HANDOFF.md`. The active scientific scope is Kármán/cloaking; Illusion remains a shared runtime capability and a preserved historical/negative evidence route. + +## Why the route was closed + +The runtime and fitting feature pool supplied the Illusion target, including target/error candidates, but the frozen selected formula omitted target and error terms. The earlier short and 400-step records measured similarity to the target without a matched long-window physical-zero efficacy gate. Under the later standardized Legacy acquisition contract, the frozen Illusion SR action decayed toward physical zero after the long warm-up, and its retained behavior and mean field matched the physical-zero role closely enough that no meaningful efficacy over zero was established. + +Consequently, the prior Illusion SR claims of target tracking, cross-size generalization, term necessity, and physical mechanism are withdrawn. The closure is evidential, not destructive: it does not erase finite historical runs, rejected alternatives, diagnostics, or the separate PPO/DRL demonstration. + +## What remains allowed + +- Illusion PPO/DRL may be described as a target-matching demonstration under its documented Legacy scene, model, norm, target, window, and metric contracts. +- Shared Illusion runtime support may remain active for target/harmonics handling, formula loading, provenance and policy-replay checks, Stage 1–3 compatibility, and standardized Target/controlled-PPO/SR/Zero acquisition. +- July discovery, frozen refit, accepted finite topology-A records, rejected topology-B records, ablations, scaling, duration, and sampled-condition packages remain historical or diagnostic evidence. +- The August standardized long-window result may be cited as negative evidence that the frozen Illusion SR deployment approached the physical-zero role under that protocol. +- Exact claims must resolve to an immutable artifact, its manifest/hash chain, metric and window, comparator, scene, role, and evidence status. + +This archive view does **not** support explicit SR target tracking, efficacy over physical zero, cross-size or distribution-wide generalization, necessity of retained Illusion terms, a unique/global symbolic law, causal wake mechanism, momentum-balance equality, or physical delay inferred from DTW alignment. + +## Immutable evidence map + +`ARCHIVE_METADATA.json` is the machine-readable index. Its categories point to the following evidence without relocating it: + +- **Accepted historical data:** frozen Illusion PPO acquisition and replay-gated inputs under `src/SR_analysis/data/runs/article-joint-data-illusion-20260718/`. +- **Discovery parents and refits:** per-case and joint feature-profile searches plus frozen topology-A/topology-B refits under `src/SR_analysis/results/runs/article-discovery-illusion_*`, `article-joint-illusion-*`, and `article-refit-illusion-*`. +- **L2/L3:** short screening and finite standard validation under `article-L2-illusion*` and `article-L3-illusionA-20260718/`. +- **Rejected topology B:** `article-L2-illusionB-20260718/`, retained as rejected failure evidence rather than promoted or removed. +- **Ablations and scaling:** the Illusion entries and formula parents in `article-ablation-formulas-v2-20260718/`, `article-ablation-L2-i_*-20260718/`, and `article-scaling-L1-v2-20260718/`. +- **Duration and sampled conditions:** `article2-long-illusion-20260720/`, its CSV views, and `article2-generalization-summary-20260720/`; these are historical bounded samples, not active generalization evidence. +- **Standardized negative evidence:** the path-bound roles below `src/drl_pinball/data/reproduction/legacy/illusion_1L/` and their derived plot manifest under `src/drl_pinball/data/reproduction_plots_sr/`. +- **Mixed packages:** final summaries, plotting packages, and aggregate manifests that contain both Kármán and Illusion material remain physically active and path-bound because active Kármán tools, manifests, hashes, and publication parents depend on their existing locations. Only their Illusion claim status is archived; the packages themselves are not moved or globally deprecated. + +## Preservation policy + +All indexed evidence is immutable and remains in place. Do not move, copy, rename, rewrite, delete, rehash, or “repair” it for archive aesthetics. Do not weaken the standardized warm-up or crossing gates, alter action scaling without a demonstrated runtime defect, or compare only with the target when efficacy against physical zero is the question. New work must use a new no-clobber run or role identity and must not silently reactivate withdrawn claims. diff --git a/src/SR_analysis/checks/README.md b/src/SR_analysis/checks/README.md new file mode 100644 index 0000000..7a3b84a --- /dev/null +++ b/src/SR_analysis/checks/README.md @@ -0,0 +1,21 @@ +# SR runtime checks + +## Role and authority + +These executable gates verify Legacy runtime wiring before data are admitted to the active three-stage pipeline. Their reports are diagnostic/provenance outputs, not standalone scientific evidence. Current claims remain governed by `../results/README.md`; archived audits under `../archive/diagnostics/`, `../archive/tools/`, or `../archive/tests/` do not replace these gates. + +## Checks + +- `order_contract.py` defines `legacy-pinball-order-v1`. In source-only mode it emits the expected body IDs, geometry, sensor/force/action layouts, PPO decoder, and kernel-slot binding for Kármán Re100 or Illusion 1L. In runtime mode it builds LegacyCelerisLab, checks actual cylinder centers, warms the flow, applies one small impulse per controlled body, and records slot/force responses. Input: scene, device, impulse size, and step count. Output: JSON to stdout and optionally an atomically written report. Source-only is CPU; runtime mode is serial PyCUDA GPU CFD. +- `policy_replay.py` defines `sr-policy-replay-parity-v1`. It reads an immutable recorded trajectory, the configured frozen Legacy norm, and frozen PPO model; it causally replays post-state `i-1` to predict normalized action `i`, then writes hashes and per-action max error/RMSE with pass/fail status. Input: scene, trajectory, model device, and required output path. Output: an atomic JSON report and process status. It requires model inference but no CFD; use CPU model inference by default. +- `__init__.py` is a package marker and exposes no additional gate. + +Run `order_contract.py` after solver, kernel, geometry, or channel-order changes. Run `policy_replay.py` before admitting a Stage 1 trajectory. A passing check establishes the stated wiring contract only; it does not validate formula quality, universality, or physical mechanism. + +## Storage and separation + +Point checks at immutable `../data/runs//...` trajectories when evaluating accepted acquisitions, and write reports into the relevant new run/provenance location. Flat `../data//` norms are runtime references and are hashed into replay reports; they are not immutable trajectory evidence by themselves. Do not overwrite accepted runs. + +These gates target LegacyCelerisLab only. V5 geometry, normalization, models, and formulas are a separate archived evidence chain and are incompatible with the Legacy ledgers. + +There is no active `SR_analysis.internal` module. If an empty `internal/` directory exists, it has no imports/API and is not used by these checks. diff --git a/src/SR_analysis/checks/__init__.py b/src/SR_analysis/checks/__init__.py index 7455650..0bae0f3 100644 --- a/src/SR_analysis/checks/__init__.py +++ b/src/SR_analysis/checks/__init__.py @@ -1 +1,5 @@ -"""Pre-fit scientific contract checks.""" +"""Pre-fit SR contract checks. + +Karman/cloaking is the active accepted scientific claim; checks may retain +executable Illusion compatibility for historical-evidence validation. +""" diff --git a/src/SR_analysis/configs.py b/src/SR_analysis/configs.py index b983905..cc79611 100644 --- a/src/SR_analysis/configs.py +++ b/src/SR_analysis/configs.py @@ -1,7 +1,9 @@ """Unified scene configuration for SR_analysis. -All scene metadata in one place. Each scene dict contains all parameters -needed for data generation, SINDy fitting, and validation. +The active accepted SR scientific claim is Karman/cloaking. Illusion scene +metadata remains executable for compatibility and historical-evidence work, +but does not represent an active accepted SR scientific claim. Each scene dict +contains the parameters needed for data generation, fitting, and validation. Re convention: - "re_code" uses reference length 2*D (matching model file naming). diff --git a/src/SR_analysis/data/README.md b/src/SR_analysis/data/README.md new file mode 100644 index 0000000..2811331 --- /dev/null +++ b/src/SR_analysis/data/README.md @@ -0,0 +1,29 @@ +# SR data + +## Authority and scope + +This directory stores inputs to the Legacy symbolic-regression workflow. It is evidence storage, not an independently authoritative claim summary: current scope and claims are defined by `../README.md`, execution by `../PIPELINE.md`, and retained evidence by `../results/README.md`. Nothing here is V5 evidence. + +## Layout and lifecycle + +- `runs/article-joint-data-karman-20260718/` is the immutable accepted Stage 1 Kármán acquisition family. Its scene directories contain run-scoped `config.json`, `manifest.json`, frozen `norm.json`, trajectory/result artifacts, and hashes used by Stage 2 and later provenance. +- `runs/article-joint-data-illusion-20260718/` is the corresponding immutable accepted Illusion acquisition family. It is retained for reproducibility and historical/negative Illusion analysis; its presence does not make Illusion an active SR claim. +- `karman//` and `illusion//` are flat runtime references used by scene configuration, norm loading, target construction, and compatibility code. They are mutable lookup surfaces, not substitutes for immutable accepted runs and not authority for reported results. +- `illusion//target_harmonics.json` includes trained and sampled-size target references. These describe runtime targets; they do not prove that an SR formula explicitly tracks the target or defines a continuous size law. +- `steady/steady/` is a flat calibration reference. Steady is used only to interpret the Kármán rear constant, not as an SR fitting objective. + +Do not overwrite, rename, flatten, or move accepted `data/runs//...` trees. Manifests and downstream article paths bind their identities. New acquisitions must receive a new run ID. Flat runtime references may point code toward norms or targets, but publication conclusions must resolve through immutable run artifacts and the evidence index. + +## Inputs and outputs + +Stage 1 reads Legacy scene configuration, frozen PPO models, and flat scene norms/targets, then writes immutable run-scoped configurations, manifests, copied norms, telemetry/result arrays, and target harmonics beneath `data/runs//...`. Stage 2 reads accepted run-scoped data; it writes formulas and diagnostics under `../results/runs/`, never back into accepted data runs. Stage 3 also writes under `../results/runs/`. + +The scientific/runtime contract is LegacyCelerisLab: native body/action order `front, upper, lower`, formula output `alpha=omega/U0`, and `Re_D=re_code/2`. Legacy norms and observations must not be mixed with modern V5 `VecNormalize` or solver outputs. Archived V5 inputs live under `../archive/data/v5/` and remain a separate, excluded evidence chain. + +## Compute + +Reading, hashing, fitting preparation, and most artifact audits are CPU work. Stage 1 trajectory acquisition is serial GPU CFD through PyCUDA; PPO inference normally stays on CPU so PyCUDA owns the selected GPU. Merely reading or validating stored data does not require a GPU. + +## Claim warning + +Historical files can suggest explicit Illusion target tracking, a continuous target-size regime, or broad generalization. The retained accepted Illusion formulas omit target/error terms, and sampled sizes are discrete deployments only. Treat Illusion data as reproducibility and negative/historical evidence unless the top-level authority is explicitly revised. diff --git a/src/SR_analysis/results/INDEX.md b/src/SR_analysis/results/INDEX.md new file mode 100644 index 0000000..9098ac5 --- /dev/null +++ b/src/SR_analysis/results/INDEX.md @@ -0,0 +1,43 @@ +# SR run catalog quick index + +This is the human lookup for immutable run IDs. `README.md` defines current scientific authority; `catalog.json` contains the complete structured family records and exact matched IDs. + +## Conclusion → evidence + +- **Canonical active Kármán formula:** `article-refit-karman-topology-a-20260718`; summarized, with older mixed framing, by `article-joint-sr-final-20260718`. +- **Finite trained-scene Kármán performance at the standard duration:** `article-L3-karman-20260718` (200 steps), after `article-L2-karman-20260718` (40-step gate). +- **Finite 400-step Kármán duration:** `article2-long-karman-20260720`; tabular view in `article2-long-timeseries-csv-20260720`; mixed summary in `article2-generalization-summary-20260720`. +- **Named pointwise Kármán conditions:** `article2-gen-karman-20260720` and `article2-generalization-summary-20260720` (one 200-step realization per named point). +- **Rear constant dominant, rear lift secondary, tested front term weak:** `article-ablation-formulas-v2-20260718`, `article-ablation-L2-k_front0-20260718`, `article-ablation-L2-k_rear0-20260718`, `article-ablation-L2-k_rear1-20260718`, and `article-scaling-L1-v2-20260718`. +- **Steady magnitude context:** `article2-steady-sweep-a0-20260720` through `article2-steady-sweep-a6-20260720`, `article2-steady-karmanlaw-20260720`, and `article2-steady-analysis-20260720`. +- **Illusion is historical/negative:** topology A and its L2/L3/Article2 descendants remain as immutable numerical evidence; `article2-long-illusion-20260720` is especially important to the current negative interpretation. +- **Illusion topology B rejected:** `article-refit-illusion-topology-b-20260718` and failure telemetry in `article-L2-illusionB-20260718`. +- **Canonical publication views:** `article2-plotting-package-20260721`; derived only, and mixed Illusion contents do not confer active authority. + +## Run family → purpose + +- `article-discovery-*`, including `-v2-`/`-v3-`: per-case broad discovery; diagnostic; unknown generations retained pending supersession audit. +- `article-joint-karman-*`, `article-joint-illusion-*`: within-objective joint topology discovery; diagnostic parent candidates. +- `article-per-case-discovery-summary-*`: aggregates discovery recurrence and feature inventories; diagnostic summary. +- `article-refit-karman-topology-a-*`: authoritative frozen Kármán formula and coefficients. +- `article-refit-illusion-topology-a-*`: historical/negative Illusion formula. +- `article-refit-illusion-topology-b-*`: rejected alternative. +- `article-L2-*`: 40-step closed-loop screening or deletion telemetry; not standard-duration acceptance. +- `article-L3-karman-*`: primary 200-step Kármán validation. +- `article-L3-illusionA-*`: historical 200-step Illusion validation. +- `article-ablation-formulas-v2-*`, `article-ablation-L2-*`, `article-scaling-L1-v2-*`: deterministic term-deletion/scaling evidence; active interpretation is Kármán-only. +- `article2-long-karman-*`: primary finite 400-step Kármán duration evidence. +- `article2-long-illusion-*`: historical/negative long Illusion evidence. +- `article2-gen-karman-*`: active pointwise Kármán extension. +- `article2-gen-illusion-v2-*`: historical pointwise Illusion extension. +- `article2-percase-refit-*-v2-*` and summary: per-case coefficient/identifiability diagnostics, not controllers. +- `article2-steady-sweep-*`, `article2-steady-karmanlaw-*`, and analysis: contextual steady calibration. +- `article2-timeseries-csv-*`: derived standard 200-step exports. +- `article2-long-timeseries-csv-*`: derived long 400-step SR exports. +- `article2-long-ppo-*` plus `article2-long-ppo-cpu-*`: split 400-step PPO baseline source shards consumed together by plotting. +- `article2-sr-elements-*`: mixed earlier synthesis; Kármán portions remain useful within current limits, Illusion-positive wording is historical. +- `article2-plotting-package-*`: canonical derived figures/tables/phase metadata; no refit and no promotion of rejected evidence. + +## Reading rules + +A display name is a mutable catalog label; a run ID is the immutable directory identity. Authority describes how a run may support the current claim, not whether its files are retained. A path/hash-bound run must remain at its recorded identity because manifests, formula parents, summaries, or exports may refer to it. `v2`/`v3` naming does not by itself prove supersession, and this catalog does not claim every retained run is necessary. diff --git a/src/SR_analysis/results/README.md b/src/SR_analysis/results/README.md index 9baa94c..6b52d76 100644 --- a/src/SR_analysis/results/README.md +++ b/src/SR_analysis/results/README.md @@ -1,59 +1,50 @@ -# Frozen SR evidence index +# SR results authority index -This file indexes the current publication evidence. `../README.md` defines scope and contracts; `../PIPELINE.md` gives the exact workflow. Only `runs/article-*` and `runs/article2-*` remain active because formula discovery parents, manifests, accepted/rejected CFD records, extensions, ablations, and plots depend on them. Non-mainline outputs are preserved under `../archive/results/`. +This directory is a non-mutating catalog over immutable `runs/article-*` and `runs/article2-*` run IDs. The machine-readable inventory is [`catalog.json`](catalog.json); the compact human lookup is [`INDEX.md`](INDEX.md). Run directories, formula JSON, telemetry, validations, manifests, and hashes are evidence artifacts: do not move, rename, delete, or edit them to improve presentation. Existing mixed packages remain in place and may contain Illusion material. -## Final formulas +## Current authority and claim boundary -The one-stop package is `runs/article-joint-sr-final-20260718/` (`readable_summary.txt` and `evidence_manifest.json`). The accepted mapped-shared candidates are: +The active scientific claim is **Kármán/cloaking**. The canonical display name is **Kármán cloaking symbolic controller (mapped-shared topology A)**; its immutable formula run ID is `article-refit-karman-topology-a-20260718`: -- Kármán: `alpha_F = odd(-0.381391 Cd_rear,a)`; `alpha_U = 1.307782 Cl_rear,s - 3.431209`; `alpha_L = -alpha_U(Gx)`. -- Illusion: `alpha_F = odd(-1.826604 Cd_rear,a + 2.064493 Cl_F)`; `alpha_U = 1.254440 Cd_rear,a - 1.528074 Cl_F`; `alpha_L = -alpha_U(Gx)`. +- `alpha_F = odd(-0.381391 Cd_rear,a)` +- `alpha_U = 1.307782 Cl_rear,s - 3.431209` +- `alpha_L = -alpha_U(Gx)` -Discovery and fixed-topology provenance are retained in the `article-discovery-*`, `article-joint-*`, `article-refit-*`, and summary families. Their parent paths and manifests are immutable provenance dependencies. +The evidence supports persistent rear counter-rotation as the dominant tested element, rear-lift feedback as secondary, and the tested front feedback as weak over its deletion window. It does not prove a unique/global formula, a universal Reynolds-number law, asymptotic stability, causal flow mechanism, momentum-balance equality, or physical delay from DTW alignment. Here `re_code` uses reference length `2D`, so `Re_D=re_code/2`. -## Training CFD +`steady` is contextual calibration of the Kármán rear constant only. It is not formula training, a third objective, or a mechanism proof. Illusion SR is historical/negative evidence, not an active controller claim: its selected formula omitted target/error terms, and retained long-window behavior does not establish meaningful target tracking. Illusion topology B is rejected because its 40-step gate became non-finite at 1L and 1.5L. Per-case refits and discovery are diagnostic. Plotting and CSV packages are derived. -Accepted 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). Each scene has 200 recorded PPO steps and 197 causally aligned fit rows; all seven passed exact policy replay. - -Standard 200-step closed-loop evidence is in `article-L3-karman-20260718` and `article-L3-illusionA-20260718`. Exact legacy-DTW similarities are Kármán `0.9543, 0.9427, 0.8560, 0.7827` and Illusion `0.8749, 0.9217, 0.8306` in the scene order above. `article-L2-*` retains short screening, including rejected Illusion topology-B failure telemetry. - -## 400-step duration - -Article2 duration families and `article2-generalization-summary-20260720` retain finite 400-step symbolic results: Kármán `0.952178, 0.944339, 0.863850, 0.833365`; Illusion `0.854379, 0.915609, 0.833587`. The plotting package also contains matched 400-step PPO baselines. These runs test duration, not asymptotic stability. - -## Pointwise unseen conditions - -With coefficients frozen, one 200-step realization was evaluated at each named condition. Kármán Re-code 25/70/150/300 gives `0.988078, 0.954339, 0.907496, 0.835758`. Illusion 0.5L/0.6L/0.8L/1.2L/2L gives `0.784055, 0.821103, 0.884573, 0.925530, 0.756880`. These are pointwise samples, not continuous parameter laws, distribution-wide generalization, or robustness statistics. - -## Term deletion, scaling, and steady calibration - -`article-ablation-formulas-v2-*` plus `article-ablation-L2-*` retain immutable formula variants and short CFD. Kármán evidence ranks the rear constant first, rear lift feedback second, and tested front feedback as weak. Every one-term Illusion deletion remained stable, so the four-term form is not unique. - -`article-scaling-L1-v2-20260718` evaluates the preregistered coefficient grid and supports the same Kármán ranking; Illusion `Cl_F` terms dominate action magnitude while `Cd_rear,a` is weaker/partly replaceable. Article2 steady families calibrate the Kármán rear constant against disturbance-free constant rotation; steady is interpretive calibration, not formula training or a separate active objective. - -## Plotting package - -`runs/article2-plotting-package-20260721/` is the canonical derived publication package. It contains causal offline predictions/residuals, additive-term contributions on PPO and symbolic trajectories, ablation/scaling tables, steady and 400-step time-series exports, phase-alignment metadata, publication PNG/PDF outputs, a flow-comparison export contract, and a SHA-256 manifest. Derived plotting does not refit formulas or promote rejected evidence. - -## Source chain +## Canonical Kármán chain ```text -accepted article data - -> per-case and within-objective discovery - -> fixed-topology all-data refit - -> short finite-CFD gate - -> standard 200-step legacy DTW - -> 400-step and sampled unseen-condition extension - -> term deletion/scaling and steady calibration - -> canonical plotting/export package +src/SR_analysis/data/runs/article-joint-data-karman-20260718 + -> article-discovery-* and article-joint-karman-* (diagnostic topology search) + -> article-refit-karman-topology-a-20260718 (authoritative frozen formula) + -> article-L2-karman-20260718 (40-step gate) + -> article-L3-karman-20260718 (standard 200-step validation) + -> article2-long-karman-20260720 (finite 400-step duration) + + article2-gen-karman-20260720 (named 200-step unseen points) + -> article-ablation-* / article-scaling-L1-v2-20260718 (necessity diagnostics) + + article2-steady-* (contextual calibration) + -> article2-plotting-package-20260721 (canonical derived publication views) ``` -The retained `article-*` and `article2-*` families are intentionally broader than a minimal list of final numbers because manifests, hashes, formula parents, failed telemetry, and plotting inputs form the auditable chain. +Direct links are recorded where manifests or exports expose them. `article-joint-sr-final-20260718` remains an important mixed evidence manifest, but its older Illusion-positive wording is not current claim authority. Paths and hashes embedded in manifests make many relationships provenance-sensitive; some old manifests contain absolute historical paths, which are recorded rather than rewritten. -## Claims +## Coverage and duration -Supported: a reproducible three-stage reduction workflow; dominant persistent Kármán rear counter-rotation with secondary rear-lift feedback; a finite symmetric Illusion numerical family; closed-loop evidence at trained scenes; and coefficient-frozen behavior at explicitly sampled Article2 conditions. +- Accepted Kármán Stage 1 data: re-code 50/100/200/400, 200 recorded PPO steps and 197 causally aligned fit rows per scene. +- Standard Kármán closed loop: `article-L3-karman-20260718`, 200 control steps at the four training scenes. +- Long Kármán closed loop: `article2-long-karman-20260720`, 400 control steps at the four training scenes. This is finite-duration evidence, not asymptotic stability. +- Pointwise Kármán extension: `article2-gen-karman-20260720`, one 200-step realization at re-code 25/70/150/300. This is not distribution-wide generalization or a continuous law. +- Term deletion: `article-ablation-L2-k_*`, 40 control steps and same-window parent comparisons. +- Steady calibration: `article2-steady-sweep-a0-...-a6-*` and `article2-steady-karmanlaw-*`, 200-step contextual deployments. +- Retained Illusion packages cover historical 0.75L/1L/1.5L training scenes and named Article2 samples. These labels are historical; the stored `target_diameter` is passed as a radius. -Unsupported: a globally optimal or unique formula; universal Kármán performance; distribution-wide Re/size generalization; explicit target tracking or necessity of every Illusion term; causal spatial mechanism; direct momentum-balance equality; or physical delay inferred from DTW alignment. +Standard exports are `article2-timeseries-csv-20260720` and point to 200-step L3 telemetry. Long SR exports are `article2-long-timeseries-csv-20260720` and point to 400-step SR telemetry. The long PPO baseline is a confusing split: Kármán re50 comes from `article2-long-ppo-20260721`, while the remaining Kármán and Illusion scenes come from `article2-long-ppo-cpu-20260721`. Plotting manifests bind to both shards; neither run ID should be merged, renamed, or assumed to supersede the other. -Historical flat formulas/validations/figures, V5, Vortex, diagnostics, and non-article run families are archived and non-authoritative. Archive paths may retain historical references and are not guaranteed executable. +## Retention and supersession + +Retention is not necessity. Unknown discovery generations are **retained pending supersession audit** because parent paths and consumers have not been exhaustively disproved. In particular, `v2` and `v3` suffixes are immutable run-name history, not sufficient evidence of supersession. Do not delete an earlier generation unless a separate dependency/hash audit establishes that no retained manifest, formula parent, summary, or plotting consumer needs it. + +Use [`INDEX.md`](INDEX.md) for conclusion-to-evidence and family-to-purpose lookup. Use [`catalog.json`](catalog.json) when exact immutable run IDs, authority status, scene coverage, duration, parents/consumers, binding status, or claim boundaries are needed programmatically. diff --git a/src/SR_analysis/results/catalog.json b/src/SR_analysis/results/catalog.json new file mode 100644 index 0000000..ff53be3 --- /dev/null +++ b/src/SR_analysis/results/catalog.json @@ -0,0 +1,988 @@ +{ + "schema_version": "sr-results-catalog-v1", + "generated_as_non_mutating_index": true, + "repository_root_assumption": ".", + "scope": { + "included_run_id_prefixes": [ + "article-", + "article2-" + ], + "run_root": "src/SR_analysis/results/runs", + "immutable_artifacts_edited": false, + "active_claim": "Karman/cloaking", + "contextual": "steady", + "historical_negative": "Illusion", + "rejected": "Illusion topology B", + "diagnostic": [ + "per-case refits", + "discovery generations" + ], + "derived": [ + "exports", + "plotting" + ] + }, + "canonical_karman": { + "display_name": "Kármán cloaking symbolic controller (mapped-shared topology A)", + "formula_run_id": "article-refit-karman-topology-a-20260718", + "formula": { + "front": "alpha_F = odd(-0.381391 Cd_rear,a)", + "upper": "alpha_U = 1.307782 Cl_rear,s - 3.431209", + "lower": "alpha_L = -alpha_U(Gx)" + }, + "chain": [ + "src/SR_analysis/data/runs/article-joint-data-karman-20260718", + "article discovery/joint-discovery families", + "article-refit-karman-topology-a-20260718", + "article-L2-karman-20260718", + "article-L3-karman-20260718", + "article2-long-karman-20260720 and article2-gen-karman-20260720", + "Karman ablation/scaling and steady context", + "article2-plotting-package-20260721" + ] + }, + "families": [ + { + "match": "article-joint-sr-final-20260718", + "display_name": "Article evidence manifest", + "run_ids": [ + "article-joint-sr-final-20260718" + ], + "authority_status": "authority-index", + "purpose": "Original mixed one-stop evidence manifest; use current catalog for claim status", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "Karman re_code 50/100/200/400", + "Illusion 0.75L/1L/1.5L" + ], + "duration_control_steps": "mixed: discovery, 40, 200", + "direct_parents": [ + "article-refit-karman-topology-a-20260718", + "article-refit-illusion-topology-a-20260718", + "article-L2-*", + "article-L3-*" + ], + "known_consumers": [ + "catalog and human index" + ], + "binding_status": "manifest contains hashes and some absolute historical telemetry paths", + "claim_boundary": "Karman entries remain primary; Illusion entries are historical/negative, not active claims.", + "notes": [] + }, + { + "match": "article-joint-data-audit-20260718", + "display_name": "Accepted-data audit", + "run_ids": [ + "article-joint-data-audit-20260718" + ], + "authority_status": "supporting-authority", + "purpose": "Inventory and policy-replay audit for accepted Stage 1 data", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "seven training scenes" + ], + "duration_control_steps": 200, + "direct_parents": [ + "src/SR_analysis/data/runs/article-joint-data-karman-20260718", + "src/SR_analysis/data/runs/article-joint-data-illusion-20260718" + ], + "known_consumers": [ + "article discovery/refit chain" + ], + "binding_status": "provenance reference", + "claim_boundary": "Audit supports data integrity, not controller acceptance.", + "notes": [] + }, + { + "match": "article-(?:joint-karman|joint-illusion)-.*-s[0-2]-20260718", + "display_name": "Within-objective joint discovery", + "run_ids": [ + "article-joint-illusion-actual_only-s0-20260718", + "article-joint-illusion-actual_only-s1-20260718", + "article-joint-illusion-actual_only-s2-20260718", + "article-joint-illusion-actual_plus_error-s0-20260718", + "article-joint-illusion-actual_plus_error-s1-20260718", + "article-joint-illusion-actual_plus_error-s2-20260718", + "article-joint-illusion-actual_plus_target-s0-20260718", + "article-joint-illusion-actual_plus_target-s1-20260718", + "article-joint-illusion-actual_plus_target-s2-20260718", + "article-joint-karman-raw_complete-s0-20260718", + "article-joint-karman-raw_complete-s1-20260718", + "article-joint-karman-raw_complete-s2-20260718", + "article-joint-karman-symmetry-s0-20260718", + "article-joint-karman-symmetry-s1-20260718", + "article-joint-karman-symmetry-s2-20260718" + ], + "authority_status": "diagnostic", + "purpose": "Joint broad symbolic topology discovery across each objective", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "objective training scenes" + ], + "duration_control_steps": null, + "direct_parents": [ + "accepted Stage 1 data" + ], + "known_consumers": [ + "fixed-topology refits" + ], + "binding_status": "immutable discovery parents may be path-bound", + "claim_boundary": "Discovery/Pareto evidence proposes topology; it cannot accept a controller.", + "notes": [] + }, + { + "match": "article-discovery(?:-v[23])?-.*-s[0-2]-20260718", + "display_name": "Per-case discovery generations", + "run_ids": [ + "article-discovery-illusion_0.75L-actual_only-s0-20260718", + "article-discovery-illusion_0.75L-actual_only-s1-20260718", + "article-discovery-illusion_0.75L-actual_only-s2-20260718", + "article-discovery-illusion_0.75L-actual_plus_error-s0-20260718", + "article-discovery-illusion_0.75L-actual_plus_error-s1-20260718", + "article-discovery-illusion_0.75L-actual_plus_error-s2-20260718", + "article-discovery-illusion_0.75L-actual_plus_target-s0-20260718", + "article-discovery-illusion_0.75L-actual_plus_target-s1-20260718", + "article-discovery-illusion_0.75L-actual_plus_target-s2-20260718", + "article-discovery-illusion_0.75L-target_only-s0-20260718", + "article-discovery-illusion_0.75L-target_only-s1-20260718", + "article-discovery-illusion_0.75L-target_only-s2-20260718", + "article-discovery-illusion_1.5L-actual_only-s0-20260718", + "article-discovery-illusion_1.5L-actual_only-s1-20260718", + "article-discovery-illusion_1.5L-actual_only-s2-20260718", + "article-discovery-illusion_1.5L-actual_plus_error-s0-20260718", + "article-discovery-illusion_1.5L-actual_plus_error-s1-20260718", + "article-discovery-illusion_1.5L-actual_plus_error-s2-20260718", + "article-discovery-illusion_1.5L-actual_plus_target-s0-20260718", + "article-discovery-illusion_1.5L-actual_plus_target-s1-20260718", + "article-discovery-illusion_1.5L-actual_plus_target-s2-20260718", + "article-discovery-illusion_1.5L-target_only-s0-20260718", + "article-discovery-illusion_1.5L-target_only-s1-20260718", + "article-discovery-illusion_1.5L-target_only-s2-20260718", + "article-discovery-illusion_1L-actual_only-s0-20260718", + "article-discovery-illusion_1L-actual_only-s1-20260718", + "article-discovery-illusion_1L-actual_only-s2-20260718", + "article-discovery-illusion_1L-actual_plus_error-s0-20260718", + "article-discovery-illusion_1L-actual_plus_error-s1-20260718", + "article-discovery-illusion_1L-actual_plus_error-s2-20260718", + "article-discovery-illusion_1L-actual_plus_target-s0-20260718", + "article-discovery-illusion_1L-actual_plus_target-s1-20260718", + "article-discovery-illusion_1L-actual_plus_target-s2-20260718", + "article-discovery-illusion_1L-target_only-s0-20260718", + "article-discovery-illusion_1L-target_only-s1-20260718", + "article-discovery-illusion_1L-target_only-s2-20260718", + "article-discovery-karman_re50-raw_complete-s0-20260718", + "article-discovery-karman_re50-raw_complete-s1-20260718", + "article-discovery-karman_re50-raw_complete-s2-20260718", + "article-discovery-karman_re50-symmetry-s0-20260718", + "article-discovery-v2-illusion_1.5L-actual_only-s0-20260718", + "article-discovery-v2-illusion_1.5L-actual_only-s1-20260718", + "article-discovery-v2-illusion_1.5L-actual_only-s2-20260718", + "article-discovery-v2-illusion_1.5L-actual_plus_error-s0-20260718", + "article-discovery-v2-illusion_1.5L-actual_plus_error-s1-20260718", + "article-discovery-v2-illusion_1.5L-actual_plus_error-s2-20260718", + "article-discovery-v2-illusion_1.5L-actual_plus_target-s0-20260718", + "article-discovery-v2-illusion_1.5L-actual_plus_target-s1-20260718", + "article-discovery-v2-illusion_1.5L-actual_plus_target-s2-20260718", + "article-discovery-v2-illusion_1.5L-target_only-s0-20260718", + "article-discovery-v2-illusion_1.5L-target_only-s1-20260718", + "article-discovery-v2-illusion_1.5L-target_only-s2-20260718", + "article-discovery-v2-illusion_1L-actual_plus_error-s0-20260718", + "article-discovery-v2-illusion_1L-actual_plus_error-s1-20260718", + "article-discovery-v2-illusion_1L-actual_plus_error-s2-20260718", + "article-discovery-v2-karman_re100-raw_complete-s0-20260718", + "article-discovery-v2-karman_re100-raw_complete-s1-20260718", + "article-discovery-v2-karman_re100-raw_complete-s2-20260718", + "article-discovery-v2-karman_re100-symmetry-s0-20260718", + "article-discovery-v2-karman_re100-symmetry-s1-20260718", + "article-discovery-v2-karman_re100-symmetry-s2-20260718", + "article-discovery-v2-karman_re200-raw_complete-s0-20260718", + "article-discovery-v2-karman_re200-raw_complete-s1-20260718", + "article-discovery-v2-karman_re200-raw_complete-s2-20260718", + "article-discovery-v2-karman_re200-symmetry-s0-20260718", + "article-discovery-v2-karman_re200-symmetry-s1-20260718", + "article-discovery-v2-karman_re200-symmetry-s2-20260718", + "article-discovery-v2-karman_re400-raw_complete-s0-20260718", + "article-discovery-v2-karman_re400-raw_complete-s1-20260718", + "article-discovery-v2-karman_re400-raw_complete-s2-20260718", + "article-discovery-v2-karman_re400-symmetry-s0-20260718", + "article-discovery-v2-karman_re400-symmetry-s1-20260718", + "article-discovery-v2-karman_re400-symmetry-s2-20260718", + "article-discovery-v2-karman_re50-symmetry-s1-20260718", + "article-discovery-v2-karman_re50-symmetry-s2-20260718", + "article-discovery-v3-karman_re400-symmetry-s0-20260718", + "article-discovery-v3-karman_re400-symmetry-s1-20260718", + "article-discovery-v3-karman_re400-symmetry-s2-20260718" + ], + "authority_status": "retained-pending-supersession-audit", + "purpose": "Broad per-case, seed and feature-profile searches", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "named run scene" + ], + "duration_control_steps": null, + "direct_parents": [ + "accepted Stage 1 data" + ], + "known_consumers": [ + "article-per-case-discovery-summary-20260718", + "article2 per-case interpretation" + ], + "binding_status": "unknown generations retained in place pending dependency and supersession audit", + "claim_boundary": "Diagnostic only; no individual run is an authoritative controller.", + "notes": [ + "v2/v3 labels do not prove supersession; do not delete or prefer solely by version suffix." + ] + }, + { + "match": "article-per-case-discovery-summary-20260718", + "display_name": "Per-case discovery summary", + "run_ids": [ + "article-per-case-discovery-summary-20260718" + ], + "authority_status": "diagnostic-summary", + "purpose": "Aggregates per-case discovery inventories", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "training scenes" + ], + "duration_control_steps": null, + "direct_parents": [ + "article-discovery*" + ], + "known_consumers": [ + "topology interpretation", + "article2-percase-refit-summary-20260720" + ], + "binding_status": "references immutable discovery run IDs", + "claim_boundary": "Diagnostic recurrence and identifiability only.", + "notes": [] + }, + { + "match": "article-refit-karman-topology-a-20260718", + "display_name": "Canonical Karman fixed-topology refit", + "run_ids": [ + "article-refit-karman-topology-a-20260718" + ], + "authority_status": "primary-authority", + "purpose": "Frozen mapped-shared Karman formula coefficients", + "objectives": [ + "karman" + ], + "scene_coverage": [ + "re_code 50/100/200/400" + ], + "duration_control_steps": null, + "direct_parents": [ + "joint and per-case Karman discovery", + "accepted Karman Stage 1 data" + ], + "known_consumers": [ + "article-L2-karman-20260718", + "article-L3-karman-20260718", + "Article2 extensions", + "plotting" + ], + "binding_status": "formula paths and hashes are provenance-sensitive", + "claim_boundary": "Canonical active Karman/cloaking controller formula; not a universal or unique law.", + "notes": [] + }, + { + "match": "article-refit-illusion-topology-a-20260718", + "display_name": "Historical Illusion topology A refit", + "run_ids": [ + "article-refit-illusion-topology-a-20260718" + ], + "authority_status": "historical-negative", + "purpose": "Frozen Illusion numerical formula retained for negative/historical analysis", + "objectives": [ + "illusion" + ], + "scene_coverage": [ + "0.75L/1L/1.5L" + ], + "duration_control_steps": null, + "direct_parents": [ + "Illusion discovery", + "accepted Illusion Stage 1 data" + ], + "known_consumers": [ + "article-L2-illusionA-20260718", + "article-L3-illusionA-20260718", + "mixed Article2 packages" + ], + "binding_status": "formula paths and hashes are provenance-sensitive", + "claim_boundary": "Not an active SR claim; selected formula omitted target/error terms and long-window behavior does not establish target tracking.", + "notes": [] + }, + { + "match": "article-refit-illusion-topology-b-20260718", + "display_name": "Rejected Illusion topology B refit", + "run_ids": [ + "article-refit-illusion-topology-b-20260718" + ], + "authority_status": "rejected", + "purpose": "Alternative fixed topology retained to explain rejection", + "objectives": [ + "illusion" + ], + "scene_coverage": [ + "0.75L/1L/1.5L" + ], + "duration_control_steps": null, + "direct_parents": [ + "Illusion discovery", + "accepted Illusion Stage 1 data" + ], + "known_consumers": [ + "article-L2-illusionB-20260718" + ], + "binding_status": "formula paths and hashes are provenance-sensitive", + "claim_boundary": "Rejected after non-finite 40-step CFD in 1L and 1.5L; must not be promoted.", + "notes": [] + }, + { + "match": "article-L2-karman-20260718", + "display_name": "Karman short gate", + "run_ids": [ + "article-L2-karman-20260718" + ], + "authority_status": "supporting-authority", + "purpose": "40-step finite closed-loop screening of canonical Karman topology", + "objectives": [ + "karman" + ], + "scene_coverage": [ + "re_code 50/100/200/400" + ], + "duration_control_steps": 40, + "direct_parents": [ + "article-refit-karman-topology-a-20260718" + ], + "known_consumers": [ + "article-L3-karman-20260718" + ], + "binding_status": "telemetry/formula hash bound", + "claim_boundary": "Screening only; standard acceptance is the 200-step L3 run.", + "notes": [] + }, + { + "match": "article-L2-illusion[AB]-20260718", + "display_name": "Illusion short gates", + "run_ids": [ + "article-L2-illusionA-20260718", + "article-L2-illusionB-20260718" + ], + "authority_status": "historical-negative", + "purpose": "40-step topology A screening and topology B rejection telemetry", + "objectives": [ + "illusion" + ], + "scene_coverage": [ + "0.75L/1L/1.5L" + ], + "duration_control_steps": 40, + "direct_parents": [ + "article-refit-illusion-topology-a-20260718", + "article-refit-illusion-topology-b-20260718" + ], + "known_consumers": [ + "historical evidence manifest" + ], + "binding_status": "telemetry/formula hash bound", + "claim_boundary": "Topology B rejected; topology A evidence is historical and not an active claim.", + "notes": [] + }, + { + "match": "article-L3-karman-20260718", + "display_name": "Karman standard validation", + "run_ids": [ + "article-L3-karman-20260718" + ], + "authority_status": "primary-authority", + "purpose": "Canonical 200-step closed-loop Karman validation", + "objectives": [ + "karman" + ], + "scene_coverage": [ + "re_code 50/100/200/400" + ], + "duration_control_steps": 200, + "direct_parents": [ + "article-refit-karman-topology-a-20260718", + "article-L2-karman-20260718" + ], + "known_consumers": [ + "article2-timeseries-csv-20260720", + "article2 plotting" + ], + "binding_status": "telemetry/formula hash bound", + "claim_boundary": "Supports finite trained-scene cloaking performance, not asymptotic stability or universal Re behavior.", + "notes": [] + }, + { + "match": "article-L3-illusionA-20260718", + "display_name": "Illusion standard validation", + "run_ids": [ + "article-L3-illusionA-20260718" + ], + "authority_status": "historical-negative", + "purpose": "Historical 200-step closed-loop topology A validation", + "objectives": [ + "illusion" + ], + "scene_coverage": [ + "0.75L/1L/1.5L" + ], + "duration_control_steps": 200, + "direct_parents": [ + "article-refit-illusion-topology-a-20260718", + "article-L2-illusionA-20260718" + ], + "known_consumers": [ + "mixed Article2 exports" + ], + "binding_status": "telemetry/formula hash bound", + "claim_boundary": "Retained numerical result; not active evidence of target tracking or mechanism.", + "notes": [] + }, + { + "match": "article-ablation-formulas-v2-20260718", + "display_name": "Deletion and scaling formulas v2", + "run_ids": [ + "article-ablation-formulas-v2-20260718" + ], + "authority_status": "supporting-authority", + "purpose": "Immutable deterministic formula variants", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "training scenes" + ], + "duration_control_steps": null, + "direct_parents": [ + "canonical topology A refits" + ], + "known_consumers": [ + "article-ablation-L2-*", + "article-scaling-L1-v2-20260718", + "plotting" + ], + "binding_status": "formula paths/hashes referenced by manifests", + "claim_boundary": "Karman term ranking is active; Illusion variants are historical/negative. v2 is an ID, not proof that every prior shard is superseded.", + "notes": [] + }, + { + "match": "article-ablation-L2-.*-20260718", + "display_name": "Short term-deletion CFD", + "run_ids": [ + "article-ablation-L2-i_front0-20260718", + "article-ablation-L2-i_front1-20260718", + "article-ablation-L2-i_rear0-20260718", + "article-ablation-L2-i_rear1-20260718", + "article-ablation-L2-k_front0-20260718", + "article-ablation-L2-k_rear0-20260718", + "article-ablation-L2-k_rear1-20260718" + ], + "authority_status": "supporting-authority", + "purpose": "40-step same-window deletion tests", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "Karman 4 training scenes or Illusion 3 training scenes" + ], + "duration_control_steps": 40, + "direct_parents": [ + "article-ablation-formulas-v2-20260718", + "canonical parent formulas" + ], + "known_consumers": [ + "article-joint-sr-final-20260718", + "article2-plotting-package-20260721" + ], + "binding_status": "telemetry/formula hash bound", + "claim_boundary": "Supports Karman ranking over tested short window only; Illusion results are historical/negative.", + "notes": [] + }, + { + "match": "article-scaling-L1-v2-20260718", + "display_name": "Coefficient scaling summary v2", + "run_ids": [ + "article-scaling-L1-v2-20260718" + ], + "authority_status": "supporting-authority", + "purpose": "Preregistered coefficient-grid diagnostics", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "training scenes" + ], + "duration_control_steps": null, + "direct_parents": [ + "article-ablation-formulas-v2-20260718", + "canonical parent formulas" + ], + "known_consumers": [ + "article-joint-sr-final-20260718", + "article2 plotting" + ], + "binding_status": "path referenced by evidence manifest", + "claim_boundary": "Karman ranking support; Illusion interpretation historical. No continuous sensitivity law.", + "notes": [] + }, + { + "match": "article2-long-karman-20260720", + "display_name": "Karman 400-step duration validation", + "run_ids": [ + "article2-long-karman-20260720" + ], + "authority_status": "primary-extension", + "purpose": "Finite-duration deployment of frozen Karman coefficients", + "objectives": [ + "karman" + ], + "scene_coverage": [ + "re_code 50/100/200/400" + ], + "duration_control_steps": 400, + "direct_parents": [ + "article-refit-karman-topology-a-20260718" + ], + "known_consumers": [ + "article2-long-timeseries-csv-20260720", + "article2-sr-elements-20260720", + "plotting" + ], + "binding_status": "telemetry and validations hash-listed", + "claim_boundary": "Tests finite 400-step duration, not asymptotic stability.", + "notes": [] + }, + { + "match": "article2-long-illusion-20260720", + "display_name": "Illusion 400-step duration validation", + "run_ids": [ + "article2-long-illusion-20260720" + ], + "authority_status": "historical-negative", + "purpose": "Historical finite-duration deployment of frozen Illusion coefficients", + "objectives": [ + "illusion" + ], + "scene_coverage": [ + "0.75L/1L/1.5L" + ], + "duration_control_steps": 400, + "direct_parents": [ + "article-refit-illusion-topology-a-20260718" + ], + "known_consumers": [ + "mixed Article2 summaries and plotting" + ], + "binding_status": "telemetry and validations hash-listed", + "claim_boundary": "Historical/negative; long-window interpretation supersedes positive target-tracking language.", + "notes": [] + }, + { + "match": "article2-gen-karman-20260720", + "display_name": "Karman sampled-condition extension", + "run_ids": [ + "article2-gen-karman-20260720" + ], + "authority_status": "primary-extension", + "purpose": "One 200-step frozen-coefficient realization at each named unseen condition", + "objectives": [ + "karman" + ], + "scene_coverage": [ + "re_code 25/70/150/300" + ], + "duration_control_steps": 200, + "direct_parents": [ + "article-refit-karman-topology-a-20260718" + ], + "known_consumers": [ + "article2-generalization-summary-20260720", + "plotting" + ], + "binding_status": "summary provenance", + "claim_boundary": "Pointwise samples only; no continuous law or robustness statistic.", + "notes": [] + }, + { + "match": "article2-gen-illusion-v2-20260720", + "display_name": "Illusion sampled-condition extension v2", + "run_ids": [ + "article2-gen-illusion-v2-20260720" + ], + "authority_status": "historical-negative", + "purpose": "Historical pointwise frozen-coefficient deployments", + "objectives": [ + "illusion" + ], + "scene_coverage": [ + "0.5L/0.6L/0.8L/1.2L/2L" + ], + "duration_control_steps": 200, + "direct_parents": [ + "article-refit-illusion-topology-a-20260718" + ], + "known_consumers": [ + "article2-generalization-summary-20260720", + "plotting" + ], + "binding_status": "summary provenance", + "claim_boundary": "Not active generalization evidence; v2 suffix does not establish all supersession relations.", + "notes": [] + }, + { + "match": "article2-generalization-summary-20260720", + "display_name": "Mixed duration/generalization summary", + "run_ids": [ + "article2-generalization-summary-20260720" + ], + "authority_status": "mixed-supporting", + "purpose": "Summarizes Karman and retained Illusion extension numbers", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "training and named unseen scenes" + ], + "duration_control_steps": "200 and 400", + "direct_parents": [ + "article2-long-*", + "article2-gen-*" + ], + "known_consumers": [ + "article2-sr-elements-20260720", + "plotting" + ], + "binding_status": "hash-listed", + "claim_boundary": "Read Karman rows as active pointwise/duration evidence and Illusion rows as historical/negative.", + "notes": [] + }, + { + "match": "article2-percase-refit-(?:karman|illusion)-v2-20260720", + "display_name": "Per-case fixed-topology refits v2", + "run_ids": [ + "article2-percase-refit-illusion-v2-20260720", + "article2-percase-refit-karman-v2-20260720" + ], + "authority_status": "diagnostic", + "purpose": "Coefficient identifiability and case heterogeneity diagnostics", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "training scenes" + ], + "duration_control_steps": null, + "direct_parents": [ + "canonical topology A refits", + "accepted Stage 1 data" + ], + "known_consumers": [ + "article2-percase-refit-summary-20260720" + ], + "binding_status": "hash-listed summary outputs", + "claim_boundary": "Diagnostic only; not validated controllers. v2 status does not resolve every older generation.", + "notes": [] + }, + { + "match": "article2-percase-refit-summary-20260720", + "display_name": "Per-case refit interpretation", + "run_ids": [ + "article2-percase-refit-summary-20260720" + ], + "authority_status": "diagnostic-summary", + "purpose": "Human/table synthesis of per-case coefficients", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "training scenes" + ], + "duration_control_steps": null, + "direct_parents": [ + "article2-percase-refit-*-v2-20260720" + ], + "known_consumers": [ + "article2-sr-elements-20260720", + "plotting" + ], + "binding_status": "hash-listed", + "claim_boundary": "Supports Karman common backbone but no simple coefficient law; Illusion retained as negative identifiability evidence.", + "notes": [] + }, + { + "match": "article2-steady-(?:sweep-a[0-6]|karmanlaw)-20260720", + "display_name": "Steady calibration CFD shards", + "run_ids": [ + "article2-steady-karmanlaw-20260720", + "article2-steady-sweep-a0-20260720", + "article2-steady-sweep-a1-20260720", + "article2-steady-sweep-a2-20260720", + "article2-steady-sweep-a3-20260720", + "article2-steady-sweep-a4-20260720", + "article2-steady-sweep-a5-20260720", + "article2-steady-sweep-a6-20260720" + ], + "authority_status": "contextual", + "purpose": "Disturbance-free constant-rotation sweep and Karman-law comparison", + "objectives": [ + "steady", + "karman context" + ], + "scene_coverage": [ + "steady" + ], + "duration_control_steps": 200, + "direct_parents": [ + "article-refit-karman-topology-a-20260718 for karmanlaw" + ], + "known_consumers": [ + "article2-steady-analysis-20260720", + "plotting" + ], + "binding_status": "telemetry export inputs; some manifests retain absolute source paths", + "claim_boundary": "Contextual magnitude calibration only; no formula training, new objective, or momentum-balance proof.", + "notes": [] + }, + { + "match": "article2-steady-analysis-20260720", + "display_name": "Steady calibration analysis", + "run_ids": [ + "article2-steady-analysis-20260720" + ], + "authority_status": "contextual-summary", + "purpose": "Interprets steady sweep against the Karman rear constant", + "objectives": [ + "steady", + "karman context" + ], + "scene_coverage": [ + "steady" + ], + "duration_control_steps": 200, + "direct_parents": [ + "article2-steady-sweep-*", + "article2-steady-karmanlaw-20260720" + ], + "known_consumers": [ + "article2-sr-elements-20260720", + "plotting" + ], + "binding_status": "hash-listed", + "claim_boundary": "Interpretive calibration only.", + "notes": [] + }, + { + "match": "article2-timeseries-csv-20260720", + "display_name": "Standard time-series exports", + "run_ids": [ + "article2-timeseries-csv-20260720" + ], + "authority_status": "derived", + "purpose": "Tabular export of 200-step L3 PPO/SR/target trajectories", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "seven training scenes" + ], + "duration_control_steps": 200, + "direct_parents": [ + "article-L3-karman-20260718", + "article-L3-illusionA-20260718", + "accepted PPO data" + ], + "known_consumers": [ + "article2-plotting-package-20260721" + ], + "binding_status": "manifests point to source telemetry", + "claim_boundary": "Derived export; Karman active, Illusion historical. Do not confuse with 400-step exports.", + "notes": [] + }, + { + "match": "article2-long-timeseries-csv-20260720", + "display_name": "Long SR time-series exports", + "run_ids": [ + "article2-long-timeseries-csv-20260720" + ], + "authority_status": "derived", + "purpose": "Tabular export of 400-step SR and target trajectories", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "seven training scenes" + ], + "duration_control_steps": 400, + "direct_parents": [ + "article2-long-karman-20260720", + "article2-long-illusion-20260720" + ], + "known_consumers": [ + "article2-sr-elements-20260720", + "article2-plotting-package-20260721" + ], + "binding_status": "manifests point to source telemetry", + "claim_boundary": "Derived export; despite name, it does not contain the long PPO baseline shard.", + "notes": [] + }, + { + "match": "article2-long-ppo(?:-cpu)?-20260721", + "display_name": "Long PPO baseline split shards", + "run_ids": [ + "article2-long-ppo-20260721", + "article2-long-ppo-cpu-20260721" + ], + "authority_status": "derived-source", + "purpose": "400-step PPO baseline telemetry split across two immutable run IDs", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "Karman re50 in non-cpu shard; remaining Karman and Illusion scenes in cpu shard" + ], + "duration_control_steps": 400, + "direct_parents": [ + "frozen PPO models/norms" + ], + "known_consumers": [ + "article2-plotting-package-20260721/long_ppo" + ], + "binding_status": "plotting manifests contain absolute source paths and hashes", + "claim_boundary": "Baseline/context only. The split is confusing but intentional provenance: do not merge, rename, or infer one shard supersedes the other.", + "notes": [] + }, + { + "match": "article2-sr-elements-20260720", + "display_name": "Mixed SR elements synthesis", + "run_ids": [ + "article2-sr-elements-20260720" + ], + "authority_status": "mixed-historical", + "purpose": "Earlier synthesis of formula elements, duration, steady and per-case evidence", + "objectives": [ + "karman", + "illusion" + ], + "scene_coverage": [ + "training, unseen, steady" + ], + "duration_control_steps": "mixed", + "direct_parents": [ + "Article2 summaries/exports" + ], + "known_consumers": [ + "historical interpretation" + ], + "binding_status": "SHA-256 evidence manifest", + "claim_boundary": "Use Karman portions with current claim limits; Illusion-positive and downstream-mechanism suggestions are historical, not active authority.", + "notes": [] + }, + { + "match": "article2-plotting-package-20260721", + "display_name": "Canonical plotting package", + "run_ids": [ + "article2-plotting-package-20260721" + ], + "authority_status": "derived-canonical", + "purpose": "Publication figures, tables, phase metadata and export contract", + "objectives": [ + "karman", + "illusion", + "steady" + ], + "scene_coverage": [ + "mixed retained coverage" + ], + "duration_control_steps": "40, 200 and 400", + "direct_parents": [ + "standard/long exports", + "generalization summary", + "ablation/scaling", + "steady analysis", + "long PPO split shards" + ], + "known_consumers": [ + "publication views" + ], + "binding_status": "package manifest hashes derived artifacts; some source manifests preserve absolute historical paths", + "claim_boundary": "Derived views never refit or promote evidence. Active figures/conclusions must foreground Karman and label Illusion historical/negative.", + "notes": [] + } + ], + "unmatched_run_ids": [], + "reverse_lookup": { + "active_karman_formula": [ + "article-refit-karman-topology-a-20260718", + "article-joint-sr-final-20260718" + ], + "trained_scene_200_step_performance": [ + "article-L3-karman-20260718" + ], + "finite_400_step_duration": [ + "article2-long-karman-20260720", + "article2-long-timeseries-csv-20260720", + "article2-generalization-summary-20260720" + ], + "pointwise_named_condition_behavior": [ + "article2-gen-karman-20260720", + "article2-generalization-summary-20260720" + ], + "rear_constant_dominant_lift_secondary_front_weak": [ + "article-ablation-formulas-v2-20260718", + "article-ablation-L2-k_front0-20260718", + "article-ablation-L2-k_rear0-20260718", + "article-ablation-L2-k_rear1-20260718", + "article-scaling-L1-v2-20260718" + ], + "steady_magnitude_context": [ + "article2-steady-sweep-a0-20260720 through article2-steady-sweep-a6-20260720", + "article2-steady-karmanlaw-20260720", + "article2-steady-analysis-20260720" + ], + "illusion_not_active_and_topology_b_rejected": [ + "article-refit-illusion-topology-a-20260718", + "article-refit-illusion-topology-b-20260718", + "article-L2-illusionB-20260718", + "article2-long-illusion-20260720" + ], + "publication_views": [ + "article2-plotting-package-20260721" + ] + }, + "supersession_policy": { + "v2_v3_status": "uncertain unless a manifest or dependency explicitly states supersession", + "unknown_discovery_generations": "retained pending supersession audit", + "retention_claim": "Cataloging does not assert that every retained run is necessary." + } +} diff --git a/src/SR_analysis/stage_1_infer.py b/src/SR_analysis/stage_1_infer.py index bc37354..e3a06cf 100644 --- a/src/SR_analysis/stage_1_infer.py +++ b/src/SR_analysis/stage_1_infer.py @@ -1,7 +1,10 @@ #!/usr/bin/env python3 -"""Stage 1 legacy PPO inference for Karman and Illusion data collection. +"""Stage 1 legacy PPO inference for SR data collection. -Outputs are isolated under ``data/runs////``. The +Karman/cloaking is the active accepted SR scientific claim. Illusion execution +is retained for compatibility and historical evidence, not as an active +accepted SR claim. Outputs are isolated under +``data/runs////``. The module deliberately keeps LegacyCelerisLab imports inside runtime functions so CLI validation and unit tests do not require CUDA. """ diff --git a/src/SR_analysis/stage_2_fit.py b/src/SR_analysis/stage_2_fit.py index b2c69ba..38ee4c2 100644 --- a/src/SR_analysis/stage_2_fit.py +++ b/src/SR_analysis/stage_2_fit.py @@ -1,8 +1,10 @@ #!/usr/bin/env python3 """Stage 2 symbolic fitting with explicit trajectory and artifact contracts. -The module intentionally delays importing PySR so ``--prepare-only`` and unit - tests can validate all inputs without Julia being installed. +Karman/cloaking is the active accepted SR scientific claim. Illusion fitting +remains executable for compatibility and historical-evidence analysis, not as +an active accepted SR claim. The module intentionally delays importing PySR so +``--prepare-only`` and unit tests can validate inputs without Julia installed. """ from __future__ import annotations diff --git a/src/SR_analysis/stage_3_validate.py b/src/SR_analysis/stage_3_validate.py index d30af9f..2d96e3d 100644 --- a/src/SR_analysis/stage_3_validate.py +++ b/src/SR_analysis/stage_3_validate.py @@ -1,8 +1,11 @@ #!/usr/bin/env python3 -"""Stage 3 legacy closed-loop validation for Karman and Illusion. +"""Stage 3 legacy closed-loop validation for SR controllers. -The module is deliberately CUDA-free at import time. Runtime CFD dependencies -are imported only by the environment factories after planning has completed. +Karman/cloaking is the active accepted SR scientific claim. Illusion validation +remains executable for compatibility and historical evidence, not as an active +accepted SR claim. The module is deliberately CUDA-free at import time. Runtime +CFD dependencies are imported only by the environment factories after planning +has completed. """ from __future__ import annotations @@ -163,6 +166,25 @@ class FormulaPair: deployment_semantics: str = "mapped_shared" +def _validate_formula_output(formula: Mapping[str, Any], name: str, expected_index: int) -> None: + output = formula.get("output") + if not isinstance(output, dict): + raise ValueError(f"{name} formula output metadata must be a dict") + expected = { + "name": "alpha", + "unit": "dimensionless", + "definition": "cylinder_surface_tangential_velocity/U0", + "native_action_order": list(ACTION_ORDER), + "native_action_index": expected_index, + } + for key, value in expected.items(): + if output.get(key) != value: + raise ValueError( + f"{name} formula output metadata requires {key}={value!r}; " + f"got {output.get(key)!r}" + ) + + def _validate_formula_role(formula: Mapping[str, Any], expected: str) -> dict[str, Any]: legacy = bool(formula.get("legacy")) role = formula.get("role") @@ -210,6 +232,8 @@ def load_formula_pair( ), } if lower is None: + _validate_formula_output(front, "front", 0) + _validate_formula_output(rear, "rear", 1) compatibility.update({ "front": _validate_formula_role(front, "front"), "rear": _validate_formula_role(rear, "rear"), @@ -221,7 +245,10 @@ def load_formula_pair( ) else: expected_roles = ("front_independent", "upper_independent", "lower_independent") - for name, formula, expected_role in zip(("front", "upper", "lower"), (front, rear, lower), expected_roles): + for index, (name, formula, expected_role) in enumerate( + zip(("front", "upper", "lower"), (front, rear, lower), expected_roles) + ): + _validate_formula_output(formula, name, index) if formula.get("role") != expected_role: raise ValueError(f"{name} formula requires role={expected_role!r}") compatibility[name] = {"canonical_role": expected_role} diff --git a/src/SR_analysis/tests/README.md b/src/SR_analysis/tests/README.md new file mode 100644 index 0000000..24bce86 --- /dev/null +++ b/src/SR_analysis/tests/README.md @@ -0,0 +1,33 @@ +# SR tests + +## Role and authority + +This directory contains the active CPU contract suite for the Legacy three-stage SR package. Tests verify implementation and artifact contracts; they do not establish scientific claims and do not replace `../results/README.md` as evidence authority. Archived tests under `../archive/tests/` belong to old campaigns and are not part of this suite. + +The suite currently baselines at **84 tests**, but that number is revision-bound: it describes the repository revision for which this README was written, not a permanent invariant. Added, removed, parametrized, skipped, or dependency-gated tests can change the collected count. Treat a clean run at the current revision as authoritative, and report the revision and environment with any count. + +## Coverage + +- `test_stage_1_infer.py`: output-root, scene, normalization, acquisition, and manifest behavior without running production CFD. +- `test_stage_2_fit.py`: dataset preparation, causal alignment, feature/profile choices, fitting/refit contracts, and CLI behavior. +- `test_feature_state_and_contracts.py`: trajectory-local state, feature construction, alignment, symmetry, and data validation. +- `test_legacy_contracts.py`: Legacy metric, action/observation, scene, ordering, and formula-deployment contracts. +- `test_policy_replay.py`: recorded-policy replay wiring and tolerances using test doubles/fixtures. +- `test_formula_provenance.py`: formula schemas, safety, deletion/scaling variants, hashes, and provenance. +- `test_telemetry_to_csv.py`: deterministic trajectory and DTW-window CSV exports. +- `test_plot_sr_diagnostics.py`: derived plotting/table helpers and package metadata. +- `test_export_flow_comparison.py`: phase selection, field orientation/cropping, manifests, and flow-export planning without production GPU CFD. + +Inputs are small synthetic arrays, temporary files, checked-in schemas/artifacts where explicitly referenced, and monkeypatched Legacy/PPO boundaries. Outputs are assertions and temporary artifacts managed by pytest; tests must not mutate accepted `data/runs/` or `results/runs/` evidence. + +## Running + +From the repository root: + +```bash +PYTHONPATH=src conda run -n sr_env python -m pytest src/SR_analysis/tests -q +``` + +The active suite is intended to run on CPU and no production CFD is part of the baseline. GPU-dependent behavior is verified through source contracts, isolated helpers, and test doubles. Run the explicit checks in `../checks/` when validating real Legacy runtime wiring; those checks have different compute requirements. + +There is no active `SR_analysis.internal` module and the tests do not define one. If an empty `internal/` directory exists, it has no imports or supported API. diff --git a/src/SR_analysis/tests/test_formula_provenance.py b/src/SR_analysis/tests/test_formula_provenance.py index 65e1839..4e6e095 100644 --- a/src/SR_analysis/tests/test_formula_provenance.py +++ b/src/SR_analysis/tests/test_formula_provenance.py @@ -212,19 +212,83 @@ def test_scaling_accepts_caller_grid_values_and_rejects_unknown_terms(): build_term_deletion_variant(parent, "x") +def _stage3_formula(role, expression, index): + return { + "schema_version": "1.0", "feature_names": ["u_m"], + "role": role, "anchor": "upper", "fitted_expression": expression, + "deployment_expression": expression, + "output": { + "name": "alpha", "unit": "dimensionless", + "definition": "cylinder_surface_tangential_velocity/U0", + "native_action_order": ["front", "upper", "lower"], + "native_action_index": index, + }, + } + + +def test_stage3_formula_output_metadata_accepts_canonical_pair(tmp_path): + from SR_analysis.stage_3_validate import load_formula_pair + + front = tmp_path / "front.json" + rear = tmp_path / "rear.json" + front.write_text(json.dumps(_stage3_formula("front_odd", "1", 0))) + rear.write_text(json.dumps(_stage3_formula("rear_shared", "2", 1))) + + pair = load_formula_pair(front, rear) + assert pair.front["output"]["name"] == "alpha" + assert pair.rear["output"]["native_action_index"] == 1 + + +@pytest.mark.parametrize( + ("mutation", "message"), + [ + (lambda formula: formula.pop("output"), "output metadata must be a dict"), + (lambda formula: formula["output"].pop("name"), "name='alpha'.*got None"), + (lambda formula: formula["output"].update(unit="rad/s"), "unit='dimensionless'"), + (lambda formula: formula["output"].update(definition="cylinder_angular_velocity"), + "definition='cylinder_surface_tangential_velocity/U0'"), + (lambda formula: formula["output"].update(native_action_order=["front", "lower", "upper"]), + r"native_action_order=\['front', 'upper', 'lower'\]"), + (lambda formula: formula["output"].update(native_action_index=2), "native_action_index=1"), + ], +) +def test_stage3_formula_output_metadata_fails_closed(tmp_path, mutation, message): + from SR_analysis.stage_3_validate import load_formula_pair + + front_formula = _stage3_formula("front_odd", "1", 0) + rear_formula = _stage3_formula("rear_shared", "2", 1) + mutation(rear_formula) + front = tmp_path / "front.json" + rear = tmp_path / "rear.json" + front.write_text(json.dumps(front_formula)) + rear.write_text(json.dumps(rear_formula)) + + with pytest.raises(ValueError, match=message): + load_formula_pair(front, rear) + + +def test_stage3_three_head_formula_indices_fail_closed(tmp_path): + from SR_analysis.stage_3_validate import load_formula_pair + + formulas = [ + _stage3_formula("front_independent", "1", 0), + _stage3_formula("upper_independent", "2", 1), + _stage3_formula("lower_independent", "3", 1), + ] + paths = [tmp_path / f"{name}.json" for name in ("front", "upper", "lower")] + for path, formula in zip(paths, formulas): + path.write_text(json.dumps(formula)) + + with pytest.raises(ValueError, match="lower formula.*native_action_index=2"): + load_formula_pair(*paths) + + def test_stage3_three_head_policy_deploys_each_formula_directly(): from SR_analysis.stage_3_validate import FormulaPair, SymbolicPolicy - def formula(role, expression): - return load_formula({ - "schema_version": "1.0", "feature_names": ["u_m"], - "role": role, "anchor": role, "fitted_expression": expression, - "deployment_expression": expression, - }) - - front = formula("front_independent", "1") - upper = formula("upper_independent", "2") - lower = formula("lower_independent", "3") + front = load_formula(_stage3_formula("front_independent", "1", 0)) + upper = load_formula(_stage3_formula("upper_independent", "2", 1)) + lower = load_formula(_stage3_formula("lower_independent", "3", 2)) pair = FormulaPair( front, upper, Path("front"), Path("upper"), "hash", {}, lower=lower, lower_path=Path("lower"), deployment_semantics="three_head_independent", diff --git a/src/SR_analysis/tools/README.md b/src/SR_analysis/tools/README.md new file mode 100644 index 0000000..b7ccd7e --- /dev/null +++ b/src/SR_analysis/tools/README.md @@ -0,0 +1,26 @@ +# SR tools + +## Role and authority + +These are active export and presentation utilities for the retained Legacy article evidence. They consume authoritative run artifacts but produce **derived** CSVs, tables, manifests, figures, and flow-comparison packages. Derived output does not refit formulas, promote rejected runs, or become scientific authority merely because a tool labels it canonical. Claim status remains in `../results/README.md`. + +## Files, inputs, and outputs + +- `telemetry_to_csv.py`: reads Stage 1/3 NPZ telemetry and an optional target; writes wide and long trajectory CSVs plus exact legacy-DTW convergence/window diagnostics. CPU. +- `prepare_plotting_data.py`: reads accepted article data, frozen refit formulas, long closed-loop runs, ablation runs, and steady sweeps; writes offline predictions, term contributions, trajectory exports, tables, summary metadata, and a SHA-256 manifest. CPU. +- `plot_sr_diagnostics.py`: reads article/article2 CSV, formula, ablation, scaling, steady, and generalization products; writes diagnostic PNG/PDF figures, tables, package README metadata, and an updated manifest. CPU. +- `plot_sr_presentation.py`: reads frozen refit formulas and plotting-package tables; writes compact presentation pages under the plotting package. CPU. +- `export_flow_comparison.py`: reads Legacy scene/formula/alignment contracts and either plans or runs same-sample phase-matched Kármán flow acquisition; writes field arrays, metadata, vorticity figures, and manifest entries. Planning/helper tests are CPU, but actual Legacy CFD field generation is serial PyCUDA GPU work; PPO inference should remain on CPU. +- `__init__.py`: package marker only; it exposes no separate command or authority surface. + +## Hard-coded article roots + +Several tools are intentionally bound to the frozen July 2026 article tree. `prepare_plotting_data.py` hard-codes formula roots `article-refit-*-topology-a-20260718`, data roots `article-joint-data-*-20260718`, long runs `article2-long-*-20260720`, the ablation glob/date, scaling run, and steady-sweep run family. `plot_sr_diagnostics.py` hard-codes the `article2-plotting-package-20260721`, standard/long CSV families, generalization and steady summaries, ablation formulas, parent validation runs, and training-scene list. `plot_sr_presentation.py` hard-codes the refit family and default plotting package. `export_flow_comparison.py` hard-codes the default plotting package, Kármán formula root, alignment file, and output stem. + +These defaults are publication reproducibility bindings, not discovery of the newest run. Running a tool against a new campaign requires explicit review or code changes and a new output package; never silently retarget the frozen article package or overwrite it. `telemetry_to_csv.py` is the generic exception: its principal input and output paths are CLI arguments. + +## Legacy/V5 and lifecycle boundaries + +All current defaults use LegacyCelerisLab data, metric, normalization, and formula semantics. Archived V5 tools/data/formulas under `../archive/` are a distinct, excluded contract and must not be combined with these exports. Flat runtime references under `../data//` may support execution, while these tools should resolve reported evidence through immutable run roots whenever the workflow provides them. + +There is no active `SR_analysis.internal` module. If an empty `internal/` directory exists, it has no imports/API and is not a hidden dependency of these tools. diff --git a/src/SR_analysis/tools/__init__.py b/src/SR_analysis/tools/__init__.py index 72452cc..b3a554b 100644 --- a/src/SR_analysis/tools/__init__.py +++ b/src/SR_analysis/tools/__init__.py @@ -1 +1,5 @@ -"""Artifact and workflow maintenance tools.""" +"""Derived and historical-package maintenance tools. + +These tools may process frozen evidence containing mixed Karman and Illusion +artifacts; only Karman/cloaking is an active accepted SR scientific claim. +""" diff --git a/src/SR_analysis/utils/README.md b/src/SR_analysis/utils/README.md new file mode 100644 index 0000000..0e717ea --- /dev/null +++ b/src/SR_analysis/utils/README.md @@ -0,0 +1,27 @@ +# SR utilities + +## Role and authority + +This package implements shared contracts used by the active Legacy Stage 1-3 pipeline, checks, tests, and export tools. Code is authoritative for runtime mechanics at the checked-out revision; scientific claim authority remains `../results/README.md`. `__init__.py` deliberately re-exports only a small active feature surface. Historical SINDy/expanded-feature helpers must be imported from explicit archived or module paths and are not thereby active article APIs. + +## Modules + +- `data_contracts.py`: validates controlled trajectories, converts normalized actions to physical `alpha`, applies trajectory-local warm-up/alignment, and builds contiguous train/validation/blind batches. Input: arrays plus scene metadata. Output: validated `BatchDataset` objects and split metadata. CPU. +- `feature_builder.py`: converts raw Legacy sensors/forces/actions and optional Illusion target values into dimensionless feature dictionaries/matrices. Its broad feature catalog records supported experiments; availability of target/error features does not mean the accepted formula uses them. CPU. +- `feature_state.py`: maintains trajectory-local lag, derivative, and previous-action state for offline and closed-loop feature parity. CPU. +- `g_operator.py`: applies the reflection operator to raw observations, target forces, and actions and computes equivariance diagnostics. Array operations are CPU; the old `diagnose_one_re` runtime helper can touch CFD and is not claim authority. +- `symmetry_dataset.py`: creates mirrored fitting batches and empirical equivariance diagnostics. CPU. +- `formula_schema.py`: loads, normalizes, hashes, safety-checks, evaluates, and constructs formula, deletion, scaling, and validation artifacts. CPU; artifact provenance does not by itself imply closed-loop acceptance. +- `metrics.py`: implements the exact `legacy_dtw_v1_abs_n_unclipped` cycle comparison. CPU. Fitted lag is alignment metadata, not physical delay. +- `harmonics.py`: analyzes target harmonics and reconstructs sampled target states. CPU; reconstructed targets are runtime inputs, not evidence of explicit target tracking. +- `provenance.py`: safe paths, canonical JSON hashing, SHA-256 hashing, and atomic JSON writes. CPU. +- `cfd_interface.py`: lazy LegacyCelerisLab loading, scene construction, observation/action conversion, PPO loading, legacy similarity wrappers, and vorticity extraction/rendering. Pure transforms and plotting can run on CPU; environment construction, stepping, DDF access, and vorticity acquisition require serial PyCUDA GPU execution. PPO inference defaults should remain CPU when CFD owns the GPU. +- `__init__.py`: limited re-export layer for active feature construction and `apply_G_alpha`; it is not a blanket compatibility API. + +## Data and generation boundaries + +Utilities may read flat runtime references such as `../data/karman/.../norm.json`, `../data/illusion/...`, and Legacy configuration/model paths when constructing a run. Accepted scientific inputs and generated evidence must remain run-scoped under immutable `../data/runs//...` or `../results/runs//...`; utility helpers must not treat flat references as accepted run provenance. + +The active runtime is LegacyCelerisLab. Do not pass V5 solver states, V5 formulas, or V5 `VecNormalize` artifacts into these contracts. Archived V5 code under `../archive/experiments/v5/` and `../archive/data/v5/` is intentionally separate. + +There is no active `SR_analysis.internal` module. If an empty `internal/` directory exists, it has no imports, re-exports, API, or authority; callers should use the explicit `SR_analysis.utils` modules above. diff --git a/src/SR_analysis/utils/__init__.py b/src/SR_analysis/utils/__init__.py index 8859313..868ce1d 100644 --- a/src/SR_analysis/utils/__init__.py +++ b/src/SR_analysis/utils/__init__.py @@ -1,8 +1,10 @@ """Shared contracts for the active three-stage SR pipeline. -The current route is inference, symbolic fitting, and closed-loop validation. -Legacy SINDy helpers remain importable for historical scripts but are not part of -that article pipeline. +The current accepted scientific claim is Karman/cloaking. Illusion support +remains executable for compatibility and historical evidence, but is not an +active accepted SR claim. The route is inference, symbolic fitting, and +closed-loop validation. Legacy SINDy helpers remain importable for historical +scripts but are not part of that article pipeline. """ from .feature_builder import ( ALL_FEAT_KEYS, diff --git a/src/drl_pinball/data/reproduction_plots_sr/README.md b/src/drl_pinball/data/reproduction_plots_sr/README.md new file mode 100644 index 0000000..1b37e9a --- /dev/null +++ b/src/drl_pinball/data/reproduction_plots_sr/README.md @@ -0,0 +1,33 @@ +# SR reproduction plots + +This directory is a derived diagnostic plotting package for standardized Legacy acquisition. It is not the acquisition payload and it is not, by itself, scientific evidence that every case or role completed. + +## Current status: partial diagnostic + +`manifest.json` currently declares `allow_partial: true`, `plot_count: 2`, and `expected_plot_count: 23`. The two rendered groups are Legacy `karman_re100` and `illusion_1L`. Therefore this directory is a **2/23 partial diagnostic**, not a complete SR reproduction package and not sufficient evidence for campaign completeness, generalization, deletion necessity, or a current Illusion result. Its absolute source paths and recorded SHA-256 values identify the inputs used for those two plots; they do not imply that the other 21 expected plots exist or passed acquisition validation. + +The current standardized reproduction claim is active for Kármán SR. The included Illusion panel is historical/negative diagnostic evidence only: it can expose behavior or incompatibility, but it must not be cited as a current validated Illusion SR reproduction. A visually plausible panel cannot override missing campaign roles, partial-manifest status, or acquisition/provenance gates. + +## Acquisition contract represented by a complete package + +For standard periodic Kármán and Illusion acquisition, `legacy_test/acquire.py` distinguishes: + +- `Target`: live target-only trajectory, with no policy action, policy normalization, or native reward metric. +- `PPO`: `controlled`, the frozen-policy Legacy trajectory. +- `Zero (physical, no control)`: normalized counter-bias that yields zero physical cylinder rotation; it is not normalized-action zero when a bias exists. +- `SR`: the canonical causal symbolic policy. +- named SR deletion diagnostics: one registered term removed and bound to the same-case canonical SR parent. + +Each standard role has 480 warm-up intervals followed by exactly 160 retained post-step boundaries. Role-local phase comes from smoothed rising zero crossings of center `uy` (`sensors[:,3]`) with a minimum-gap filter. The field artifact contains exactly eight nearest boundary snapshots at the eight requested phases; these are unaveraged snapshots selected across complete cycles. Its `mean_ux` and `mean_uy` are arithmetic means over all retained boundary fields in complete half-open cycles, not means of those eight snapshots. + +Telemetry keeps the native Legacy reward DTW where available and adds a distinct target-channel-max-abs-normalized rolling six-channel cycle DTW. These must remain separately labelled; target trajectories do not have native reward DTW. + +Acquisition publishes only after same-filesystem staging and exact schema validation. Outputs are no-clobber unless overwrite is explicit, prior output is restored if atomic replacement fails, and failed runs remove staging rather than publishing partial evidence. + +Generalization cases intentionally contain `Target`, `SR`, and physical `Zero` only; absence of PPO is part of the acquisition design, not missing data. Canonical SR and deletion variants share `SR_analysis.stage_3_validate.SymbolicPolicy`, while metadata binds formula-file hashes, artifact IDs, the pair hash, and deployment-expression hashes. + +## Operational warning + +Legacy compiler configuration and PTX output are shared files (`LegacyCelerisLab/kernels/macros.h` and `kernel.ptx`). CFD configurations must not compile concurrently. Run them serially and stagger shared-file configuration changes so the previous GPU context and compilation have fully released the files before the next case starts. + +Regenerating this directory should use the plotting command's complete-campaign mode for evidence publication. `--allow-partial` is appropriate only for diagnostics and must continue to be labelled partial. diff --git a/src/drl_pinball/data/reproduction_plots_sr/legacy/illusion_1L.png b/src/drl_pinball/data/reproduction_plots_sr/legacy/illusion_1L.png new file mode 100644 index 0000000..347a154 Binary files /dev/null and b/src/drl_pinball/data/reproduction_plots_sr/legacy/illusion_1L.png differ diff --git a/src/drl_pinball/data/reproduction_plots_sr/legacy/karman_re100.png b/src/drl_pinball/data/reproduction_plots_sr/legacy/karman_re100.png new file mode 100644 index 0000000..b5d2680 Binary files /dev/null and b/src/drl_pinball/data/reproduction_plots_sr/legacy/karman_re100.png differ diff --git a/src/drl_pinball/data/reproduction_plots_sr/manifest.json b/src/drl_pinball/data/reproduction_plots_sr/manifest.json new file mode 100644 index 0000000..93f45f7 --- /dev/null +++ b/src/drl_pinball/data/reproduction_plots_sr/manifest.json @@ -0,0 +1,259 @@ +{ + "schema": "drl-pinball-sr-reproduction-plots-v1", + "plot_count": 2, + "expected_plot_count": 23, + "allow_partial": true, + "no_ppo_cases": [ + "karman_re25", + "karman_re70", + "karman_re150", + "karman_re300", + "illusion_05L", + "illusion_06L", + "illusion_08L", + "illusion_12L", + "illusion_2L" + ], + "no_ppo_contract": "Generalization conditions intentionally contain Target/SR/Zero only; PPO is absent by acquisition design.", + "variant_contract": "Each diagnostic binds the named variant to its same-case parent SR.", + "vorticity_limit": 0.001, + "vorticity_contract": "fixed symmetric [-0.001, +0.001] for every vorticity panel", + "plots": [ + { + "pipeline": "legacy-sr", + "group": "illusion_1L", + "plot": "legacy/illusion_1L.png", + "roles": [ + { + "role": "Target", + "source": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/target", + "field_file": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/target/phase_fields.npz", + "field_slot": 0, + "selector": "target_phase", + "selector_value": 0.0, + "source_files": [ + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/target/metadata.json", + "sha256": "a2cf42953d5db190f8624b04473c6023325b181a92667cd7b1f2e1f5fc972c61", + "bytes": 2741 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/target/timeseries.csv", + "sha256": "3c99f92a52b9d985087f24bcb8c3d128438e1f060c8a4824cf79d484c4211f3c", + "bytes": 34174 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/target/phase_fields.npz", + "sha256": "d8d23021406aaef0953aa5dfe5a6c71ae5e50179c2c170e8de099b4befbb36e7", + "bytes": 40369515 + } + ] + }, + { + "role": "PPO", + "source": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/controlled", + "field_file": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/controlled/phase_fields.npz", + "field_slot": 0, + "selector": "target_phase", + "selector_value": 0.0, + "source_files": [ + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/controlled/metadata.json", + "sha256": "82b8c1623c0d1f275c561b7ead68db24f590bec183c3893e2ed3c5ec956ed688", + "bytes": 4213 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/controlled/timeseries.csv", + "sha256": "5825b81380058e16185904addbd9e3e176dd312f2ac1de92a461b2befe16423c", + "bytes": 66780 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/controlled/phase_fields.npz", + "sha256": "cc55cb2171f72589b915c46ec2556ce4e9155023da77e7721a908dacbe360ad9", + "bytes": 40359513 + } + ] + }, + { + "role": "SR", + "source": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/sr", + "field_file": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/sr/phase_fields.npz", + "field_slot": 0, + "selector": "target_phase", + "selector_value": 0.0, + "source_files": [ + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/sr/metadata.json", + "sha256": "199d3ecdb712dc7c60508b8b7069a8fcb0a9ce99e7e522bc5374cd61a9b271b9", + "bytes": 7293 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/sr/timeseries.csv", + "sha256": "40c16e3dbe8791b6ee1e394d6eb58f16cb84cefae07b2201897212b8bd7dce29", + "bytes": 68641 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/sr/phase_fields.npz", + "sha256": "5ec1ddbf9d43fbb91f482613d03fc832b2854f0ff31cb15b87bf1749bfc0ea3f", + "bytes": 40767829 + } + ] + }, + { + "role": "Zero (physical, no control)", + "source": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/zero", + "field_file": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/zero/phase_fields.npz", + "field_slot": 0, + "selector": "target_phase", + "selector_value": 0.0, + "source_files": [ + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/zero/metadata.json", + "sha256": "e474ac05bc232ea051469d49143d62066ab5ef4a44fba63558594ec47981ad57", + "bytes": 3529 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/zero/timeseries.csv", + "sha256": "7d13a5c6cb4482fa49b305b49e2f46b522fcf79ce1807905bd5c625e511605ef", + "bytes": 55641 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/illusion_1L/zero/phase_fields.npz", + "sha256": "839c2dda70e08f302fd993a3b3c83fcb1c6a15798c2792948fe04590ecf91509", + "bytes": 40767278 + } + ] + } + ], + "vorticity_limit": 0.001, + "sensor_limits": { + "u": [ + 0.469472325, + 1.480624775 + ], + "v": [ + -0.7604088545, + 0.7605766445 + ] + } + }, + { + "pipeline": "legacy-sr", + "group": "karman_re100", + "plot": "legacy/karman_re100.png", + "roles": [ + { + "role": "Target", + "source": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/target", + "field_file": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/target/phase_fields.npz", + "field_slot": 0, + "selector": "target_phase", + "selector_value": 0.0, + "source_files": [ + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/target/metadata.json", + "sha256": "9dd81c66c48bc037dc1a500359f468541a52660f07c3b4cd8f23cd32a7cdcab0", + "bytes": 2707 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/target/timeseries.csv", + "sha256": "fc6f5a59506bd18e7dcc255b5402fe3dc6b43f2e01b4969fe645f015b367bf6d", + "bytes": 33929 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/target/phase_fields.npz", + "sha256": "02555a5e56d5b2ba37adf29592643396c19c426ff089a7963b07c7ece58453ec", + "bytes": 40268975 + } + ] + }, + { + "role": "PPO", + "source": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/controlled", + "field_file": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/controlled/phase_fields.npz", + "field_slot": 0, + "selector": "target_phase", + "selector_value": 0.0, + "source_files": [ + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/controlled/metadata.json", + "sha256": "49aa079917b5669a427826a244f953fdc9c96fc35f2e7e73d0925d5d78c69364", + "bytes": 4137 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/controlled/timeseries.csv", + "sha256": "6a0073e9b1b56d8dfe88751f161e5604a5b194284adbb0385f12fef0a5c372a5", + "bytes": 66345 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/controlled/phase_fields.npz", + "sha256": "ab376c1f0f3b6cb2562101d477ef5f004c819c3769b736959fddde9e028eb606", + "bytes": 40397652 + } + ] + }, + { + "role": "SR", + "source": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/sr", + "field_file": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/sr/phase_fields.npz", + "field_slot": 0, + "selector": "target_phase", + "selector_value": 0.0, + "source_files": [ + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/sr/metadata.json", + "sha256": "436c3b625abca9c815e2def33047137015ac3d9579f08c6e91059878e2c15930", + "bytes": 6622 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/sr/timeseries.csv", + "sha256": "3fef92c67228f0a703235c51cc8df938b1e8690eb666e05501697ce89c7c2d61", + "bytes": 66563 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/sr/phase_fields.npz", + "sha256": "4c483b901216318c1bbe836d1c3e5d7222f49f7427162a1f7888d173ebf999de", + "bytes": 40425098 + } + ] + }, + { + "role": "Zero (physical, no control)", + "source": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/zero", + "field_file": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/zero/phase_fields.npz", + "field_slot": 0, + "selector": "target_phase", + "selector_value": 0.0, + "source_files": [ + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/zero/metadata.json", + "sha256": "422918d5c5a50e62c736959844cae0ab75c009bc632a66161048e5adf668fc94", + "bytes": 3494 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/zero/timeseries.csv", + "sha256": "f7fdf2c1aef8ea46a3f7cd7bb2f7838195930b22ec6d0249acf24f984056d77e", + "bytes": 55829 + }, + { + "path": "/home/frank14f/optane/DynamisLab/drl_pinball/reproduction/legacy/karman_re100/zero/phase_fields.npz", + "sha256": "45620f982a94d580195fb712a1ead44e259fa109a3f560828c42c62df67378ac", + "bytes": 41109718 + } + ] + } + ], + "vorticity_limit": 0.001, + "sensor_limits": { + "u": [ + -0.1968925135, + 1.4000026435 + ], + "v": [ + -0.738342885, + 0.720610985 + ] + } + } + ] +} diff --git a/src/drl_pinball/legacy_test/README.md b/src/drl_pinball/legacy_test/README.md index 6ea051c..cefb546 100644 --- a/src/drl_pinball/legacy_test/README.md +++ b/src/drl_pinball/legacy_test/README.md @@ -15,3 +15,28 @@ Supported cases: Karman Re50/100/200/400, Illusion 0.75/1/1.5, Vortex lamb/taylo In normal mode, at run start, the selected `legacy_test/output/` directory is removed and recreated so stale files cannot be mistaken for current evidence; other case directories are untouched. Each run writes only `{signals.npz,reset_contract.npz,norm.json,metrics.json,final_vorticity.png}` there. `norm.json` records separate `policy` and `recomputed` sections, while `metrics.json` records the policy norm source path and SHA256. `metrics.json` distinguishes target-native legacy DTW (the reward input), normalized target-scale DTW computed offline, reward summaries, model/config provenance, and an optional `frozen_reference_comparison` loaded only from the active `src/SR_analysis/data///controlled.npz` path. With `--metrics-only`, the same full CFD/policy rollout and in-memory metrics/frozen comparison run, but no case directory is inspected, created, deleted, or written and rendering is skipped; compact metrics JSON is printed to stdout. The vorticity PNG uses the shared `CelerisLab.common.render` renderer, Legacy flag-masked `q/RHO_ref` physical lattice velocity/vorticity with `RHO_ref=1`, solid masking, and fixed limits `[-0.001, 0.001]`. The previous scene-specific scripts are retained under `archive/duplicated_scripts/` and are not active entry points. CPU-only contract tests live in `tests/`; they do not initialize CUDA. + + +## Standardized acquisition (`acquire.py`) + +`acquire.py` is the evidence-acquisition entry point, separate from the generic reproduction runner above. For standard periodic Kármán and Illusion cases it assigns these role semantics: + +- `target`: a live builder-generated target trajectory; policy actions, policy normalization, and native reward metrics are unavailable. +- `controlled`: the frozen Legacy PPO trajectory using its frozen policy normalization. +- `zero`: the physical-zero/uncontrolled trajectory. The normalized command counteracts the configured action bias so the physical cylinder rotation is zero; the frozen norm is used only where the historical native reward diagnostic requires it. +- `sr`: the causal symbolic controller, loaded through the shared `SR_analysis.stage_3_validate.SymbolicPolicy` implementation and bound to the canonical formula pair. +- `sr_`: a named one-term deletion variant, restricted to its registered parent case and compared with that same case's canonical SR. Deletion changes the selected formula artifact; it is not a PPO role. + +A standard periodic role runs 480 warm-up control intervals and then retains exactly 160 post-step boundaries. Every retained boundary contributes telemetry and one unaveraged FP32 `ux`/`uy` candidate field. Phase is determined independently for each role from the fixed center-sensor transverse velocity `sensors[:,3]`: one-pass `[1,2,1]/4` smoothing, interpolated `uy <= 0 < uy_next` rising crossings, and a minimum-gap filter. Publication requires at least four accepted crossings. From all retained candidate boundaries lying in complete half-open cycles, `[first crossing, last crossing)`, the collector publishes exactly eight nearest unaveraged fields at the eight target phases. `mean_ux` and `mean_uy` are separate arithmetic means over every candidate boundary in those complete cycles; they are not averages of the eight phase fields. + +The timeseries preserves the native Legacy reward DTW when that metric exists and also computes a separate rolling six-sensor cycle DTW after max-absolute normalization by each target channel. These metrics have different scales and purposes: the target-normalized diagnostic does not replace or retroactively redefine the native Legacy reward metric, and the target role has no native reward DTW. + +Publication is transactional and fail closed. A role is built in a hidden same-filesystem staging directory, its exact file set and phase-field schema are validated, and only then is it atomically renamed into place. Existing role output is no-clobber by default; `--overwrite` is explicit, uses a temporary backup, and restores the old directory if publication fails. Any acquisition or validation exception removes staging and exposes no partial role as current evidence. + +The standardized SR campaign includes trained cases plus coefficient-frozen generalization cases. Generalization intentionally has only `target`, `zero`, and `sr`: no PPO model is claimed or acquired there. Canonical and deletion roles use the same `SymbolicPolicy` runtime. Metadata records formula file SHA-256 identities, formula artifact IDs, the formula-pair hash, and front/rear deployment-expression hashes so a role is bound to the exact deployed formulas. + +Legacy compilation rewrites shared `LegacyCelerisLab/kernels/macros.h` and `kernel.ptx`. Do not compile different configurations concurrently. Run CFD serially and stagger configuration changes long enough for the previous GPU context and compiler use of those shared files to finish; otherwise one process can compile or load another case's configuration. + +## Evidence boundary + +The current standardized claim is the active Kármán SR acquisition/evaluation path. Illusion material in older reproduction outputs is historical or negative evidence unless and until a complete current standardized acquisition is validated; in particular, do not promote an old Illusion plot into a current SR claim merely because it renders. The SR-analysis package may retain its own frozen historical Illusion numerical-family evidence, but that does not make this reproduction acquisition complete or current.