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_PATH → BLENDER_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:
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.
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.