Skip to content

ecCKD/ecRad radiation platform and validation harness - #8

Open
glwagner wants to merge 21 commits into
mainfrom
glw/ecckd-radiation-platform
Open

ecCKD/ecRad radiation platform and validation harness#8
glwagner wants to merge 21 commits into
mainfrom
glw/ecckd-radiation-platform

Conversation

@glwagner

@glwagner glwagner commented May 21, 2026

Copy link
Copy Markdown
Member

PR: ecCKD / ecRad radiation platform and validation harness

This branch rebuilds NumericalRadiation.jl into a standalone, ecRad/ecCKD-
compatible radiation package. It adds the staged runtime API, official ecCKD
file ingestion, cloudless and cloud-overlap solvers, cloud and aerosol optics,
a package-native RRTMGP comparison extension, a validation/audit harness, an
Artifacts-backed ecRad/ecCKD data path, and the groundwork for Reactant/Enzyme
ecCKD model recovery.

The design contract and acceptance criteria live in docs/src/design.md.
The campaign-era audit trail (audits, working logs, experiment artifact
history) is preserved on the archived ref audit-trail-2026-07-17 (branch
audit-trail-pre-cleanup); frozen greedy-era reduced-model endpoints are in
validation/FROZEN_DIAGNOSTICS.md.

Headline figures

Generated from the committed artifacts by figures/make_pr_figures.jl
(julia --project=figures figures/make_pr_figures.jl).

Accuracy. Official 32×32 ecCKD matches ecRad on the clear-sky tropical
column: LW flux RMSE ≈ 0.003 W m⁻², SW flux RMSE ≈ 0.007 W m⁻², heating-rate
RMSE ≈ 0.006 K day⁻¹. The hard ecCKD cloudless gate passes, and all six
promoted published LW×SW combinations (32/64 LW × 32/64/96 SW) pass the clean
package-native gate against matched references.

Performance. The streaming gas-optics + transport kernel fuses g-point
optical-depth computation into the column transport loop (no 4-D τ
intermediates). H100 speedups vs RRTMGP through Breeze's update_radiation!
surface, post-warmup medians on the same workload:

k-model RH median [ms] RRTMGP median [ms] Speedup
32 LW × 32 SW 794.7 5863.3 7.4×
32 LW × 64 SW 1047.3 5864.2 5.6×
32 LW × 96 SW 1279.3 5867.7 4.6×
64 LW × 32 SW 1352.7 5869.8 4.3×
64 LW × 64 SW 1603.6 5870.1 3.7×

The RCEMIP-style 32×32×64 production benchmark in the dedicated Breeze
checkout records ≈ 31.3× speedup (7.8 ms vs 244.0 ms median update) with
Nsight Systems/Compute reports, passing the ≥ 4× gate.

Training. Reactant compilation + Enzyme reverse-mode gradients are
demonstrated end-to-end on a toy fixed-topology fixture (≈170× loss drop) and
on the production-shape 16-g RRTMGP-target loss.

What landed

  • Staged runtime APIsrc/abstract_types.jl, src/runtime_interfaces.jl:
    ColumnAtmosphere, RadiativeFluxes, and staged entry points
    (optical_properties!radiative_heating!, radiation_workspace) so
    host models can stop at any layer. The legacy column API is preserved.
  • ecCKD ingestion — dependency-free schema/resolution in
    src/io/ecckd_definition.jl; runtime LUT gas optics in
    src/gas_optics/ecckd_forward.jl; NetCDF readers in
    ext/NumericalRadiationNCDatasetsExt.jl; Artifacts.toml pins ecrad/ecckd
    snapshots with RH_ECRAD_DATA_PATH/RH_ECCKD_SOURCE_PATH overrides.
  • SolversCloudlessLongwave, CloudlessShortwave,
    CloudOverlapLongwave, CloudOverlapShortwave (Tripleclouds-style modes,
    verified to ≈1e-5 W m⁻² against ecRad reference optics), cloud/aerosol
    optics with absorption/scattering/asymmetry channels, and official
    droplet/ice scattering-table ingestion mapped to g-point grids.
  • RRTMGP comparison extensionext/NumericalRadiationRRTMGPExt.jl
    computes RRTMGP clear-sky fluxes from the same ColumnAtmosphere; weak deps
    RRTMGP@0.21, ClimaComms@0.6, NCDatasets@0.14.
  • Metricssrc/metrics.jl provides the common metric/threshold layer
    used by every gate.
  • Validation harnessvalidation/ writes paired .json/.md artifacts
    under validation/results/: reference materialization and candidate
    writing, the cloudless and all-sky hard gates, published-model accuracy,
    RRTMGP comparison, AD calibration, and the ecCKD recovery/preflight group
    (training manifest, teacher-student recovery, CKDMIP data preflight,
    original-objective terms/loss/dataset checks).
  • Tests, docs, examples — test suites for solvers, ecCKD schema/forward
    path, official file recognition, the RRTMGP extension, validation-script
    contracts, and the SpeedyWeather extension; docs pages for design,
    architecture, ecCKD files/workflow, CKDMIP training data, and API
    reference; literate examples including the RRTMGP validation report and the
    training recovery report.

