The branch combinator — every branch is DISCRIMINATED; the only question is whether the key already exists or is derived here.
KEYED — dispatch on a field or computed resolved UPSTREAM (declared before
the .use, so members read it through the ordinary ctx-over-ext merge).
The members table is the switch as data: one entry per member graph,
however many key values it serves, and the key literals type the arms:
defineGraph() .field('ecosystem', ECOSYSTEM) .use(branch('ecosystem', [ [['SD1', 'SDXL'], sd], [['Kling'], kling], ]))
TAGGED — the key is DERIVED from ext and stamped into state as a computed (the version-family shape); the members record's keys type the tag:
branch('wanVersion', (ext) => versionOf(ext.ecosystem), { 'v2.1': v21, 'v2.2': v22, })
Pass { emit: false } to keep a derived tag in state (where the UI and
rules read it) but off the wire — for a tag the consuming protocol does
not carry.
There is deliberately NO untagged form: a pick function's control flow is
invisible to the type system, so an untagged branch cannot type its arms —
every dispatch that looks untagged is either keyed (the discriminator is a
field) or tagged-with-emit: false (it is derived but private).
The branch combinator — every branch is DISCRIMINATED; the only question is whether the key already exists or is derived here.
KEYED — dispatch on a field or computed resolved UPSTREAM (declared before the
.use, so members read it through the ordinary ctx-over-ext merge). The members table is the switch as data: one entry per member graph, however many key values it serves, and the key literals type the arms:defineGraph() .field('ecosystem', ECOSYSTEM) .use(branch('ecosystem', [ [['SD1', 'SDXL'], sd], [['Kling'], kling], ]))
TAGGED — the key is DERIVED from ext and stamped into state as a computed (the version-family shape); the members record's keys type the tag:
branch('wanVersion', (ext) => versionOf(ext.ecosystem), { 'v2.1': v21, 'v2.2': v22, })
Pass
{ emit: false }to keep a derived tag in state (where the UI and rules read it) but off the wire — for a tag the consuming protocol does not carry.There is deliberately NO untagged form: a pick function's control flow is invisible to the type system, so an untagged branch cannot type its arms — every dispatch that looks untagged is either keyed (the discriminator is a field) or tagged-with-
emit: false(it is derived but private).