Skip to content

Polarization: the validated vector-polarization arc (pol-core → dev) - #67

Open
ajax147 wants to merge 68 commits into
devfrom
pol-core
Open

Polarization: the validated vector-polarization arc (pol-core → dev)#67
ajax147 wants to merge 68 commits into
devfrom
pol-core

Conversation

@ajax147

@ajax147 ajax147 commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

What this is

The polarization arc developed and gated on pol-core since 2026-07-25: engine physics, the language-neutral API, the Jones-pupil/polarization-aberration layer, and the validation report. Every landing carries a review packet with non-vacuity checks, and — the load-bearing fact for dev consumers — polarization-OFF behavior is bit-identical, gated rather than asserted (Reference-twin gates, scalar-mode bit-identity of the vector refactor, GMI regression 6/6 bit-identical).

Contents

  • Phase 1 API (macos_api_mod): pol_set/pol_get, vecdif_set, coat_set/coat_get, rayfield_get; Ex0Ey0= parse + SAVE round-trip (was silently swallowed).
  • Engine fixes, all latent for years and invisible to intensity-level tests: uninitialized NaCmplx in the polarized propagation phase; coated-branch incident medium (stale nb_arr(0)); signed incident cosine (reciprocal-coefficient bug); and the reflected-p̂ / Fresnel r_p sign (2022 import) — single-mirror cross-polarization restored from Py/Px ≈ 1 to 2.07e-4 with the physical ρ² law; two-mirror results bit-identical across the fix.
  • Coated-Refractor transmission radiometry: one factor applied once after the Airy recursion; |T|² is again the power transmittance (pre-fix a coated lens under-reported detector flux by 1/1.5 on an index-matched control).
  • Phase 3 elements: TrPolarizerElt finished, new WavePlateElt; the off-normal material-axis convention (anchored on Korger et al., Opt. Express 21, 27032) gated at 20° AOI on both dispatch chains (tracesub + propsub).
  • Phase 3a Tranche 1: three-component vector propagation on every leg (PFFPROP retired into FFPROP×3; seed-once assembly; vignetting honored at the seed); cfield_plane_get for per-component fields.
  • Phase 2c contrast floor: analyzer derived from the pupil coherency matrix; co/cross/longitudinal split at the detector.
  • External anchors: van Harten, Snik & Keller (PASP 121, 377, 2009) reproduced in-engine with their inputs at 2.8e-14 / 4.9e-14 against their ±0.01; the protective-overcoat quarter-wave reversal engine-measured on both sides (25.9×) with an achromatic-counterfactual non-vacuity control.
  • Validation report (docs/macos-manual/polval/, 12 sections + 4-page executive summary): every number machine-generated from the gate suites; build guards block publication on any stale figure, number, or template.

Known boundary (labeled, not hidden)

Vector mode carries polarization onto the diffraction grid up to the first propagation leg (Tranche 1). A polarizing surface between legs transforms rays but not the grid; the per-ray running-Jones design (Tranche 2) is specified, not built. The report states this wherever capped numbers appear, a runtime warning fires, and tripwire tests force Tranche 2 to come back through them.

Evidence

  • mmacos fast suite green under gfortran (~500 tests, 0 fail); pymacos suites green under ifx — both compilers throughout the arc.
  • Ten review packets (REVIEW_POL_*.md) with the diagnosis/evidence/decision trail; POLARIZATION_PHASE0_AUDIT.md; PLAN_POLARIZATION.md.

Merge rehearsal (done before opening this PR)

Trial merge onto origin/dev: clean, zero conflicts; the merged tree differs from pol-core by exactly the two fixREADME line deletions — so pol-core's green suite status carries to the merge result verbatim.

Sequencing

Per the engine-first/resources-second rule (CLAUDE.md): after this merges, MACOS_resources pol-coredev (bindings + gate suites), then pol-ifodev (IFO arc + Bench pol emitters, which depend on the element types added here).

🤖 Generated with Claude Code

ajax147 and others added 30 commits July 25, 2026 14:47
…l-core kickoff)

Reviewed + rewritten from the Opus draft, engine claims line-verified:
Track A = IFO/bench metrology (visibility budget, PSI s/p systematic,
the AOI trade, Bench coating emission + polarizer/waveplate), Track B =
coronagraph polarization-limited contrast floor (Jones pupil -> co/
cross-pol decomposition -> incoherent sum).  Phases: 0 audit, 1 expose
(pol_set/vecdif_set/coat_set/rayfield_get + the silently-swallowed
Ex0Ey0 keyword), 2 Jones pupil (double-pole basis default, unitarity
gate) + contrast floor + IFO metrology, 3 elements (polarizer,
waveplate, VVC with first-class retardance error), 4 spatially-variable
coatings (zone-map form).  Includes verified coating-wavelength
semantics (stacks are stored physical; broadband already correct; SAVE
writer inverts), branching/sequencing (pol-core here; pol-ifo stacked
on bench-builder), and the CCMac/Claude-5 execution split with per-
phase acceptance gates.

Phase 0+1 are CCMac's entry point -- see "Branching & execution
sequencing" in the doc.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…am, resources@bench-builder)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Six-item audit gating the polarization work (no engine code):
- 0.1 vector-prop coverage: only the far-field FFT hop (PFFPROP) is
  vector-capable; near-field/plane/DFT legs + FFObscure are scalar.
  Confirms "vectorize the chain" = a real Phase 3a (VVC-gating);
  Track A (IFO PSI) unaffected.
