# CCD colour-translation construction preflight — 2026-10-04

## Headline / Conclusion

The two-coefficient CCD-frame colour translation is numerically distinct from the existing A3 17 coefficients on the archived C4 scene. Construction, saved-leaf roundtrip, optimizer-stage, reference-colour, and finite-difference checks pass. The shared-adapter baseline/candidate arms have bit-exact zero initialization. This is a local conditional identifiability test, not a fit, held-out improvement, joint WCS/ePSF identifiability result, or intrinsic-PSF claim. A colour-dependent astrometry/preparation discrepancy remains a possible interpretation. Next: matched full joint A3 versus A3+2 training on fresh inputs with physically excluded held pixels, same roles, initialization, budget, and scoring support.

## Model and implementation

The addition is

$$\Delta\boldsymbol{x}_i=(u_i-u_{\rm ref})(t_x,t_y).$$

Here $\Delta\boldsymbol{x}_i$ is the added CCD-frame centroid shift of catalogue source $i$ in TESS pixels; $u_i$ is the source's recorded input colour coordinate; $u_{\rm ref}=0.9601242145750014$ is the saved C4 reference colour; and $(t_x,t_y)$ are the two fitted coefficients in TESS pixels per unit colour. In this preflight both coefficients are initialized to zero. The addition is exactly zero at the recorded reference colour. Existing A3 quadratic-colour shifts need not be zero there and remain unchanged.

The adapter calls the original `loss.chroma_slot_terms`, preserves its first return value and all field terms, and adds the shifts using `ctx.chroma_delta[star_occ]` (not the first returned multiplier). It preserves the existing normalization, node blending, anchor/nuisance roles and nuisance stop-gradient rule. No production source was edited. Model preparation discrepancies cannot be assigned to intrinsic PSF physics by this test.

Adapter: `/home/kshukawa/syndiff_pipeline/dev/.claude/worktrees/epsf-model-closure-20261004/model_closure_20261004/ccd_colour_shift.py`.

Final SHA256: `49ad6a444f2470f203ec3526921c4f6cc861d11caabdb95214b95f16d0a267cb`.

Renderer pin: production `3609d467a7f17c9ed56a434d71f131ca5cf15528`, archived under `/astro/armin/koji/syndiff/dev_runs/epsf_model_closure_20261004/models/pin`.

Source branch/worktree: `codex/epsf-model-closure-20261004`, `/home/kshukawa/syndiff_pipeline/dev/.claude/worktrees/epsf-model-closure-20261004`.

Checkpoint: `/astro/armin/koji/syndiff/dev_runs/paper_dataset_20261001/C4/fit/params.npz`; scene: sibling `scene_boot`. Original saved state, noise, active-pixel mask, source roles and reference colour are retained.

The preflight code derives its scene/model reconstruction and sampled-JVP method from `restricted_preflight.py` in the same owned source folder. That earlier optimizer was not rerun here. Its nuisance-values caching is used **only** to check a finite difference against the intended stop-gradient derivative, never by the fitting/scoring adapter. No claim is made that native moving-nuisance estimating equations equal full finite differences of the refreshed scalar objective.

## Results

| Check | Result | Evidence |
|---|---:|---|
| Actual residual-Jacobian sample | 50,000 / 2,317,814 unique active pixels | `summary.json`, `jacobian.npz` |
| Column-normalized Jacobian rank / condition | 19 / 40.0023 | `jacobian_rank.png` |
| Added x/y derivative norm remaining after all 17 A3 columns projected out | 48.39% / 58.15% | `derivative_stamps.png`, `summary.json` |
| Remaining x/y derivative correlation | 0.7581 | `summary.json` |
| Slot zero-coefficient parity | exactly 0 | `parity.json` |
| Added shift at reference colour | exactly 0 | `parity.json` |
| Unit/formula float32 maximum error | 1.49e-8 pixel | `zero_audit/parity.json` |
| Stage1/2 labels; stage3/4 labels | frozen; train_chroma | `parity.json` |
| Native checkpoint load and model setup preserve leaf | pass | `parity.json` |
| Matched shared-adapter frozen/trained arms at zero | exactly 0 difference | `zero_audit/audit.json` |
| Adapter zero vs unmodified renderer, active-pixel residual RMS | 2.318e-6 noise units | `zero_audit/audit.json` |
| Same relative L2 / maximum / 99th percentile | 3.095e-7 / 9.627e-4 / 0 | `zero_audit/audit.json` |
| Refined x derivative FD relative L2 error | 0.0915%, step 1e-4 | `precision/fd_17.json` |
| Refined y derivative FD relative L2 error | 0.0546%, step 3e-4 | `precision/fd_18.json` |

Initial coarser finite differences (steps 0.001–0.01) are less accurate, consistent with crossing interpolation-cell boundaries. The refinement enabled x64 for coefficient/coordinate arithmetic; native residual accumulation still casts to float32. It checks the construction, not a changed precision training policy. No absolute zero-parity claim is made across distinct float32 compiler graphs; shared-adapter comparison arms remove that discrepancy.

The Jacobian is conditional on fixed ePSF/WCS and baseline nuisance template values. It is not the Jacobian of every joint-fit parameter. The sample is deterministically drawn with seed 3104 from the same unique owned valid active pixels.

## Inspected supporting figures

All three figures were opened and inspected on 2026-10-04. The source stamps show actual native C4 data/model/residuals. The derivative images show position-dependent A3 radial shifts alongside fixed-axis CCD shifts and the remaining patterns after projecting out all 17 A3 columns. The three selected stars include crowded stamps; neighbouring-star features in the derivatives are expected because these are full scene, flux-profiled residual derivatives.

![Actual source data/model/residual stamps](source_stamps.png)

![Actual residual derivative stamps and A3-projected remainders](derivative_stamps.png)

![Sampled derivative correlation and singular values](jacobian_rank.png)

## Reproduction and handoff API

Activate `syndiff` first. Run each diagnostic with `taskset -c 8-15 env OMP_NUM_THREADS=8 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 python <absolute-owned-source-path>/<script>`:

- `ccd_shift_preflight.py`: actual native parity, 19-column JVP, rank, coarse FD.
- `ccd_shift_precision.py`: refined numerical FD (x64 diagnostic).
- `ccd_shift_zero_audit.py`: matched shared-adapter zero parity and active-pixel roundoff audit.
- `ccd_shift_figures.py`: three supporting figures.

For candidate training: `python <adapter> fit <native scene_fit arguments>`.
For matched A3 baseline: add `--freeze-ccd-shift`; use exactly the same zero initial leaf and input checkpoint.
For evaluation: `python <adapter> score <native score_oof arguments>`.

Programmatic training: install the desired production pin on `sys.path`; import adapter; call `install(initialize=True, freeze=<baseline>)` before checkpoint load/model creation/JAX tracing; set `args.chroma_ccd_shift_model=dict(provenance(), coefficients_frozen=<baseline>)`; call native `scene_fit.run(args)`. Scoring calls `install()` before native scorer `build` or `main`. The leaf is `chroma_ccd_shift`, shape `(2,)`, in `[tx,ty]` order. Native optional-leaf registries are patched only in that process, so the existing loader, checkpoint writer, and chromatic stage3 learning-rate bucket carry it. `set_chroma_model` preserves it. A baseline `freeze=True` preserves an incoming leaf rather than silently resetting it: explicitly assert the baseline initial leaf is zero. The common cold A3 initialization inserts zeros automatically.

**Conclusion:** ready for controlled A3 versus A3+2 cross-fitting; not a selected production model or evidence of intrinsic PSF chromaticity.
