Faces whose roles an operation recorded on the shape take those names when
the namespace matches operationType. extrude records 'extrude:start',
'extrude:end', 'extrude:side:' and 'extrude:hole:side:', which
survive later moves and booleans.
Faces a primitive namer doesn't recognize (a rotated box's non-cardinal faces),
and every face of any other operation type, fall back to positional names
('opType:face_0', 'opType:face_1', ...) — so each face always gets a role.
Map from role name to its face hash codes (one per role, except a
recorded role whose face a later operation split; updateRoles adds more
when it tracks a split).
Auto-assign role names to a shape's faces from its operation type.
Known primitives get semantic names from face geometry — rebuild-stable across parameter edits that preserve orientation:
box: cardinal names by normal ('box:top'/'bottom'/'front'/'back'/'left'/'right').cylinder/cone(Z-axis): 'top'/'bottom' caps + 'lateral' wall.sphere: 'sphere:surface'.Faces whose roles an operation recorded on the shape take those names when the namespace matches:side:', which
survive later moves and booleans.
operationType.extruderecords 'extrude:start', 'extrude:end', 'extrude:side:' and 'extrude:holeFaces a primitive namer doesn't recognize (a rotated box's non-cardinal faces), and every face of any other operation type, fall back to positional names ('opType:face_0', 'opType:face_1', ...) — so each face always gets a role.