- 0.2 srtrace.F ifPol: non-issue. Hardcoded .false. lives only in
  dead SRTRACE_Test (caller under #if 0); production SRTrace/CRTrace
  thread ifPol as an arg.
- 0.3 coating/wavelength semantics correct; coat_set(physical)
  sidesteps the waves-at-parse-lambda coupling; round-trip test noted.
- 0.4 precision clean: SREAL=REAL*8, all field/coating/FFT stages
  Complex*16/Real*8. No single-precision stage.
- 0.5 two coating subsystems (A: Coating/IndRefArr complex-index,
  polarization path; B: nCoatElt/AirGap NS-refractive real-index).
  Phase 1 targets A.
- 0.6 phase convention pinned: exp(+iwt)/exp(-ikz), n-ikappa,
  kappa>0=loss; consistent with recursion + IFO empirical finding.

Dave decisions (2026-07-25): extend Model A only (leave B); Ex0Ey0
carries source-pol STATE only (on/off stays with API/CLI).

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

Engine API (macos_api_mod.F90), beam_set/beam_get template:
- pol_set/pol_get: drive POLARIZATION/NOPOLARIZATION + source Ex0/Ey0
  (DARG(1..4) on the command line per LoadStack); assert mWF>=3 before
  enabling (rejects rather than silently degrading on a custom param
  file). pol_get reports ifPol/ifVecDif3 + Ex0/Ey0.
- vecdif_set: VECTOR/SCALAR; returns FAIL (not the CLI's silent reset)
  when polarization is off or mWF<3.
- coat_set/coat_get: Model-A thin-film stack (EltCoat/IndRefArr/
  ExtincArr/EltCoatThk) in PHYSICAL thickness units (sidesteps the
  waves-at-parse-lambda coupling); populates boundary media from
  adjacent-element IndRef/Extinc as the parser does; sets modified_rx.
  coat_get o coat_set == identity.
- rayfield_get: harvest RayE(3,:) + ray direction cosines + element
  surface normal + per-ray RayStatus on the ray grid -- the full
  signature Phase 2 (Jones pupil) needs for a correct transverse basis
  and honest vignetting statistics.

Ex0Ey0 keyword fix (msmacosio.inc + iosub.inc):
- was a silent GO TO 50 swallow; now parses four reals (ExRe ExIm EyRe
  EyIm) into Ex0/Ey0 (STATE only -- on/off stays with API/CLI per Dave).
- SAVE writer (PrtSourceInfo) emits Ex0Ey0= after Flux=, gated on a
  non-zero state so polarization-free Rx SAVE stays byte-identical.
- SAVE_KEYWORD_AUDIT.md updated.

Verified: gfortran build clean; CLI load->SAVE round-trips
Ex0Ey0= 1 0 0.5 0.25 exactly; polarization-free Rx emits zero Ex0Ey0
lines (byte-identical SAVE). Bindings + matlab/pytest tests next.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Documents the polarization physics map + the Phase-0 conventions:
what exists (RayE 3-vector, Fresnel/thin-film coatings, vector
diffraction = far-field FFT leg only), the stubs (RfPolarizer/
TrPolarizer, dead JmatElt, srtrace dead-code ifPol), the pinned
conventions (exp(+iwt)/exp(-ikz), n-ikappa, linear Jones basis,
coating waves-at-parse-lambda), the two coating subsystems (extend A,
leave B), and the Phase-1 API surface.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The ifPol propagation block in Reflector used NaCmplx in
C2=DCMPLX(0d0,S1)*NaCmplx before its first assignment (which sat in the
nCoat==0 branch below).  ifx stack garbage made every polarized trace
all-NaN (RayE + intensity); gfortran's zeroed stack made C1=exp(0)=1,
silently DROPPING the propagation phase from RayE -- wrong for the
Phase-2 Jones work even where it looked fine.  Refractor already sets
NaCmplx before use (elemsub.F:1022); Reflector now mirrors it.

Found at the Phase-0/1 gate review: pymacos (ifx-linked) failed the new
test_polarization ray-field/intensity tests with NaN while mmacos
(gfortran-linked) passed on the same Rx.  After the fix ifx and gfortran
agree bit-identically (max|Ex| 0.00882196, intensity sum 0.893766 on
Rx_Cass_FarField).  mmacos tPolarization 10/10 + fast 261/261; pymacos
test_polarization 10/10 + PROPER phases all green, both compilers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Full section added (math basis checked + code map + two tranches +
validation ladder + execution split), from a pol-core code review:
- Per-component Cartesian propagation through the scalar kernels is
  rigorous (componentwise Helmholtz); Fresnel/S-S legs inherit exactly
  the scalar paraxial envelope; coupling lives at surfaces (rays) and
  in the divergence constraint (ray-sampled, paraxial-consistent).
- Two pre-existing defects to fix first: PFFPROP omits FFPROP's
  1/(i*lambda*dz)*dx^2 + output-chirp factors (fatal for chains); the
  ifPol assembly RELOADS WFElt from RayE at every physical leg
  (propsub.F:1389), erasing prior diffraction -- seed-once-then-update
  semantics mirroring the non-pol branch (which multiplies by the
  incremental CumL phase).
- Tranche 1 = call-site K=1,3 loops (all 8 kernels mapped by line) +
  3-plane FFObscure + assembly fix + far-field unification -> closes
  mask-type (coronagraph) chains; Ca2Int already vector-aware, ReGrid
  ray-side only.  Tranche 2 = running per-ray 3x3 J_run for chains
  with coated/reflective surfaces between legs (IFO DO_NEARFIELD).
- Validation: energy conservation, x-pol==scalar per leg, polarized
  re-run of the PROPER cross-checks at committed tolerances, chain
  closure on CoroExample, single-hop A/B for the normalization change.
Open-questions bullet resolved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The POLARIZATION command changes trace-relevant state (ifPol; Ex0/Ey0
seed RayE at source-grid setup) but does not reset the cached trace, so
a pol-state change followed by a re-trace harvested the PREVIOUS
state's RayE (verified stale: y-polarized re-trace returned the x-trace
field).  Same dirty-the-trace convention as coat_set / the grid
setters.  vecdif_set gets the same treatment (VECTOR/SCALAR changes
propagation state).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both in the ifPol multilayer recursion, both invisible to
intensity-level tests, both fatal to Jones-pupil work; found and now
pinned at 1e-12 by the Fresnel-analytic gate (tJonesPupil, mmacos).

1. Incident medium: the recursion read nb_arr(0) =
   IndRefArr(0,iElt) = IndRef(iElt-1).  For a coated mirror following
   another mirror that slot holds the previous mirror's
   conductor-idiom substrate (Extinc=1e22) -- light modeled as
   arriving from inside a perfect conductor.  Use na,kxa
   (CurIndRef/CurExtinc, the medium the ray actually travels in; what
   the uncoated branch always used) at the chain start and at the
   ic=1 outermost interface.

2. Signed incident cosine: ccfb_arr(0)=DDOTC(ihat,Nhat) is negative
   when the normal faces the beam (psi convention), turning every
   interface coefficient into its reciprocal (1/r): |R|>1, s/p roles
   swapped, retardance sign flipped -- while |D| survives, which is
   why nothing ever caught it.  DABS, mirroring the uncoated branch's
   ccfa.  Diagnostic signature if it returns: measured/analytic RS/RP
   ratio = (RP/RS)^2 exactly.

After both: coated 45-deg Al fold matches closed-form Fresnel per ray
at 1e-14 (magnitude and phase); stock conductor unitarity gate
unchanged at round-off.  ifPol-gated throughout -- polarization-off
traces (GMI corpus) untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CLAUDE.md polarization section: the two coated-branch fixes, the
pol_set dirty-trace fix, the engine launch frames (collimated uniform
xGrid/yGrid vs point-source per-ray yray=unit(RayDir x xGrid) frame),
the conductor-idiom-as-unitarity-gate note, and the Phase-2 binding
surface.  PLAN: Phase-2 status block (gates + numbers).

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

Command Reference:
 * make cmdref-regen -- catalogs the six Phase-1/2 binding functions
   (polarization, vector_diffraction, coating, ray_field, jones_pupil,
   pol_maps) in Part II, and catches Part III up with the bench-builder
   classes (design.Bench, ideal_lens, twyman_green).
 * NOTES prose for all six: physical-vs-waves coating thickness, the
   launch frames (collimated uniform vs point-source per-ray), the
   double-pole default + local-sp diagnostic-only warning, mean-vs-
   variation separation, near-pi ambiguity flag, conductor idiom as a
   free unitarity gate, load_rx-clears-coatings.
 * Part I enrichment: POLarized (physics summary, conventions, Ex0Ey0=
   cross-ref, binding pointers), VECtor/SCAlar (far-field-only scope
   caveat; mWF planes repurposed as Ex/Ey/Ez).

Manual:
 * Section 4: new 'Coatings and Polarization Data' -- IndRef/Extinc as
   complex index, the perfect-conductor mirror idiom, Coating= syntax
   with the waves-at-parse-Wavelen rule and the after-IndRef ordering
   rule, thick-metal-layer modeling guidance, Ex0Ey0= keyword.
 * Section 5: new 'Polarized Ray Tracing' subsection -- what the
   polarized trace models, launch frames, conventions (n - i*kappa,
   exp(+i*omega*t)), pointer to the Jones-pupil analysis layer.
 * Section 6: vector-diffraction scope caveat under VECTOR.

PLAN_POLARIZATION: standing rule -- every phase's definition-of-done
includes its cmdref entries + manual section, so the gap does not
re-open at Phase 3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… 2026-07-26)

