npcs/CHARACTER_FACTORY_PLAYBOOK.md
Chartered by Josh, 2026-08-07: *"track what the trends were and what we did to make these
better… this pipeline needs to be automated… we have a lot of shit to create."*
What this is. The protagonist's end-to-end journey, distilled into the pipeline every other
living asset runs — companions, supporting cast, NPCs, bosses, creatures where humanoid. One
character was carried from a blank prompt to four approved exemplar plates and a measured 3D
route over roughly thirty-six hours of graded iteration. That run produced a set of recipes that
work and a longer set of things that do not, each of them measured. **This document is the
extraction: the winning recipe per stage, the named traps with their numbers, the instruments,
and the exact points where Josh's eye is the gate.** It is the driver spec for the automation.
Status: ACTIVE v1.0 · Tier T99 operational — it sets no canon and changes none. Where it
states a design fact it cites the ruling that made it.
Citation form: path plus an exact quoted string or JSON key, never a line number. Gate 46
line_citations records the line-range backlog as an Option-A worklist that *must shrink*, and a
new playbook is a poor reason to mint two hundred fragile pointers into a shared tree. Every claim
below is greppable.
Honest tier: EXTRACTION. Nothing here is a new capability. Every recipe cited as WINNING has a
landed record and, where the record says so, a Josh grade. Every stage marked BUILD is named
as unbuilt rather than described as if it ran.
---
Read these first; every stage below is one of them applied.
1. THE SIMPLEST FAITHFUL OPERATION BEATS EVERY ENGINEERED CHAIN. The merge that Josh approved is
the *control arm*: the raw exemplar head aligned onto the picked body, minimal processing. Four
engineered passes — exposure match, head rescale, body restore, membrane heal — were each built to
close a defect an instrument reported, and none survived his eye. His words on the winner:
*"if youre seeing defects it might be your math thats wrong"*
(docs/spine/DECISIONS_PENDING_JOSH.md :: RAWHEAD CONTROL APPROVED). Instruments recalibrate
against approved cells as ground truth; defect maths that scores an approved cell down is wrong by
definition.
2. THE EYE OUTRANKS THE INSTRUMENT, AND THE LAW IS NOW WRITTEN. The DIRECTOR EYE-PASS LAW: no
gradeable reaches Josh without the director's own per-tile sighted audit recorded first; a lane's
gate table is an input, never the pass (DECISIONS :: JOSH GRADES THE AGE LADDER - HORRIBLE). Its
3D twin: *"no 3D stage advances on instrument numbers alone"* (DECISIONS :: 3D UNGATED FROM
IN-BETWEENS + DIRECTOR SIGHTED 3D LAW).
3. IDENTITY DOES NOT TRAVEL ACROSS AN AGE GAP, AND AGE DOES NOT TRAVEL BETWEEN TWO REFERENCES.
Both directions are measured. A full-strength reference sets the AGE as well as the face; and two
references over one canvas produce a ghost, not a midpoint. Every age rung conditions on a
reference already at its age (build/art/characters/face_evidence/inbetween/AGING_METHOD_RESEARCH.md
§1).
4. GEOMETRY IS SOLVED BEFORE ANY GENERATIVE PASS, NEVER AFTER. A head-unit ratio says nothing
about where the chin sits; solving on it set four neck lengths +20/+25/+26/+5 percent long
(DECISIONS :: MERGE LANDED — GEOMETRY FIRST, IDENTITY MEASURED).
5. THE MISSING STAGE WAS A BASE MESH, NOT A BETTER MODEL. Every 3D defect Josh named —
*"scoliosis… doesn't look like actual 3D models"* — followed from assembling lofted parts and
solving proportions onto the assembly. The rejected chain was nearly perfectly symmetric and
still read bent, because the defect was part seams (build/3d/PIPELINE_RESEARCH_AUG2026.md,
"The finding that reframes the whole problem").
6. AN INSTRUMENT THAT HAS NOT BEEN MUTATED IS NOT ARMED. Three separate instruments in this run
were wrong in a way that nearly inverted a verdict, and each was caught by a positive control, not
by review. The rule is in §5.
7. PROPORTION TRUTH IS RESEARCH, NOT INTUITION. The single most damaging artefact of a scaled
adult is an identical leg-to-trunk ratio at every age; the cormic index actually falls to a minimum
at 13 and rises again (build/3d/characters/body_specs/AGE_PROPORTION_RESEARCH.md §3).
---
Every character is stamped from this chain. EXISTS = a proven tool with a landed record.
BUILD = specified, not built. The architecture is ratified: ONE BARE MESH, PARTITIONED — geometric
merging of independently generated parts is BANNED, with the head↔body bridge as the single named
RETIRING exception (DECISIONS :: THE PARTITION IS RATIFIED; brief at
docs/pipeline_review/BODY_ASSEMBLY_ARCHITECTURE_BRIEF_2026-08-06.md §6).
| # | Stage | Winning recipe lives at | State | Human gate |
|---|---|---|---|---|
| 0 | Reference & concept intake | build/art/characters/CHAR_0001_CANON_SHEET.md · the canon row | EXISTS | Josh supplies floor references |
| 1 | Face exemplar — bracket → pick → per-age direct | harness/asset_factory/keystone_direct.py, keystone_wave2.py | EXISTS | JOSH PICKS the cell, per age |
| 1b | Bare / bald conditioning derivatives | harness/asset_factory/bare_derivative.py, bald_derivative.py | EXISTS | verify-only |
| 2 | Body — anthropometry solve → physique bracket | build/3d/characters/body_specs/BODY_AGE_*.json, body_keystone_lane.py | EXISTS | JOSH PICKS the physique bracket point |
| 3 | 2D merge — face onto body (the rawhead recipe) | build/3d/characters/body_specs/merge_route_a_v8.py, merge_identity_v6.py | EXISTS | JOSH APPROVES the merged keystone |
| 4 | Aging ladder — keystones first, landmark-warp in-betweens | harness/asset_factory/aging_ladder.py, face_landmark_warp.py, inbetween_faces.py | EXISTS | JOSH PICKS each in-between |
| 5 | Cage source decision + wrap/conform | build/3d/cage/CAGE_PICK.json (Lane S2 picked) | EXISTS | director; blend-proof blocker CLOSED as an instrument-reference defect (blend_fix/BLEND_G4_REFERENCE_FINDING.json, 869ba32f; superseded in place 2026-08-10) |
| 6 | 3D mesh generation — image-to-3D as base sculpt | Hi3DGen (live default); TRELLIS.2 arm pending a gate | EXISTS | director sighted, every artifact |
| 7 | Cleanup — shell removal, symmetrize on the fitted plane | build/3d/bakeoff/measure_mesh.py + the fitting stage | PARTIAL | — |
| 8 | Lattice-fit to spec — raised-cosine girth drive | build/3d/bakeoff/fit_girth_lattice.py | EXISTS | — |
| 9 | Region partition + doll-underwear standards | the partition ruling; R05_PELVIC_GIRDLE carve-out | BUILD | — |
| 10 | Texture — 6-view MV-Adapter, chunk-by-chunk, SeedVR2 detail | harness/asset_factory/mv_texture_bake.py, seedvr2_refine.py | EXISTS / weights owed | director sighted |
| 11 | Rig + bind + ROM calisthenics | bl_skin_to_mannequin.py; ROM unbuilt | PARTIAL | — |
| 12 | Turntable acceptance — every angle, iterate to identical | build/3d/cage/render_turntable.py, docs/LOOKDEV_STANDARD.md §4 | EXISTS | director sighted; Josh on the final |
| 13 | Game import + the swap gauntlet | emit_manifest_from_landed.py; HumanityGarmentComponent | PARTIAL | in-engine capture |
Critical path: 5 → 8 → 9 → 11. Everything downstream of the cage is blocked on the cage. Stages 1,
2, 3, 4, 6 and 10 run in parallel today on tools that already work.
---
THE RECIPE. A character enters the factory with three things on disk before a pixel is generated:
its canon row (registries/T0_Character_Index [ACTIVE v1.1]), a canon sheet naming what is fixed
(build/art/characters/CHAR_0001_CANON_SHEET.md, CHAR_0002_CANON_SHEET.md), and a **floor
reference** — Josh's own panel, which is the minimum bar and never the target.
THE FLOOR/EXEMPLAR DISTINCTION IS LOAD-BEARING AND WAS RULED TWICE. *"These are the floor"* then
*"Floor is not exemplar"* — the panels are the MINIMUM; the exemplar must EXCEED them: the panel's
appeal, warmth and charm RETAINED with photographic fidelity ADDED ON TOP. A cell that merely
reproduces the painted panel fails on fidelity; a cell that trades the panel's charm for fidelity
fails on appeal (DECISIONS :: CONFIRMATION / CLARIFICATION, 2026-08-06 night).
Landed floors for CHAR_0001: build/art/characters/CHAR_0001_AGE_BAND_FLOOR_JOSH_20260806.png
(age 7), CHAR_0001_AGE11_FLOOR_JOSH_20260806.png, CHAR_0001_AGE14_FLOOR_JOSH_20260806.png, and
CHAR_0001_AGE18_PROPORTION_REF_JOSH_20260806.jpeg — the last of which is explicitly not a floor:
Josh named the identity mismatch himself and gave it proportions-and-age-read status only.
THE TRAP — THE FLOOR'S OWN OVERSHOOT. Josh's original ChatGPT ladder is the beauty floor but its
adult panels overshoot: *"the age 18-24 looked like 20s to mid 30s."* Adult keystones take the floor's
CHARM read, never its literal adult age read (DECISIONS :: THE KEYSTONE AGING METHOD + TOOL FREEDOM).
---
THE WINNING RECIPE, verbatim from the record (build/3d/characters/CHAR_0001_KEYSTONE_7.json
:: wave2_josh_fixes.recipe_unchanged):
FLUX.2-klein-4B, M1's preserved first-contact graph, 1344 / 28 steps / cfg 4.0 / euler-simple,
cleaned reference VAE-encoded full size through ReferenceLatent at full strength, start latent
EMPTY. Only clauses and refine strength move in this wave.
The age-7 pick that validated it is BRACKET_B_HEAD_D22_S1 — a klein refine over the graded base's
own pixels at denoise 0.22, at the base's own generation seed 972000. Josh: *"on the
protagonist face, yes tile 4 i agree this is perfect"* (DECISIONS :: THE PICK). Every asset in the
record carries its sha256: the conditioning plate 37cafb4e…, the pick c29e34db…, the prompt string
3b6c15e3….
THE GRAPH, node for node (harness/asset_factory/bench_face_models.py, graph_flux2_first_contact;
checkpoints flux-2-klein-base-4b.safetensors / clip qwen_3_4b.safetensors type flux2 / vae
flux2-vae.safetensors): UNETLoader → CLIPLoader → VAELoader; CLIPTextEncode(prompt) and
CLIPTextEncode(""); EmptyFlux2LatentImage(1344,1344); `LoadImage(reference) → VAEEncode →
ReferenceLatent(conditioning, latent) → KSampler → VAEDecode → SaveImage`. **The reference is
VAE-encoded at FULL SIZE with no megapixel rescale**, and the start latent is EMPTY. When reference
strength drops below 1.0 a ConditioningAverage is spliced in; at full strength it is not.
THE BRACKET SHAPE, exactly as it ran (build/3d/model_survey/face_2026_08_06/BRACKET_VERDICT.json).
HELD: the prompt, the base's own pixels as start latent, the anchor's recipe/sampler/steps/size. SWEPT:
denoise 0.22 / 0.26 / 0.30 / 0.34 / 0.38 × seeds 972000-972003 = 20 cells, **plus 4 NULL cells at
denoise 0.02 (the instrument's own noise floor) and one generation-side anchor cell — 25 total**.
Preceding waves in the same survey: BENCH (2 candidates A/B) → TUNE (cfg 3.5/5.0/7.0 × reference
strength) → SURFACE_SWEEP → REFINE → BRACKET. Gate thresholds are measured, not chosen:
aspect_delta_abs_max 0.004877, hair_mass_delta_abs_max 0.006799, identity_copy_to_M1_min 0.9558,
iou_sanity_band 0.93 — 8 of 20 cells failed.
THE SEED IS THE LEVER, and the record refuses to rank on the axis its instrument cannot separate.
Seed 972000 lands 1.34–1.40× the anchor's detail at *every* denoise; the other three seeds land
1.08–1.14× — no overlap anywhere in the bracket. Meanwhile denoise 0.22/0.26/0.30/0.34 give
1.392/1.396/1.373/1.369, a 2% spread inside the NULL cells' own 0.047 noise floor, so
*"THE DETAIL INSTRUMENT CANNOT SEPARATE THEM, and this record refuses to rank them on it."*
THE ANCHOR GATE, and the drift it caught. BRACKET_ANCHOR must reproduce BENCH_B_HEAD_M1 at
silhouette IoU 1.0000 before any cell counts. It fired: graph_flux2 had been silently rewritten to
the vendor template's shape (SamplerCustomAdvanced + CFGGuider + Flux2Scheduler + a 1 MP reference
rescale), so *"the 'anchor' was running a different graph and calling itself the anchor"* — measured at
IoU 0.930, detail 1.19×, hair flipped SILVER→warm. **That is the second time in this programme a control
has caught a recipe drifting under a record's feet.**
THE PROMPT IS ONE FUNCTION, PROVEN BY REPRODUCTION. fullprompt_control(P) (sha256
72f611a0…, 6,114 chars) is called by both the refine and the bracket so the prompt cannot drift,
and the byte-verbatim claim is proven by reproducing the string rather than asserted from a hash. Its
clause stack is imported byte-verbatim from the generation-1/2/3 plate lanes (COMPLEXION, EAR_SWEEP,
EAR_ANATOMY, EAR_TRANSLUCENCE, EAR_SKIN, CATCHLIGHT, EYE_SURFACE_G3, IRIS, LASH_LINE,
LIGHT, REGISTER_RH, STAGING_PRE, STAGING_POST, TEXTURE_RH, NOSE, ORIENT, SKIN,
FRAMING, EXPRESSION) — clauses are imported, never retyped.
THE PER-AGE DIRECT RECIPE — and it supersedes the transform chain. Four iterations of deriving
11/14/18 from the age-7 pick by transform all degraded identity AND fidelity. RULED: each age keystone
is generated directly from its own Josh reference — clean/upres the reference → identity-condition
on it → photographic direction → refine at its own seed → judge against the floor. Cross-age
continuity is enforced by CHECKS against the pick, never by transform chains (DECISIONS :: THE
PER-AGE DIRECT RECIPE + SEPARATE CONTEXT WINDOWS). It is the first thing in the programme Josh graded
*"these turned out really well."*
Implementation: harness/asset_factory/keystone_direct.py — `RECIPE = dict(CANDIDATES["B"], steps=28,
cfg=4.0, size=1344, scheduler="simple", path="first_contact_ksampler"), SEEDS = [972000, 972001]`
(two candidates per age), cleaned references at `build/art/characters/face_cond_keystones/
CHAR_0001_FLOOR{n}_clean_1344.png` — *"head-and-shoulders on a flat mid-grey field at 1344"*, the keeper
step of the age-7 recipe. The judging is deliberately not the script's: *"the two-axis
exceed-the-floor verdict — the floor's charm/warmth RETAINED, photographic fidelity ADDED — is the
director's sighted read."* Wave-2 successor: keystone_wave2.py; winners in
build/art/characters/face_evidence/KEYSTONE_WAVE2_WINNERS.json (W2_7FX18N, W2_11W2R_GEN_S1,
W2_14W2_RL18_S1, W2_18FX18), with rung 7's winner being **the pick held as its own reference and
refined over its own pixels at seed 972000, denoise 0.18.**
THE THREE MEASURED FINDINGS THAT DROVE WAVE 2, each of which now binds every future age rung
(KEYSTONE_WAVE2_VERDICT.md):
ReferenceLatent sets the AGE, not just the face. Conditioning the age-14 prompt on the age-7 pick returned the age-7 pick — and still did at ConditioningAverage blend weights 0.35
*and* 0.55 (copy-to-pick 0.9958 at both). So identity never travels across an age gap.
whenever the base was a reference; only an EMPTY-latent generation came back without it.
THE NAMED TRAPS.
clause had already demonstrated: *"if you state that its going to be too over conservative… youll
force the model to focus on that only and losing significant context token value that needs to be
spent on keeping to the identity and fidelity."* RULED: coverage/register is **removed from prompt
text entirely**, implemented as framing defaults and sighted post-checks at zero prompt cost
(DECISIONS :: THE REGISTER MOVES OUT OF THE PROMPT). The same law killed per-lane recitation of
rules and hard lines: *"remove the existing rules and hard lines! youre wasting context tokens."*
model to preserve the very proportions the edit exists to move. Wave 2 holds identity FEATURES and
releases the proportions in as many words.
on sheets come from a sighted read (DECISIONS :: JOSH GRADES THE AGE LADDER - HORRIBLE).
FluxKontextImageScale SNAPS THE EDIT INPUT TO ~1 MP — so the model draws at 800×1328 and thealignment carries it back up. Measured cost across four rungs: figure micro-texture 48.9→41.3,
103.7→84.8, 74.9→61.7, 77.6→65.7 — 16 to 18 percent, spent on a resample that buys nothing. The
busts are 1344², already a clean latent shape: remove the node (DECISIONS :: THE BLUR HAS A
MEASURED CAUSE AND A PERMANENT FIX).
and the 18 robe are on the face defect list; face plates are bare-base head-and-shoulders at
every age (DECISIONS :: SUPERSESSION - 95821f11 WAS A DIRECTOR MISREAD).
THE HUMAN GATE. Josh picks the cell, per age, from the contact sheet. Four picks are locked:
age 7 BRACKET_B_HEAD_D22_S1, age 11 KEY11D_REF_S2, age 14 W2_14W2_RL18_S1, age 18 W2_18FX18
(DECISIONS :: KEYSTONE PICKS LOCKED). Faces were subsequently closed: *"the four bare keystones are
'perfect faces'"*.
---
Two derivative stages exist because the geometry lift must never see a garment or a mass of hair.
BARE DERIVATIVE (harness/asset_factory/bare_derivative.py; four-keystone driver
bare_keystones.py). The picked plate's garment region is inpainted to bare shoulders/upper chest at
the pick's own seed 972000, denoise 1.0 inside the mask, with the pick composited back everywhere
the mask is zero. Byte identity outside the mask: max abs difference exactly 0 on all four rungs —
age 7 1,322,496 of 1,806,336 px untouched, age 14 1,399,104, age 18 1,252,608; age 11 was already bare
and passed VERIFY-only (docs/PIPELINE_LEDGER.md :: FACE LANE — THE FOUR KEYSTONE BARE BASES).
THE ARCHITECTURAL CLAIM, in the tool's own words: *"identity is held by a MASK rather than by a low
denoise: the latent noise mask confines every changed pixel to the garment band … the denoise inside
the band can go to 1.0 without touching the thing Josh graded."*
Constants: GARMENT_MARGIN = 0.08 (required mean(R−B) separation, skin vs cloth) ·
SKIN_PROBE = (0.78, 0.845) / CLOTH_PROBE = (0.88, 0.98) as fractions of subject height ·
MASK_TOP_MAX_FRAC = 0.55 · MASK_LIFTS = {TIGHT 0.02, MID 0.045, ROOM 0.07} — the three-cell mask
bracket, and ROOM landed at both 14 and 18 · FEATHER_FRAC = 0.012 of frame height ·
NULL_DENOISE = 0.02 · DEF_SEED = 972000. Landed masks: age 14 top y=1066 (25.5% regenerated),
age 18 top y=958 (33.5%). The mask is full-width by design — *"a bare shoulder is NARROWER than
a clothed one, so the pass must be free to paint background where the tunic used to be."*
Graph: the img2img graph plus LoadImageMask(channel="red") → SetLatentNoiseMask, feeding the
sampler's latent input.
THE COMPOSITE IS NOT OPTIONAL, AND THE REASON IS MEASURED. *"The latent noise mask holds the
unmasked LATENT, not the unmasked PIXELS: the whole frame is still VAE-decoded at the end, and that
re-decode moves the face box by about 2.9 levels of 255 against a null-cell floor of 1.0."* So
the output is recomposited under the same feathered mask, with hard_top = mask_top_y − 3×feather_px,
and max_abs_diff == 0 above hard_top is asserted.
BALD DERIVATIVE (harness/asset_factory/bald_derivative.py) — the same method inverted, a
top-anchored mask, closing the pre-texture blocker D-W1 at its cause. **Identity is held by the MASK,
not by a low denoise**, and the record says why: a refine strong enough to delete a heavy tousled mane
is strong enough to redraw the face — three of four bracket cells failed the identity leg at denoise
0.38. Byte identity outside the mask over 1,119,558 px, 61.98% of the frame. In-game hair is a separate
groom stage, so the bald source costs the pipeline nothing.
THE TRAP — THE SEGMENTER IS REPORTED, NEVER THE LANDMARK. The pixel segmenter puts the age-14
tunic's top edge 142 rows low (y=1302 against a sighted y=1160), and on the bald pass it also
catches the eye apertures, both lash lines and the lip line because those are dark, cool and busy. So
the mask landmark is SIGHTED and declared, with the segmenter's own answer recorded beside it.
The colour-only garment instrument likewise cannot separate skin from a warm-toned garment (age-14
red-gold tunic, ‖d′‖ 0.287), which is why a texture axis (local luminance std) was added and armed
two-sided per plate: 14 d′ +1.28, 18 +0.83, 7 +0.13, **11 −0.29 — and that refusal IS the age-11
verification**, because the same instrument unchanged arms on the other three.
---
THE SPLIT IS THE RULING. Face and body generate on separate axes, in separate context windows:
FACE lanes see face references and face canon only; BODY lanes see ONLY the age-agnostic anatomical
proportion descriptions (feet to shoulders) and physique specs, never face material. Cross-axis context
contamination is a named defect (DECISIONS :: THE FACE/BODY SPLIT · THE PER-AGE DIRECT RECIPE +
SEPARATE CONTEXT WINDOWS). The evidence: *"face identity succeeded wherever references drove it;
failures clustered where body and face competed in one generation."*
BODIES NEVER CONDITION ON A REFERENCE IMAGE. Josh: *"if these are the ones that look like reference
images they arent minimalistic, their identity doesnt match our protagonists life."* Bodies generate
from descriptions — the BG3/CP2077 parametric pattern (DECISIONS :: BODY LADDER RULING).
THE SPEC LAYER. build/3d/characters/body_specs/BODY_AGE_{7,9,11,12.5,14,16,18}.json, emitted by
emit_body_specs.py against BODY_PROPORTION_METHOD.json. Its own words: *"the body ladder
INSTANTIATED at age N — every number derived by BODY_PROPORTION_METHOD.json, none typed in."*
33 top-level keys, including 18 segment_lengths_cm (foot length/breadth, ankle, knee, trochanter,
biacromial, biiliac, chest breadth, hand length/breadth, upper arm, forearm, acromion, thigh, shank,
elbow, wrist, across-shoulder soft tissue), 14 girths_cm (neck_base, chest, underbust, waist,
hip_max, thigh, knee, calf, ankle, bicep, elbow, forearm, wrist, hand circumference), 5 age_biases,
training_clock, segment_mass_fraction / _kg / mass_closure_kg, subcutaneous_fat_scalar,
metahuman_conformance, and 14 regions.
| 7 | 9 | 11 | 12.5 | 14 | 16 | 18 | |
|---|---|---|---|---|---|---|---|
| stature cm | 123.213 | 133.929 | 145.610 | 155.361 | 166.720 | 177.758 | 180.544 |
| head height cm | 19.155 | 20.089 | 21.107 | 21.545 | 22.055 | 22.789 | 22.974 |
| head-units | 6.4326 | 6.6668 | 6.8985 | 7.2109 | 7.5592 | 7.8002 | 7.8586 |
| hip fraction | 0.5417 | 0.5556 | 0.5694 | 0.5775 | 0.5809 | 0.5854 | 0.5899 |
| mass kg | 23.683 | 29.237 | 36.044 | 44.171 | 54.479 | 66.671 | 73.667 |
| role | KEY | between | KEY | between | KEY | between | KEY |
THE GIRTH TABLES are BODY_PROPORTION_METHOD.json :: girth_coefficients — one row per girth
carrying k, a_muscularity, a_adiposity, an age_shape_bias at the four keystones and an
age_shape_bias_derived at the three in-betweens. E.g. neck_base `k 0.2077, a_m 0.08, a_f 0.04,
bias {7: 0.8333, 11: 0.90, 14: 0.95, 18: 1.00}; chest k 0.516, a_m 0.12, a_f 0.06; waist_natural`
k 0.4321, a_m 0.04, a_f 0.14. The solve, in one line:
G = k · H · S · B · (1 + a_muscularity·m_n) · (1 + a_adiposity·f_n)
with H(age) anchored on the CDC-50 curve between a measured age-8 child anchor (stature 129.0,
head_units 6.567, 63,448 verts sampled) and the adult engine anchor (180.544, 7.8586); slenderness
S = sqrt[(M/M_adult)/(H/H_adult)³]; segment L = fraction_of_H · age_bias · H; **acromion height is
DERIVED, never fractioned**; physique axes ride MetaHuman's own units (muscularity ±2.323, adiposity
±2.753); and the anti_chisel_gate caps surface_definition_index at 0.62 with a declared failure
band of [0.7, 1.0]. Citations on the record: WINTER2009, DRILLIS1966, DEMPSTER1955, CDC2000.
THE ANTHROPOMETRY IS RESEARCHED, NOT INTUITED — Josh's order after rejecting the clay lineup:
*"exam photos online of what each and every age range looks like and also scientific research…
build those proportions at every angle, and then alter it for our exemplar bodies."* The research is
build/3d/characters/body_specs/AGE_PROPORTION_RESEARCH.md, machine half
AGE_PROPORTION_TARGETS.json, field-level diff AGE_PROPORTION_REBUILD_REPORT.json. Its four
load-bearing findings:
grows only 8.5% from 7 to 18 while stature grows 44% and biacromial breadth 52%.
hu); the artistic canon measures to the hair silhouette (adult 7.5). This pipeline measures in
the hair convention and must target it — the rejected lineup's whole defect.
13** → 0.5215 at 18. A thirteen-year-old's legs are proportionally longer than a grown man's. A
monotone leg-length curve cannot have that phase, and the rejected lineup's was monotone.
years; head breadth over shoulder breadth moves 29% (0.529 → 0.376). There is no other reference
in the silhouette.
THE PHYSIQUE BRACKET — THE HUMAN GATE. The 18 rung ping-ponged three times on physique, so V5
stopped guessing and delivered a 3-cell physique BRACKET per graded rung around the target, so Josh
picks the calibration point (DECISIONS :: BODY V5 GRADES + FACES ON). He picked the TARGET column at
every age: BodyV5_A7_TARGET_a0, BodyV5_A11_TARGET_a1, BodyV5_A14_TARGET_a1,
BodyV5_A18_TARGET_a0 (DECISIONS :: BODY PICKS LOCKED). **This is the pattern for every future
character: a bracket, not a single-point guess, the moment an axis oscillates twice.**
THE PHYSIQUE LAW — THE TRAINING CLOCK, not a generic age chart. *"11 should have some tone and some
ab definition yes, weve already lived in the human world for 4 years at this time."* The body at every
age shows what the spine's lived history has earned by that chapter. Final calibration after the curve
was steepened: real tone at 7, defined at 11, sharply athletic at 14, genuinely chiselled at 18 — with
18 lean-chiselled, a swimmer/climber cut, not bulk (DECISIONS :: TONE CURVE STEEPENED ·
AGE-18 PHYSIQUE CALIBRATION). The surviving kill criterion is the age read: an 18 that reads 40
fails regardless of physique quality.
THE NAMED TRAPS.
trainingwear → blank doll → chunked photoreal → true photoreal → clothed → reverted. The clothed
ruling was a director misread of which sheet Josh was pointing at and is VOID. The settled state:
true photoreal at every rung, the in-game minimal-underwear swap layer worn at 7/11/14, tasteful
minimal at 18, the crotch never photoreal anywhere. **The lesson generalises: confirm which artifact a
grade refers to before deriving a ruling from it.**
reported zero clamps on every constraint at every rung and still returned an unusable source at
the young ones: at age 7, 11 of 21 requested constraints sat outside the model's own windows, the
solved bideltoid span came back 2.11× the rung's, and the conform then squeezed it laterally by
0.474×. BODY_AGE_7.json :: metahuman_conformance had written the warning down before any of it ran
and nobody had read it as a capability limit.
(1 − scale) CANNOT BE FOUND AT THE RUNG THE TOOL WAS BUILT ON.** conform_true_base.py's per-part centre curve had a second-difference std of 4.27 cm on the leg
parts. A vertex moves to c + (v−c)·s, so an error in c displaces it by (1−s)·error — about 2 mm
at A14 where s≈1, and ~1.5 cm of ringed corrugation down the thigh and shin at age 7 where
s≈0.65.
7.859** — forbidden by the file's own law. Cause: stature interpolated on the violently concave CDC
curve while head-size bias was read linearly in age. Two curvatures over one span, and head-units
is one divided into the other. Fixed at cause; the BETWEENNESS tooth caught it on its first run.
through an ellipse — measured wrong by about 30%. A thorax is not an ellipse and the error is not
a rounding error. Three sibling traps ride with it: breadth is taken at maximum inspiration and depth
at quiet respiration (two numbers from one table are not from the same breath); calliper breadths
compress soft tissue and tape girths do not; and a skeletal landmark (biacromial) must never be
fed into a soft-tissue envelope site (bideltoid), because a mesh cross-section measures an
envelope (AGE_PROPORTION_RESEARCH.md §9, "FOUR METHOD TRAPS").
failed. The researched whole-body proportion truth is the solve target, not a site list
(DECISIONS :: CLAY LINEUP REJECTED).
NIST AnthroKids numbers, not its measurement-position plates; the recommended visual reference is
museum sculpture, because the silhouette masses are already resolved in three dimensions — the
Spinario against the Getty Victorious Youth is exactly our 12.5→18 delta
(AGE_PROPORTION_RESEARCH.md §7).
---
THE APPROVED CHAIN, ENTIRE, verbatim from the ruling (DECISIONS :: THE KEYSTONE MERGE CLOSES ON
THE SIMPLEST CHAIN):
the picked V5 TARGET cell on the canvas merge_identity_v6.place() solves; ONE Qwen-Image-Edit-2511
head replacement at that cell's own seed, exemplar bust at full 1344 px as image2, the body as image1
AND the start latent, denoise 1.0; ONE similarity alignment into the picked plate's frame. **Nothing
else.**
Tooling: build/3d/characters/body_specs/merge_identity_v6.py (the canvas solve, place()),
merge_route_a_v8.py (prepare() → align() → finish()) and merge_race_a14.graph_qwen_edit().
The edit runs **euler / simple, 40 steps, cfg 4.0, ModelSamplingAuraFlow shift 3.1, CFGNorm,
TextEncodeQwenImageEditPlus**, on qwen_image_edit_2511_fp8mixed.safetensors with clip
qwen_2.5_vl_7b_fp8_scaled.safetensors. The path that runs the graded chain and nothing else is
--approved-only: *"THE JOSH-GRADED CHAIN AND NOTHING ELSE: canvas, edit, align, save."* The aligned
plate is written before any post-pass — *"until this line moved, one did."*
| age | arm | seed | scale | dx / dy | iou | placed head px | seam row | canvas |
|---|---|---|---|---|---|---|---|---|
| 7 | CONTROL_RAWHEAD_s0 | 9507211 | 1.04971 | 1 / 28 | 0.98625 | 223.8 | 306 | 832×1440 |
| 11 | CONTROL_RAWHEAD_s0 | 9511242 | 1.05497 | −2 / 9 | 0.98592 | 191.8 | 269 | 832×1416 |
| 14 | CONTROL_RAWHEAD_s0 | 9514242 | 1.05280 | 1 / 7 | 0.98661 | 171.1 | 246 | 832×1416 |
| 18 | BIGHEAD_s0 | 9518211 | 1.04885 | 1 / 38 | 0.97330 | 174.7 | 253 | 832×1456 |
Rung 18's final is ALIGNED_BIGHEAD_s0_A18; 7/11/14 are frozen on the aligned-rawhead cells. Josh
closed the axis: *"yes the v3 sheet is exemplar for 7, 11, 14, and 18."*
FOUR PASSES WERE BUILT AND EXCLUDED BY THE GRADE. The record states it flatly: *"NOT APPLIED:
exposure match, head rescale, body restore, membrane heal — all four were built this sitting against
instrument readings and all four are excluded by the grade."*
| pass | function | why it was built | why it is out |
|---|---|---|---|
| exposure match | match_backdrop() | a join between two photographs; a backdrop-only fit left a visible step in the skin, so the fit also takes shoulders and upper chest | excluded by the grade — the graded cell is the raw aligned plate |
| head rescale | resize_head() via measure_head() | the instrument said the head was off-spec | driven off a neck minimum that lands on the jaw; it GREW rung 14's head 4.6% when it needed shrinking, and Josh on the scale-ups: *"deformed proportions - abandon them"* |
| body restore | the restore in finish() | route A redraws the physique below the join; this puts the picked cell's pixels back byte-exact | excluded by the grade |
| membrane heal | one_sided_membrane(), JOIN_FEATHER = 8, MEMBRANE_BAND = 56 | removes the join tone step in the gradient domain | excluded by the grade |
A future lane must not re-add them without a grade that asks for them. One ordering lesson is kept
in the source even though the passes are out: exposure match first, then head fit, then body
restore — running the exposure match last *"printed a horizontal band across the whole frame."*
THE NAMED TRAPS.
and blend — and the visible paste was its direct consequence (Josh: *"i dont think youre able to just
copy and paste them on there"*). RULED: the 2D merge is GENERATIVE; face identity is **PROVEN BY
MEASUREMENT** (copy-index ≥ 0.99 against the exemplar plus a sighted 1:1), never frozen by hash
(DECISIONS :: MERGE FIX - IDENTITY-LOCK REPLACES BYTE-LOCK).
the panels looked** — the signature of a detector correlated with the thing it was supposed to
measure independently.
sighted chin at 229, so crown-to-neck under-measures the head by a sixth, and a rescale driven off
it GREW that head 4.6% when it needed shrinking. Good chin landmark, useless head-height one.
find_face COLLAPSES TO 0.58–0.60 at rungs 7 and 11 — on the plates Josh called great — which itsown docstring already records as an instrument failure. Both instruments are **advisory; neither
gates** (DECISIONS :: TWO INSTRUMENTS ARE WRONG ON THESE PLATES).
a body-sized canvas fixes the head size (183 px against a 174 px target) and returns **a different
boy**: identity 0.848 scaled and 0.820 native against the raw bust's 0.968. A head at final size is a
~170 px face inside a 1 MP frame and carries almost no identity for the vision encoder to copy. **The
solved head-unit ratio cannot be delivered on the reference side.** On rung 7 a split reference (bust
for WHO, composite for HOW BIG) recovered 0.971; on 14/18 the plain raw bust was already right.
(merge_perimeter_v6b.py) shrank face protection to exactly the inner-face rectangle — brow to
just above the chin, inside the cheeks — which is precisely the window the identity gate measures, so
the identity number could not move and the sighted read was the only real one. The lane said so on
its own face. That is the correct posture and the correct disclosure; it is not a passing gate. The
same defect had killed V6 from the other side: *"the inner-face metric went vacuous while everything
outside it regenerated — the exemplar drifted."*
refused every age-11 perimeter rung. Its ranking was still right at the extreme (the genuinely broken
d0.76 rung, which grew a ghost second face, scored worst), so the threshold was relaxed **for
perimeter passes only** and the eye decides inside it.
would have taken denoise 0.52; the eye took 0.40 (0.64 restyles the hair lighter and enlarges the
ears; 0.76 grew a ghost face on the cheek). On A18 auto would have taken 0.76 purely on a blob score;
the eye took 0.52 (0.40 is fringe-clean but carries a blue-teal temple streak).
--age 14 then --age 18left a pass record containing only 18 — the same class as a gate reporting a clean pass on an empty
set. The log now merges.
THE PERIMETER PASS, as it actually ran. Protection = the inner_face_box rectangle, alpha-ramped
by PROTECT_FEATHER = 16 px on a distance transform; crop padded 0.30 of the head-column span
horizontally and 0.16 of head height vertically, extending to seam + 1.1 × head_px, rounded to
multiples of 8; denoise ladder [0.40, 0.52, 0.64, 0.76]; seed = the unification pass's seed + 401 + i.
| age | kept denoise | copy-index (inner face) | largest blob | micro-texture |
|---|---|---|---|---|
| 7 | 0.64 | 0.99345 | 0.00747 | 106.7 |
| 11 | 0.40 | 0.99258 | 0.03474 | 164.72 |
| 14 | 0.40 | 0.99371 | 0.00511 | 106.0 |
| 18 | 0.52 | 0.99116 | 0.00470 | 113.32 |
Note age 11's blob at 0.03474 against the guard's SILHOUETTE_BLOB_MAX = 0.012 — that is the
mis-calibrated guard being overridden by the eye, on the record.
MEASURED OUTCOME OF THE MERGE LANE (the bar every future character inherits): identity
0.99116–0.99371 against the ruled 0.99 floor; body fidelity 0.970–0.983 against Josh's picked
cells; micro-texture 106–165 against a 75.1 photoreal floor.
THE REFERENCE HIERARCHY, ruled after the merge landed. *"Exemplar Face Picks + Exemplar Body Picks
Exemplar Full Body. Exemplar Full Body loses some detail."* The SOURCE PICKS are the detail ground
truth — faces reference the KEYSTONE_BARE busts, bodies the BodyV5 TARGET cells, at full fidelity.
The merged full-body plates are composition reference only (head-on-body proportion, framing, the
approved whole). This binds 3D face wraps, chunk-photoreal texture comparisons, palette sampling,
in-between bridging and every polish pass (DECISIONS :: REFERENCE HIERARCHY).
---
THE LADDER IS SEVEN AGES: 7, 9, 11, 12.5, 14, 16, 18 — keystones plus in-betweens (DECISIONS ::
MERGE DISCIPLINE + SEVEN AGES; this supersedes the 12-age framing that
BODY_ASSEMBLY_ARCHITECTURE_BRIEF_2026-08-06.md §6.1 stage 5 still carries).
THE KEYSTONE ORDER IS JOSH'S OWN, and it is the largest jumps first: anchor ages 7, 11, 14, 18
built first — 7→18 the extremes, then 11 (prepubescent) → 14 (postpubescent) across the puberty
boundary — then interpolate between keystones. **Fill ages derive from graded keystones, never the
reverse** (DECISIONS :: THE KEYSTONE AGING METHOD + TOOL FREEDOM).
WHAT FAILED FIRST, AND WHY IT WAS A CATEGORY ERROR. Dual-anchor conditioning — both adjacent
approved busts through FLUX.2's chained ReferenceLatent — does not average. It picks one. Three
cells settle it: IB_9_BR_S1 (7 then 11, seed 972000) copy→7 0.9964 / copy→11 0.458;
IB_9_BR_S2 (same order, seed 972001) 0.4333 / 0.9947; IB_9_RB_S1 (reversed order, seed 972000)
0.9954 / 0.4582. Opposite orders at the same seed land on the same anchor; the same order at
different seeds lands on opposite anchors. **The seed decides, which is another way of saying the model
never mixes them. Nothing lands between at any setting. The mechanism: ReferenceLatent appends**
to the conditioning's reference list — it concatenates, it does not interpolate — and two whole-frame
references over one canvas are two mutually inconsistent spatial priors, so the model satisfies both by
drawing both. **The registered 50/50 pixel blend returned exactly what Josh named: a double-exposure
ghost, two ear sets, overlaid hair shells.** Ruled out permanently
(AGING_METHOD_RESEARCH.md §1).
**THE RESEARCH SAYS THE SAME THING, which is what makes Josh's replacement the endorsed method rather
than a fallback.** All four production and research families — parametric blendshape age morphs (DAZ
Genesis, Reallusion CC, Unreal/Blender shape keys), Disney's FRAN, **StyleGAN latent age
directions (SAM and the 2025 Idiap SVR successor), and diffusion age editors (TimeMachine**, MAE
3.84 y across 10–70 against SAM's 5.34) — condition on ONE face and move it along an age axis.
None is shown two photographs of the same person at two ages, because that is compositing, and
compositing two faces is the ghost.
TWO RESEARCH FINDINGS THAT CHANGED HOW THE LADDER RUNS. TimeMachine's ablation (drop age control →
MAE 20.52; drop identity control → similarity 0.06) means **age and identity are separate control
channels and both are named outright** in every instruction. REED-VAE's measurement that encode/decode
alone accumulates visible artifacts within 5–10 iterations means **chained candidates are judged on
micro-texture, not only on the age read** — and it happened here, in both directions: A9_FWD7_1Y1Y
(7→8→9) and A9_REV11_1Y1Y (11→10→9) both came back with darkened speckled freckles, which the ruled
freckle clause forbids in as many words. **The cost is direction-independent, which is exactly what a
VAE round-trip cost should be.**
ROUTE S (instruction edit) IS REFUTED FOR STRUCTURE — measured, not preferred. Wave 2 rebuilt it
properly (age direction carried as named anatomy — *"the midface lengthens, the cheek fat pads
recede, the jaw takes an angle at its rear corner"* — plus a corrected hold clause and an emphatic arm).
At 12.5 it moves nothing: struct_pos −0.005 measured and −0.031 emphatic forward; +0.915
and +0.946 reverse — and the emphatic arm moved LESS than the measured one in both directions,
which is saturation reproducing under the strongest phrasing the lane could write. At 16 it costs
44% of the anchor's micro-texture (3142–3239 against 5724) and the emphatic reverse plate scored
ratio_pos +1.483 — it aged him *past eighteen* when asked to de-age him to sixteen. A single
Route-S edit costs ~37% of micro-texture.
ROUTE W IS THE WINNING RECIPE, AND IT CANNOT GHOST BY CONSTRUCTION. Dense landmarks on both anchors;
the other anchor's set brought into this plate's frame by full similarity; the sets averaged at the age
fraction; and ONE anchor image's own pixels warped onto the result by a thin-plate-spline backward
map with fixed border control points. One image's pixels are moved, and a pixel between two positions
is one pixel. Tooling: harness/asset_factory/face_landmark_warp.py (warp + instruments) and
aging_ladder_w2.py (driver + heal).
Exact parameters. PAIRS = {12.5: (11, 14), 16: (14, 18)}; WARPS runs both directions at
fraction 0.5 — A12H_W_F11_RAW (11's pixels), A12H_W_R14_RAW (14's pixels), A16_W_F14_RAW,
A16_W_R18_RAW. Landmarks: MediaPipe FaceMesh, `static_image_mode=True, max_num_faces=1,
refine_landmarks=True, min_detection_confidence=0.3` — 478 points detected, 468 used, the ten iris
points excluded because *"a boy looking a millimetre left is not a boy with a different skull."* Warp:
RBFInterpolator(dst, src−dst, kernel="thin_plate_spline", smoothing=0.0) evaluated on a coarse grid
and bilinearly raised, with 9 fixed border control points per edge, resampled by cv2.remap at
Lanczos-4 with BORDER_REPLICATE. Heal: one pass at HEAL_DENOISE = 0.30 on the RAW warp —
*"the warp decides the structure and the heal only removes warp artifacts."* The lane runs in a pinned
3.12 venv because mediapipe and OpenCV have no 3.14 wheels.
warps score struct_pos +0.403 / +0.604 at 12.5 and +0.504 / +0.563 at 16, with ratio_pos
agreeing — **both instruments agreeing in both directions at both ages, which no other route
managed.**
anchor's own detail_index (6310 against 6389; 5639 against 5724).
15% of micro-texture. Both plates ship so Josh prices the trade.
JOSH'S FROM-OLDER-ANCHOR PATTERN IS THE DEFAULT PRIOR. Every in-between he has picked derives from
the OLDER anchor: age 9 = A9_REV11_3Y (the approved 11 reverse-aged three years); age 12.5 =
A12H_W_R14_HEAL (the reverse-from-14 landmark warp, healed). And his rejection of the 16 candidates
states the principle directly: *"the A14 ones you pushed to 16 had smaller jaw structures than even
their A14 which isnt right especially if were trying to be the in between to A18"* — **a rung must
progress toward the older anchor's structure, never regress it.** Wave 3 builds 16 from the 18 side
(DECISIONS :: AGE-9 EXEMPLAR PICKED · AGE-12.5 PICKED + 16 REJECTED AGAIN). **Default the generator to
the older-anchor derivation and offer the younger-anchor arm as the alternate.**
THE PRESENTATION SPEC IS JOSH'S OWN AND IT IS A GATE. *18 candidate-context ladders + the final* —
ladders 1-6 slot each age-9 candidate into [7, 9c, 11, 14, 18]; 7-12 each 12.5 candidate into
[7, 11, 12.5c, 14, 18]; 13-18 each 16 candidate into [7, 11, 14, 16c, 18]; ladder 19 is the final
[7, 9, 11, 12.5, 14, 16, 18] from his picks. **Every candidate is judged IN PROGRESSION CONTEXT, never
as a tile** (DECISIONS :: FROZEN FINALS STAND + THE 19-LADDER SPEC). The companion law: every keystone
cell is judged in a side-by-side against Josh's own reference for that age, inline on the sheet —
*"a sheet without the references inline is un-DONE"* (DECISIONS :: THE SIDE-BY-SIDE LAW).
THE IDENTITY CURVES THAT RIDE THE LADDER (canon, four fixed points, read at the target age rather
than picked): hair silver-blonde at 7 (fairy realm) → visibly warm sandy-blond by 11 → dirty blonde
through 14–18; freckles — the pattern is permanent identity, the INTENSITY fades, pronounced at 7 →
minimal by 18, never dark and never speckled; warmth — the age-7 keystone's warm skin and light
read carry through every age, and a shiny/waxy/metallic glow is a named defect class.
THE IN-BETWEEN BODIES DO NOT GET 2D PLATES. They build directly in 3D from the landed specs
(solve → conform on the picked S2 route), textured chunk-by-chunk against the adjacent approved
keystone plates' palette (interpolated), reviewed as turntables. In-between FACES do get portraits —
head-and-shoulders only, bridged from the approved busts — and they anchor the 3D face wrap at those
ages (DECISIONS :: IN-BETWEEN PATH REVISED - 3D-DIRECT).
---
THE DERIVATION DIRECTION IS THE WHOLE ARCHITECTURE. The cage conforms to the plates; it never
derives from them. A complete template body is wrapped onto the plate-derived shape:
topology, regions and UVs are the cage's; form is the plates'. Anatomical completeness comes from
the cage — parametric, complete by construction — so **the plate never needs to depict what the mesh
must contain** (DECISIONS :: THE CAGE REVIEW STACK + THE SWAP GAUNTLET · THE TWO-REGISTER BARE).
THE TWO REGISTERS OF "BARE", never conflated. The plates are 2D grading surfaces in the
tasteful-minimal display register. The 3D base mesh is dev-only and TRUE BARE — anatomically
complete under everything — because per-region suppression and the swap floor only work over a complete
substrate, and the game's historical cultural apparel (minimal-coverage wraps, open dress across regions
and eras) demands a base that is correct wherever gear does not cover.
THE WRAP RECIPE PICKED: Lane S2, the numpy landmark-NRICP (build/3d/cage/CAGE_PICK.json,
RACE_CLOSE.md). Ranked max over both targets: S2 p95 0.01749 / mean 0.003678 / landmark 0.17602
against S1's 0.04965 / 0.017915 / 0.18718 and a do-nothing FLOOR of 0.05232 / 0.018373 / 0.17905. **S2
is 2.84× better than S1 and 3.0× better than doing nothing — while S1 is only 5.4% better than doing
nothing.** S1 wins wall-clock alone (16.29 s against 351.46 s), which the spec ranks last.
**THE BLOCKER, CLOSED BY ITS OWN REFERENCE (superseded in place 2026-08-10, director-rows wave;
originally: "S2's blend proof fails — 3 of 30,540 faces, min normal agreement −0.620 vs the −0.5
bar").** The failure was the INSTRUMENT'S, not the recipe's: bench_cage.blend() judged G4 against
PARENT A while gate_G4's own _why names THE CAGE as the reference — proven by four controls
(t=1.0 is parent B bit-for-bit and reads 23 flips vs parent A but 0 vs the cage; the bite and mirror
mutations still FAIL against the cage, so the corrected reference did not go soft). Re-referenced,
the blend proof PASSES; verdict and controls in
build/3d/cage/blend_fix/BLEND_G4_REFERENCE_FINDING.json (landed 869ba32f), diagnosis in
BLEND_FLIP_DIAGNOSIS.json. All seven WRAP_A*_V3Q.obj exist under solver_nricp/. **The
seven-age lane's release gate is CLEAR on this axis.**
THE FLOOR ROW IS WHY THE PICK COULD BE READ AT ALL. Without a do-nothing arm in the table, S1's
0.04965 would have looked like a result. It was 5.4% better than not running. **Every future bake-off
carries a do-nothing floor row.**
BE PRECISE ABOUT WHAT EXISTS AT THIS STAGE, because three different things are easy to conflate.
export_metahuman_bare_body.py → mh_true_base.py (frame map, weld, measure) → TRUE_BARE_BASE.json (partition + UDIM + material
slots). It welded 32,334 UV-split vertices onto 30,455 positions, adopted a stature of
155.292 cm from two independent anchors that agree (knee 155.292 against trochanter 151.377,
spread 0.025 — *"Two anchors that agree are a measurement, one is an assumption"*), and reads all six
girth sites plus a neck base measured **on the open neck rim as a closed polyline of 92 boundary
edges**.
genuinely absent — a proportion-correct symmetric base to inherit topology from: CC0 assets, copyleft
binding the tool and not the output, no revenue threshold, no engine coupling, and *"the only option
that takes proportions in real centimetres."*
brief calls it *"the highest-value thing this brief can point at."* Anny is corroborated at
**13,380 v / 13,378 quads / 163 bones, Apache-2.0 + CC0, WHO-calibrated infant→elder, 2.7 mm fit on
child scans** — with a second source disagreeing at 13,718 v / 104 bones, which is itself worth knowing
before a GPU hour is spent. Its proof is specified: a blind A/B plus a child-proportion read against
the canon 6.567 head-units, with both arms re-rendered by the SAME instrument.
Tooling options are priced: Faceform WrapCmd is genuinely headless and batchable at Indie $570;
Blender gives Surface Deform and Shrinkwrap but not landmark-constrained coarse-to-fine NICP, which
is the real cost delta. Acceptance is specified — same vertex count and order as the cage, surface
deviation under a stated tolerance, the ear retained (the one morphological elven marker) — with a
per-vertex deviation heat-map on a fixed colour scale as the proof image. **The named failure band is
child-vs-adult proportion for wrap without landmarks**, which is precisely why the cage choice should
prefer something already parametric over something that must be wrapped into the child band.
WHY THE WRAP IS NON-NEGOTIABLE, in one measured line: *"two age states generated independently
CANNOT be blended — there is no vertex correspondence to blend along."* Identically-topologised wraps
are blendshapes of each other; independently generated ones are seven different assets. **That single
fact is what makes a Tier-A age ladder affordable, and it is gated entirely on this stage.**
THE TRAP THAT PRECEDED THE COMPARISON — an instrument scoring emit conventions, not wraps. Two of
five defects in build/3d/cage/instrument_fix/ROOT_CAUSE.json scored a lane on its choice of OUTPUT
FRAME: the alignment optimised an untrimmed mean over a similarity including scale **with no lower
bound, whose global optimum is scale zero — and it took it, at 0.057 of the honest unit ratio**; and the
flipped-face criterion compared normals in two different frames, moving the same geometry between 0 and
20,694 flipped faces in two files. One lane emitted in centimetres and the other at target scale, and
the spec never named a unit. **A pick from those numbers would have been a pick between emit
conventions.** The patch was applied only after all twelve existing self-test arms still bit — the
condition being that it had to take nothing away.
THE FINDING THAT OUTLIVED THE LANE: there was no nude base anywhere in the lineage. Measured
vertex-for-vertex on identical topology, 26,196 of 63,448 vertices are garment-covered and **16,279 of
them — 62.1% — did not move at all** in the ruled de-merge to bare (below the knee 96% unmoved, torso
82%, head and neck 100%). The mesh passed as --nude renders as a sleeveless tunic and shorts. So the
doll crotch and the no-collision underwear had no skin to sit on, and the 3D asset and the 2D plates
were not showing the same body. **Order corrected: nude base first, then keystone faces in 3D, then the
blend-proof blocker, then the rungs. The general law: verify that the artifact named bare is
bare, on the pixels, before anything conditions on it.**
THE FOUR REVIEW LAYERS Josh set for the cage — (1) the cage source, judged on anatomical
correctness, articulation-ready topology, child-through-adult range and licence; (2) conform correctness
per character and age against the plate-derived shape on the ruled axes; (3) ROM calisthenics on the
rigged result; (4) THE SWAP GAUNTLET (stage 13).
---
THE REFRAME FIRST, because it is the whole finding. The rejected chain was not losing on model
quality — it had no base mesh under it, so it assembled lofted parts and solved proportions onto the
assembly. Measured: the rejected chain is the only genuinely multi-part mesh (**4 connected components,
70.6% of faces in the largest, against 99%+ for every generated arm) and the lumpiest (0.0104**,
~2×) — while being **nearly perfectly bilaterally symmetric because it is mirror-built by
construction.** So the "scoliosis" was never asymmetry: it was part seams and head-to-yoke integration,
and a lane that had gone chasing symmetry would have fixed nothing and reported success.
TWO ROUTES ARE LIVE AND THEIR STATUS DIFFERS — state it precisely, because they are easy to confuse.
RATIFIED PRODUCTION GEOMETRY: TripoSG. `TRIPOSG_SETTINGS = {seed: 42, steps: 50, guidance: 7.0,
faces: 250000, octree: 9}, invoked gen3d.py --image <ref> --out <raw> --save-cond <cond> --faces
250000`. 21.63 s mean (n=13, 14.6–44.4) at 5.31 GiB peak (5.16–6.09), manifest DL_0005, MIT code
and weights with RMBG-1.4 deliberately not used. It is not an unreviewed default: it won a blind
A/B, and the arm that lost — arm f, Hi3DGen used as a MULTI-VIEW geometry conditioner — regressed
at silhouette −0.89 and form_identity −1.00 across nine items with **four ties, four
regressions, zero improvements, including a regressed CONTROL**, which is the signature of a route
that is worse in general rather than worse on hard cases. Its mechanism was diagnosed, not guessed:
*"i2mv INHERITS THE PLATE'S STAGING"* — a plate whose six views are not a turnaround of one object
collapsed to 1/1, while a clean turnaround tied 5/5. **The bound the record itself sets: only
UNREGISTERED views feeding a stochastic multi-image sampler lose on thin multi-part subjects.**
RECOMMENDED FOR CHARACTERS, PROPOSAL TIER: Hi3DGen / Stable3DGen single-image (weights
Stable-X/trellis-normal-v0-1, MIT, already installed). Constants: `seed 42, ss_steps 50, slat_steps 6,
cfg_strength 3 on both samplers, with a StableNormal_turbo normal bridge (yoso-normal-v1-8-1`),
preprocess at 1024 and normals at 768. Measured on the A14 plate: `t_load 20.36 s + t_normal_load
7.43 + t_normal 0.45 + t_geometry 23.3 = 59.15 s total, peak_vram_alloc 10,849 MiB / reserved
12,104 MiB`, 86,322 verts / 172,674 faces, not watertight (euler −17), on torch 2.9.0+cu128 at
compute capability 12.0. Across nine bench items: 25.26 s mean geometry, 10.99 GiB mean peak —
with the caveat carried on its own record that *"includes a per-call cold WSL model load; a batch would
amortise it (t_geometry alone measured 4.3–6.5 s)."*
It wins every symmetry and straightness column of the bake-off outright — sym p95 0.0022 / drift
0.0029 / width-asym 0.0035 against the rejected chain's 0.0052 / 0.0051 / 0.0072 and TripoSG's
0.0060 / 0.0115 / 0.0231 — and wins them against an arm that is symmetric by construction. It puts
99.1% of its faces in one body and is the only arm with defined knees, a real garment, separated
fingers and a face with structure. The bake-off is PROPOSAL tier and adopts nothing; its own
recommendation is to run generation as the stage with Hi3DGen as the live default for characters and
re-run the bake-off with TRELLIS.2 as a fourth arm the moment the gate opens.
THE BLACKWELL LANDMINE, solved: XFORMERS_DISABLED=1. Hi3DGen's crash was not its own attention
backend — it honours ATTN_BACKEND=sdpa, and the run log confirms Using backend: sdpa — but
DINOv2 auto-detecting xformers independently, and xformers has no sm_120 kernel. One environment
variable, prefixed on the WSL invocation; then 59 seconds.
THE REAL 3D DEFECT WAS THE CANDIDATE SET, NOT THE CHOICE — the benchmark's own words:
"only_one_multiview_model_was_available".
THE TRELLIS.2 ARM IS SUBMITTED AND AWAITING REVIEW. TRELLIS.2-4B is installed on the box with 16.2
GB of weights (D:\assetgen\models\TRELLIS2, 22 files) and is one click from running: its image
encoder facebook/dinov3-vitl16-pretrain-lvd1689m is a GATED Hugging Face repo whose terms **the
account holder must accept**. The DINOv3 licence does permit commercial use; the gate is a
contact-information agreement, and accepting an agreement is Josh's to do, not a lane's. The
instrument, conditioning and sheet builder are all written, so the arm is a minutes-long re-run once it
opens.
The install recipe is build/3d/bakeoff/install_trellis2_win.ps1 — venv D:\assetgen\venv_trellis2_win,
python 3.12, torch==2.8.0+cu128, with prebuilt cp312 wheels for cumesh, flex_gemm and o_voxel
— after upstream's pinned torch 2.6.0+cu124 (no Blackwell kernels at all) and its six source-built CUDA
extensions took the WSL VM down twice with Wsl/Service/E_UNEXPECTED and no OOM in dmesg.
nvdiffrast and nvdiffrec_render are deliberately NOT installed, and the script says why in a
comment: *"NVIDIA Source Code Licence, which is NON-COMMERCIAL — installing them would make an
MIT-headlined pipeline unshippable in fact."* The verify log's `MISS o_voxel ModuleNotFoundError No
module named 'nvdiffrast'` is therefore the expected, correct output — it is the licence boundary
showing up as a clean import failure on the export path only.
THE LICENCE READS THAT BIND THIS STAGE.
excluding the European Union, United Kingdom and South Korea; §2 grants rights for the Territory
only; §4.c bars use or display of the OUTPUT outside it, and §1.h defines Output to include the
generated meshes. A worldwide Steam release violates that by definition. It was installed and run for
evidence (watertight, 60 s, 8.65 GB, visibly softer with mitten hands) and struck on the sheet's own
face so no later lane re-tries it. Note hy3dshape/minimal_demo.py still carries a stale
NON-COMMERCIAL header; the LICENSE file governs.
TRELLIS.2's render/preview side, not its generation side, and both it and nvdiffrec are opt-in
setup flags. With a find_spec guard and a positive control proving the guard bites,
trellis2.pipelines imports cleanly without nvdiffrast and o_voxel does not — so the geometry
path is licence-clean and the taint sits in the GLB exporter, which is the substitution point for the
already-proven Blender-headless route (the same substitution already ratified for MV-Adapter).
THE HAIR-FREE CONDITIONING SOURCE IS ROUTE-AGNOSTIC AND BELONGS HERE. Any image-to-3D generator
handed CHAR_0001_KEYSTONE_BARE_14_BALD.png sees a skull instead of a mass of separated strands. The
A/B that produced it had already relocated the defect: --scalp-policy skin_only was worse, which
proved the crust is not the scalp's but the fringe band's, where strand hair overhangs skin — so the
fix is upstream, in the conditioning plate, and not a solver parameter.
GENERATIVE 3D IS A BASE SCULPT AND A BLOCKOUT, NOT A SHIPPABLE ASSET — and the vendors say so
themselves: Meshy's documentation concedes fused fingers and asymmetric faces and calls DCC repair
standard practice; Tripo's own blog notes auto-retopology has no concept of where an elbow bends. A
controlled academic comparison put AI at 238 minutes against 716 for hand work and concluded the
contribution is ideation and early prototyping. That is the correct job description, and it is
exactly the job the rejected chain was doing badly by hand.
---
BOTH PASSES IN THIS STAGE ARE CHARTERED AND UNBUILT — say so rather than describing them as running.
connected components at 99.1%" means (TripoSG is worse in count: 18 components at 99.8%). *"A
shell-cleanup pass belongs in the fitting stage."* No script implements it.
surveyed: bpy.ops.mesh.symmetrize(direction='NEGATIVE_X', threshold=0.0001) when one side is
authoritative and topological symmetry is required; `symmetry_snap(..., threshold=0.05, factor=0.5,
use_center=True)` when a near-symmetric generated mesh should keep detail from both sides; and the
ordering rule that decides correctness — **transform the mesh so the fitted plane becomes the world
YZ plane through the origin FIRST, then call the operator.**
WHAT DOES EXIST. finish_mesh2 with FINISH_SETTINGS = {pre: 60000, quads: 6000}, per-item
overridable (the serpent used 24,000); and a second-chance --volume-fallback that voxelises when
surface repair leaves the mesh open, still judged by the battery's 3% silhouette threshold.
THE FORMAT ADAPTER THAT DELIBERATELY DOES NOTHING ELSE. condition_generated.py carries its own
scope in its header: *"no smoothing, no decimation, no symmetry, no proportion fitting. Those are later
stages and they must not be allowed to hide inside a format conversion."* Its axis map
[[-1,0,0],[0,0,1],[0,1,0]] is asserted to have determinant +1 so no arm's asymmetry is silently
mirrored.
THE TRAP — A REFERENCE PLANE FITTED TO THE FEET. measure_mesh.py's first draft referenced band
drift to *"the median x of the lowest 6% of the figure"* — the feet. With a figure standing with its
feet APART that median lands inside whichever foot carries more vertices, so the reference plane sat
half a stance off centre: **every generated arm scored ~0.30 width asymmetry and the mirror-built arm
scored near perfect. The fix is a symmetry plane fitted per mesh** by minimising the mirror residual
over offset and yaw, applied identically to every arm including the one already centred on x=0. **It
nearly produced the opposite verdict.**
---
THE MEASUREMENT STACK SURVIVES THE MOVE TO GENERATED GEOMETRY — tested, not asserted. Read with the
house instrument (build/3d/cage/body_stage/body_probe.cross_section — the same exact triangle-plane
perimeter proportion_review.py uses, so the test is not circular), the Hi3DGen output already
lands within a few percent of the A14 spec at every readable site with no fitting at all: knee +2.5%,
waist −3.3%, hip +5.5%, chest −1.4%. That is because the plate was built to the spec and
generation preserves it.
**THE WINNING RECIPE: a raised-cosine radial lattice, C1 at both band edges so no crease and no seam is
introduced.** build/3d/bakeoff/fit_girth_lattice.py: weight w = 0 beyond the band, else
0.5·(1 + cos(π·d)) where d = |V_z − z| / band; scale s = 1 + (k−1)·w; k solved by secant from a
circular first guess k = target/g0, breaking at relative residual < 1e-4; --band default 22.0 cm,
--iters default 4. Its own docstring: *"A linear ramp would be C0 and would leave a visible ring — the
exact class of artefact the rejected chain shows."*
k = 1.03435, **residual −8.29 ppm, ONE iteration** (FIT_GIRTH_HI3DGEN_waist.json).
k 0.73737 → 0.73722,two iterations, residual 0.16 ppm — the "before" figure is itself the trap below.
Non-circularity is structural: girth_at() imports body_probe and calls BP.cross_section +
BP.loop_stats, the same functions proportion_review.py uses — the fitter does not carry a
measurement of its own.
THE INSTRUMENT. body_probe.cross_section — *"Every triangle straddling the plane contributes
exactly one segment. Segments are welded on their endpoints and walked into loops; an unclosed chain is
returned as an open polyline and reported, never silently closed."* PROFILE_STEP = 0.25 cm,
WELD_TOL = 1e-7. Its own justification for existing: *"the chin detector was wrong on 4 of 4 busts…
A planar cross-section is not a heuristic: the triangle-plane intersection is exact, the loop count at a
height is an integer."*
THE TRAP — THE NAIVE LARGEST-LOOP SITE PICKER IS WRONG ON GENERATED GEOMETRY. At chest height it
selected a spurious 111 cm loop over the true 80.8 cm torso. It is not a bake-off curiosity: in
the field the same picker read a hip at 152.1 cm against an 82.9 cm target because the section was
enclosing both forearms — the trochanter sits at 87.0 cm while the wrist sits at 80.8 cm at age 14.
The GIRTH_SITES table in proportion_review.py carries that derivation inline and marks the row
*"Confounded, published, not scored."* **The house confound logic must come across with the
measurement, never be reimplemented.** Two working replacements exist and should be preferred:
build_true_bare_base.py picks the loop nearest the midline for torso sites (plus a pelvic-window
guard, because a section at the crotch is closing over two thighs and reads a hip that is two legs), and
proportion_review_v2.py anchors on topological transitions instead — z_crotch from the loop-count
2→ transition, z_arm_hi from the longest run of three loops. A sibling instance of the same class:
cross-section topology refused itself on the assembly pose because the thighs were in contact and the
legs read as merged from 40 cm — which is a knee.
---
THE RATIFIED ARCHITECTURE. ONE bare mesh, partitioned into real anatomical regions — each with its
own proportions, physical values (density / weight / failure semantics), record, UV block, and
material slot for per-region suppression under gear. Expressing the partition in the UV layout as
well as in material slots is an authoring-time decision that cannot be retrofitted cheaply: UV blocks
are what Mutable's RemoveMeshBlocks and MetaHuman's Body Hidden Face Map both consume.
THE PARTITION IS BUILT AND GATED — 14 REGIONS, R01–R14.
build/3d/characters/body_specs/BODY_REGION_PARTITION.json: R01_FOOT, R02_LOWER_LEG, R03_KNEE,
R04_THIGH, R05_PELVIC_GIRDLE, R06_ABDOMEN, R07_THORAX, R08_SHOULDER, R09_UPPER_ARM, R10_ELBOW,
R11_FOREARM, R12_WRIST, R13_HAND, R14_NECK_SEAM. Each carries bilateral, proximal/distal extents,
governing_girths[], mass_segment, surface_area_fraction (R07 thorax 0.171 largest, R03 knee 0.026
smallest), mechanics_class, palette_zones[] and an enhancement_spec pointer. Its stated law:
*"REGIONS OF ONE MESH. A region pass writes back into the shared mesh; it never merges geometry."*
PER-REGION PHYSICAL VALUES ARE REAL FILES WITH A REAL GATE. Fourteen specs at
build/3d/characters/body_specs/regions/R*.json, every number carrying _basis
(measurement / derived / calibrated) and _cite[]. R05 for example: density 1.03 g/cm³ (WINTER2009,
DEMPSTER1955); mass 4.026 / 6.085 / 8.229 kg at ages 11 / 14 / 18; skin Young's modulus 0.25–0.42 →
0.42–0.75 MPa across the same ages; gluteal muscle 8–20 kPa relaxed / 50–100 contracted; pelvic cortical
16–20 GPa; sacroiliac motion 2–4°. An adipose value is declared a PROXY on its own face rather than
passed off as measured. The gate is check_region_specs.py → REGION_SPEC_GATE.json: 14 expected / 14
present, per-region citation and unmeasured counts, ladder values restated and checked, findings [],
verdict PASS.
UV BLOCKS AND MATERIAL SLOTS ARE ALLOCATED, ONE PER REGION. TRUE_BARE_BASE.json gives each region
one UDIM tile and one material slot — R01 → 1001 / M_BODY_R01_FOOT, R02 → 1002, and so on — with
R05 → udim 1005 / M_BODY_MANNEQUIN, which is the doll slot.
THE STANDARDS THAT ARE ABSOLUTE.
photoreal pass, at any age, permanently. This is structural — it is its own UV block and its own
material slot, so a texturing pass cannot address it even by mistake."* The chunk-enhancement
roster in body_ladder_v3.py correspondingly has no R05 entry: no crop band, no prompt, no
submission. Geometry-side, the median raphe, perianal radial folds and perineal rugae are absent
while staying curvature-continuous with surrounding anatomy — and the spec states why that is
geometry and not a texture trick: *"a texture cannot make geometry absent."*
build/3d/cage/body_stage/DOLL_UNDERWEAR_{SPEC.md,PARAMS.json}. Its topology is a conforming shell
whose vertices are the cage's vertices displaced along cage normals, so *"skin weights inherited
vertex-for-vertex from the cage. No transfer, no nearest-neighbour search, no error term."* Thickness
ships at ¾ of budget in every zone — waistband-over-crest 0.45 of 0.60 mm, waistband-flank 1.50 of
2.00, gluteal panel 1.50 of 2.00, leg-opening band 1.13 of 1.50, front panel and gusset 1.50 of 2.00 —
against a cloth collision proxy of 2.0 mm, a rigid-plate standoff of 3.0 mm at 120° hip flexion, and
0.6 mm over bone. Per-age patterns are solved (waistband seat 68.59 / 84.68 / 98.68 / 108.33 cm at 7 /
11 / 14 / 18), and the seat re-derivation agreeing with R05's stated heights to 0.02 cm at 11 and 18
is itself a tooth in the parameter file. The four-part no-collision contract: a thickness budget; a
compression inheritance (*"its collision proxy is the body's, never its own"*); a visibility contract
(a gear piece masks the garment's UV block, never deletes it); and the end state — *"at unequip-all
the scene holds exactly two meshes, body and garment, at a constant positive offset, with zero rigid
colliders."*
a parameter file… It is not a mesh, and it is not evidence that any built mesh matches it."* Three
named gaps ride on its face, including that R05 carries ages 11/14/18 only, so **age-7 cleft length and
inguinal offset are declared extrapolations.**
equipment swaps the visible state to the minimal underwear layer; attempt-to-unequip-below-floor is a
tested refusal, not an assumption. The counterweight has equal force: the floor never forces
coverage onto culturally-accurate dress — minimal-coverage wraps, loincloths and open dress render
authentic to their culture and era.
alone isnt illegal, but we still dont want to publish that to our game since its not necessary."* Not
a legal requirement, not a care obligation. Future content questions cite this as a chosen line, never
as evidence of a conservatism mandate.
presentation gate does its work at the player boundary. Generated imagery of the minor rungs keeps the
tasteful-minimal register **at zero pipeline cost, because mesh completeness at every age comes from
the parametric cage, never from generated imagery.** The architecture already separated these; the
ruling only names it.
THE MERGE BAN, restated because it is the partition's whole point: geometric merging of
independently generated parts is BANNED. A partition has zero seams by construction, which is what
satisfies Josh's five if-modular conditions without a modular route. "Remerge" in the pass loop means a
region pass writes back into the shared mesh.
BUDGETS ARE TEETH, NOT NOTES. Character-class meshes take the NPC row of docs/asset_budgets.json,
which inherits Creatures: LOD0 24,000 / 60,000 / 120,000 triangles (Steam-Deck minimum / mid-range
PC / high-end PC) and 4 / 4 / 3 LOD chain steps, with A1_vertex_tri_ratio_max = 2.0. Enforced at
the LOD stage by GATE 75 asset_budgets. **Named gap: material_slot_cap reads NOT_DECLARED for the
NPC class** — the gate prints it under DECLARED NOT-ARMED with its arming condition rather than
inventing a threshold, and a character factory that stamps hundreds needs that number declared. The
reason the gate exists at all: the hood measured 5.59× over floor with no gate anywhere.
---
THE RATIFIED COLOUR ROUTE: MV-Adapter ig2mv 6-view + harness/asset_factory/mv_texture_bake.py,
superseding the v1 single orthographic projection on real blind evidence (surface +1.89 per item
against a measured 1.125 judge-noise floor — and the noise floor is a tooth: *"an aggregate texture
win inside the measured judge-noise floor refuses the emit"*).
Generation params: seed 42, steps 50, guidance 3.0, res 768, ref_scale 1.0, negative *"watermark,
ugly, deformed, noisy, blurry, low contrast"*. ig2mv camera set: elevation [0,0,0,0,+90,−90],
azimuth [−90,0,90,180,90,90], distance 1.8, ortho scale 1.1. Merge params: --facing-power 3.0,
--facing-floor 0.05 (*"views more grazing than this contribute nothing"*), depth bias radius/200,
hole fill by nearest-valid push at max 64 dilate rounds. Bake res 1024 for the v2 route (the stage
tool defaults to 2048).
TWO CONSTRUCTION CHOICES THAT ARE WHY IT WORKS. The conditioning images and the merge's
world_to_camera matrices come from the SAME camera objects, exported once to JSON, *"so generated
colour cannot land on the wrong texels."* And the mesh is normalised `vertices / max(abs(vertices)) ×
0.5 about the ORIGIN before conditioning, because positions are encoded pos+0.5` into [0,1] and *"a
mesh outside [−0.5, 0.5] clips to a flat block and the model is conditioned on garbage."*
nvdiffrast is absent by design and the guard is mutation-proven. `import_nvdiffrast_result:
ModuleNotFoundError; the loader raises SystemExit if 'nvdiffrast' in sys.modules`, and injecting a
fake module makes it fire — *"a check that has never been seen to fire is decoration, not a tooth."*
Rasterisation is Blender-headless instead.
Measured: 26.0 s generate / 48.12 s total (n=9), 20.49 GiB allocated but 29.06 GiB RESERVED — and
the reserved figure is the one that governs scheduling: *"~29.6 GiB reserved on a 32 GiB card means this
stage cannot run beside a second heavy lane, and the driver waits for ~24 GiB free before it starts…
plan the batch as: all geometry first (shareable), then the texture pass alone."* The honest price is
stated too: the route *"replaces a 2.25 s bake with a 26.0 s generation, so the per-asset machine cost
rises from about 57.5 s to about 81.3 s. That is the honest price of surface +1.89."*
COVERAGE. The v1 projection was measured observing 30.3% of the surface (253,435 of 837,130
texels observed; 583,695 hole-filled) and inventing the rest; the 6-view route observes 0.516–0.794
across the nine bench cells, mean 0.61, and reports holes rather than inventing them — the
record emits observed_fraction, texels_hole_filled and per-view contribution counts, because *"a
hole that got filled is still a texel nobody observed."* Real production batches run higher: equipment
11 items mean 0.8375, serpent 0.9883. A 24-view geometric ceiling exists for comparison (0.986).
Population tooth over 254 landed assets: median untextured fraction 0.24, worst 0.7395 — declared
"REPORTS, does not reject."
CHUNK BY CHUNK, AND THE ORDER IS RULED. Proportion the whole first → enhance region by region
pre-merge → merge on the cage → verify the caged whole (photoreal / proportion / anatomy / physics) →
layer → gauntlet (DECISIONS :: THE PASS DISCIPLINE · PRE-MERGE ENHANCEMENT PASSES). Photoreal texture
is applied per chunk on the partition's UV blocks and material slots — full photoreal on every visible
region at every age — **because texturing is per-chunk on the mesh and never requires a full-body bare
photoreal render to exist.**
THE FREE WIN, AND THE CORRECTION THE AUDIT OWED ITSELF. xatlas.parametrize() was called bare, so
the library defaults applied — padding=0, bruteForce=False, blockAlign=False, max_iterations=1 —
and islands touch, so every asset we have ever baked carries bake bleed at every seam. Measured at
bake resolution on landed meshes: CR_0001 12 touching island pairs, EQS_0013 19, WPN_001 8, with
59 / 79 / 36 four-by-four mip blocks holding more than one chart. *"That is the seam bleed, it is a
property of the ATLAS, and no work in the bake or the texture route can remove it."*
**THE AUDIT'S PRESCRIBED FIX DOES NOT WORK ON THE INSTALLED BINDING, and this is exactly why the call
sites 'forgot' to pass options. Installed xatlas is 0.0.11**, whose signature is
parametrize(positions, indices, normals=None, uvs=None) — it accepts no options at all. Options
reach xatlas only through the class API: Atlas.generate(chart_options=..., pack_options=...). Landed
at harness/asset_factory/uv_pack_options.py.
ADOPTED: UV_PADDING_TEXELS = 2 (scaled: padding_for(res) = max(1, round(2 × res/1024)), so 4 at
2048), UV_BRUTE_FORCE = True, UV_BLOCK_ALIGN = True, UV_CHART_MAX_ITERATIONS = 1. Result: **zero
2×2 and zero 4×4 blocks hold two charts, against 6/11/1 and 59/79/36 before** — and it is *"STRICTLY
DOMINANT… it removes every touching pair and every contaminated mip block while RAISING
uv_area_utilization by +3.2% / +2.3% / +8.0%"*, at ~0.2 s per asset. blockAlign is also **6×
faster** (1.0 s against 6.0 s on CR_0001) and prevents a BC block straddling two islands.
DECLINED, with the numbers rather than by taste: padding=3 buys a 5-texel gap and costs 1.7% texel
density; max_iterations=2..4 consolidates charts (CR_0001 246 → 212) but costs utilisation −5.2% /
−6.1% / −4.5% — *"trading it away for a chart count no gate reads is a regression, not a win."* A
--uv-legacy-defaults flag reproduces the pre-fix atlas for historical measurement only. And both the
requested and the realised gutter are recorded (gutter_realised_at_bake_res), because *"recording
both is what stops a caller claiming a padding it did not get."*
**PBR IS THE WORST CAPABILITY GAP IN THE STACK, and it is a missing physical quantity rather than a
stale model.** Every equipment generation.json reads *"No texture-generation model used"*, and
emit_manifest_from_landed.py writes the ORM contract as *"R = REAL baked AO; G and B = DECLARED
CONSTANTS, not maps."* **A 2026 AAA surface is not reachable from constants and no amount of geometry
work closes it. Named replacement: Material Anything** (MIT) as a decomposition pass bolted onto the
existing bake — albedo + roughness + metallic + bump, PyTorch3D + Blender, no nvdiffrast. THIN EVIDENCE
on maintenance: verify before adopting.
THE DETAIL / REFINEMENT STAGE: SeedVR2, wired at harness/asset_factory/seedvr2_refine.py. The slot
was positive-controlled EMPTY — *"12 files use ComfyUI scaling node params, 0 load any upscale model"* —
while the face lane asked in writing for *"an upscaler/refiner with its own conditioning"* for four
generations. SeedVR2 synthesizes hair, skin and fabric texture rather than resampling, which is
exactly the missing top-octave energy the judge measured. It is Apache-2.0 and its **nodes are native in
the installed ComfyUI 0.29.0**.
this box and re-verified against the RUNNING server's /object_info:
`LoadImage → ImageScaleBy → SeedVR2Preprocess → VAEEncodeTiled → SeedVR2Conditioning → KSampler →
VAEDecodeTiled → SeedVR2PostProcessing → SaveImage, with VAELoader and UNETLoader` feeding in.
Widget values carried verbatim: steps 1 (*"SeedVR2 is a one-step restoration sampler"*),
cfg 1.0, euler / simple, denoise 1.0, tile 512 / overlap 128, --scale 2.0,
--color-correction lab. One substitution is declared in-file (ImageScaleBy lanczos for the
template's dynamic-combo node, identical maths).
--validate structurally checks every class_type, required input, link target and output slot against the live server (11 nodes, 0 findings); --self-test
MUTATES the real graph five ways and requires all five to go red (5/5 caught).
nodes_seedvr.py builds both the positiveand the negative conditioning out of the input's own VAE latent — **there is no text encoder in the
graph at all** — so it has nothing to drift toward. That is the opposite of the Qwen refine ladder,
which bought sharpness and paid identity monotonically every rung: head-band micro 598.16 → 433.87 →
398.14 → 391.67 while exemplar_match fell 0.91889 → 0.90621 → 0.89790 → 0.88914.
— so the model is never credited for pixel count a resampler already gives.
WEIGHTS: seedvr2_3b_int8_convrot.safetensors (3.46 GB) + seedvr2_ema_vae_fp16.safetensors (0.50 GB)
from Comfy-Org/SeedVR2 (Apache-2.0), 3.96 GB total. Under the blanket install authorization
(§7) this proceeds.
LOOKDEV IS THE LIGHT UNDER WHICH POLISH IS JUDGED. Renders are Cycles at view transform
Standard, look None, exposure 0.0, gamma 1.0, world strength 1.0 — not AgX, because
AgX deliberately does not round-trip a known sRGB value and the chart is only a pipeline check if a
known input can be compared to a measured output. **A beauty pass under AgX is a different artifact and
must say so on its face.** De-light is mandatory on any basecolor that is captured, photographed,
plate-derived or generated; the 30–240 sRGB dielectric band is a lighting detector wearing a colour
check, because a basecolor with lighting baked in carries the capture's shadow terminator and specular
highlight as pigment (docs/LOOKDEV_STANDARD.md §§4-6). **A/B arms are re-rendered by the instrument
doing the comparing** — a bench once compared one lane's cavity-shaded clay against another lane's flat
turnaround and read backwards.
---
WHAT EXISTS. Bind on the whole body, never a partial mesh (bl_skin_to_mannequin.py). Landed
figures for CHAR_0001: bind stature 150.877 UE-cm at component scale 0.855 → rendered 129.0 cm, coord
fit worst residual 9.94e-07 Blender units, export verify **worst bone error 0.000186 cm over 88
bones; four LODs at 21,154 / 11,622 / 6,340 / 3,170 tris with unweighted_vertices: 0**, influences
pruned 10 → 4, worst weight-sum error 0.0, orphan vertices 0, max drift 0.065%. Honest tier declared
on its own face: PREVIZ-AUTOSKIN — *"bone heat on a welded copy… Not a hand-painted weightmap;
joints will pinch under extreme flexion."*
A SPLIT-BIND FINDING THAT GENERALISES. Outfit pieces bind on the WHOLE set and are split by
material afterwards, because *"binding each piece alone HARD FAILED that control on the chest (derived
yaw 0, best measured 180)… The control is not weakened; the bind moved to where it is valid."*
THE ONLY DETERMINISTIC RIGGER IN THIS REPO IS THE LIMBLESS ONE.
harness/asset_factory/bl_limbless_rig.py, anatomy-law bound at 22–64 deform bones with a **25°
per-joint lateral cap** — and the floor is derived, not chosen: *"a coiled serpent bind pose that wraps
1.5 turns needs 540° of cumulative lateral curvature. At the measured 25°-per-joint ceiling that is 21.6
joints, so 22 is the floor."* On CR_0002 it produced 38 bones, mean length 12.6 cm, cumulative curvature
439.32°, joints over cap: 0 — because joint spacing is solved against the cap by bisection
(k = 1.30994, max turn 28.257° → 25.0°) rather than placed at equal arc, which *"passed on the mean
and put six joints over the cap, because the neck's reverse bend carries a third of the body's curvature
in a tenth of its length."* Weights are **authored geodesic-arc blends, ≤2 influences, partition of
unity by construction** (weight_coverage 1.0, min and max weight sums both exactly 1.0) — and the
record states the alternative's measured cost: bone heat produced an 11.73× tear because *"on a body
that folds back toward itself the two sides are surface-far and space-near, heat leaks across, and one
bone ends up owning skin on both sides."*
WHAT IS MISSING ON THE HUMANOID SIDE. The installed previz rigger offers quadruped / serpentine /
spine-only and has no biped mode at all; UniRig is the ruled auto-rigger and is NOT INSTALLED.
So the humanoid path is a MANUAL BIND to SKM_Manny_Simple — CHAR_0001_CLOTHED_SKIN_CLOSURE.json
says it verbatim: *"MANUAL BIND, not UniRig."* Named replacement: MetaHuman 5.8 Mesh-to-MetaHuman,
which now conforms a full body from arbitrary topology (the docs name Meshy/Tripo meshes as valid
input), free and UE-native.
WHAT IS UNBUILT. ROM / calisthenics: 0 authored, creatures and humanoids alike. The JOINT-ROM
CORRECTNESS LAW is a rider on every auto-rig above. **The unpriced line item nobody names: no learned
auto-rigger emits archetype-named joints.** Archetype tables say glenohumeral, rigs say spine_02,
and nothing joins them — so adopting SkinTokens or MetaHuman costs a naming map per body plan. Price
it in the same change.
THE SHAPE THE ROM WORK SHOULD TAKE, from the research: no product takes a rigged character and emits
validated joint limits, and the published work is about *pose-conditioned* limits (Akhter & Black CVPR
2015 — elbow ROM depends on shoulder orientation). So: **hand-author one ROM/constraint profile per
archetype against a biomechanical reference, and let a shared cage transfer it to every character by
construction**, with a learned pose prior used only as a QA gate. The same argument makes rigging itself
collapse from a per-character authoring task into a vertex-index lookup once the cage is fixed.
SkinTokens is a Josh-tier licence read, not a lane's. MIT code and weights, +98–133% skinning
accuracy over UniRig — **but trained 70% ArticulationXL2.0 / 20% VRoid Hub / 10% ModelsResource (ripped
game models). An MIT weight licence does not launder the training corpus.** It is also blocked on a
flash-attn wheel for torch 2.9 / cp312 / cu12.
---
THE BAR IS JOSH'S OWN AND IT IS A LOOP, NOT A CHECK: *a PROPORTION REVIEW AT EVERY ANGLE — turntable
renders, iterated until perfect — and a PHOTOREAL PASS ON EVERY POINT with comparison to the reference
plates, identical-identical.* The acceptance loop is **render → compare → fix, per angle and per region,
evidence imaged each iteration** (DECISIONS :: 3D ACCEPTANCE BAR).
THE INSTRUMENT. build/3d/cage/render_turntable.py — one instrument for every arm, every figure
conditioned to a common height by build/3d/bakeoff/condition_generated.py, **whose axis map is
asserted to be a rotation rather than a mirror so no arm's asymmetry is silently flipped.**
AZIMUTHS = [0, 45, 90, 135, 180, 225, 270, 315], ORTHO_MARGIN = 1.12, CAM_DIST_FACTOR = 6.0, --res 1100.
ortho_scale = height × 1.12is computed ONCE from the figure and held for all eight passes. The sibling instrument normalises
each mesh to a fixed bbox diagonal so two different meshes frame identically — *"that is right for
comparing wraps and wrong here: a turntable of ONE asset wants the same camera at every angle so the
silhouette can be compared across the sheet."*
light STUDIO, color_type SINGLE at (0.60, 0.60, 0.62), show_cavity True with `cavity_type
BOTH and ridge/valley factors 1.0, render_aa 8, world background (0.30, 0.30, 0.33)`,
film_transparent False. Azimuth 0 is the face; the turn goes to the subject's right.
camera block — so a sheet can be proven to be the sheet it claims to be.
(X right, Y front, Z up, cm), and *"a mesh that is not will render wrong and this note is the only
warning there is."*
THE MEASURED HALF RUNS AT THE SAME EIGHT AZIMUTHS, proportion_review.py, *"on the geometry rather
than off the pixels, so a reading and its picture are the same angle by construction."* Three readings
in descending order of what they can prove: girths, silhouette width per azimuth at the rung's landmark
heights, then head-units — and head-units is declared a control, not a discovery: chin and crown are
placed by construction, so *"a non-zero residual here means the assembly step is broken."* The only
spec-scorable silhouette width is the acromion at azimuth 0/180 against across_shoulder_soft_tissue,
because that is the only breadth the spec states in soft tissue. No pass/fail threshold is encoded —
the VERDICT block publishes scored_girth_sites, worst_scored_girth_residual_frac,
stature_residual_cm and head_units_residual, and the eye decides.
The presentation deliverable is the lookdev sheet: every declared environment × 8 turntable views,
laid out 4 per row so it reads on a phone in one vertical scroll, with a header carrying the calibration
lock (view transform, look, exposure, gamma, renderer, samples, device, triangle count) and a footer
carrying the Guerrilla rule and the honest tier.
WHAT AN ACCEPTED ASSEMBLY LOOKS LIKE, from the one that passed at structure tier: stature exact to
0.000 cm, head-units residual under 0.0002 at all eight angles, neck-join clearance +0.029 cm
on the contract's side of zero, exact bilateral symmetry, and topology and UVs untouched **so an age rung
is a morph and not a different asset.** The conform's ladder assumption was tested rather than asserted —
predicted biacromial 31.434 cm against the mesh's measured 31.264, 0.54% apart.
**FOUR DEFECTS THE ASSEMBLY LOOP FOUND IN ITSELF, each carrying a number, each invisible to a topology
gate:** a per-axis least-squares fit let the rim's own saddle set the vertical scale and returned
scale_z 0.515, crushing the collar to a 17.0 cm neck; the zipper laid its band inside out at **305
winding defects** while reporting zero boundary edges, zero non-manifold edges and exactly three
components — all intended — which is why winding_defects is now measured and why the traversal is
READ off each surface's own directed boundary instead of guessed; a front anchor got into an np.interp
whose x must ascend, so D1 came back at 10.10 cm mean against a true 3.27 and closed the neck ring to
a 0.10 cm point — a defect no topology gate can see, because **collapsing a ring breaks no manifold
rule**; and the head is now clipped ON the plane rather than by face centroid, retiring a 200-vertex cut
ring whose polyline was 96.04 cm around a 32.39 cm neck.
THE STRUCTURAL LESSON: a Hermite filling surface cannot carry a clavicle. A cubic between two rings
has one degree of freedom per azimuth and per height, so it can bulge but cannot carry a ridge that runs
ACROSS azimuth — which is exactly what a clavicle is, and why three tangent gains were A/B'd and the eye
refused all three. The fix was to use the solved MetaHuman face half's own neck-and-shoulder geometry
warped onto the body's rim through a 92↔92 correspondence paired BY AZIMUTH, licensed by a
monotonicity control: index-for-index measures 16.58 cm mean against 2.79 for the paired one, so a
file that assumed shared indexing would have shipped a twisted collar. The bottom seam became a
WELD, not a zip — same index, max deviation 0.0 cm, zero triangles contributed. And the defect it
closed (D-V3, neck_base +7.7% → +0.3%) closed itself with no taper change of any kind: **the excess
was the Hermite's own flare, not the head's.**
---
WHAT PROVES AN ASSET IS WIRED. DescribeAssemblyJson() read-back proves what is on the body; a swap
test proves hide/restore is exactly reversible at every LOD index; and the ruling requires both
the read-back JSON (what it IS) and the frame (what it looks like). Add ULODSyncComponent so the body
and every gear component switch LOD together — MetaHuman ships it by default and we have nothing.
THE LANDING GATE IS BUILT AND HAS NINE TEETH. harness/asset_factory/verify_landed.py, last full
run 254 checked / 254 clean / 0 findings: T1 id tooth (record id == directory name; every media
filename is SM_<id> or T_<id>_*) · T2 media presence *and* non-zero size · T3 registry join
through an id-namespace prefix map, with every recorded cell re-compared against the live CSV · T4
battery re-measurement from the lane's own finish/export records using the same imported battery(),
not a copy · T5 licence pairing · T5b no care-gated asset ever reaches READY_FOR_IMPORT ·
T6 withdrawn is never importable *and* never still in candidates · T7 anatomy vs spec on rigged
imports (roster / segment count / required bones / ROM / centreline) · T8 phys-profile present.
Two meta-controls make the gate trustworthy rather than decorative: a VACUITY CONTROL — zero
candidates matched raises *"a checker that cannot find anything must not report a clean bill"* — and a
RULER-ROT CONTROL: T7 and T8 re-run their own mutation self-tests first, and a failure there exits
as a SETUP failure, never as a finding.
THE MANIFEST IS RE-DERIVED FROM DISK, NOT REMEMBERED, and the reason is a real loss: a slice-creature
run landed 142 candidates and produced no manifest because *"the GPU producer thread died mid-run on a
UnicodeEncodeError raised by a species name with a diacritic."* The fix is architectural —
*"a run is a process and a process can die, but the candidates it already landed are FILES and files
survive"* — so emit_manifest_from_landed.py reads the landed records and **no batch result and no run
summary at all**: *"a manifest that depends on a process surviving is not a manifest."* It also enforces
that landing is not permission to import: only ids still on the current worklist's route appear, and
care-gated rows land as PREVIZ_HOLD.
PATHS. Props follow /Game/Meshes/<class>/SM_<id>, the same string the runtime resolver prints.
Characters land off-convention at /Game/Characters/CHAR_0001/…, with the landed body at
/Game/Meshes/Characters/SK_CHAR_0001_CHILD and an engine seam that *"prefers the asset, falls back to
SKM_Manny_Simple; withdrawal is a file move and was proven by performing one."* Every shipped file is
pinned by bytes + sha256 per LOD and per texture in the import manifest. Named gap: there is no
.uasset package-bytes verifier in this repo — that proof lives in the game repo's QA bench, which this
lane treats as read-only, since the sole-writer slot belongs to the engine wave.
THE SWAP GAUNTLET is the collision answer and it is a named gate. Garments are **fitted on the cage
body**, sharing its surface definition — the BG3 pattern, which eliminates collision by construction —
and factory-complete additionally requires the **full equip/unequip cycle IN-ENGINE across all 16 slots,
their combinations, and every age state**: suppressed regions render nothing; garment inner surfaces show
ZERO penetration of visible body, measured not eyeballed; unequip-all lands on the swap floor;
captures imaged per the every-pass law. No character is factory-complete without passing the gauntlet
(DECISIONS :: THE CAGE REVIEW STACK + THE SWAP GAUNTLET).
AT SCALE, THE GAUNTLET IS A BATCH INSTRUMENT — all slots × all bodies × all ages, mechanical collision
proof per asset, so quality and collision-freedom survive the multiplication to tens of thousands
(DECISIONS :: THE SCALE MANDATE + FOUR ENHANCEMENTS, item 3).
THE PUBLISH GATE. A factory's output populates the review book ONLY when that factory is COMPLETE
through the full chain — Josh-graded exemplar → built asset → wired in-game (package-bytes verified) →
full motion where the class carries motion. Until then its pages show canon text and the honest empty
state. Building never pauses; only publishing waits (DECISIONS :: THE FACTORY-COMPLETE PUBLISH
GATE).
---
The protagonist's ladder is not a protagonist feature. Supporting characters age too, because the
player revisits places across story years — and the policy below is derived from the spine's own
measured clock rather than assumed.
From registries/T0_Chapter_Index [ACTIVE v1.2] (protagonist_age / protagonist_age_end /
age_stage), across all 79 nodes:
age_stage splits Childhood 14 nodes / Adolescence 25 /Adulthood 40.
· Ch 8 = 10→11 · Ch 9 = 11 · Ch 10 = 11→12 · Ch 11 = 12 · Ch 12 = 12→13 · Ch 13 = 13. **The vertical
slice alone (Prologue→Ch 13) consumes ages 7 through 13.**
**The consequence for the factory is exact: age-variant cost is concentrated in the slice, and 41 of the
last chapters share a single adult state.** A cast member introduced in the modern arc needs one age.
Counting actors: lines across all 79 docs/spine/CH_*.md nodes: **130 distinct staged character ids,
of which exactly 7 appear as actors in more than one chapter.**
| id | who | chapters | ages seen | span |
|---|---|---|---|---|
| CHAR_0005 | the Elven King / father | 5 | 7, 18 | 11 y |
| CHAR_0017 | Ana | 22 | 9, 16, 18 | 9 y |
| CHAR_0002 | Ntala, the healer's child | 56 | 9, 13, 14, 15, 16, 17, 18 | 9 y |
| CHAR_0056 | Binti Hassan | 2 | 10, 14 | 4 y |
| CHAR_0003 | the Architect | 2 | 14, 18 | 4 y |
| CHAR_0009 | Elder Rato | 2 | 7, 9 | 2 y |
| CHAR_0071 | Kxao | 2 | 11, 13 | 2 y |
Cross-checked against T0_Chapter_Index.seed_npc_ids: 114 distinct seeded NPC ids, **9 in more than one
chapter**, max span 9 years, and 105 of 114 single-chapter. The two filters disagree in membership and
agree in shape — recurrence is rare and the spans are bounded.
The driving fact is biological, not budgetary: **an 11-year span barely moves an adult and completely
rebuilds a child.** So the policy keys on the entity's own age band at first appearance, crossed with its
measured revisit span.
| Tier | Who | Age variants | Method |
|---|---|---|---|
| A — FULL LADDER | The protagonist. Any companion or cast member who is a minor and recurs across ≥ 4 story years | 7 rungs (his: 7, 9, 11, 12.5, 14, 16, 18); a companion's ladder spans only the chapters they are present | Keystones by the direct recipe at each Josh reference; in-betweens by Route W landmark warp from the older anchor |
| B — KEYSTONES ONLY | A minor who recurs across 2–3 story years; an adolescent who crosses the puberty boundary | 2–3 rungs at the band edges | Direct recipe at each rung; no in-betweens — the gap is too small to read |
| C — ONE VARIANT | An adult who recurs across any span up to ~12 years; every rooted teacher, elder or contact | 1 base + 1 optional late variant (grey/weathering pass only, no proportion change) | Base exemplar; the late variant is a texture/groom pass on the same mesh, never a new solve |
| D — SINGLE AGE | Everyone met once — 105 of 114 seeded NPCs, the modern-arc cast, every crowd tier | 1 | Base exemplar, or the variant engine (§3.5) |
Companions inherit ALL of it. Josh's ruling is unqualified: *"Every companion needs to follow the same
rulings across all ages"* — the same keystone method, the same bars, the same physique and identity laws
(DECISIONS :: THE KEYSTONE AGING METHOD + TOOL FREEDOM).
The named consumer today: CHAR_0002 Ntala. She recurs across 56 chapters and 9 story years, which
is Tier A. Her prep package already adjudicates a keystone set of 13 pick / 18 / 14, fills 15-17, with
the 9-12 low band contingent and reveal-gated because the pre-Ch-13 watcher is a HELD reveal
(build/art/characters/CHAR_0002_EXEMPLAR_PREP.md §2). That is Tier A with the ladder correctly clipped to
her presence window — the pattern for every companion.
The age swap is a discrete state change on the chapter clock, with no runtime interpolation: the
engine swaps age states at the chapter boundary and garments refit per state. The acceptance image is the
same in-engine camera across consecutive age states as a strip, **so the step reads as gradual rather
than as a jump** (BODY_ASSEMBLY_ARCHITECTURE_BRIEF_2026-08-06.md §6.1 stage 12).
Because every rung is a morph target on one cage with identical topology and UVs, an age variant is
not a different asset — it is a blendshape. That is the property the whole cage programme exists for,
and it is what makes Tier A affordable at cast scale.
Companion-grade MASTERS per cultural region, then parametric variation in the cage morph space plus
palette and feature ranges grounded in that region's REAL population anthropometry (accuracy as
respect: bodies per region drawn from real proportion data), plus per-NPC unique details via the persona
system. Tens of thousands of lawful faces from graded masters, zero per-individual grading
(DECISIONS :: THE SCALE MANDATE + FOUR ENHANCEMENTS, item 1). Its companion library is **cultural dress
per region and era**, zone-catalog grounded and research-cited — loincloth to full armor, every piece on
the cage, suppression-mapped, *historically true because the bare base underneath is anatomically true.*
The anthropometry caveat that binds it. AGE_PROPORTION_RESEARCH.md §6 states its own population
scope: the cormic index varies **47.3 to 55.8 between populations — a 7-point swing that dwarfs the entire
7→18 age signal of 1.5 points. The landed targets are US/European-descent medians. A regional master's
proportions are a per-region research input, not a recolour of the protagonist's numbers.**
registries/T0_Character_Index [ACTIVE v1.1] carries mesh_id_ref, mesh_pipeline_type,
generation_status, generation_tier, regeneration_trigger, ue_asset_path and binding_kind — and
no age-variant column at all. Measured today: 167 rows, generation_status = pending on 167/167,
and mesh_pipeline_type / generation_tier / binding_kind empty on 167 of 167. That is the honest
state of the cast factory: zero characters have entered the pipeline.
FINDING FOR THE DIRECTOR (this playbook may not change a registry): the driver in §4 needs an
age_variant_tier (A/B/C/D) and an age_rungs list per character row, or the policy above lives only in
prose. Recommended as a registry_extensions-declared column pair on T0_Character_Index, derivable
mechanically for every row from the two measurements in §3.2.
---
The shape is already proven in this repo. harness/asset_factory/standing_batch.py is the precedent:
a pipelined driver over a proven stack that does not reimplement a single rung and does not edit one —
the lane's tools are called as subprocesses exactly as the serial runner calls them, *"so this runner and
that one cannot drift apart in what they actually execute."* The character driver is its sibling.
python harness/asset_factory/character_factory.py \
--character CHAR_0002 --config build/art/characters/CHAR_0002_FACTORY.json \
[--stage face|body|merge|ladder|lift|fit|partition|texture|rig|turntable|import] \
[--age 7|9|11|12.5|14|16|18|all] [--resume] [--limit N] [--dry-run]
age_variant_tier + age_rungs,the Josh reference per rung, the locked recipe ids, the physique clause set, the region partition
profile, and the licence records for every model touched. Nothing is typed at the call site.
CHAR_NNNN_<STAGE>[_<age>].json) with modelid, seed, denoise, every input's sha256, wall-clock, VRAM peak, and the instrument readings — the shape
the existing keystone/body/merge records already carry.
its data, on a named instrument. A pass without its image is un-DONE — this is a hard ruling, not
a convention.
--resume skips any stage whose record exists and whose input hashesstill match. A recipe change is a hash change, so it re-runs by itself.
The driver stops and emits a review artifact. It never advances past a gate on its own.
| Gate | Artifact the driver emits | Who |
|---|---|---|
| G1 FACE BRACKET | per-age contact sheet, every cell labelled with lineage + detail_index + copy_to_pick, Josh's own reference inline beside each tile | Josh picks a cell |
| G2 PHYSIQUE BRACKET | the 3-cell bracket per graded rung around the target | Josh picks the calibration point |
| G3 MERGED KEYSTONE | the keystone sheet, all rungs, at 1:1 | Josh approves / rejects |
| G4 IN-BETWEEN LADDERS | the 18 candidate-context ladders + the final (§ stage 4) | Josh picks per age |
| G5 3D TURNTABLE | 8-view lookdev sheet per environment, plus the plate comparison | director sighted every artifact; Josh on the final |
| G6 IN-ENGINE | equip/unequip frames at a fixed camera, hem close-ups, one frame per LOD border, plus the read-back JSON | director; Josh at factory-complete |
Before G1/G3/G4 the driver runs the DIRECTOR EYE-PASS: a per-tile sighted audit recorded to disk. A
lane's gate table and its own eye-calls are inputs, never the pass.
The default priors the driver ships with, each of them Josh's established pattern rather than a guess:
in-betweens derive from the OLDER anchor; a bracket replaces a single-point guess the moment an axis
oscillates twice; candidates are judged in progression context, never as a tile; the lane **does not
down-select** — it labels and ships every cell.
Inherited wholesale from standing_batch.py, because the constraints are identical:
bake for characters already through the card. The serial runner leaves ~40% of every asset's wall-clock
on the table.
ComfyUI queue-depth check before every submit. This lane YIELDS. It never assumes the card, it never
calls ComfyUI's /free (which would evict another lane's loaded model), and if the card is busy it
waits instead of OOMing — *a self-inflicted OOM reads as a real hardware trigger and costs the other
lane its run too.* The face lane's own runner already does this: it submits, waits its turn, backs off,
kills nothing. MV-Adapter's 29.06 GiB makes this binding on a 32 GiB card.
class named**, because rejects are cheap and the class is the lesson.
is theirs.
context; BODY lanes receive only the age-agnostic proportion spec; CHUNK lanes receive only their chunk's
spec and palette. Contamination is a named defect, so the driver passes disjoint context sets.
--age as an int and loads BODY_AGE_%d.json. Rather than edit files another lane holds open, import them as
MODULES with SPECS/HERE pointed at a generated alias directory keyed on age × 10, then rewrite the
emitted age/spec fields back to the true rung and **declare every rewrite in the record's own alias
block.** Proven in lineup7_build.py.
Every one of these exists because its absence cost a run:
a MISSING baseline FAILS rather than passes, because an unverifiable claim is not a satisfied one.
real method defect on its first run (§ stage 2).
two-sided on the plate's own bands before its verdict counts.
seedvr2_refine.py catches 5/5; acquire_exemplar.py runs 37/37. A checker that cannot fail is not a checker.
---
| Instrument | What it measures | Where | Standing |
|---|---|---|---|
identity copy-index (merge_identity_v6.copy_index) | Pearson correlation of two crops reduced to 64×64 grey (LANCZOS) | merge / ladder | COPY_FLOOR = 0.99; vacuous when protection equals its own window |
exemplar_match (merge_route_a_v8.measure_head → merge_race_a14.find_face) | FFT normalised cross-correlation to LOCATE, then the 64×64 copy-index to SCORE, searched only inside the figure mask | merge | ceiling is 0.98994, not 1.0 — a 1344 px bust against a ~170 px placed head — *"a raw 0.99 floor on this instrument is not a bar any route can clear"* |
struct_pos (face_landmark_warp.py) | full-Procrustes position on the young→old shape axis; ⟨S_c−S_y, S_o−S_y⟩ / ‖S_o−S_y‖². 0 = young anchor's bone structure, 1 = old anchor's, 0.5 = a true in-between | in-between faces | gates the ladder. --selftest runs before every build and refuses unless anchors score exactly 0 and 1 (±1e-9), a 50/50 landmark blend reads 0.500 ±0.02, and a 90/10 reads 0.900 ±0.02 "or the axis is not linear." Full Procrustes is what stops the age-11 plate's known framing difference (41.7 px/cm against 48) masquerading as growth |
ratio_pos (same file) | the median of four scale-free skeletal proportions over interocular distance | in-between faces | rides beside struct_pos because *"struct_pos projects onto the WHOLE shape difference… including expression."* Median not mean — face_w_over_iod reads temple-to-temple where hair crosses the landmark and on one plate scored −1.11, dragging a four-value mean from ~0.32 to 0.02 on its own |
detail_index (face_overcopy_g4.detail_index) | std(box − gaussian(box, σ=1.2)) × 1000 on the central 50% | faces / ladder | the chained-pass cost meter |
micro-texture (body_ladder_v3.micro_texture, wrapped by merge_identity_v6.micro) | Laplacian variance over figure pixels | merge / body | floor 75.1 — and it is the *geometric mean of the two measured arms* (doll 40.0, real 141.0), because an earlier borrowed constant of 190.0 killed every real plate |
girth tables (body_probe.cross_section + loop_stats) | exact triangle-plane perimeter at named sites; PROFILE_STEP 0.25 cm, WELD_TOL 1e-7; an unclosed chain is reported, never silently closed | body / fit | the house instrument; its confound logic must come across, never be reimplemented |
measure_mesh.py (fit_symmetry_plane, symmetry_residual, band_profile, surface_quality) | sym p95, drift range (not mean — *"a figure standing off-centre is merely translated and that is not a defect"*), width asym, components / largest share, lumpiness | 3D bake-off | plane fitted per mesh by coarse-to-fine search over ±8% offset and ±12° yaw, 5 refinement rounds. Declares its own bound: a lower bound on point-to-surface, *"so a bad score is trustworthy and a good score also asserts dense sampling."* Reports; encodes no threshold |
| landing battery | watertight, manifold, max_bodies 8, max_deviation_pct 3.0, uv_in_unit_square, min_uv_utilization 0.18, tris 1,200–60,000, normal_baked, ao_mean_range [0.05, 0.98] | landing | the armed threshold set (build/3d/verify_all.json) |
texel_coverage_tooth.py | observed texel fraction | texture | mean 0.61 (0.52–0.79) on bench; declared "REPORTS, does not reject" |
winding_defects | inside-out bands that pass every manifold check | assembly | reads 0 on the prior path too — that control is what proves the number is not merely reporting new code |
| garment / hair segmenters | coverage estimates | derivatives | REPORTED, NEVER THE LANDMARK — the landmark is sighted and declared |
find_face, silhouette neck-finder, chin detector, crown-only hair reader, silhouette blob guard, containment (for facing) | — | — | NAMED WRONG on these subjects. Advisory only; none gates |
**The eye outranks the instrument, and an instrument that scores an approved cell down is wrong by
definition.** Four independent proofs from this run, listed because one would be an anecdote:
1. Four engineered merge passes each closed an instrument-reported defect and none survived his eye.
2. The auto-picker and the eye disagreed on both perimeter rungs, and the eye's pick was right both
times.
3. find_face collapsed to 0.58–0.60 on the two plates Josh called great.
4. The metric ranking put the composite route first (0.971/0.943) while Josh graded the instruction edit
best by eye (0.952/0.946) — **and the gap is the finding: nothing in the stack was scoring "reads as one
photograph."**
The corollaries, which are the operational half:
face rather than reporting a pass.
operation only, and let the eye decide inside it.
In the rig (this factory's own instance). The containment score — mean bone-to-nearest-vertex
distance over all deform bones, sampled at all four right-angle yaws — was the instrument used to
establish a character's facing. It cannot. A body is near front-back symmetric in that metric, so **0°
and 180° land within a fraction of a centimetre of each other** while both beat 90/270 by centimetres:
*"Containment therefore establishes the LATERAL axis and nothing more, and a flip that survives it would
ship a character walking backwards through every clip"*
(build/3d/characters/bl_skin_to_mannequin.py). What actually gates the flip is containment **for the
lateral axis only, plus the rig's own clavicle_l/clavicle_r derivation, plus two rendered witness
frames — and a disagreement between derived and best-measured yaw is a hard fail, not a shrug.** Mean
is used deliberately over max, because *"a max is one outlying finger away from being uninformative."*
Two flip instruments were retired on their own calibration and named so they are not revived:
face_vs_occiput_cm (reads the modelled hair mass at the occiput, not the nose — the bare-headed
mannequin calibration does not transfer) and toe_vs_heel_cm (mannequin margin 0.98 cm against a 2.0 cm
bar — uninformative).
**In a matcher (the same class, caught in the audio lane, imported here because the character factory
will need identity and variant matchers).** Scored on RAW substrings in both directions at a flat 0.90,
FINAL FANTASY V is a substring of FINAL FANTASY VI — **a match across a token boundary, v being a
prefix of the token vi, never that token — and a wrong cue attached at total 0.91, past every bar**
(docs/PIPELINE_LEDGER.md :: THE CONTAINMENT POISON CLOSES). The fix: **containment requires a
contiguous TOKEN RUN and is scored ASYMMETRICALLY** — shorthand earns the credit, a strict subset earns
nothing — plus a sequel veto. And the arming proof matters more than the fix: reading every
strict subset as a refusal — the naive reading — reddened the control by flagging seventeen landed rows.
**That is why the rule is asymmetric rather than blanket, and why the mutation control is the tooth
rather than the rule.**
The law both instances teach: a score that separates one axis is not evidence about the axes it does
not separate. Write down what an instrument establishes and what it does not, on its own face.
views_used 0, observed_fraction 0.0, 673,692 texels hole-filled — *"yet still wrote an atlas and
a GLB that looked fine at a glance."* Cause: the view renderer runs inside WSL and recorded /mnt/d/…
paths, so the Windows-side merge failed os.path.exists on all six. **Why it was caught: because the
merge REPORTS holes instead of hiding them. A merge that silently nearest-filled would have shipped
this.** A cell whose bake observed nothing is now FAILED and never reaches a blind sheet.
Four of six views of a flat weapon rendered a featureless dot or hairline strip. The fix is a ratio
gate at 1.6, not a class list, because at 1.6 it fires on exactly the three long thin subjects
(8.85 / 3.38 / 6.57) and leaves the near-equidimensional ones (1.01–1.07) authored.
defect.** The weapon class ships round-sectioned rods for canon-flat blades (flatness 0.99–1.79 against
a real flat blade's 3–7); *"a textured rod shot at 23° elevation from four cardinal azimuths reads as a
paddle"*, and *"WPN_036 photographed down its own long axis is a CIRCLE."* The bound the record then
places on itself: the routing table may not claim weapon IDENTITY is solved.
happened once, on two near-identical proportions. Declared impact NONE, and the fix named for the next
benchmark: show the judge the canon row id and its morphology text per cell.
wrong for a body metres long: *"the serpent rebuild landed 4,712 tris over a 4.8 m animal — a facet
roughly every 10 cm — visible in its own silhouette render."*
--resumereuse on purpose, because *"a cached raw glb carries no record of whether the plate behind it was
judged."* A staleness check additionally discards a cached reference made from a different subject,
*"or the fix would have changed nothing."*
errors="replace" IS LOAD-BEARING, NOT TIDINESS. A subprocess tail captured through cp1252 killed every reader thread on a UnicodeDecodeError and returned EMPTY output. *"The runs happened to succeed
and wrote their records to disk, which is the only reason it was visible at all — a FAILING run would
have been reported with no tail to diagnose it from."* Same family: a diacritic in a species name
killed a producer thread and cost 142 landed candidates their manifest.
report full coverage."* Count weighted vertices.
Weld by position and keep both arrays: *"the welded one is what topology is measured on, the UV-split
one is what ships."*
in the lowest tenth of the figure the heel reached 0.1117 against the forefoot's 0.0982, *"so the
control that demanded a markedly asymmetric extreme fired correctly and the answer was not taken."*
Replaced by a band-by-band depth-profile correlation that refuses below |corr| 0.90 — because *"a
heuristic that quietly returns the wrong sign is exactly the failure class the merge lane's chin
detector already cost this programme."*
the wrist sits at 80.8 cm and the waistband at 98.7, so the forearms and hands pass straight through
the band and the garment shell **grew arm vertices, reaching ±22.2 cm on a pelvis about half that
wide.** Fix: take the largest patch containing the midline.
therefore a 4.8 m animal at one third of its length"*; and for orientation, *"a tilted S reads 129 cm
tall on a body 30 cm thick."* Scale the traced centreline arc length, never the bbox.
---
Wall-clock and VRAM as recorded, not estimated. Where a figure is an estimate the row says so.
build/3d/V2_ROUTING_RATIFIED.json :: costs_measured unless noted)| Stage | n | mean | range | VRAM |
|---|---|---|---|---|
| 2D plate per candidate | 16 | 5.44 s | 5.31–5.64 | null — declared unmeasurable (runs inside a shared ComfyUI) |
| Instruction edit (Qwen-2511, 20B fp8) | — | 2 m 17 s steady state; ~7 min first cell (model load) | 24 cells ≈ 1 h on the shared queue | not recorded |
| Landmark warp (Route W) | — | no diffusion pass at all | — | negligible |
| TripoSG geometry | 13 | 21.63 s | 14.6–44.4 | 5.31 GiB (5.16–6.09) |
| Hi3DGen geometry | 9 | 25.26 s | 22.5–33.98 | 10.99 GiB (10.59–13.78) |
| Hi3DGen, single full A14 run | 1 | 59.15 s (20.4 load + 7.4 normal-load + 23.3 geometry) | — | 10,849 MiB alloc / 12,104 reserved |
| Hunyuan3D-2.1 (struck on licence) | — | 84.0 s @ octree 256 / 77.9 s @ 512 | — | 7.63 / 8.65 GiB |
finish_mesh2 | 31 | 11.87 s | 4.52–32.05 | — |
| v1 single-projection bake (superseded) | 22 | 2.25 s | 1.93–2.62 | — |
| MV-Adapter generate | 9 | 26.0 s | 23.97–29.15 | 20.49 GiB alloc |
| MV-Adapter total | 9 | 48.12 s | 41.25–52.99 | 29.06 GiB RESERVED — serialises the card |
| Cage wrap — Lane S2 (picked) | — | 351.46 s | — | CPU / numpy |
| Cage wrap — Lane S1 (lost) | — | 16.29 s | — | — |
| Girth lattice fit | — | 1 iteration to 8.3 ppm | 2 iterations on a confounded site | negligible |
| SeedVR2 3B detail | — | not yet run (weights owed) | — | 3B int8 3.46 GB + VAE 0.50 |
| LOD chain | — | 119,994 / 59,996 / 29,998 / 11,998 tri, ear retained 99.20% | — | — |
| Local LLM (prompt-assembly fallback) | — | qwen3:14b 53.9 t/s; phi4 146.8; 4b 361.1; 1.7b 479.7 | — | 14,388 MiB peak |
The VRAM method is declared, and it matters: *"torch.cuda.max_memory_allocated inside each model's
own process — a running maximum, never an nvidia-smi sample."* And the plate generator's VRAM is
recorded as null with its reason rather than filled with a plausible number.
The ratified per-asset figure is 81.3 machine-seconds, or 103.1 with one replate
(plates ×4 21.8 + TripoSG 21.63 + finish_mesh2 11.87 + MV-Adapter texture 26.0). Two costs are
deliberately not in it: the judged PICK (attended) and queue wait — *"this lane yields the card to
three other lanes and the yield is unbounded by design."* The replate budget is evidence-based: a
defining feature appeared in 3 of 8 canon-keyed candidates, so *"a one-shot text conditioning had
roughly a 50% chance of shipping the wrong object."*
Production batches, end to end (build/3d/batch_result_*.json):
| batch | attempted | passed | recycled | wall clock | per asset |
|---|---|---|---|---|---|
| weapons (the clean reference) | 72 | 72 | 0 | 2,161.2 s | 30.0 s |
| flores props | 42 | 26 | 16 | 2,820.2 s | 67.1 s |
| slice creatures | 9 | 5 | 4 | 1,275.8 s | 141.8 s |
| equipment | 14 | 11 | 3 | 359.6 s | 25.7 s |
finish_mesh2 is the variance source, not generation — its per-item maximum reached 1,222.3 s on
slice creatures and 106.5 s on equipment, against an 11.87 s mean. Multi-view texture passes run
~50–75 s/item in production (equipment 11 items in 547.7 s) with one 749.3 s outlier on the serpent.
The GPU-bound stages are texture (29.06 GiB reserved, serialising) and the instruction editor
(~2 m 17 s per cell). **But everything that made the protagonist expensive was ITERATION COUNT, not
per-unit cost** — the 18 rung's physique oscillated three times, the face ladder ran four generations,
the body register changed six times in one night, and the merge produced four passes that the grade then
excluded. **The bracket-instead-of-guess rule, the older-anchor default, and the do-not-down-select rule
all exist to cut iteration count, and that is where this factory's economics actually live.**
one turntable — order of a card-hour, zero human iteration.
(which are nearly free) — and its 3D age rungs are morph targets on one cage, not seven assets.
---
**BLANKET INSTALL AUTHORIZATION (Josh, 2026-08-07, relayed by the director this sitting; OWED a
DECISIONS_PENDING_JOSH.md entry so it is citable from the record rather than from this file).**
Downloads and installs proceed as needed — weights, node packs, wheels, tools — without a per-item ask.
The SeedVR2 3.96 GB acquisition and the TRELLIS.2 wheel set are the immediate consumers.
LICENCES ARE STILL CHECKED PER ITEM, and the Hunyuan3D lesson is why. The authorization removes the
*permission* step, never the *licence read*. Hunyuan3D-2.1 was installed, run, benched and struck — its
territory clause excludes the EU, UK and South Korea and binds the OUTPUT, which a worldwide Steam release
violates by definition, and nobody had written that down until the read was performed against the
licence file already pinned in our own repo. The standing posture: **face-value reads, flag only explicitly
triggered prohibitions** — and record the read so it is not re-litigated. Every licence-blocked tool of this
cycle is named once so a bench day is never spent on it again: SUPIR (weights rights withheld),
NVIDIA PiD v1.5 (NSCLv1 weights — and it ships a decoder trained *specifically* for our own
Z-Image-Turbo), PartUV (Apache core, non-commercial NVIDIA checkpoint), Krea 2 (revenue-triggered
cessation, mandatory filter, mandatory name prefix), SkinTokens (MIT weights over a partly-ripped
training corpus — a Josh-tier read), XTTS-v2 (CPML non-commercial and Coqui dissolved, so nobody can
sell a commercial licence — the MPL-2.0 *code* licence is the trap).
TOOL FREEDOM IS STANDING. *"you dont always have to use claude and should always use whats best suited
for achieving our AAAAA quality across everyything"* — survey and adopt whatever model or open-source tool
does a task best, then alter, enhance and polish on our locked recipes. The licence bar and the
identity/provenance laws are unchanged (DECISIONS :: THE KEYSTONE AGING METHOD + TOOL FREEDOM).
THE ANTI-ORPHAN RULE, restated because this stack already lost 872 lines to it.
build/3d/research/LOCAL_MODELS_AUG2026.md — fully cited, carrying the working Windows install recipe that
later unblocked TRELLIS.2 — sat **untracked, unregistered in DOC_MAP, absent from the ledger, and consumed
by nothing.** *"The stack did not fall behind because nobody looked. It fell behind because what someone
found never reached a decision."* Every artifact this playbook's stages produce gets a record, a DOC_MAP
row and a named consumer in the same commit.
GATE STATE at the time of writing, attributed rather than smoothed. python harness/run_gates.py
exits 1 at HEAD on two failures that predate this document and belong to other lanes: ledger (a DANGLING
DOC_MAP entry for records_B/DIAGNOSE_BEFORE.json, plus ORPHAN GROWTH at 68 against a baseline of 66) and
line_citations (two NEW line-range citations in an untracked bestiary sheet). This document adds a
DOC_MAP row and mints zero line-range citations, so it moves neither number — which is the check that
neither is ours.
---
Named so the gaps are on the artifact's face rather than discovered later. Ranked by what blocks most.
downstream depends on it: age morphs (which are only cheap because identically-topologised wraps are
blendshapes of each other), the region partition on a shared vertex order, the swap gauntlet, and the
whole Tier-A economics. Priced: Faceform WrapCmd, headless and batchable at Indie $570, or build
landmark-constrained coarse-to-fine NICP, which Blender does not provide.
UNDECIDED AND THE BLEND PROOF FAILS").** The blend-proof half CLOSED as an instrument-reference
defect — G4 was judged against parent A while its own _why names the cage; re-referenced with
four controls holding, the proof PASSES (build/3d/cage/blend_fix/BLEND_G4_REFERENCE_FINDING.json,
869ba32f), so the seven-age lane's release gate is clear on this axis. The Anny-vs-MHR
PARAMETRIC-PRIOR question remains live and is now owned by charter row S4 (the prior lands as a
BOUND, never a target; the pose-and-prior wave ed40161d is executing it); MPFB2 remains not
installed.
facebook/dinov3-vitl16-pretrain-lvd1689m's gated terms. Submitted and awaiting review. Minutes to
re-run once open; the instrument, conditioning and sheet builder are all written.
full AFTER measurement path is dry-run green against a lanczos stand-in. Proceeds under §7. Minor
residue: the validate/self-test result exists in prose in the ledger, not as a JSON artifact.
Material Anything (MIT) is the named replacement; verify its maintenance status first.
ordering rule are already researched, so these are build items, not research ones.
xatlas PACKING OPTIONS — landed at uv_pack_options.py and strictly dominant; theremaining work is re-baking the corpus through it, which improves every existing asset.
18 side with the pair-cohesion problem (the 18 anchor's three-quarter pose and scar making
derivatives read disjoint) solved structurally.
every auto-rig migration carries an unpriced joint-naming map per body plan. Two mechanical
residues ride with it: verify_landed's rig-truth glob points at build/3d/rigs/, **which does not
exist**; and the one armed ROM instrument reads deflection as the angle between consecutive bone
direction vectors from component-space positions, convention-free by construction, *"because half
the false ROM findings in rigging come from reading a local Euler as if it were a joint angle."*
T0_Character_Index has no age_variant_tier / age_rungs.A registry change, and therefore a director's call, not this document's (§3.6).
material_slot_cap IS NOT_DECLARED for the character / NPC budget class.anatomy schemas needs its own cage on the same partition principles. **One cage per archetype, never
one per project** — a quadruped and a serpent cannot share a vertex order. Census: 187 rows —
QUADRUPED 62, NEEDS_CANON_BODY_PLAN 42, WINGED 32, AQUATIC 20, LIMBLESS 13, ARBOREAL_PRIMATE 11,
SPRAWLING_QUADRUPED 4, MULTI_LEGGED 3.
commercially usable is human-shaped. Plan creature motion as AUTHORED and procedural against our
own archetype rigs, rather than waiting for a tool that is not coming.
4% at every derived rung and inside 0.2% at 14, published with their spread as the uncertainty. It is
not wired into AGE_PROPORTION_TARGETS.json, and the reason is a tool gap rather than a data gap:
conform_true_base.py's lateral field is ISOTROPIC, so there is no lever that can set a depth
independently of a breadth. OWED: an anisotropic lateral field (separate sx(z) and sy(z)),
after which those four rows become solve targets.
(16–18% of figure micro-texture) because *"the shared ComfyUI queue interrupted this sitting's native
run mid-sampler and Josh selected the plate that existed."* Never-degrade beats restore — the
native regeneration should make the refine pass unnecessary rather than compensate for it.
---
docs/PIPELINE_LEDGER.md — the matching entry; rows C1 (protagonist face), C2 (body + outfit),C4 (companions), E1 (creature plates), G1 (rig + ROM), I5 (factory enhancement stages).
build/art/characters/CHAR_0002_EXEMPLAR_PREP.md — the companion programme's charter; §1's inheritanceregister and §4's conditioning plan take their stage list and their gate points from here.
docs/pipeline_review/BODY_ASSEMBLY_ARCHITECTURE_BRIEF_2026-08-06.md — the ratified architecture thisplaybook operationalises (and whose §6.1 stage-5 "12 morph targets" is superseded by the seven-age ruling).
docs/EYE_STAGE_SPEC.md · docs/GROOM_STAGE_SPEC.md · docs/LOOKDEV_STANDARD.md · docs/asset_budgets.json — the four factory-enhancement stages this chain calls.
docs/MODEL_STACK_AUDIT_AUG2026.md · build/3d/PIPELINE_RESEARCH_AUG2026.md — the model choices andlicence reads every stage above inherits.
docs/DOC_MAP.md — the catalogue row.