Acceptance gate status

Gate Status
Clean ecCKD cloudless hard gate (official inputs) passed — official 32×32 worst TOA/surface forcing ≈ 0.008 / 0.014 W m⁻²; all six published combinations pass against matched references
32-g production gas optics + RRTMGP comparison passed — direct package-native RRTMGP metrics on tropical / RCEMIP-style / all-sky-clear-projection ensembles
All-sky gate + dynamic Breeze integration with H100 speedup passed — all-sky IFS gate passed (best sweep ratio ≈ 0.387, Tripleclouds reference-optics match ≈ 1e-5 W m⁻²); H100 RCEMIP benchmark ≈ 31.3× vs RRTMGP
Reactant + Enzyme recovery of a published ecCKD model outstanding — teacher-student recovery passes for all six published definitions and all CKDMIP training data is ready; original-objective recovery under the optimizer-only-delta rule, then a recovered-pipeline 48-g model, remain

Reproducing

Package tests and examples are self-contained (LazyArtifacts downloads the
pinned ecrad/ecckd data on first use):

julia --project=. -e 'using Pkg; Pkg.test()'
julia --project=. examples/analytic_column.jl
julia --project=. benchmark/benchmark_suite.jl

Validation audits need the NCDatasets-aware test project:

julia --project=test -e 'using Pkg; Pkg.instantiate()'
julia --project=test validation/materialize_ecrad_references.jl
julia --project=test validation/write_ecrad_candidates.jl
julia --project=test validation/ecrad_accuracy_gate.jl
julia --project=test validation/ecrad_all_sky_ifs_gate.jl
julia --project=test validation/reduced_ecckd_accuracy.jl
julia --project=test validation/reduced_ecckd_32g_rrtmgp_comparison.jl

The heavy paths are documented in the docs: the ecCKD original-objective
recovery requires a ~1 TB CKDMIP tree plus locally generated derived training
fluxes (validation/download_ckdmip_training_data.sh,
validation/generate_ecckd_derived_fluxes.sh; the live workspace preflight
reports ready_for_original_ecckd_objective). The H100 evidence is produced
in the dedicated Breeze checkout
(/shared/home/greg/Projects/BreezeRadiativeHeatingDev/Breeze.jl,
benchmarking/radiative_heating_h100_acceptance.sh); this PR does not modify
Breeze and does not depend on it at package-build time.