CCMac is out of tokens for the month and Fable time is the scarce
resource: anything Opus-executable is handed to Opus.  The Opus lane is
model-defined, not machine-defined (CCMac when tokens reset, or an Opus
session on the Linux box meanwhile; the ifx smoke stays Linux-only).

Opus worklist, priority order, each with spec + gates already in the
document: (1) Ph3a Tranche 1 incl. the two 3a.1 fixes to spec (revised
from written-here: Fable line-reviews the finished diff instead),
(2) Ph2b low-order expansion, (3) Ph2c contrast floor, (4) Ph3
polarizer+waveplate, (5) Ph2d mechanical half (Bench coating wiring,
visibility driver), (6) Ph4 spatial coatings.  Every item ships its
cmdref + manual entries (standing rule).

Fable lane trimmed to: gate reviews, the VVC, Tranche 2 (J_run), and
the Ph2d interpretation half (PSI systematic / AOI-trade error-budget
conclusions).  3a.5 updated to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Second review pass over the Phase 3a (vector near-field) section with
what Phase 2a/2b taught us, re-verified against propsub.F:

 * The seeded field now depends on THREE engine fixes (NaCmplx e2f680a
   + the two coated-branch fixes d137a97), not one -- a coated surface
   upstream of the seed leg poisoned the field until yesterday.
 * pol_set's new modified_rx (bef4598) makes the seeded-flag lifecycle
   automatic off the trace-start reset.
 * Explicit scope decision for the ifPol-SCALAR assembly branch
   (propsub.F:1397-1414, same erase-diffraction class): Tranche 1 fixes
   BOTH branches with the incremental-multiply update; the |RayE|
   amplitude reload it replaces is only load-bearing for between-leg
   amplitude changes, which the Tranche-1 mask-type validity condition
   excludes (Tranche 2's J_run handles them).
 * Validation test 2 frame note: 'Ex-only' = the engine launch frame
   (collimated uniform vs point-source per-ray).

Core math and structure unchanged -- the section remains the Opus-lane
item-1 spec.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
New 'Validation document' section: reviewer-facing report with PNG
evidence from the validation suite, at docs/macos-manual/polval/ built
by the existing pandoc toolchain (make polval).  Every figure and
quoted number regenerated by one driver (no hand-copied numbers);
structure mirrors the validation ladders, one evidence section per
gate; Phase 0-2b evidence (unitarity maps, Fresnel-fold residuals,
2-theta orientation, basis-artifact figure, engine-fix provenance) is
producible today.  Skeleton + figure driver added as Opus-lane item 7
(interleave work); the standing definition-of-done rule now includes
each phase's validation-report evidence section alongside cmdref +
manual entries.

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

Promotes vector diffraction from "far-field FFT leg only" to every
propagation leg, so a physical-optics CHAIN (pupil->FPM->Lyot->focal)
preserves the vector field.  Unblocks the Phase-3 VVC acceptance test.
All in propsub.F; no api_mod change, no new bindings.

3a.2 -- per-component leg loops.  One kWF1..kWF2 range computed once
before the leg dispatch (1..3 under ifVecDif3, else iWF..iWF), so every
DO kWF=kWF1,kWF2 degenerates to the original single call in scalar mode
and those paths stay bit-identical.  Covers NFPROP (PropType 2,5), PPPROP
(4,6), SFPROP (7,8), SPH2PL/PL2SPH (10,11), FRPROP (12), NFPropDFT
(13,14), FFPropDFT (15).  Leg dx/z bookkeeping stays outside the loop.
FFObscure is applied per plane (a 0/1 transmittance is a diagonal Jones
t*I), each call handed a fresh xObs copy because FFObscure
re-orthogonalizes its xGrid argument in place.  The 13 ray-side clip
sites and 2 taper sites go through new WFZeroPt/WFScalePt helpers.

3a.1(1) -- PFFPROP retired.  It was a bare per-component FFT omitting the
Fresnel output factors FFPROP applies via applyfac2 (1/(i*lambda*dz)*dx1^2
plus the output quadratic phase): harmless for a terminal intensity hop,
fatal in a chain where the missing output curvature is the next leg's
input.  The far-field leg now runs FFPROP per plane, so vector and scalar
share one kernel by construction.  A/B on Rx_Cass_FarField at model 128:
vector total power 8.9377e-01 -> 1.8155e+06, now exactly equal to the
scalar total (Parseval).  Intended normalization change, documented.

3a.1(2) -- assembly seeds once, then updates.  Both ifPol branches
reloaded the grid from RayE at every physical-leg assembly, erasing
earlier legs' diffraction, while the non-pol branch multiplied by the
incremental geometric phase.  A SAVE'd LWFSeeded (reset with CumLStart at
trace start) now seeds on the first assembly and multiplies thereafter,
advancing CumLStart identically in both branches.

Two deliberate departures from the written spec, both flagged in
PLAN_POLARIZATION for the review:

  - Coverage extended to SPH2PL/PL2SPH and to the ray-side clip/taper
    sites.  Same scalar-only class; the seed-once fix makes the ray-side
    masking load-bearing where it previously did not matter.
  - A THIRD defect of the 3a.1 class was found and fixed: RayE carries no
    aperture clipping (surface routines report it via LRayTrans and never
    zero Evec), so seeding from RayE resurrected vignetted rays.  Both
    polarized branches now gate the seed on LRayPass.  Consequence:
    polarization-ON/vector-OFF is now BIT-IDENTICAL to polarization-OFF;
    it was wrong by 21% after one leg and 38% after two.

The seed applies NO phase-convention bridge, and that is measured rather
than derived -- elemsub.F:395 read alone suggests RayE is conjugate to
WFElt, but a c-scan of RayE*exp(i*c*TPL*CumRayL) (far-field centroid shift
= (c+1)x the scalar tilt shift) and the Rx_VecChain gate both put c=0.
The residual sign question is unresolved and called out for review in both
PLAN_POLARIZATION and the macos_f90/CLAUDE.md Phase-3a section.

Gates (both compilers built; gfortran for mmacos/GMI, ifx for pymacos):
  ladder 1  energy per leg      vector total == scalar total, 0..2.2e-16
  ladder 2  x-pol == scalar     4.5e-16..6.8e-16, also 45deg and circular
  ladder 3  polarized PROPER    scalar and pol-scalar reproduce the
                                committed 4.836e-13 macos<->PROPER
                                residual exactly; vector differs 1.3e-2,
                                consistent with |Ez|/|E|~2.7e-2 there,
                                at identical total power
  ladder 4  chain closure       two-leg mask chain vector == scalar at
                                round-off; mask throughput equal to 1e-14
  ladder 5  single-hop A/B      as above
  mmacos    412 pass / 0 fail   pymacos 6645 pass, PROPER-compare 26/26
  GMI       6/6 bit-identical (vs-ref = 0.000e+00)

