Asset production pipeline (typed request → checked GLB)
Generated from
pattern-library/registry.json— do not edit by hand; change the registry and runbun run patterns:build.
Category: 3D · Tier: deep · Maturity: proven (verified 2026-10-29 @ 6a2cd80-dirty) · Risk: medium — real CPU per request (bounded by budget and rate limit); checks prove file and surface integrity, never structural strength
A structured, validated request becomes a checked 3D asset: a deterministic TypeScript generator builds parametric geometry, an inspector proves every shell closed and outward, a DOM-free writer emits byte-stable GLB with its derivation key inside and reads it back, and one job shape — report, PROV-DM provenance, measurements, a write-once owner-scoped store — serves an HTTP route, a CLI and MCP tools, in-process or in a killable worker process.
When to use: Use when an app must generate 3D assets from parameters — configurators that export, procedural parts, AI-requested variations — and every file must be reproducible, validated and attributable before anyone loads it.
Avoid when
- The assets are authored by hand in a DCC tool and only need viewing — the model viewer pattern is enough
- The geometry needs B-rep CAD operations (fillets, STEP exchange, tolerances) — use a CAD kernel (OpenCascade via replicad) behind the same request and report
- The target needs one booleaned watertight solid (3D printing, volumes) — add a CSG union (manifold-3d) first; this pipeline proves closed shells, not a union
- Imported user files must be converted, decimated, unwrapped or baked — that is Blender's job, in a container worker with typed operations
Alternatives
- OpenSCAD in a container, then a mesh converter to glTF — prefer when the models already exist as OpenSCAD scripts and CSG is the core operation
- Headless Blender (bpy) in a CPU/GPU container worker with a closed list of scripts — prefer when the work is conversion, retopology, baking or rendering, not parametric generation
- Three.js GLTFExporter in the browser — prefer when the asset never leaves one user's tab and no server-side proof or storage is needed
Docs
- docs/blueprint/3d/asset-production.md — The full pattern: engine comparison, pipeline, invariants, gates, environments, security, MCP, measurements, managed-service path, anti-patterns (GitHub · GitLab)
Code
src/lib/asset-production/— Framework-free core: engine, generators, mesh intermediate, inspection, GLB writer and read-back gate (GitHub · GitLab)src/lib/asset-production/README.md— The core's boundaries and one responsibility per file (GitHub · GitLab)src/lib/schemas/asset-production.ts— The request schema and the one bounds table the UI and tools read (GitHub · GitLab)src/lib/server/asset-production/— Job lifecycle, report and provenance, derivation, write-once stores, in-process and isolated environments, MCP tool registry (GitHub · GitLab)src/routes/api/showcases/asset-production/+server.ts— The rate-limited HTTP adapter (GitHub · GitLab)scripts/asset-production/produce.ts— CLI with the directory store (GitHub · GitLab)scripts/asset-production/worker.ts— The isolated worker entrypoint a container would run (GitHub · GitLab)scripts/asset-production/bench.ts— The measurements the doc quotes (GitHub · GitLab)
Tests
src/lib/asset-production/engine.test.ts— Determinism, exact estimates at the bounds, sixteen refusals, cancellation and deadline, the boundary gate (GitHub · GitLab)src/lib/asset-production/glb.test.ts— Khronos validator: no error or warning; GLTFLoader loads it; damaged files refused (GitHub · GitLab)src/lib/asset-production/inspect.test.ts(GitHub · GitLab)src/lib/server/asset-production/run-job.test.ts— Report and provenance, label-independent derivation, write-once stores, lifecycle (GitHub · GitLab)src/lib/server/asset-production/isolated-process.test.ts— Same bytes on Bun and Node; worker killed at deadline, on cancel and past its output cap (GitHub · GitLab)src/lib/server/asset-production/tools.test.ts— MCP registry: typed operations only; code, unknown generators and over-budget requests refused (GitHub · GitLab)tests/browser/produce.spec.ts— Playwright: generate, see the model and the report, refuse a conflict — bun run test, outside validate (GitHub · GitLab)
Proof
Invariants
- Callers ask through one strict request schema — a generator id and bounded parameters; no request can name a script, a file or an engine flag.
- The budget is checked from an exact estimate before anything is built and from the real mesh after; an over-budget request costs one arithmetic pass.
- Same request, same bytes — in-process or in a worker, on V8 or JSC; the label is presentation and never enters the derivation key.
- Every exported GLB passes inspection (closed outward shells, finite values, declared envelope) and its own read-back gate; tests hold it to the Khronos validator with zero errors and warnings.
- Findings are data with a fixed severity per code; a refused or failed run returns no bytes, and a cancelled one keeps nothing.
- Stores are write-once and owner-scoped: a repeat run reuses, different bytes under a kept key are refused, and a job never publishes.
- The core imports no framework, DOM or runtime API, so the same engine runs in a function, a worker process, a terminal and a browser.
Emulation notes
- Write the request schema and its single bounds table first; let the UI sliders and the tool description read the same table.
- Give every generator an exact estimate and test estimate = actual at every bound — that is what makes the a-priori budget honest.
- Write your own byte-stable GLB writer for generated meshes rather than exporting a scene graph; run the Khronos validator in tests.
- Start in-process; add the isolated worker (SIGKILL deadline, stripped env, capped output) before any untrusted or heavy engine, and only then a container.
- Expose AI access as typed operations through the same schema; mount the tool where calls are authenticated and metered, never on an anonymous endpoint.
Depends on
- Threlte integration (SSR-off, code-split model registry)
- Derivation key (freshness by input fingerprint)
- Provenance record (entity, activity, agent — PROV-DM core)
- Rate limiting (sliding window, fail-closed)
- Hosted MCP (two trust surfaces: public read-only · bearer admin)
Machine-readable record: asset-production-pipeline in pattern-library/registry.json.