Expand description
Turning a Transform Face refusal into a sentence about the user’s model.
Move Face and Rotate Face refuse BY DESIGN — a motion that carries the selection off the body it belongs to has no answer, and the kernel says so rather than building something unsound. What it says, though, is written for the lane that raised it:
TF1: move_faces: the translation inverts the solid (signed volume changed sign) — refusingmove_faces is a function name, and “signed volume changed sign” is the
kernel’s own criterion, not a statement about the part on screen. Worse, the
message never names the face the user picked and is dragging: the rotation
refusal names Box_NZ and Box_PY, which are the NEIGHBOURS that could not
follow, so the two faces it does name are both the wrong answer to “which
one did I break?”.
This module re-says it. It reads the kernel’s text, recognises WHICH refusal
it is from the few stable phrases each one is built on, and rebuilds the
sentence around the face the user actually selected — which the app knows
from params.faces and the kernel message does not carry.
One thing the sentences here must get right, because it is what the user is looking at: a REFUSED Transform Face contributes NOTHING. The feature drops out of the build entirely rather than falling back to its last good motion, so the face springs back to where it was before the feature ran — measured 2026-09-21, a block lifted to z = 17.9188 by a good drag snapped back to z = 14 the moment a later drag refused. A hint that said the part was “still exactly as it was” would be describing a different app.
The kernel text is never thrown away. FaceTransformRefusal::kernel
keeps it verbatim, and an unrecognised message becomes the reason unchanged:
when the kernel lane rewords a refusal under us, this degrades to exactly
the message the app showed before this module existed, rather than losing
it. That is the whole reason the match is on phrases rather than on a
prefix — nothing here can make a refusal less legible than it was.
Structs§
- Face
Transform Refusal - A Transform Face refusal, said three ways: what happened, why, and what to do — plus the kernel’s own words, kept.
- Refusal
Facts - What the run report says about a feature’s refusal beyond its text: WHY,
read off the kernel refusal’s class and slug
(
brep_kernel::face_transform_reason), and whether the motion that refused was a TURN (featureRefusals[id].step, which the feature records).
Functions§
- explain_
refusal - Explain a Transform Face refusal.
- selected_
face_ names - The face names in a Transform Face’s
facesparam, as the kernel resolves them — re-exported here so the APP can name the selection in a refusal without taking a dependency on the kernel of its own.