Which pipeline a render item needs (§64 stage 7, §66 sort key 3).
A backend cannot draw a textured quad with the flat-colour pipeline, so an
item has to say which one it is. The discriminant is carried on the item
rather than derived from the material's class at draw time, for the reason
§64 gives for compact render items in the first place: the draw path must not
make a virtual call, an instanceof check, or a property probe per object.
It is also the field §66's key 3 ("pipeline/material compatibility") will sort
on when batching (§65) lands (decision, WP-3a.3).
A string union rather than an enum, matching TransformAuthority,
RendererBackend, and GeometryDrawMode: it serializes, logs, and compares
as itself.
"lit" joined with the §68 lighting packet (2026-08-04): a Renderable
generates "unlit" or "lit" according to its material's own kind
discriminant (§57) — a material property, not a node property, because
which pipeline shades a surface is exactly what a material is.
"standard" joined with §59's metallic-roughness workflow (R-13,
2026-08-08), by the same rule and for the same reason. Widening this union is
still an edit to this package, which is R-12's remaining half: the closed
union is the staging mechanism, not the destination — it keeps every arm
type-checked end to end while the pipeline registry §64 asks for is designed
(see pipelineOf).
"skinned-unlit" and "skinned-lit" joined with §54's skinning (RFC 0003,
2026-08-28), and they are the one pair whose discriminant is not the
material's kind alone: a skinned draw is the same §57 material family
through a different vertex stage, so the kind is the material's family
crossed with "this node has an active skin" — a Mesh with a Skeleton
over a geometry carrying joints/weights (see collect). Skinning is a
separate pipeline rather than a uniform switch because useMap's trade
inverts in the vertex stage: a useSkinning uniform would add four palette
fetches and a weighted sum to every vertex of every draw to serve the
rare skinned one (RFC 0003 §5, alternative B rejected).
Note for RFC 0001 (which inherits this shape)
RFC 0003 landed first, so this widened closed union — one string member per
compiled pipeline, discriminating the item union, with the backend's draw
loop switching on it — is the shape RFC 0001's pipelineId follow-up
refines rather than reinvents: a registry-issued pipeline id would replace
the closed-ness (a consumer material could bring its own arm), not the
discriminant-on-the-item design, and the two skinned members show what a
vertex-stage variant looks like in it (family × vertex path, decided at
item-generation time, never per draw). Until then, widening remains an edit
to this file, and an exhaustive consumer switch over RenderItemKind is
broken by every widening — the §90 note both RFCs record.
"node" joined with §60's node materials (RFC 0001, 2026-08-28), and it is
the shape that note anticipated, implemented at the item tier: one
member discriminates the whole node-material family — decided at
item-generation time from the material's kind, like every other member —
while the compiled-pipeline identity inside that family is the graph's
structure, resolved by the backend's program cache off
item.material.graph (one program per distinct graph, however many
materials share it). The registry-issued pipelineId that would replace
this union's closed-ness therefore remains a follow-up; what §60 needed was
a member whose pipeline count is open while the member set stays closed.
An unregistered backend skips a "node" item with a one-time §85
warning — pipelineOf's flat-colour fallback is deliberately excluded for
it, because a graph the author wrote is a specific picture and drawing an
unrelated one is R-6's "a JSON value must not become a different picture"
in the material domain.
Which pipeline a render item needs (§64 stage 7, §66 sort key 3).
A backend cannot draw a textured quad with the flat-colour pipeline, so an item has to say which one it is. The discriminant is carried on the item rather than derived from the material's class at draw time, for the reason §64 gives for compact render items in the first place: the draw path must not make a virtual call, an
instanceofcheck, or a property probe per object. It is also the field §66's key 3 ("pipeline/material compatibility") will sort on when batching (§65) lands (decision, WP-3a.3).A string union rather than an enum, matching
TransformAuthority,RendererBackend, andGeometryDrawMode: it serializes, logs, and compares as itself."lit"joined with the §68 lighting packet (2026-08-04): aRenderablegenerates"unlit"or"lit"according to its material's ownkinddiscriminant (§57) — a material property, not a node property, because which pipeline shades a surface is exactly what a material is."standard"joined with §59's metallic-roughness workflow (R-13, 2026-08-08), by the same rule and for the same reason. Widening this union is still an edit to this package, which is R-12's remaining half: the closed union is the staging mechanism, not the destination — it keeps every arm type-checked end to end while the pipeline registry §64 asks for is designed (seepipelineOf)."skinned-unlit"and"skinned-lit"joined with §54's skinning (RFC 0003, 2026-08-28), and they are the one pair whose discriminant is not the material'skindalone: a skinned draw is the same §57 material family through a different vertex stage, so the kind is the material's family crossed with "this node has an active skin" — aMeshwith aSkeletonover a geometry carryingjoints/weights(seecollect). Skinning is a separate pipeline rather than a uniform switch becauseuseMap's trade inverts in the vertex stage: auseSkinninguniform would add four palette fetches and a weighted sum to every vertex of every draw to serve the rare skinned one (RFC 0003 §5, alternative B rejected).Note for RFC 0001 (which inherits this shape)
RFC 0003 landed first, so this widened closed union — one string member per compiled pipeline, discriminating the item union, with the backend's draw loop switching on it — is the shape RFC 0001's
pipelineIdfollow-up refines rather than reinvents: a registry-issued pipeline id would replace the closed-ness (a consumer material could bring its own arm), not the discriminant-on-the-item design, and the two skinned members show what a vertex-stage variant looks like in it (family × vertex path, decided at item-generation time, never per draw). Until then, widening remains an edit to this file, and an exhaustive consumerswitchoverRenderItemKindis broken by every widening — the §90 note both RFCs record."node"joined with §60's node materials (RFC 0001, 2026-08-28), and it is the shape that note anticipated, implemented at the item tier: one member discriminates the whole node-material family — decided at item-generation time from the material'skind, like every other member — while the compiled-pipeline identity inside that family is the graph's structure, resolved by the backend's program cache offitem.material.graph(one program per distinct graph, however many materials share it). The registry-issuedpipelineIdthat would replace this union's closed-ness therefore remains a follow-up; what §60 needed was a member whose pipeline count is open while the member set stays closed. An unregistered backend skips a"node"item with a one-time §85 warning —pipelineOf's flat-colour fallback is deliberately excluded for it, because a graph the author wrote is a specific picture and drawing an unrelated one is R-6's "a JSON value must not become a different picture" in the material domain.