Non-vacuity was checked by rebuilding the pre-fix engine: it fails the new
gates at 0.21..0.38 relative error and mis-states total power by 4-7%.

Docs: manual section 6 VECTOR/SCALAR scope rewritten, cmdref VECtor/SCAlar
and vector_diffraction NOTES, new macos_f90/CLAUDE.md Phase-3a section.
Tranche 2 (per-ray running Jones for coated surfaces between legs) is
untouched, as scoped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Review of a0f6dba (engine) + resources 9f461e0.  Diff verified
mechanically (kWF loops with bookkeeping outside, seed-once lifecycle +
LRayPass gate, FFObscure fresh-xObs-per-plane, PFFPROP retirement);
gates re-run independently (tVecChain 5/5, tJonesPupil 5/5,
tPolarization 10/10 gfortran; pymacos 29/29 ifx-linked = standing
smoke).

The flagged sign question is resolved, not merely re-measured: the
Return-leg 'RayL=-RayL' flip (applied after the surface call) makes the
two phase bookkeepings diverge by construction -- CumRayL SUBTRACTS
return legs while RayE's per-surface C1=exp(-i*2pi*L*N/lambda) phases
ADD them.  The RayE-vs-scalar-WFElt phase relation is therefore
TRAIN-DEPENDENT: measured same-convention at the Cass FF exit pupil
(circular concentration 0.994 same / 0.002 conjugate; signed far-field
tilt response equal), measured conjugate on the plain trace-to-detector
flow (slope -0.9995 vs the OPD map).  No universal bridge exists; the
no-bridge seed is correct WITH the behavioral gates carrying the claim,
and Tranche 2's J_run must track phases explicitly against the CumRayL
bookkeeping rather than assuming a sign.  Docs updated in both places
that carried the unresolved flag; plus the obscured-ray ATAN2(0,0)
debug gotcha that cost this review an hour.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fable gate-review adjustment.  "Vector differs 1.3e-2 from scalar,
consistent with |Ez|/|E| ~ 2.7e-2" was plausible-number reasoning
presented as a finding.  Per-plane content is NOT directly measurable
today -- there is no plane-selectable complex-field getter -- so the
attribution cannot be checked, only the magnitude bounded.

Marks it unverified in the status table and carries it forward as an
open item: a complex_field(srf,'plane',k) getter would close it out, and
Phase 2c's co/cross-pol decomposition wants the same thing, so that is
probably where it should land.

Also records that Tranche 1 shipped no validation-report evidence
section -- the standing rule adding it to every item's definition of
done (worklist item 7) postdates this landing, so it needs back-filling
once the polval/ skeleton exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
docs/macos-manual/polval/ -- the reviewer-facing companion to the
polarization test code.  Six sections: provenance/frontmatter,
conventions + engine-fix provenance, Phase 1 exposure gates, Phase 2a/2b
Jones pupil, Phase 3a Tranche 1 vector chain, gate index + coverage and
gaps.  Six generated figures.  Targets: polval, polval-pdf,
polval-regen, polval-check.

Beyond the stated scope, this also back-fills Tranche 1's evidence
sections -- the gap that landing explicitly left open, since the
standing rule postdated it.

