Blender add-on: createObject and renderStill refuse what they cannot do #8

Merged
libby merged 4 commits from libby/blender-refusals into main 2026-11-10 23:14:06 +00:00
Member

Two gap cuts from the Noka MKI harness (G3, G4), where actions returned accepted receipts for things that did not happen, or killed the process.

What changed

  • createObject refuses an unknown objectType and any meshType other than cube (TEXT and CURVE used to fall through to an EMPTY with an accepted receipt). meshType is checked only for MESH; an explicit null objectType is refused.
  • renderStill refuses BLENDER_WORKBENCH and BLENDER_EEVEE headless when libEGL is not loadable (they aborted the whole Blender process with no receipt). The probe is cached for the process, Linux only, a module-level function so tests replace it.

Stacking: #5, #6 and #7 are merged; this branch is main merged in.

Verified

  • Unit (fake bpy): 150 tests OK, 10 skipped (need cultmesh_py). Soul pass found one surviving mutant (whitespace strip on meshType); pinned by a test in 01d25c6.
  • Live headless Blender 5.2.2 LTS, ad hoc script (earlier head): refusals name the allowed set; WORKBENCH fails with a receipt naming libEGL.so.1; CYCLES still renders.

Not verified: libEGL probe on a host where it loads; Windows/macOS; Blender not installed in the current run, live scripts not rerun.

🤖 Generated with Claude Code

Two gap cuts from the Noka MKI harness (G3, G4), where actions returned accepted receipts for things that did not happen, or killed the process. What changed - createObject refuses an unknown objectType and any meshType other than cube (TEXT and CURVE used to fall through to an EMPTY with an accepted receipt). meshType is checked only for MESH; an explicit null objectType is refused. - renderStill refuses BLENDER_WORKBENCH and BLENDER_EEVEE headless when libEGL is not loadable (they aborted the whole Blender process with no receipt). The probe is cached for the process, Linux only, a module-level function so tests replace it. Stacking: #5, #6 and #7 are merged; this branch is main merged in. Verified - Unit (fake bpy): 150 tests OK, 10 skipped (need cultmesh_py). Soul pass found one surviving mutant (whitespace strip on meshType); pinned by a test in 01d25c6. - Live headless Blender 5.2.2 LTS, ad hoc script (earlier head): refusals name the allowed set; WORKBENCH fails with a receipt naming libEGL.so.1; CYCLES still renders. Not verified: libEGL probe on a host where it loads; Windows/macOS; Blender not installed in the current run, live scripts not rerun. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Builds a ring array, boundary_step and a seeded scatter natively and through
BrokkrBlenderTarget actions on Blender 5.2.3; records the gaps.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
createNodeGroup, addNode, linkSockets, addModifier, setModifierInput (node_actions.py);
setObjectCustomProperty refuses a name that is a Geometry Nodes modifier input instead of
accepting with no effect; object snapshots carry the evaluated counts, bounds and locations.
Live proof on Blender 5.2.3: ring, boundary_step and seeded scatter rebuilt by actions only
match the native trees (66 checks).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A refused linkSockets puts back the link it displaced; snapshot positions keep local and world
bounds apart, scan instances once per capture, skip positions above 1M vertices and flag
non-finite values; Int values capped at 4096; id/key patterns use fullmatch; addModifier names
the object type it cannot take; setObjectCustomProperty refuses only a modifier input identifier.
Live: 108 checks pass on Blender 5.2.3.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Cycles and self links are refused before Blender is asked; the snapshot's instance scan stops at
100k depsgraph items and says instancesComplete=false (2000x2000 instanced grid: 22 s -> 1.4 s);
the daemon advertisement lists the scene-action and node-graph capabilities. Live: 156 checks pass
on Blender 5.2.3.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
bpy hands out a fresh wrapper per access, so id() keys made reaches() stop early and accept cycles
on chains of six or more nodes; keyed by as_pointer() with one adjacency map per call. Objects the
stopped instance scan never reached report instanceCount null. removeModifier validates its name.
Live: 158 checks pass on Blender 5.2.3.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A refused link restores the displaced link's is_muted; removeModifier no longer applies the
creation-name pattern to a lookup, so hand-made Unicode modifier names are removable; the
pattern message lists the space it allows. Live: 166 checks pass on Blender 5.2.3.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
TEXT and CURVE used to fall through to an EMPTY with an accepted receipt.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
BLENDER_WORKBENCH and BLENDER_EEVEE aborted the whole Blender process inside
bpy.ops.render.render with no receipt. The probe is cached, Linux only, and a
module-level function so tests replace it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libby force-pushed libby/blender-refusals from cace39c135 to 6b7d6ae9e2 2026-11-10 17:55:55 +00:00 Compare
# Conflicts:
#	surfaces/blender/tests/test_scene_actions.py
libby merged commit 47d27271e7 into main 2026-11-10 23:14:06 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/Brokkr!8
No description provided.