Skip to content

Bind the new fleet technique-methods by Role#539

Merged
xmap merged 2 commits into
mainfrom
worktree-new-method-roles
Jul 3, 2026
Merged

Bind the new fleet technique-methods by Role#539
xmap merged 2 commits into
mainfrom
worktree-new-method-roles

Conversation

@xmap

@xmap xmap commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Summary

Extends the role_kind binding (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 --strict clean
  • catalog-only change; all Role targets verified against catalog presents_as

Generated with Claude Code

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>
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

Coverage report

This PR does not seem to contain any modification to coverable code.

…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>
@xmap xmap merged commit cb4f325 into main Jul 3, 2026
16 checks passed
@xmap xmap deleted the worktree-new-method-roles branch July 3, 2026 13:37
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