Bind the new fleet technique-methods by Role#539
Merged
Conversation
Extends the role_kind binding to the ~20 technique-methods that landed on
main from the fleet-expansion work, applying the same per-method
abstraction assessment used for the original method set.
Full role-mappable (14) -> required_roles, every family presents a Role:
powder_diffraction, small_wide_angle_scattering -> [Detector]
radiography, xray_emission_spectroscopy -> [Detector]
(radiography: Scintillator drops -- detector-Assembly constituent)
macromolecular_crystallography -> [Positioner, Detector]
coherent_diffraction_imaging, ptychography -> [Detector, Positioner]
xray_photoelectron_spectroscopy, hard_xray_photoelectron_spectroscopy,
angle_resolved_photoemission -> [Detector, Positioner]
serial_crystallography -> [Positioner, Detector, Controller]
xray_fluorescence_mapping -> [Sensor, Positioner]
resonant_inelastic_scattering, inelastic_scattering -> [Positioner]
(SpectrometerArm presents Positioner)
Mixed (4) -> Detector role + the no-Role family kept anatomical:
single_crystal_diffraction, surface_diffraction,
grazing_incidence_scattering -> roles [Detector] + needed [PseudoAxis]
transmission_xray_microscopy -> roles [Detector] + needed [ZonePlate]
The reciprocal-space PseudoAxis and the ZonePlate objective present no
Role (computed coordinate / imaging optic, not functional contracts), so
they stay on needed_families; each carries a note explaining the mix.
Kept family_id (assessed, unchanged): absorption_spectroscopy +
continuous_absorption_spectroscopy (Monochromator only, no Role),
energy_characterization, beamline_energy_change (the deferred energy
abstraction), hexapod_reboot (device-specific recovery).
A Method may carry both required_roles and needed_families (independent
fields, no XOR) -- that is what the mixed methods use. All Role targets
verified against catalog presents_as (EmissionSpectrometer->Detector,
SpectrometerArm->Positioner, EnergyDispersiveSpectrometer->Sensor, etc.).
Co-Authored-By: Claude <noreply@anthropic.com>
…g at runtime The #539 catalog conversions introduced a "mixed" method shape (a Detector role_kind slot PLUS a needed_family coverage requirement for a no-Role family: single_crystal_diffraction / surface_diffraction / grazing_incidence_scattering keep PseudoAxis, transmission_xray_microscopy keeps ZonePlate). That coexistence was asserted from the schema (both fields, no XOR) but never exercised at runtime -- the #539 commit was catalog-only, and catalog methods are docs-only, so no binding fired. This adds the missing proof over the REST surface: - happy: a Camera (Detector) + a PseudoAxis asset -> define_plan accepts (needed_family coverage holds) AND the Detector role_kind slot binds. - negative: a Plan with only the Camera (no PseudoAxis) -> define_plan 409 (needed_family_ids not covered), even though the Detector slot could bind -- proving the role slot and the family-coverage set are independent and both enforced. Closes the coverage gap between #539 (catalog) and the runtime binding machinery, matching the proof discipline used for tomography (#534), xpcs/Shutter (#534), and the Diffractometer fixture (#538). Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends the
role_kindbinding (shipped in #534) to the ~20 technique-methods that landed on main from the fleet-expansion work, applying the same per-method abstraction assessment — not a mechanical sweep.Full role-mappable (14) →
required_roles(every family presents a Role):powder_diffraction,small_wide_angle_scattering,radiography,xray_emission_spectroscopy→[Detector](radiography drops Scintillator — detector-Assembly constituent)macromolecular_crystallography→[Positioner, Detector]coherent_diffraction_imaging,ptychography→[Detector, Positioner]xray_photoelectron_spectroscopy,hard_xray_photoelectron_spectroscopy,angle_resolved_photoemission→[Detector, Positioner]serial_crystallography→[Positioner, Detector, Controller]xray_fluorescence_mapping→[Sensor, Positioner]resonant_inelastic_scattering,inelastic_scattering→[Positioner](SpectrometerArm presents Positioner)Mixed (4) → Detector Role + the no-Role family kept anatomical, each with an explanatory note:
single_crystal_diffraction,surface_diffraction,grazing_incidence_scattering→ roles[Detector]+ needed[PseudoAxis]transmission_xray_microscopy→ roles[Detector]+ needed[ZonePlate]The reciprocal-space PseudoAxis and the ZonePlate objective present no Role (a computed coordinate / an imaging optic, not functional contracts a Method targets), so they stay on
needed_families. A Method may carry both fields (independent, no XOR).Kept
family_id(assessed, unchanged):absorption_spectroscopy+continuous_absorption_spectroscopy(Monochromator only — no Role),energy_characterization,beamline_energy_change(the deferred energy abstraction),hexapod_reboot(device-specific recovery).Test plan
pytest tests/unit/deployments/test_catalog_descriptor.py(drift + referential validation)pytest tests/unit/deployments tests/contract -k "catalog or method"(258 passed)mkdocs build --strictcleanpresents_asGenerated with Claude Code