SPEC: Cut toolkit — eyes / hands / prove (BlenderRun)
Status: DRAFT
Repo: the-shit/kit
Slug: cut-toolkit
Depends on: kit#10 factory-seats (Cut receipt stays "one slice queued" until this lands)
Related: kit#6 ImageToMesh (TRELLIS/Hunyuan) — blockout only, not the edit loop
Lie: Kit "does 3D modeling." Today Cut cannot see or touch meshes (ImagineStill only; factory-seats locks Cut against Blender). This SPEC makes the lie true for one closed loop: see → act → measure → retry.
Seat: Cut agent (smart brain: Astra via OpenRouter for now; swappable). Look stays honesty. Ship stays PR/CI, never merge. No LLM on /api/assign.
Number (done-when): For a single catalog asset job, LookCompare score ≥ agreed threshold on the four views (front/side/back/3-quarter) AND ValidateGLB green, within N Cut turns (default 5). Pitcher owns the threshold when the job is assigned.
Locked
Eyes (sense)
RenderViews — render orthographic/perspective stills from current GLB for front|side|back|ride (match ImagineStill view names). Output paths under factory tree only.
- Vision critique — Cut brain receives those stills + brief + prior fail notes. SHALL NOT invent what a mesh looks like from filenames alone.
LookCompare — score candidate vs reference per region/check. Reuse Look honesty rules: fail ⇒ message contains fail, never visual_ok.
Hands (act)
BlenderRun — bounded bpy only (allowlisted ops: load/save GLB, transform, boolean, remesh/decimate, weld, simple material assign). No free shell, no network from bpy, no arbitrary Python import outside allowlist.
ImageToMesh — optional blockout when starting from zero; implementation may call kit#6 backends. Receipt is a GLB path + catalog id.
MeshOps — non-Blender repairs when cheaper. Prefer BlenderRun when topology must change.
Prove (scoreboard)
ValidateGLB — manifold, poly budget, units, required LODs/catalog schema. Hard fail blocks Ship.
- Turn cap — Cut SHALL stop and report honest fail when N turns exhausted without number met.
- Ship — only after ValidateGLB + LookCompare pass; hallway still
does not merge.
Brain / routing
- Cut is one of the 1–3 smart house seats. Brain is config (
KIT_CUT_MODEL, default OpenRouter Astra-class when available; fallback documented).
- Look and Ship stay cheap/local — do not promote them to frontier models for this SPEC.
- Assign still has no LLM.
Host / GPU
- Blender execution host is Loki (creative default) with Thor borrow when idle. This SPEC SHALL NOT hardcode cloud burst.
- PEM/secrets stay off shared Cursor VM.
Files (proposed)
| Path |
Job |
specs/cut-toolkit/spec.md |
This contract |
app/Tools/RenderViews.php |
GLB → stills |
app/Tools/BlenderRun.php |
Allowlisted bpy runner + receipt |
app/Tools/ValidateGLB.php |
Hard checks |
app/Tools/LookCompare.php |
Wire/extend look report scoring for Cut loop |
app/Factory/CutLoop.php |
see→act→measure orchestrator with turn cap |
tests/Feature/CutToolkitTest.php |
Fake Blender + fixtures; no real GPU required in CI |
Acceptance
Non-goals
- Unreal/editor driving
- Free-form bash or unrestricted bpy
- Merging PRs / restack babysit beyond today's Ship hallway
- Multitenancy (kit#11)
- Replacing Feel/Bench identities
- Making Look or Ship into frontier agents
- Full TRELLIS training stack (belongs to kit#6)
After APPROVE
- Land
specs/cut-toolkit/spec.md on the-shit/kit; comment spec: specs/cut-toolkit/spec.md here.
- Implement tools + CutLoop behind feature flag; dogfood one catalog asset on Loki.
- Only then point Cut brain at Astra (or successor) — tools before brain.
- Do not label
night-ready until SPEC is on GitHub and Jordan wants pickup.
SPEC: Cut toolkit — eyes / hands / prove (BlenderRun)
Status: DRAFT
Repo:
the-shit/kitSlug:
cut-toolkitDepends on: kit#10 factory-seats (Cut receipt stays "one slice queued" until this lands)
Related: kit#6 ImageToMesh (TRELLIS/Hunyuan) — blockout only, not the edit loop
Lie: Kit "does 3D modeling." Today Cut cannot see or touch meshes (
ImagineStillonly; factory-seats locks Cut against Blender). This SPEC makes the lie true for one closed loop: see → act → measure → retry.Seat: Cut agent (smart brain: Astra via OpenRouter for now; swappable). Look stays honesty. Ship stays PR/CI, never merge. No LLM on
/api/assign.Number (done-when): For a single catalog asset job, LookCompare score ≥ agreed threshold on the four views (front/side/back/3-quarter) AND
ValidateGLBgreen, within N Cut turns (default 5). Pitcher owns the threshold when the job is assigned.Locked
Eyes (sense)
RenderViews— render orthographic/perspective stills from current GLB forfront|side|back|ride(match ImagineStill view names). Output paths under factory tree only.LookCompare— score candidate vs reference per region/check. Reuse Look honesty rules: fail ⇒ message containsfail, nevervisual_ok.Hands (act)
BlenderRun— bounded bpy only (allowlisted ops: load/save GLB, transform, boolean, remesh/decimate, weld, simple material assign). No free shell, no network from bpy, no arbitrary Python import outside allowlist.ImageToMesh— optional blockout when starting from zero; implementation may call kit#6 backends. Receipt is a GLB path + catalog id.MeshOps— non-Blender repairs when cheaper. Prefer BlenderRun when topology must change.Prove (scoreboard)
ValidateGLB— manifold, poly budget, units, required LODs/catalog schema. Hard fail blocks Ship.does not merge.Brain / routing
KIT_CUT_MODEL, default OpenRouter Astra-class when available; fallback documented).Host / GPU
Files (proposed)
specs/cut-toolkit/spec.mdapp/Tools/RenderViews.phpapp/Tools/BlenderRun.phpapp/Tools/ValidateGLB.phpapp/Tools/LookCompare.phpapp/Factory/CutLoop.phptests/Feature/CutToolkitTest.phpAcceptance
specs/cut-toolkit/spec.mdwithspec:on this issuevisual_okphp artisan test --filter=CutToolkitgreen without GPUNon-goals
After APPROVE
specs/cut-toolkit/spec.mdonthe-shit/kit; commentspec: specs/cut-toolkit/spec.mdhere.night-readyuntil SPEC is on GitHub and Jordan wants pickup.