Disciplines · Audits

Bellona Blender executable smoke — Phase 5.3 (2026-09-06)

Probe order mirrors the shipped blenderExecutableCandidates() in

6sections3 minread

On this page

Pinned real-Blender smoke for EVE_SOTA_GAP_CLOSURE_TODOS_2026-09-01 task 5.3: probe the actual executable on this host, then handshake → health → safe execute_python → save/readback → export, all driven through the shipped @bellona/blender-agent stdin RPC bridge outside the agent/LLM planning loop. A different host's record is not availability evidence; this record is for the host that produced it.

Host executable (probed)#

field value
executable path /usr/bin/blender
version banner (blender --version) Blender 4.0.2
session blenderVersion (from health) 4.0.2
architecture x86_64
OS Linux
Blender Python 3.12.3
mode headless (background: true)
headless recipe blender --background --factory-startup --python <bootstrap>
add-on state bellona_addon importable (has bl_info); NOT enabled as a live WS server in this smoke — the stdin transport needs no addon
enabled built-in exporters (factory-startup) io_scene_gltf2, io_scene_fbx, io_mesh_stl, io_scene_x3d, io_curve_svg, io_anim_bvh, io_mesh_uv_layout

Probe order mirrors the shipped blenderExecutableCandidates() in apps/bellona/remote-host/src/blender-adapter.ts: BELLONA_REMOTE_HOST_BLENDER_PATHBLENDER_EXECUTABLE/Applications/Blender.app/Contents/MacOS/Blender (macOS) → blender on PATH.

Smoke sequence (shipped stdin bridge, real Blender 4.0.2)#

step result
handshake + health protocol 1.0, executionMode: headless, sessionId: stdin:4.0.2, supports python/file/operator execution
safe execute_python created SmokeCube; object count → 4
save .blend + readback reported 853,784 bytes == on-disk 853,784; magic BLENDER
export .glb (export_scene.gltf, GLB) + readback reported 3,448 == on-disk 3,448; magic glTF (binary glTF)
export .obj (wm.obj_export) 1,866 bytes written and read back

Observed refusal when the executable is absent#

Driving the same shipped bridge with blenderExecutable: /nonexistent/blender-does-not-exist fails loud — no fabricated success:

text
refusal.result = "refused"
refusal.error  = "spawn /nonexistent/blender-does-not-exist ENOENT (request <uuid>)"

The spawn error is delivered on the child-process error event and cleanupPending rejects the in-flight handshake request with it.

Reproduce#

Gated integration spec (runs only when a Blender executable is configured, skips otherwise): libs/bellona/blender-agent/src/blender-executable-smoke.integration.spec.ts.

text
BELLONA_AUDIT_BLENDER_PATH=/usr/bin/blender \
  npx vitest run libs/bellona/blender-agent/src/blender-executable-smoke.integration.spec.ts

Limits#

One host, one Blender (4.0.2, x86_64 Linux), headless only. This is first-light smoke evidence for the stdin transport — it proves the executable is reachable and drivable to save/export on this host. It does NOT prove the WebSocket-addon path against real Blender, macOS/arm64, breadth, or governed leased execution (tasks 5.6–5.8). The .blend/.glb/.obj byte counts are host- and version-specific and will differ elsewhere.

Task 5.20 compressed-save repair checkpoint (2026-09-16)#

The original smoke's .blend check was not compression-safe: it required the first seven bytes to be ASCII BLENDER. The repaired executable probe now saves the same scene both uncompressed and compressed, resets Blender, reopens each file in Blender itself, and compares the named object, transform, dimensions, material, frame range, FPS, and unit settings. It then exports each reopened scene to GLB and OBJ, matches reported bytes to disk, and decodes both formats to verify the object, material, and mesh content.

The source candidate is 49eaec056c4312fa75f44209d71a3cdd94e6ac7d. The source-bound local receipt is docs/audits/eve-sota-blender-save-export/2026-09-16.linux.probe.json. On Linux x86_64 Blender 4.0.2, the uncompressed file began with BLENDER; the compressed file began with a different byte sequence; both reopened with identical scene semantics. Corrupt, truncated, wrong-format, and missing files were refused, and the Blender process and temporary root were cleaned up.

This is an implementation and local-regression checkpoint, not Task 5.20 closure. The specifically required macOS Blender 5.0.1 reproduction/retest and independent DCC QA are still missing.