Repository navigation
Description
ADR 0008 lets a reference fit a union of groups when the output's type fits one alternative. Every alternative carries a tag field (kind: Literal['given']), so an output that should fit a union must be of a tagged class. A producer then has to know its consumers. The form spike (#89) shows the cost. The toy FIND_CENTRE outputs BeamCentre, which fits IOFQ's beam_centre: BeamCentre, but not a union GivenCentre | FindCentre. So the spike needed a second finder that outputs a tagged GivenCentre(BeamCentre). Reference-only alternatives such as ComputedTransmission carry a tag that no request ever writes.
Proposal. A place given by reference is a plain group, possibly typed X | None. A union of groups is written inline only:
beam_centre: BeamCentre = BeamCentre() # typed in, or from a record: finder.ref('centre')
beam_centre: Annotated[GivenCentre | FindCentre, Field(discriminator='kind')] = GivenCentre()
# typed in, or found in this graph; no reference fitsWorkflowSpecrefuses an alternative that a request cannot write inline, i.e. one with a data value.- A request with a reference at a union place is refused at submission.
- The params schema of a union has no reference form.
- In a generated UI, a group offers {its fields, a record}, and a union offers {its alternatives}.
Noneadds one option to either.
Removed: tags on outputs; tagged reference-only alternatives (ComputedTransmission with kind); reference fitting for unions (the union branches of fits and of the reference schema in _forms); the mixed group/union/record case in UIs. Tags stay as pydantic-native kind fields on input groups, as in scipp/esslivedata#1426.
What has to change:
- Story C2:
normalization: ComputedNormalization | PublishedNormalization | None. It becomesComputedNormalization | None, given by reference. A published normalization file reaches it through a loader workflow that outputs aComputedNormalization. In general, "a record, or another way" becomes "a record", plus a workflow that produces the output type from the other way. - README and ADR 0008 examples: transmission
FromFile | ComputedTransmission, and a beam-centre union that acceptsfinder.ref('centre'). - Spike feat: Panel forms and apps generated from specs, and the client calls they need #89: drop
LOCATEandGivenCentre's second role, and the union's record option.
What is given up: one place can no longer offer "type it in, compute it here, or take it from a record" together. The spec author picks one style. No story needs the mix.
Out of scope: each case above is Computed | File, an output of a workflow or a file of the same data. A way to support that, or hide the difference, may come later.
Activity
docs: the spike's union offers no record
docs: the spike's union offers no record
docs: the spike's union offers no record