Notes for reviewers

  • Code review can scope to src/, ext/, test/, docs/, and examples/;
    validation/results/*.{json,md} are evidence rather than code.
  • docs/src/design.md is the design contract and acceptance criteria.
  • validation/external/ is gitignored; let LazyArtifacts resolve the
    ecRad/ecCKD sources or set the env overrides.

🤖 Generated with Claude Code

glwagner and others added 7 commits May 21, 2026 00:24
This is a large branch that turns AnalyticBandRadiation.jl into the
standalone, ecRad/ecCKD-compatible radiation package described in
`radiative_heating.md`. See `PR_WORK_SUMMARY.md` for the full narrative
and reproduction instructions.

Highlights:

- Staged runtime API (`runtime_interfaces.jl`, abstract optics/solver/backend
  types) sits beside the existing `RadiativeTransferColumn` path so host
  models can stop at any layer.
- ecCKD ingestion (`io/ecckd_definition.jl`, `gas_optics/ecckd_forward.jl`),
  artifact-backed official ecRad + ecckd source resolution (`Artifacts.toml`),
  and NCDatasets-backed loaders behind `AnalyticBandRadiationNCDatasetsExt`.
- Cloudless and cloud-overlap longwave/shortwave solvers, cloud and aerosol
  optics scaffolding, ecRad cloud scattering table ingestion and g-point
  mapping.
- Optional `AnalyticBandRadiationRRTMGPExt` for direct package-native RRTMGP
  comparisons through `ColumnAtmosphere`/`RadiativeFluxes`.
- Validation metrics (`metrics.jl`) and an extensive `validation/` audit
  harness writing paired `.json` + `.md` artifacts under
  `validation/results/`, plus prompt-to-artifact and recovery-goal audits.
- Tests for every new surface (solvers, cloud/aerosol optics, ecCKD schema,
  RRTMGP comparison, every validation script, the full goal/recovery audits).
- Docs (Architecture, ecCKD files, CKDMIP training data) and a single-column
  staged example.
- CPU benchmark scaffold for the staged runtime path.
- Removed the in-repo Breeze extension; Breeze now owns
  `BreezeRadiativeHeatingExt` in a dedicated checkout, as recorded by the
  goal-audit artifacts.

Goal acceptance: cloudless ecRad gate, all-sky IFS gate, and the dedicated
Breeze H100 ≥4x RRTMGP performance gate pass. Exact Reactant/Enzyme
original-objective ecCKD recovery is blocked on locally derived ecCKD
CKDMIP training flux products (`5gas-*` LW, `rel-*` LW/SW); generation is
running under Slurm. See `PR_WORK_SUMMARY.md` §4.3 for reproduction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ed descent)

`figures/make_pr_figures.jl` regenerates four PNGs from the committed
artifacts and dedicated-Breeze JSONs:

- fig1_ecckd_vs_ecrad_profiles.png: official 32x32 ecCKD vs ecRad
  up/down LW + SW flux profiles and heating rate on the clear-sky
  tropical column. LW flux RMSE ~0.003 W m-2, SW flux RMSE
  ~0.007 W m-2, heating-rate RMSE ~0.006 K day-1.
- fig2_h100_speedup.png: H100 RCEMIP-style 32x32x64 / 1024-column
  median radiation-update timing for RadiativeHeating.jl vs RRTMGP.jl
  across three k-model configurations (32x32 validated ecCKD, 32x16,
  16x16). Speedups 31.3x / 29.8x / 27.0x.
- fig3_training_curves.png: Reactant/Enzyme calibration. Left: 13-epoch
  toy fixed-topology ecCKD recovery loss decay (Enzyme gradient-checked).
  Right: 8 epochs of Reactant-compiled, Enzyme reverse-mode gradient
  descent on a 48-parameter 16-g RRTMGP-target shortwave loss.
- fig4_reduced_descent.png: worst boundary-forcing error vs accepted
  optimizer moves for the reduced 16-g shortwave chain, with the
  0.3 W m-2 hard-gate threshold marked. Drops from 7.18 W m-2 at the
  naive 16-g start to 2.14 W m-2 (current best) - still ~7x above
  the gate.

Figures live in figures/ with their own Project.toml. PR_WORK_SUMMARY.md
embeds them inline. figures/Manifest.toml is gitignored.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…del coverage

Two real issues in the original plot:

1. The three RRTMGP bars implied three RRTMGP configurations, but RRTMGP
   is the same 256 LW x 224 SW lookup in every run. The variation came
   from samples=1 vs samples=3 across the production benchmark and two
   reduced-pareto scaffolds (the single-shot scaffolds include first-call
   compile/warmup overhead in the RRTMGP timing).

2. The plot suggested we have measured H100 timings across "all" reduced
   ecCKD k-models, but in fact only 32x32 (validated ecCKD, production)
   has a defensible measurement. 32x16 and 16x16 are fixed-coefficient
   scaffolds (gas_model_source=missing). Published 64-g and 96-g ecCKD
   models in our artifact inventory have no H100 timing yet.

Redrawn as two panels:
- Left: production head-to-head, RadiativeHeating 32x32 validated ecCKD
  (7.79 ms, samples=3) vs the single RRTMGP baseline (244 ms, samples=3),
  31.3x speedup.
- Right: RadiativeHeating timing across ecCKD k-models, all referenced
  to the same 244 ms RRTMGP baseline as a horizontal dashed line.
  Bars are coloured by provenance: validated ecCKD (samples=3),
  fixed-coeff scaffold (samples=1), published ecCKD model with no
  H100 timing yet (grey). With the corrected baseline the scaffold
  speedups land at 13.3x (32x16) and 11.7x (16x16) rather than the
  warmup-inflated 29.8x / 27.0x.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the inflated cross-baseline speedups (29.8x, 27.0x) with the
honest comparison against the one defensible RRTMGP baseline (244 ms,
n=3, post-warmup), and call out the published 64-g / 96-g ecCKD models
that have no H100 timing yet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Stands up benchmarking/ as a self-contained environment that path-deps on
this repo's AnalyticBandRadiation.jl and a developing Breeze checkout, so
the H100 RCEMIP benchmark can co-evolve with both repos without going
through Breeze's workspace machinery.

The benchmark exercises Breeze's update_radiation! entry point (so it
measures the production call path) and writes JSON in the schema
figures/make_pr_figures.jl reads.

H100 sweep at 512x512x128 / 262,144 columns, samples=5 post-warmup
median, validated ecCKD provenance for all five published k-model
combinations:

  k-model                                       RH ms   RRTMGP ms   speedup
  32 LW × 32 SW  (fsck-32b   × rgb-32b)          794.7    5863.3       7.4x
  32 LW × 64 SW  (fsck-32b   × window-64b)      1047.3    5864.2       5.6x
  32 LW × 96 SW  (fsck-32b   × vfine-96b)       1279.3    5867.7       4.6x
  64 LW × 32 SW  (narrow-64b × rgb-32b)         1352.7    5869.8       4.3x
  64 LW × 64 SW  (narrow-64b × window-64b)      1603.6    5870.1       3.7x

RRTMGP is essentially constant because it runs its own 256-LW / 224-SW
k-table regardless of the ecCKD k-counts. RadiativeHeating scales
sub-linearly with g-point count under the streaming-kernel rewrite that
just landed in BreezeRadiativeHeatingExt (no (ngpt, Nx, Ny, Nz)
intermediate optical-property buffers).

The figure now has a single defensible RRTMGP baseline (5863.3 ms,
samples=5, post-warmup) instead of three warmup-contaminated bars, and
all five published ecCKD k-models are measured rather than four shown
as "pending".

figures/make_pr_figures.jl prefers the local benchmarking/results/
artifacts and falls back to the dedicated Breeze checkout for runs not
re-measured under the streaming kernel.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Auto-updated by the running Slurm job that generates the 18 derived ecCKD
training flux products and re-runs the preflight + recovery audits. No
code changes; just refreshes RUNNING_REVIEW.md and the
ckdmip_training_data_preflight, ecckd_derived_flux_generation_plan, and
recovery_goal_audit JSON/MD snapshots.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Renames the package, module, and extension surfaces:

  package: AnalyticBandRadiation -> Lightflux
  module:  module AnalyticBandRadiation -> module Lightflux
  ext:     AnalyticBandRadiationNCDatasetsExt    -> LightfluxNCDatasetsExt
           AnalyticBandRadiationRRTMGPExt        -> LightfluxRRTMGPExt
           AnalyticBandRadiationSpeedyWeatherExt -> LightfluxSpeedyWeatherExt

`using AnalyticBandRadiation` / `import AnalyticBandRadiation` are
updated everywhere in src/, ext/, test/, validation/, benchmark/,
benchmarking/, docs/, examples/, figures/, and the top-level markdown
notes.

GitHub URL references in the README, docs, and PR_WORK_SUMMARY are kept
literal because the GitHub repo itself is still
`NumericalEarth/AnalyticBandRadiation.jl` (the on-disk directory is also
unchanged). The `Project.toml` `name` field is now `"Lightflux"`, so the
package loads as `using Lightflux` regardless of the directory.

The companion BreezeRadiativeHeatingExt rename in the dev Breeze checkout
lands in a separate commit on branch glw/streaming-ecckd-gpoints in
NumericalEarth/Breeze.jl.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
glwagner and others added 14 commits May 22, 2026 19:54
- Live audit/preflight artifacts now reflect the completed CKDMIP derived-
  flux generation: ckdmip_training_data_preflight is
  ready_for_original_ecckd_objective, ecckd_objective_reconstruction_check
  is ready_to_reconstruct_original_objective, recovery_goal_audit has
  blocked=0, partial=3.
- New validation scripts and tests for the ecCKD reduction work:
  leave-one-out heating residual localization, heating table optimizer,
  refit breakdown, single-table move scan, weight coordinate descent
  (+ continuation, + scan, + boundary polish), published model accuracy,
  and training recovery targets.
- Updated validation scripts (band accuracy pareto, published training
  manifest, recovery goal audit, official ecCKD training, reduced ecCKD
  RRTMGP comparison, reduced ecCKD accuracy) and their paired tests.
- PR_WORK_SUMMARY.md and RUNNING_REVIEW.md updated with the unblock work
  and ongoing review notes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…gate

- Original-objective recovery scaffolding: ckdmip_original_objective_dataset,
  ckdmip_original_objective_ad_batch, ecckd_original_objective_terms,
  ecckd_original_objective_loss; with paired tests and result artifacts.
  Sets up the AD-batched optimizer probe against the captured published
  objective terms.
- Published-model recovery vector path:
  ecckd_published_recovery_target, ecckd_published_recovery_vector, and
  ecckd_published_recovery_vector_training -- analytic quadratic descent
  in log-vector space, 204896 params, final loss 1.6e-17, log-RMSE 1.6e-10.
- Published all-sky accuracy gate (ecckd_published_all_sky_accuracy): all
  six promoted official ecCKD combinations (32x32 / 32x64 / 32x96 /
  64x32 / 64x64 / 64x96) pass under matched Tripleclouds/aerosol config.
- ecRad reference materialization extended to the same six combinations:
  validation/reference/ecrad/ecckd_{32x64,32x96,64x32,64x64,64x96}_*.nc
  for all_sky_tropical_column, clear_sky_tropical_column, and
  rcemip_style_column_subset.
- ecRad reference optics solver gap + 32x64 gate (paired test +
  result artifacts).
- Matched reference plan artifact (ecckd_matched_reference_plan) records
  which ecCKD/ecRad combinations are inventoried and recovered.
- Updated audit artifacts: recovery_goal_audit gains 10+ new sub-statuses
  (objective_terms_captured, dataset_samples_ready, optimizer_batch_ready,
  published_recovery_target_ready, published_recovery_vector_training,
  candidate_objective_score_ready, table_writeback_* probes, written_
  coordinate_descent_improved). Best reduced candidate so far: 32x31
  (63 g-points), worst boundary forcing 0.2998 W/m^-2, passing the 0.30
  hard threshold for the first time.
- New REVIEW_HANDOFF.md summarizes the current state for the next operator.
- RUNNING_REVIEW.md and PR_WORK_SUMMARY.md updated with the unblock /
  optimization progress and ongoing review notes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Second rename in this PR's history. UUID `cd8119b0-1744-44d6-9ede-6ad1ad750b26`
unchanged across both renames so downstream consumers only need to update the
package name in their manifests.

Chain:

1. `AnalyticBandRadiation` → `Lightflux`
2. `Lightflux` → `NumericalRadiation` (this commit)

Touchpoints (66 files, +197/-192 lines):

- `src/Lightflux.jl` → `src/NumericalRadiation.jl` (file + module decl)
- `ext/Lightflux{NCDatasets,RRTMGP,SpeedyWeather}Ext.jl` →
  `ext/NumericalRadiation*Ext.jl` (file + module decl + `using`)
- `Project.toml`: name + `[extensions]` stanza targets
- `docs/Project.toml`, `docs/make.jl`, all `docs/src/**/*.md` references
- `examples/`, `test/`, `validation/`, `benchmark/`, `benchmarking/`:
  `using` and `Base.get_extension(NumericalRadiation, :NumericalRadiation*Ext)`
- User prose: `README.md`, `radiative_heating.md`, `PR_WORK_SUMMARY.md`
- `.gitignore`: add `.claude/` + `.handoff_monitor.*` (local session state)

All `Manifest.toml` files are gitignored; they regenerate on next
`Pkg.instantiate()` against the renamed `Project.toml`.

Deferred (NOT in this commit):

- On-disk directory `AnalyticBandRadiation.jl/` → `NumericalRadiation.jl/`
  (must be done outside this session; changes CWD).
- Breeze downstream rename: 12 files referencing `Lightflux` plus path-fallback
  constants and the `BreezeLightfluxExt` extension at
  `BreezeRadiativeHeatingDev/Breeze.jl/`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Working-tree state verified on the head node: Pkg.test() passes
(2768 pass / 31 skipped-slow / 0 fail, plus SpeedyWeather ext 11/11)
and all six examples run (analytic_column, ecckd_column,
rrtmgp_comparison, literate 01-04). Includes the Lightflux ->
NumericalRadiation rename fallout, new docs pages, model-selection
interface + test, and fresh validation artifacts.

Committed as-is to serve as the audit-trail archive point for the
upcoming validation/results + experiment-script prune.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove the dead-end optimizer experiment history while keeping every
gate, audit, and the exact current best models:

- Delete 126 one-off experiment scripts (scans/descents/refits/probes),
  their 28 slow-test wrappers, and ~260 results artifacts they produced.
- Delete the experiment-history gap report (script + 1051-line test +
  artifacts) and trim goal_audit_check / recovery_goal_audit /
  band_accuracy_pareto to pipeline-and-gate rows only; gate criteria,
  statuses, and blocker semantics are unchanged (baseline parity:
  blocked 1 / partial 2, same single gate-4 blocker).
- Strip per-iteration optimizer logs from the load-bearing accepted-move
  artifacts that reduced_ecckd_accuracy.jl replays (e.g. slot-blend
  126k -> 79 lines, boundary polish 45k -> 336). Verified lossless: all
  63 replay readers produce byte-identical outputs before/after.
- Delete RUNNING_REVIEW.md / HANDOFF.md / REVIEW_HANDOFF.md session
  logs; point PR_WORK_SUMMARY.md and radiative_heating.md at the
  archived ref instead; add artifact policy to validation/README.md;
  gitignore docs/src/generated.

Everything removed is preserved on branch audit-trail-pre-cleanup
(tag audit-trail-2026-07-17).

Verification: Pkg.test() green (1983 pass / 0 fail / 3 skipped-slow,
SpeedyWeather ext 11/11) and all 7 examples run, matching the pinned
pre-cleanup baseline minus deleted experiment tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Maintainer-approved strategic demotion: only the published official
ecCKD path remains in the reduced-model registry, while every acceptance
gate keeps identical semantics (goal audit stays not_complete with the
same single official/reduced gas-optics training blocker; the 32-g
ecCKD/RRTMGP comparison completion-blocker row stays "passed"; the
recovery audit header stays Blocked 1 / Partial 2).

- validation/reduced_ecckd_accuracy.jl (3258 -> 627 lines): REDUCED_MODELS
  is now only the official 32x32 full_official anchor. Delete the ~60
  accepted-move artifact readers (latest_*/best_available_*), all apply_*
  move/refit appliers, the greedy construction methods (even_select,
  greedy_subset*, weighted/cumulative/similarity/anchored bins, the 32x31
  leave-one-out boundary-polish replay), and the REDUCED_*_JSON replay
  constants. The evaluation path (candidate_arrays/case_metrics), the
  indexed/weighted tabulated-model builders, and the frozen 16-g subset
  constants stay for the surviving consumers (published-model accuracy,
  optical-depth fit preflight). The artifact-writing main and acceptance
  thresholds are unchanged.
- Delete the greedy preflight leg: reduced_ecckd_optimization_preflight
  and reduced_ecckd_pressure_band_refinement_preflight (scripts + tests)
  and test_reduced_ecckd_metadata, plus their runtests includes. The two
  gate-4 slow tests (ckdmip AD batch, published recovery vector training)
  are kept.
- validation/official_ecckd_training.jl included the deleted preflight
  and recomputed the gate-4 blocker artifact from the greedy chain; it is
  now a frozen-evidence checker. The committed artifact (status
  "partial", final/target 8.605) is kept byte-identical and never
  recomputed; regeneration lives on the archived ref.
- Audit rewiring (same pattern as d1dfd16): goal_audit_check drops the
  eight greedy evidence rows (optimization preflight/gap/objective/block/
  coordinate/topology/subset-search scans and the 16-g hard-threshold
  record) from REQUIRED_ARTIFACTS and the prompt checklist, and the
  Breeze reduced-accuracy scaffold row now expects the passing registry;
  recovery_goal_audit drops the boundary-polish summary, evidence, and
  finding branches; ecckd_band_accuracy_pareto drops the boundary-polish
  parser (now 7 points, all passing); ecckd_training_recovery_targets
  requires band counts [48, 96], drops the canonical 32x31 row logic, and
  adds the recovered-pipeline-only rule for new band schemes (status
  "partial" purely from the official-recovery ratio).
- Freeze the greedy endpoints as prose in validation/FROZEN_DIAGNOSTICS.md
  (16-g canonical diagnostic ~7.006 -> 8.605, never near the gate; 32x31
  boundary polish passing at objective 0.99942 with boundary forcing
  0.29983/0.3 W m^-2, heating RMSE 0.04988/0.05 K day^-1, omitted SW
  g-point 23, 17 accepted moves - proving 63 total g-points feasible) and
  reference it from the README artifact policy. All producing scripts and
  artifacts remain on the archived ref audit-trail-2026-07-17 (branch
  audit-trail-pre-cleanup).
- Artifact sweep: remove the 62 now-unreferenced accepted-move/scan/refit
  JSON artifacts (~60k lines deleted overall with the scripts).
- Regenerate the committed gate/audit artifacts against the demoted
  registry (reduced accuracy now a passing 32x32-only table; 32-g RRTMGP
  comparison official-path-only and passing).

Verification: Pkg.test green (1844 pass / 0 fail / 2 skipped-slow,
SpeedyWeather ext 11/11) and examples 03/04 exit 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Remove the /goal audit machinery (goal_audit_check, radiation_goal_audit,
recovery_goal_audit, prompt-artifact checklist, ecrad convention gap
report) and their tests: with the validation campaign concluded, the
repo demonstrates capability through tests, docs, and examples rather
than a self-verifying ledger. Evidence artifacts whose only readers
were the audits are removed; the gate-4 training pipeline, all
capability gates, and frozen diagnostics are untouched.

Remaining goal status (gates 1-3 passed, gate-4 recovery outstanding)
is recorded in validation/FROZEN_DIAGNOSTICS.md and the archived ref
audit-trail-2026-07-17.

Verification: Pkg.test() 1597 pass / 0 fail / 2 skipped-slow,
SpeedyWeather ext 11/11; literate examples 03 and 04 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…iles

Stage R4 of the repo restructure: replace the 5,084 lines of campaign
prose with a 270-line durable design page.

- Add docs/src/design.md (wired into docs/make.jl): what the package is,
  the staged-runtime/ecCKD/solver/extension architecture rules, every
  acceptance-criteria table (hard cloudless gate, all-sky gate, RRTMGP
  comparison at 0.30 W m^-2 forcing / 0.05 K day^-1 heating RMSE,
  published-model recovery metrics final/target <= 1.05, weight L1
  <= 0.02, optical-depth log RMSE <= 0.02, and the new-band-scheme
  criteria with required 48/96-g points and the recovered-pipeline-only
  rule), gates 1-3 passed with headline numbers, gate 4 outstanding
  (recover one published ecCKD model varying only optimizer settings,
  then train 48-g), and a short Future Extensions section distilled
  from FUTURE_WORK.md.
- Delete radiative_heating.md (3,875-line design contract + campaign
  status narrative), PR_WORK_SUMMARY.md (1,041 lines; its current-state
  narrative moves to the GitHub PR description), and FUTURE_WORK.md
  (168 lines; distilled into design.md). All are preserved on the
  archived ref audit-trail-2026-07-17 (branch audit-trail-pre-cleanup).
- Fix the one dangling reference (figures/make_pr_figures.jl comment now
  points at the archive ref and validation/FROZEN_DIAGNOSTICS.md).
- Evidence re-sweep found zero newly unreferenced tracked artifacts
  under validation/results/ and zero orphaned validation scripts: the
  prior cleanup commits already closed the reference graph, so nothing
  else is removed.

Verification: Pkg.test() green (1597 pass / 2 expected broken slow-skips,
SpeedyWeather ext 11/11), docs build succeeds with design.md rendered,
examples/literate 03 and 04 exit 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Merge ~61 one-check-per-file tests into 12 subsystem test files
(solvers, ecCKD I/O, ecCKD accuracy, ecRad gates, CKDMIP pipeline,
reduced ecCKD, misc), each original file preserved verbatim as its own
module block; every @testset and assertion carries over (suite pass
count unchanged at 1597). The orphaned 16-g Reactant/Enzyme calibration
test is now wired as a third slow-skip.

Evidence policy: committed validation/results artifacts are now only
(1) repo-path test inputs the harness asserts on directly,
(2) external-data / frozen / slow-skip evidence (CKDMIP, official
training, 16-g calibration, recovery-vector training), or
(3) docs/example/figure inputs read outside the harness.
16 regenerable artifacts deleted; producer-before-consumer ordering
inside the merged files guarantees the tempdir copies regenerate.

Verification: Pkg.test() 1597 pass / 0 fail / 3 skipped-slow,
SpeedyWeather ext 11/11; literate examples 03 and 04 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ifact

Untrack the 21 reference NetCDF products under validation/reference/ecrad
(~11 MB working set; the README stays tracked) and distribute them as a
lazy Pkg artifact instead:

- Artifacts.toml gains [ecrad_reference_data] with
  git-tree-sha1 6070697 and a download
  block pinned to the deterministic future asset URL
  https://github.com/NumericalEarth/AnalyticBandRadiation.jl/releases/download/validation-data-v1/ecrad_reference_data.tar.gz
  (sha256 91e6ff211a8936c7bc9befac32f27baafeed05b1370f516466ed90848d9bfe4f).
  The tarball is prepared but not yet published; publishing that release
  asset is what activates fresh-clone materialization.
- validation/validation_results.jl gains validation_reference_dir(), the
  single resolution point for the reference tree:
  NUMERICAL_RADIATION_VALIDATION_REFERENCE_DIR override, else an existing
  local validation/reference data copy (developer checkouts keep working
  unchanged), else a writable copy materialized from the artifact into the
  working tree. The copy must be writable because validation runs write
  candidate variables into these NetCDF files in place, so the artifact is
  never consumed read-only from the artifact store.
- All existing lookups route through the helper: reference_path() in
  ecrad_reference_manifest.jl resolves validation/reference/ strings via
  the helper, and the direct joinpath sites in
  ecckd_matched_reference_plan.jl, reduced_ecckd_32g_rrtmgp_comparison.jl,
  materialize_ecrad_references.jl, ecrad_reference_optics_solver_gap.jl,
  test/test_ecrad_gates.jl, and figures/make_pr_figures.jl now build on
  validation_reference_dir().
- .gitignore covers validation/reference/**/*.nc so the on-disk copies
  stay for local runs without showing as untracked.

Verified in local-directory mode: Pkg.test() 1597 pass / 0 fail / 3 broken
plus SpeedyWeather Extension 11/11, examples/literate/03 and 04 exit 0,
and the artifact materialization branch exercised from the local artifact
store produces a writable 22-file copy with the README intact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This branch now carries only the NumericalRadiation.jl package: src/, ext/,
the package test suite (solvers, ecCKD I/O, misc, SpeedyWeather extension),
docs, and the standalone examples. The complete pre-split state (564f4d1) is
preserved on the validation-platform branch, so nothing is deleted from
history — the validation/ scripts and results evidence, FROZEN_DIAGNOSTICS,
benchmark/ and benchmarking/, figures/, the platform test files, and the
literate validation/recovery report examples all live there. The ecRad
reference NetCDF data used by the platform is the validation-data-v1 release
(the lazy ecrad_reference_data artifact entry stays in Artifacts.toml).

Package-capability check scripts that the kept tests exercise moved into
test/: access_points_check.jl and ecckd_model_inventory.jl, both rewired to
write their reports to a temporary directory (or
NUMERICAL_RADIATION_VALIDATION_RESULTS_DIR) instead of validation/results.
The official ecRad cloud-scattering testset now resolves data through the
package's own artifact path resolution instead of the validation/external
checkout. The official-ecCKD-files-check testset (which depends on the
platform's ecrad_reference_manifest) moved to the validation-platform branch.

test/runtests.jl drops the temporary-results harness and the slow-validation
include machinery — plain includes remain. test/Project.toml drops the
training-pipeline deps (Reactant, Enzyme) and other now-unused deps. Docs
pages that documented platform workflows are trimmed to pointers at the
validation-platform branch; docs/make.jl drops the generated 03/04 report
pages; design.md's gate/evidence/FROZEN_DIAGNOSTICS pointers now name the
validation-platform branch and the archived ref audit-trail-2026-07-17.

Test suite: 641 passes, 0 failures (630 NumericalRadiation + 11 SpeedyWeather
extension). Docs build and all four kept examples run clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…verage

- New explanation pages: docs/src/solvers.md (cloudless longwave/shortwave
  two-stream solvers, all-sky cloud-overlap modes, the streaming ecCKD
  gas-optics feed, and a worked ColumnAtmosphere -> fluxes -> heating data
  flow) and docs/src/cloud_optics.md (layer cloud/aerosol models, the
  cloudy-region convention, scattering-table g-point mapping).
- New docs/src/validation.md: how to run the test suite; the validation
  platform, gates, and gate-4 training pipeline live on the
  validation-platform branch; reference data ships as the
  validation-data-v1 release artifact; campaign history on the archived
  ref audit-trail-2026-07-17.
- docs/src/index.md rewritten as a landing page: package identity, a
  runnable ecCKD quickstart, and links into every section.
- docs/make.jl: pages reorganized into Home / Design & acceptance criteria
  / Tutorials / Gas optics / Solvers & schemes / API reference /
  Validation; checkdocs = :exports and full warning strictness (warnonly
  removed) so coverage regressions fail the build. All 96 exported symbols
  were already documented and in exactly one @docs block.
- Accuracy fixes verified against the pinned upstream ecCKD source and its
  manual (doc/ecckd_documentation.tex in the ecckd_source artifact):
  correlated_k.md now describes ecCKD's actual g-point construction
  (fixed wavenumber-to-g reordering on the MMM median profile,
  tolerance-based equipartition, Hogan 2010 hypercube gas overlap;
  Hogan & Matricardi 2022, DOI 10.1029/2022MS003033), and
  ecckd_training_recovery.md documents the published four-stage pipeline
  (Idealized-dataset LUT init, shortwave direct-beam scaling at mu0 = 0.5,
  bounded Adept L-BFGS on log coefficients over Evaluation-1, staged
  major-then-minor gas optimization).
- read_ecckd_tabulated_gas_optics docstrings (src stub and NCDatasets
  extension) now state the runtime-ingestion-bridge semantics: dynamic
  H2O mole-fraction table, relative-linear reference subtraction, uniform
  longwave weights, solar-irradiance shortwave weights; not full ecRad
  equivalence. ecckd_runtime_workflow.md and ecckd_model_selection.md drop
  the stale fixed-H2O claim and state gas units (mol m^-2 column amounts)
  and top-to-bottom array orientation.
- examples/literate/01_ckdmip_data_inventory.jl prints availability
  statuses instead of absolute local paths; generated pages and built docs
  carry no local paths.

Verified: julia --project=docs docs/make.jl exits 0 under strict settings;
Pkg.test() 630/630 + SpeedyWeather extension 11/11; examples/
analytic_column.jl and the index quickstart run clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The package module was already NumericalRadiation; this updates the
remaining GitHub URLs (badges, install instructions, Documenter config,
artifact release URL) to match the renamed repository.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@glwagner

Copy link
Copy Markdown
Member Author

Gate-4 recovery diagnostics: status pointer

The Gate-4 recovery diagnostics are documented through the C3-IB
iteration-budget control and live on glw/gate4-recovery at
8a67688. This comment is a status
pointer only: no code integration is proposed or implied, and the
diagnostics tree intentionally stays off this PR's branch for this
integration action.

Licensed C3-IB result (verbatim ledger constant): "under this ONE
fixed setup, the higher-cap (9000) base arm reported Converged at
iteration 4211, and its pinned package objectives were
+0.012812853359393 / +0.01281285335942 (raw2, primary/secondary
evaluator) and +0.013840350139788 / +0.013840350140555 (final)
relative to the two token-identical 3000-budget controls; raising
this cap did not improve these measured pinned objectives. Nothing
further. Converged is a REPORTED STATUS under one criterion in one
fixed setup, never proof of an optimum."

Gate-1 status: the committed terminal Gate-1 state (FAILED at
22.824617997003102 against the <=1.05 bound) is unchanged and
unexplained; all mechanism classes remain open and unranked.

Linked records (commit-pinned, all eleven ledgers plus the plan):
G3 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_g3_run_ledger.json,
G1 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_g1_objective_ratio.json,
C1 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_c1_bounds_flag_completion_ledger.json,
B0 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_b0_era_stack_completion_ledger.json,
S1 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_s1_state_sync_completion_ledger.json,
X1 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_x1_direct_capture_completion_ledger.json,
P1 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_p1_completion_ledger.json,
P2 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_p2_completion_ledger.json,
C3-IB 4578 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_c3_ib_4578_failure_ledger.json,
C3-IB 4580 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_c3_ib_4580_failure_ledger.json,
C3-IB 4584 https://github.com/NumericalEarth/NumericalRadiation.jl/blob/8a6768803cd96d8100e83df474c67054ab5a0b28/validation/results/gate4_c3_ib_4584_completion_ledger.json,
synthesis plan https://github.com/NumericalEarth/NumericalRadiation.jl/blob/fa85ed2e5d68b9725bdb5fcaccf0c8cac21fff30/validation/gate4_synthesis_integration_plan.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant