README: the FBX routes are planned until the next idunn up; the seed and the export's file handling as built (Soul s1: front-door-claims-fbx-live)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-24 23:19:17 +02:00
commit b015658962

View file

@ -8,11 +8,11 @@ Linux. It runs on Yggdrasil as an Idunn target (see Front Door).
## Front Door
- **Value:** a supervised path from a text prompt to generated body motion. The daemon spawns one resident Kimodo worker, caps its threads, and returns motion artifacts (`motion.npz`, BVH, and FBX for Unity) for a job.
- **Value:** a supervised path from a text prompt to generated body motion. The daemon spawns one resident Kimodo worker, caps its threads, and returns motion artifacts (`motion.npz` and BVH; FBX for Unity is planned, see below) for a job.
- **Problem:** Personas and games need generated motion, but cold per-request model loads cost minutes. One daemon owns job identity, worker lifecycle, the thread budget and artifact references, so callers touch no model state.
- **Entry points:** `scripts/vili-daemon.mjs` (the daemon; `npm start`, `npm test`), `scripts/idunn-entry.mjs` (the process Idunn runs), `deployment/idunn/recipe.toml` (the sealed release), `scripts/kimodo-resident-worker.py` (the worker it spawns), `scripts/kimodo-text-encode.py` (the one-shot encoder child), `POST /motion/generate` (see Motion Generation), `docs/verse-service-contract.md` and `docs/motion-pipeline-target.md`.
- **Live:** the Idunn target `vili` on Yggdrasil at `http://10.77.0.1:8824` (WireGuard only), CPU only: `POST /motion/generate` (add `"fbx": true` for a Unity-ready FBX per clip), `POST /motion/rest-fbx` (the avatar's rest pose), `GET /motion/artifacts/{jobId}/{name}` (the FBX and BVH bytes), `GET /health`, `GET /operator-state`, and the CultCache service store. FBX export is `scripts/bvh-to-fbx.py` in the release's own Blender 5.2.2; see FBX Export.
- **Planned:** worker intake closed to local callers only, publication to Odin, and a Thing 2 operator surface. The text-prompt-to-Unity-clip path with no hand steps is `docs/motion-pipeline-target.md`.
- **Live:** the Idunn target `vili` on Yggdrasil at `http://10.77.0.1:8824` (WireGuard only), CPU only, running the revision deployed before the FBX export: `POST /motion/generate` (`motion.npz` and optional BVH on the SOMA skeleton; no FBX), `GET /health`, `GET /operator-state`, and the CultCache service store.
- **Planned:** FBX export, which is in this tree and not yet deployed: `"fbx": true` on `POST /motion/generate` (a Unity-ready FBX per clip), `POST /motion/rest-fbx` (the avatar's rest pose) and `GET /motion/artifacts/{jobId}/{name}` (the FBX and BVH bytes), from `scripts/bvh-to-fbx.py` in the release's own Blender 5.2.2 (see FBX Export). They answer only after the next `idunn up`. Also planned: worker intake closed to local callers only, publication to Odin, and a Thing 2 operator surface. The text-prompt-to-Unity-clip path with no hand steps is `docs/motion-pipeline-target.md`.
## Authority
@ -128,7 +128,7 @@ Supported request fields:
- `numTransitionFrames` / `num_transition_frames`
- `constraints` as an object/list, or `constraints`, `constraintsPath`, or
`constraints_path` as a path on the worker host
- `seed` (absent: the daemon mints one, and every job records the seed it used)
- `seed` (an integer from 0 to 2^31 - 1, anything else is a 400; absent: the daemon mints one; the job records the seed the worker was given)
- `cfg`, `cfgType` / `cfg_type`, `cfgWeight` / `cfg_weight`
- `bvh`, `bvhStandardTpose` / `bvh_standard_tpose`
- `fbx` and `clipName` (see FBX Export)
@ -144,6 +144,8 @@ exports CSV when that model is resident.
## FBX Export
Planned until the next deploy: the live unit does not have these routes or the `fbx` field yet.
`"fbx": true` makes the job's BVH an FBX for Unity, beside it: `motion.fbx`, or `motion/motion_NN.fbx` for several
samples. It implies `bvh` and `bvhStandardTpose`; an explicit `bvhStandardTpose: false` is a 400. `clipName`
(`^[A-Za-z0-9_-]{1,64}$`, default the job id; sample N of several is `<clipName>_NN`) names the armature, the action
@ -151,9 +153,12 @@ and the FBX take. With Blender not ready (`backend.blender` is `unconfigured` or
`Blender 5.2.2 LTS ...` line) an `fbx` request is a 503 `blender-unavailable` and nothing is written.
The worker never runs Blender. After it answers, the daemon runs the release's Blender
(`blender -b --factory-startup --python-use-system-env --python scripts/bvh-to-fbx.py`) on each BVH it listed, and
only on a regular file inside the job's artifact directory; the FBX path is the BVH's, so it is derived from the
job id. Blender converts and nothing else: the SOMA77 joint names are Kimodo's, the pose is the standard T-pose in
(`blender -b --factory-startup --python-use-system-env --python scripts/bvh-to-fbx.py`) on each BVH it listed.
The BVH must be a regular file inside the job's artifact directory, opened without following a symlink; Blender is
handed a private copy of it and writes a private FBX in a directory made for that export (`<state>/work/`), and the
daemon creates the FBX beside the BVH exclusively, so a path planted in the job directory is never read, written
through or replaced. The FBX path is the BVH's, derived from the job id, which is the clock plus random bits and is
taken by an exclusive mkdir. Blender converts and nothing else: the SOMA77 joint names are Kimodo's, the pose is the standard T-pose in
metres, and the clip's travel stays on `Hips` (Root is static), so Unity derives root motion or bakes it into the
pose as the caller chooses. Blender runs under the write gate in its own process group at nice 10, with
`HOME=/nonexistent`, `PYTHONHASHSEED=0` and `LD_LIBRARY_PATH=<blender>/lib` as its whole environment, a 120 s