No hand-copied numbers, enforced rather than aspirational:
  * prose lives in polval/*.md.in and contains NO numeric literals,
    only @@token@@ placeholders; polval/*.md are generated;
  * render_polval.py resolves every token before writing anything, so a
    failed render leaves no half-updated .md on disk;
  * tools/check_polval.py is a prerequisite of `make polval` and
    rejects a template edited without re-rendering, a figure newer than
    numbers.json, or a surviving placeholder;
  * the report stamps engine + binding SHA, branch, model size, MATLAB
    and host;
  * the driver asserts 19 gate thresholds mirroring tPolarization /
    tJonesPupil / tVecChain and ABORTS on regression, so the report
    cannot document a broken gate as round-off.  Guard verified
    non-vacuous against degraded values for all three comparison
    operators plus the missing-measurement path.

Numbers this box cannot produce (pymacos/ifx, PROPER compare, GMI, and
the HISTORICAL pre-fix engine A/Bs) live in the driver's external.json
with their producing command and capture date, and are labelled
(external, captured DATE) in the report -- not omitted, not presented as
regenerated.

Finding, made while writing the unitarity section: the
transmission-uniformity gate reports std/mean ~ 5.1e-14, but the true
spread of that map is 6.1e-15 p-v (30 distinct doubles) -- mean() over
11484 points accumulates 5.1e-14 of summation error, LARGER than the
quantity being measured.  The gate is a valid upper bound and is left
as reviewed; the report publishes the median-referenced spread and RMS
alongside it plus the summation floor itself, and the figure panel is
referenced to the median (the mean was painting a spurious uniform
offset across the whole pupil).

Driver lives in MACOS_resources (mmacos/tools/pol_validation_report).
mmacos fast suite 281 pass / 0 fail; all three document formats build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Validation report gains section 2.5 (the two-mirror literature form) and
a new figure: the coefficient bar chart IS the comparison -- two bars
stand up, everything else is floor -- beside the measured map, its
Zernike reconstruction and the residual.  Six new measured tokens, six
new driver gate thresholds (25 total).

Scope stated rather than glossed: this matches the ANALYTIC FORM the
literature predicts (2-theta azimuth, quadratic radial law, vanishing
circular component), NOT a numeric regression against a specific
published system.  Ladder rung 5 accordingly moves from "not done" to
"partly done", with what is still missing spelled out.

Also in the report: the fit quality now reports the UNCAPTURED fraction
(3.0e-10) and the relative residual RMS (1.8e-5) instead of "explained =
1.000000", which told the reader nothing and read as an exact claim.

cmdref NOTES for pol_zernike (mode convention, why least-squares, the
mean/variation separation, the expected two-mirror answer as a debugging
aid, and the ambiguous-point exclusion).

Manual section 5: describes the expansion and its two-mirror result --
and fixes a STALE line left by the Tranche-1 landing, which still told
readers only the far-field leg was vector-capable.

Engine cheatsheet records why this matters engine-side: the mode pattern
is now the sharpest cheap check that the coating/s-p machinery and the
pupil reference frame are both right, since a broken frame breaks the
pattern and not just the map.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
cfield_plane_get in macos_api_mod -- purely additive (61 insertions, 0
deletions), built under both compilers.  iPlane=0 is cfield_get exactly
(bit-identical, what the bindings pass by default); iPlane=1..3 are the
Ex/Ey/Ez component planes and are REFUSED unless ifVecDif3, because in
scalar mode plane k is an unrelated wavefront rather than a field
component -- returning it would look plausible and be wrong.

WHY: Phase 3a Tranche 1 could only GUESS why the vector run differs from
the scalar one on an off-normal train, because the per-plane contribution
to a propagated intensity was unreachable.  It is now measurable, and the
guess was HALF RIGHT.  Two mechanisms, both driven by the out-of-plane
content:

  1. POWER REDISTRIBUTION (dominant).  The scalar run seeds from |RayE|,
     so ALL the power -- including what is physically out-of-plane --
     propagates in ONE plane, while the vector run leaves only
     f = 0.997890 in Ex.  A near-pure rescale: 1 - corr = 4e-8.
  2. Ey and Ez diffract to their own pattern.

Iv ~ f*Is + Iy + Iz takes the difference from 2.5638e-3 to 2.8983e-4.
The naive expectation -- that the difference equals the out-of-plane
intensity, 2.11e-3 -- is wrong by ~2x, which is exactly why it needed
measuring rather than asserting.  What remains at 2.9e-4 is a shape
difference between the scalar field and Ex, consistent with their
different seeds; labelled not-further-verified, and nothing depends on
it.

Report section 3.5 rewritten from "an unverified attribution, carried
forward" to "the attribution, now measured", with the decomposition
table; the coverage section's open item is struck.  Six new measured
tokens, three new driver gate thresholds (28 total).  cmdref NOTES and
manual section 6 document the plane selector, including why a component
plane is refused in scalar mode.

Also adds REVIEW_POL_2026-07-26.md: a gate-review packet for the Fable
lane covering worklist items 7 and 2 and this landing, with the four
JUDGMENT calls ranked for a token-short pass and the REFUTED hypotheses
recorded so they are not re-investigated.

Phase 2c is NOT in this commit -- see PLAN_POLARIZATION item 3 for the
two design findings that stopped it and the parked WIP.

Gates: mmacos fast 287/0, pymacos 6651, PROPER-compare 26/26, GMI 6/6
bit-identical (vs-ref = 0.000e+00), both compilers built, all three
documents build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Refreshes media/ + numbers.json so the report's provenance points at real
commits rather than at a dirty working tree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
engine dd8f5dd / resources f10b234, both dirty=false -- the numbers in
this report are now reproducible from published commits, which is what
the provenance block exists to assert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Corrects the MACOS_resources SHA (the binding commit was rewritten before
push to strip an accidental 740 MiB artifact payload), and adds the
provenance-stamp fix and the git add -A near-miss, both of which postdate
the sections already written.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1. polval provenance re-stamp.  The published report stamped resources
   f10b234 -- a commit DESTROYED by the 740 MiB payload-strip reset,
   existing only in this box's reflog.  A reproducibility stamp pointing
   at an unfetchable commit defeats its own purpose.  Re-stamped to the
   pushed 9f2eed4, whose code content is identical for everything the
   run consumed (verified: the only diff vs the dangling tree is the
   unrelated, accidentally swept Rx_e5hex1.in).  Re-rendered; the E->e
   exponent-case churn in numbers.json is the Python json rewrite,
   values bit-identical.  check_polval clean.

2. cfield_plane_get: vector branch now enforces the same ownership rule
   as iPlane=0 (iEltToiWF(iElt) > 0).  iPlane selects the storage slot
   directly, so without the guard a direct API caller querying before
   any propagation got the untraced WFElt buffer back as a "field" --
   the plausible-and-wrong read the routine's own comment promises to
   prevent.  Severity LOW: unreachable through the shipped bindings
   (complex_field always propagates to the queried element first --
   measured).  Pinned at the raw-API level by
   test_component_plane_refused_before_any_trace (MACOS_resources).

Both compilers rebuilt; mex + f2py relinked.  Gates post-fix: tVecChain
8/8, test_vec_chain 18/18 (+1 new), test_jones_pupil green (ifx smoke).

Review verdict on the rest of b3e0322/dd8f5dd/3721dde and the payload
recovery: sound -- appended to REVIEW_POL_2026-07-26.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 2026-07-26 session ran five landings in one continuous run and its
errors (the 740 MiB add -A sweep, the dangling f10b234 provenance
stamp, a self-watching watcher) all clustered at the end -- a
session-length failure mode, not a competence one.  Five rules: one
worklist item per session; stage by explicit path with a staged-size
check; grep for old SHAs after any commit rewrite; watchers watch
external state; stop-and-write-down at the two-failed-fixes /
slow-push tripwires.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase 2c cannot produce an honest contrast floor yet.  Not because of the
2c design -- that is now settled and simpler than either earlier sketch --
but because the pupil polarization state is untrustworthy on any train
with an ODD number of mirrors.

Reflector assembles Eout in a p-hat-follows-the-outgoing-ray basis
(prhat = shat x rhat, elemsub.F:431/592) but multiplies the p-component
by -r_p (:455; the standard +r_p sits commented out one line above as
"dcr's original").  Near normal incidence that reflects the transverse
field about the local p-hat instead of negating it.

Measured on Rx_Cass_FarField -- the Phase-2 gate fixture -- x-polarized,
perfect conductors, model 256:

  after 1 mirror   Py/Px = 1.0163e+00   (50/50 x/y, at <2 deg AOI)
  after 2 mirrors  Py/Px = 7.0612e-07

Physics allows O(sin^2 beta) ~ 1e-3 for an isotropic surface.  Two
independent reasons it cannot be physics: the magnitude is FLAT IN PUPIL
RADIUS (1.014/1.016/1.010/1.005 at rho = 32/64/96/128 px) where a real
AOI-driven effect must vanish on axis and grow as rho^2; and a scratch
build with +r_p restored gives 2.07e-4 for one mirror while leaving the
two-mirror number BIT-IDENTICAL.  Ruled out as the point-source launch
frame by a control on Rx_VecChain (that contributes ~NA^2/2, measured
1.02e-5 at NA 0.0045).

Nothing landed: the scratch patch was built, measured and reverted; both
compilers rebuilt, mex relinked, fast suite back to 287 pass / 0 fail.

Why every gate is green today -- four independent reasons, all holding at
once: the defect is an INVOLUTION so a mirror pair cancels it exactly and
Rx_Cass_FarField has exactly two; Rx_VecChain has no reflectors; the
defect is UNITARY so the unitarity gate cannot see it; and the Fresnel
gate builds its "analytic" RPa from the engine's own expression
(tJonesPupil.m:166) and compares a ratio, which is circular in this sign.

Decision packet (Fable lane -- this is a convention change in the Fresnel
core, and it moves two landed basis-artifact assertions): the new
REVIEW_POL_SP_SIGN_2026-07-27.md.  Engine-side summary added to the
polarization section of macos_f90/CLAUDE.md.  Reproducer lives in
MACOS_resources (mmacos/tools/pol_sp_sign_probe/).

Also recorded in the item-3 block, from the same session:
  * the settled 2c design -- the chain is linear in the input Jones state
    (4.2e-16), so a uniform analyzer COMMUTES with propagation and the
    co/cross split is taken at the detector on the engine's own component
    planes.  No pupil multiplier at all, which retires both the
    Jones-pupil-multiplier design and its "divide by the scalar run"
    successor.  Analyzer = dominant eigenvector of the pupil coherency
    matrix (phase-insensitive, and by construction the analyzer that
    minimizes cross-pol -- the operational form of Finding 1).
  * Rx_Coro.in needs model >= 512 (nGridpts=511).  Below that the engine
    "resets npts" and then SIGSEGVs intermittently -- ~1/3 of runs at 128.
    Corrects the earlier "runs at model 128" note.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The 2022 bulk import ("fixed by jzlou") negated the standard Born&Wolf
r_p while the assembly basis (prhat = shat x rhat) follows the OUTGOING
ray -- the convention that REQUIRES the standard sign.  Effect: the
transverse field was REFLECTED about the local p-hat instead of negated.
The error is an involution (cancels EXACTLY on mirror pairs) and
unitary, so every two-mirror / unitarity / magnitude-ratio gate passed
while a single near-normal mirror turned x-pol into Py/Px = 1.0163
(physical bound O(sin^2 beta) ~ 1e-3).  Diagnosed by Opus
(REVIEW_POL_SP_SIGN_2026-07-27.md + pol_sp_sign_probe reproducer);
decision + independent verification + landing by the Fable lane
(decision section appended to the packet).

Fix: uncoated RP -> the commented "dcr's original" line (which was
correct all along); coated innermost RP + per-layer RP1 -> standard
form.  The Airy recursion propagates the interface flip exactly (the
denominator's r*r product is sign-invariant), so the coated final RP
was exactly -(standard multilayer r_p) with |RP| unchanged -- one clean
sign restoration, no magnitude change.  Refractor deliberately
untouched: its transmitted output contains only r*r products (invariant
under the consistent flip) and its TP1 is already standard; normalizing
its internal convention is the scoped audit.

Verification: probe A/B reproduces the packet bit-for-bit (one mirror
1.0163 -> 2.0724e-4; two mirrors 7.0612e-7 BIT-IDENTICAL, so all
published two-mirror evidence survives), and post-fix the single-mirror
cross-pol grows as rho^2 (3.8/8.5/14.7 vs rho^2 = 4/9/16) where pre-fix
it was FLAT -- slope-driven AOI physics restored.  PEC idiom is now
RS=-1, RP=+1 (ray-following basis), E_out = -E_in at normal incidence.

One packet conclusion corrected: the scratch 285/2 suite prediction came
from a HALF-patched engine (uncoated branch only; the Al-coated
secondary stayed flipped).  On the fully corrected engine the local-sp
retardance artifact is real at 247x, so the two basis-artifact
assertions are KEPT unchanged.  The only test change is the fold gate's
analytic RPa/RP2, transcribed from the textbook instead of from the
engine's own expression -- it was circular in exactly this sign
(MACOS_resources side).

Gates: mmacos fast 287/0 (incl. de-circularized fold gate), pymacos
test_jones_pupil 8/8 + test_vec_chain 18/18 (ifx smoke), both compilers
built, mex + f2py relinked.  PLAN_POLARIZATION 2c flipped to UNBLOCKED;
follow-on tail (odd-mirror rho^2 gate, Refractor audit, polval regen +
PROPER/GMI re-runs) listed in the packet for the Opus lane.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Item 2 of the r_p sign-fix tail (REVIEW_POL_SP_SIGN_2026-07-27.md,
Fable-lane decision).  Refractor's coated branch carried its own copy of
the Airy recursion with the same negated r_p the 2022 import put in
Reflector -- innermost RP plus per-layer RP1.  Both are restored to the
Born & Wolf form.

Here the flip was INTERNAL, not emitted: Refractor assembles its output
from TP/TS (transmission, where p-hat does not flip and TP1/TP were
already standard), and RP reaches the transmitted field only through the
products RP1*RP in the Airy denominators, which are invariant under a
CONSISTENT flip.  Verified rather than assumed, on a Bench-emitted
singlet with a 3-layer absorbing stack on the powered face (209 rays,
45-degree linear AND circular input): the transmitted Ex/Ey/Ez are
BIT-IDENTICAL before and after.

That A/B is not vacuous.  Flipping only RP1 (the inconsistent
normalization a careless edit would produce) was built and measured:
transmitted x-power moves -3.24%, max per-ray |dEx|/|Ex| = 1.87e-2.  So
the branch does run and RP is load-bearing; it is the consistency that
makes the result invariant.  The stale "!RP1=-RP1 ! testing" line is
dropped with it.

AUDIT FINDING, recorded but NOT fixed here -- coated and uncoated
Refractor transmission are on DIFFERENT amplitude normalizations.  The
uncoated branch multiplies by the radiometric factor
sqrt(n2 cos02 / n1 cos01) (elemsub.F S1, ~:1147); the coated branch
omits it entirely.  Measured with an index-matched single layer (n=1.5
on an n=1.5 substrate, optically a bare interface): coated/uncoated
|Ex| = 0.816442 at normal incidence = 1/sqrt(1.5) exactly, falling to
0.804789 off-axis.  A coated lens therefore under-transmits by ~18% in
amplitude relative to the same surface uncoated.  Fixing it changes
results and deserves its own decision + gate, so it is logged in
PLAN_POLARIZATION and macos_f90/CLAUDE.md instead of being folded in
here.  Note also that the coated Refractor branch has no analytic gate
at all today -- the Fresnel gate covers Reflector only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The report gains §4 (polval/50_sp_sign.md.in): the odd-mirror evidence
for cb29ea5 / 25c4386, which is the one place the defect was ever
visible -- every other measurement in the report is on an even-mirror
train, and that was load-bearing rather than incidental.  The section
carries the perfect-conductor closed-form comparison (median 2.1e-15),
the radial law (slope 1.871 against the required 2), the O(sin^2 AOI)
bound, the measured pre-fix A/B, and the Refractor scope note.  Gate
index rows 4.1/4.2; engine-defect entry #4 in the conventions section,
including the admission that the §2.2 fold gate could NOT have caught
this because its analytic was transcribed from the engine's own
expression.

Every figure and number regenerated by make_polval.sh; 33 gate
thresholds pass.  Across the engine fix the report's physics numbers
did not move: 33 of 67 numeric tokens bit-identical, the rest within
round-off, largest mover the unitarity gate's peak retardance
IMPROVING from 2.46e-15 to 5.79e-16.  Running it was the check.

macos_f90/CLAUDE.md: the OPEN block is marked CLOSED (kept as the
reference case for how a whole gate set can be structurally blind),
and the fix block gains the landed tail -- the two odd-mirror gates,
the Refractor normalization with its bit-identical A/B, and the
inconsistent-flip control that proves that A/B non-vacuous.

NEW OPEN FINDING recorded in CLAUDE.md, PLAN_POLARIZATION and the
report's coverage section: coated and uncoated Refractor transmission
use different amplitude normalizations -- the uncoated branch applies
the radiometric sqrt(n2 cos02/(n1 cos01)) factor, the coated branch
omits it, so a coated lens under-transmits by ~18% in amplitude
(measured 0.816442 = 1/sqrt(1.5) exactly, index-matched layer).  The
coated Refractor branch also has no analytic gate at all.  Not fixed
here: it changes results and wants its own decision and gate.

PLAN_POLARIZATION §2c: the Opus tail is marked CLOSED with its
numbers.  §2c itself (analyzer-at-detector) remains the next session,
untouched here.

Gates: mmacos full suite 420 pass / 0 fail; GMI 6/6 with
vs-ref = 0.000e+00; pymacos PROPER-compare 26/26 (ifx); pymacos
polarization tests 36 pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ajax147 and others added 13 commits July 28, 2026 00:18
Docs side of MACOS_resources a89b077.  Closes PLAN_POLARIZATION worklist
item 6b (the MgF2/Al external cross-check Fable added in REVIEW_POL_2C).

New polval SECTION 8 (85_external_anchor.md.in) + 7 gate-index rows: the
thin-film machinery is now anchored to an OUTSIDE source on a
dielectric-on-metal stack -- the configuration class a protected mirror
belongs to, and the one no previous gate covered.  Engine vs the
publication's own model, at the publication's own inputs: 2.828e-14
(diattenuation) / 4.937e-14 (retardance) against their stated +-0.01 per
normalized Mueller element.

CORRECTION to section 5.5.  Its measured numbers stand and are reproduced
two independent ways in section 8.3, but the sentence generalising them was
backwards.  Rx_Cass_FarField runs at Wavelen = 1.0E-06 m while the 2c
coating constants are commented "Al at 632.8 nm" and "~quarter wave at
632.8 nm"; at 1 um the 110 nm MgF2 film is 0.607 quarter-waves, not a
quarter wave.  The overcoat trade REVERSES across that condition -- a true
quarter wave (181.2 nm at 1 um) SUPPRESSES the floor to 0.0157x of bare
aluminium instead of raising it -- so "the protective overcoat costs most
of another decade" is withdrawn and replaced by a correction notice
pointing at 8.3.  The measured 151.3x is kept, reframed as a datum for one
specific sub-quarter-wave film rather than a protected-aluminium design
rule.

macos_f90/CLAUDE.md gains the anchor summary and, more usefully, the two
measurement traps it exposed -- a fold mirror's DEVIATION is 180-2*AOI,
and the single-trace s/p extraction depends on the engine's per-ray launch
frame -- BOTH of which are self-cancelling at exactly 45 deg, the one
angle the pre-existing Fresnel gate runs at.  Plus the p-hat bridge, which
is MEASURED as zero on the perfect-conductor case rather than assumed
from the ray-following doctrine.

No engine change.  40_phase3a_chain.md moves only because it carries the
suite-count token (fast group 329 -> 337).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
van Harten reproduction verified (8/8 re-run; 2.8e-14/4.9e-14 vs their
0.01).  The corrected physics -- overcoat trade reverses across the
quarter-wave condition -- inverts the design rule: a proper lambda/4
overcoat SUPPRESSES the floor ~1.8 decades.  Judgment ruled: gated
fixtures do not move; a companion 632.8 nm evidence run gates both
sides of the reversal; design-rules line rewritten chromatic.  One
small Opus slice.  Near-miss narrative (two self-cancelling bugs at
the one gated angle, broken by a units check) recorded as methodology.

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

Slice-3 packet: rotating-analyzer polarization PSI, three gates (null
1.8e-16 rad, textbook 2-omega retardance-error signature, pol-off
Reference-twin bit-identity), pol-component error budget, and the measured
configuration comparison (coated-BS arm retardance aliases from negligible
piston in scalar IFO to 2.38 nm OPD-dependent phase error in the polarization
PSI; PZT stepping preferred unless a moving mirror is unacceptable).

Slice-2 riders (per the slice-2 Fable review): total fringe-contrast budget
at 45 deg and the 17.5 deg knee (scalar throughput-imbalance ~D^2/8 and
polarization-differential ~ret^2/8 side by side); and the note that the
visibility metric assumes both s and p lit (for s/p-aligned input the
differential Jones is diagonal, V=1, cost migrates to the excluded amplitude
term).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Aliasing headline independently modeled (mechanism + order confirmed;
2.38 nm is the sub-fringe rms of a 5.95 nm-rms/8.4 nm-peak ripple).
Gate pinning discipline endorsed; double-passed-retarder psi-flip trap
recorded.  Version-skew flag closed by merging pol-core into pol-ifo
(7a268a9, union suite resolution; tBench 7/7 + tPolElement 27/27 on
the merged tree).  Configuration verdict endorsed as measured.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sls-dev deleted in both repos 2026-07-28 (Andy on nasa-jpl/macos; matched
on MACOS_resources -- dev fully contained it: dev = old sls-dev + the
expose-beam beam-API commits).  New work now lands on dev; repos kept
branch-symmetric.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… the sls-dev retirement is shared

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Records slice-3 (rotating-analyzer polarization PSI, Fable PASS, arc
COMPLETE) and the branch changes: expose-beam PR #64 merged (BEAM API);
MACOS_resources dev created (= sls-dev + beam commits); sls-dev retired
both repos; bench-builder promoted via MACOS_resources PR #10 and retired
both repos; repos are NOT branch-identical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move the 2026-07-28 CCL session note into NOTES/ under the dated naming
convention; add NOTES/README.md documenting it. Developer-facing (lives on
dev, stripped from main).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…both sides

Closes the follow-on Fable opened in REVIEW_POL_EXTERNAL_2026-07-28.md.
That packet found the Phase-2c 110 nm MgF2 overcoat is 0.607 quarter-waves
at Rx_Cass_FarField's own 1 um -- not the 0.96 its "632.8 nm" comment
describes -- and that the overcoat polarization trade REVERSES across the
quarter-wave condition, inverting the 5.5 design rule.  The correction
rested on an independent analytic; it now has engine numbers on both sides.

Ruling honoured: gated fixtures do not move.  Rx_Cass_FarField stays at
Wavelen=1.0E-06 and tPolContrast's 27.898/151.31 stay asserted; the
companion wavelength is applied at RUNTIME with macos.set_src_wvl after
load_rx.  Nothing on disk moves and no engine code is touched.

Engine-measured (model 256, x-pol, both mirrors coated, cross-polarized
TOTAL power -- never a fixed-pixel annulus, which subtends a different
lambda/D range at each wavelength): MgF2/bare = 5.2707x at 1 um (costs),
0.2035x at 632.8 nm (suppresses), reversal 25.899x; a true quarter wave
gives 0.0532x at either wavelength.  The 1 um leg reproduces the recorded
27.8977/151.311 in the same harness.

Non-vacuity is a physical counterfactual reached from the REAL engine: an
achromatic film (thickness pinned in waves -- 110 nm x 632.8/1000 = 69.6 nm
at 632.8 nm) lands back on the 1 um answer to 2.1e-8 and shows no reversal;
3 of 3 of the gate's 632.8 nm assertions fail against it.  Three further
identities localise the effect in the film: the metal-only leg (1.3e-8),
the quarter-wave condition (1.9e-8) and the uncoated geometric floor
(1.6e-15) are all wavelength-invariant.

Design rule, chromatic form: a protective overcoat is neither inherently a
polarization cost nor a benefit -- the sign is its optical thickness AT THE
WORKING WAVELENGTH.  Specify overcoats at lambda/4 of the working lambda.

  polval 8.3    gains an engine column beside the analytic one
  polval 8.3.1  new -- both sides, the invariances, the control, and the
                reconciliation of the engine's TOTAL ratio with the
                analytic's coating-only one via the geometric floor
  polval 5.5    correction notice now cites engine numbers on both sides
  polval 9      three gate-index rows
  macos_f90/CLAUDE.md, PLAN_POLARIZATION.md  the record

Gates: tPolContrast 15/15 (was 14), tPolExternal 8/8, polval regen green
(18 thresholds at model 256, was 10).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e; §5.5 shrink ruled+queued)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Doc-only.  No engine change, no measurement, no fixture moved.  The report
was re-RENDERED (render_polval.py stage 3), not re-measured;
generated/numbers.json is untouched.

A — reader's digest.  New polval/05_summary.md.in, sorting between the
frontmatter and Conventions so it renders as an UNNUMBERED front section:
scope, the conventions table verbatim, one paragraph per major result each
anchored by its key number, and a where-to-go-deeper table.  Motivation:
the primary reviewer will not read 47 pages.

Token reuse only — every number is an existing @@token@@ from the current
numbers.json / external.json.  No new tokens, no hand-typed values, so
check_polval stays green without change.

Load-bearing constraint held: the deck, the packets and the verdicts cite
§4 / §5.5 / §5.6 / §6.7 / §8.3.1 / §8.5 by number.  Before/after diff of
the rendered numbered headings is IDENTICAL — 43 of them, byte for byte;
the only additions are the summary's five unnumbered headings.

Standalone hand-out: `make polval-summary` builds
build/macosPolVal_summary.{pdf,docx,html} from the same single source, no
TOC.  Renders to 4 pages (3 of prose + the packet-pointer table) rather
than the 3 asked for: the verbatim conventions table costs ~1 page on its
own, and cutting either it or result substance to hit a page count was not
worth it.  Dropping the table's third column would get there.

Drift guard, tools/check_polval.py.  The conventions table now has two
homes, which is exactly the arrangement Fable flagged as drift-prone for
§5.5.  It is bracketed by <!-- CONVENTIONS-TABLE:BEGIN/END --> in both
files and check_polval now compares every same-tagged block byte for byte.
Verified non-vacuous: a one-word edit to the copy fails the guard.

B — §5.5 shrink, per REVIEW_POL_OVERCOAT_CHROMATIC_2026-07-28.md's Fable
ruling.  The correction NOTICE stays (a published number was mislabeled;
that trail is not erasable) but reduces to three things: what was wrong,
the chromatic design rule, and a pointer to §8.3.1 as the single home of
the physics.  The restated mechanism and the duplicated magnitudes go —
two homes for one result will drift.  §5.5's own measured 151.3x is
unchanged and still stated as correct for the film as configured.

Also: §5.3's cross-reference to the grid-carry discussion said (§5.5); it
is §5.6.

Verified: render green (12 sections), make polval-check green, no
unresolved tokens, numbered-heading diff clean, polval + polval-pdf +
polval-summary all build.  Nothing else re-run and nothing else can have
moved — this touches only Markdown, one Makefile and one consistency
script.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… good)

Note-only.  The one item the 2026-07-29 polval doc pass left open was
whether to drop the conventions table's provenance column to bring the
standalone executive summary from 4 pages to the 3 originally asked for.
Dave: 4 pages is good -- the column stays, the summary stays at 4.

Marked settled in both places the note raised it so the next session does
not re-open it to chase a page count.  No source, no render, no build
output changes; the summary as pushed at 69be9b5 is final.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…erge-ordering rule (Dave 2026-07-28)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ajax147 ajax147 self-assigned this Jul 30, 2026
@ajax147

ajax147 commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

Concrete evidence for the sequencing note: while verifying an unrelated (engine-independent) design-layer commit against dev, we found the resources pol-branch MEX cannot even load against the dev engine — its binding layer references cfield_plane_get, an engine symbol this PR adds. The resources pol promotions are hard-gated on this merge at the symbol level, not merely by policy.

@andykee

andykee commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Is this still a work in progress or is this a complete feature ready to be merged into dev? Scott, Luis, and I are trying to figure out exactly what's happening here.

@ajax147

ajax147 commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

It's an important upgrade and fix to the basic capability that is already there -- fixing errors and omissions. It also adds a couple polarizing elements needed for modeling HWO testbeds and instruments. There will eventually be new features, but that's work that wil go on for a while, and get iterated with HWO folks and data. So this is a good time to get the basic physics corrected and into the dev branch. Then, after use proves it all out, into the main branch.

@sabasinger

sabasinger commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Dave: we looked at the commits and they mostly appear to be additions to MD files. To keep our paradigm of keeping MD files out of main, Andy would have to spend hours understanding each commit and cherry picking only code changes (and not MD files) from this one merge (to dev) when we decide to merge with main. And the hours will pile up with each new merge if MD files continue to be changed. So we need to change the paradigm and do either:

  1. Allow MD files in main. Erik Hovland suggests moving them out of the root directory and putting them in a hidden directory.
  2. You have to use Claude to separate (and combine) changes to MD files.

I like 1 better. The MD files are in dev and the world can see them if they look. A hidden directory is a little more discrete.

Another note: We are not able to parse the initial comments above ("What this is", "Comments", etc.). Can you ask Claude to be less verbose and make the comments more human readable, e.g. use less jargon?

@ajax147

ajax147 commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator Author

I need the .md files as organizational, planning and communications tools. This practice is essential to making effective use of Claude on these larger projects, especially now that I'm running on 2 machines, and others are also developing code.

We could put most .md files in a single .internal directory -- this would require some rewiring of references on my part, and might break something, but nothing that can't be fixed. The CLAUDE.md files really do need to be in their respective directories. Good discipline would be needed to make sure each file is correctly saved and referenced. Of course any user could pull dev and read whatever they want -- but users who only need to make main would not be buried under TMI.

We could also set dev up so all developer-facing and CLAUDE.mds are automatically stripped when merging into main. That's a 1-way street -- a future branch off of main would not have the key developer info, so we'd have to keep dev going permanently. But that's the plan anyways...

@andykee

andykee commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

We could also set dev up so all developer-facing and CLAUDE.mds are automatically stripped when merging into main.

I couldn't find a way to make this work automatically. It looked like we were going to be stuck cherry-picking individual commits to get the reduced content set onto main. Are you aware of a better way?

@ajax147

ajax147 commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author

I sent Andy a candidate procedure for stripping .md files from main -- Andy did you get it? But this merge request is for dev, where we want to keep our developer files. So -- can someone please review it? I'm happy to answer any and all questions --
-Dave

@andykee

andykee commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

@ajax147 where did you send it? I done see anything here or in any of my email inboxes.

ajax147 added a commit that referenced this pull request Aug 2, 2026
Promotes the slice record to the finished state: the delivered design
and its four-rung score, the three-stage structure after two reorders,
the six findings, the verification state, and the open items.

Also records the post-cleanup engine state -- ~/dev/macos is the PRIMARY
tree and is now on dev ba23d93, the throwaway macos_dev pairing worktree
is gone, and the pairing between repos is carried by the BUILD WIRING
rather than by directory names.  Re-verified after the move rather than
assumed: rebuilt, relinked, tStrictKernel 4/0, tE2E2Axial 7/0,
s3_report.txt byte-identical.

Flags for whoever picks this up: the rodgers1 rung-3/rung-4 artifacts
are stale by 2-3e-4 and their regeneration is a reviewed step not yet
done; s3_score.m's distortion_ wants fresh eyes; and MACOS_res_polifo
needs a macos counterpart decision when pol-ifo revives after PR #67.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ajax247 and others added 2 commits August 3, 2026 11:34
Session summary: bench_ctb generic CTB example + add_oap off-axis fix +
faithful DST2R parallel reference (all on MACOS_resources pol-ifo c9fcbeb);
next stage = insert the diffraction/physical-optics model layer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CCMac's frozen-EP assertion verified -- true of dw_dx_multi ONLY; the
grid/surf/zernike supervisors have reset_xp (default true, per FIELD,
never per poke) all along.  Task spec: add the same reset_xp /
reset_xp_method surface to dw_dx_multi, convention stamp + run_compare
assert, fp_mode composition test, continuity + wide-field gates;
default and baseline-regen decision goes to Dave.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

4 participants