EYE_STAGE_SPEC.md

systems/EYE_STAGE_SPEC.md

THE EYE STAGE SPEC — the named sub-stage of the character factory

What this is. The build spec for EYES as a standing stage of the character factory chain, per

Josh's factory-enhancement roster item 2: *"EYES as a named sub-stage: cornea/iris shading,

subsurface, and a look-at rig — the FF7R appeal at runtime is mostly eyes; currently an owed note,

now a stage."* (docs/spine/DECISIONS_PENDING_JOSH.md L4708-4709, THE FACTORY ENHANCEMENT ROSTER.)

It converts that one line into a material stack, a texture contract, a rig, an LOD ladder, and a

review law, each grounded on what the repo has already measured.

Authority. PROPOSAL-TIER, and it rules nothing. Canon, the CVD and Josh's rulings bind every

line. Where this spec and canon disagree, canon wins and this spec is the defect. It says HOW the

eye stage runs; it never says what the character looks like — the plate lineage and the T3 colour

canon already said that.

Honest tier. Every claim below about the current state is a measured read off a landed record.

No claim is made that any eye asset is shippable. *(Superseded in place 2026-08-10, director-rows

wave: this line originally carried "the count of Josh-graded-acceptable generated plates across

three generations is 0". That register is closed — the V4 body plates are generated and

Josh-approved as the exemplar set ("Yeah v4 is approved", BODY_V4_CARRY_SEVEN_AGE.json). The

shippability claim above is unchanged.)*

---

0. THE UNBLOCK TRIGGER — superseded in place 2026-08-10 (director-rows wave, roadmap C-01)

**This section originally read "nothing in this spec executes yet / every execution step below is

BLOCKED" behind two blockers. Blocker 1 is DISCHARGED BY EVENTS; blocker 2 stands. Execution has in

fact landed:** eye records exist on the ROUTE-A lineage

(build/3d/best_a14/face_pass/EYE_ALBEDO_A14_V3.json, EYE_ALBEDO_A14_V32_ANCHOR_B.json,

L11_EYE_ANCHOR_FORK_V32.json, author_eye_a14.py; the aperture probe under

build/3d/best_a14/eye_aperture/), and the remaining eye-shader work (limbus/iris parameters, the

three geometry pieces — lacrimal meniscus, caruncle blend, eyelid occlusion) is carried by the

charter's S10 row (docs/pipeline_review/CHARACTER_FACTORY_MASTER_CHARTER.md), which is now the

authoritative sequencing for it. A doc still reading "blocked" while the work is landed is the drift

class the living-source law exists to kill; hence this supersession.

PICK = S2 numpy landmark-NRICP, p95 0.01749 vs do-nothing 0.05232) and its blend-proof release

blocker closed as an instrument-reference defect, proven by four controls

(build/3d/cage/blend_fix/BLEND_G4_REFERENCE_FINDING.json, landed 869ba32f). The original

text's caution ("must not presume which cage wins") is preserved as history below and needs no

further observance.

chain has not proven first (prep/reads exempt)"*

(docs/HANDOFF_2026-08-05_ACCOUNT_SWITCH.md L1003-1005, THE CONVERGENCE TARGET). The eye stage

runs on CHAR_0001 first, at the graded keystone ages, and cascades to companions/NPCs/creatures

only after it has proven itself there.

What is NOT blocked, and is what this wave landed: this spec, the parameter-contract tool

(GAME:Tools/char/eye_material_contract.py), and its synthetic fixture proof. None of them

generate a character, a plate, or a mesh.

Superseded §0 text (2026-08-10, preserved verbatim)

## 0. THE UNBLOCK TRIGGER — nothing in this spec executes yet
**This spec is SCAFFOLDING. Every execution step below is BLOCKED until both of the following
land, in this order.**
- BLOCKER 1 — THE CAGE VERDICT. The cage-source bake-off is the standing chain's stage-2 gate
and the next architecture verdict due (docs/spine/DECISIONS_PENDING_JOSH.md L4642-4644, THE
PARTITION IS RATIFIED). Facial topology is one of its judged criteria, because *"expressions
live or die on the cage's face loops"* (same file, L4704-4707, roster item 1). The eye stage
consumes the winning cage's face loops — the palpebral aperture ring, the lid margin island, the
eye-socket region of the partition — and must not presume which cage wins. The bench that
decides it is build/3d/cage/CAGE_BENCH_SPEC.md (READ-ONLY to this lane; the W-CAGE seat is
live).

---

1. WHAT ALREADY EXISTS — reused, replaced, and named

The stage does not start from nothing. The authored head lineage already solved the geometry half

and named its own material gap in writing. **What this spec reuses is stated so the execution wave

does not rebuild it, and what it replaces is stated so nobody defends the old thing.**

1.1 REUSED without change

globe with the polar axis on +Y — the direction the eye looks — *"so the iris, the limbal ring

and the pupil are concentric rings in texture space instead of a decal that has to be aligned by

hand and drifts."* Every map in §3 below is authored against that convention. This is the single

highest-leverage thing the lineage already got right and it is not touched.

cornea cap with its own material**, on the stated reasoning that *"the wet specular that reads as

'alive' is a SECOND surface over the iris, not a highlight painted on one."* Measured on disk:

eye_l/eye_r at 704 verts / 1,344 tris each, cornea_l/cornea_r at 320 verts / 576 tris each

(build/3d/characters/CHAR_0001_HEAD_AUTHORED_RECORD.json /geometry/counts).

lid margin projected onto the globe (which is what closes the canthal gap a constant inset

leaves open), the margin ring carrying its own UV island so the bridge paints a wet lid margin

instead of a smeared strip of cylindrical skin (CHAR_0001_HEAD_AUTHORED_RECORD.json

/geometry/eye_aperture; the cutter is char_head_author.py L573-598). Cornea apex sits

0.03 cm behind the lid plane — the solved pair that keeps the cap from poking through.

and EYE_SET_BACK = 0.34 cm (char_head_author.py L143-144), eye radius 1.14 cm,

eye-to-head-height ratio 0.1161 (CHAR_0001_HEAD_AUTHORED_RECORD.json /geometry/measured).

These are the age-7 values; §4.4 makes them a per-age curve rather than constants.

IRIS_INNER (0.632, 0.702, 0.735), LIMBAL (0.185, 0.222, 0.268),

SCLERA (0.930, 0.912, 0.892) (build/3d/characters/char_head_textures.py L129-132). The canon

line behind it is the only sentence canon carries about elven colouring: the Elven King's *"eyes

are the same color as the protagonist's but deeper — the same shade with ten thousand years of

light behind them"* (_source/03_Tier_3_Characters/T3_Core_Characters [ACTIVE v1.0].md L563).

The shared quantity is the EYE colour. It does not move on any rung, at any age, on any route.

already carry used_with_skeletal_mesh: True, and already survived an engine import

(CHAR_0001_HEAD_AUTHORED_RECORD.json /engine_import/materials; the importer is

GAME:Tools/char/import_char_0001_headasm.py L75-95). **They are the bind points. This stage

fills them; it does not mint new slots.**

(CHAR_0001_HEAD_AUTHORED_RECORD.json /geometry/reveal_firewall). No emissive term appears

anywhere in §2. The eye is lit; it never lights.

1.2 REPLACED, and the record already says why

importer's own tier string is the honest confession — *"AUTHORED GEOMETRY, DEFAULT-LIT MATERIAL —

the refractive cornea the portraits render needs a transmissive shader; here it is a very smooth

dielectric, which gives the wet specular but not the refraction"*

(GAME:Tools/char/import_char_0001_headasm.py L83-88). §2.1 replaces it.

and the importer states plainly that it is *"NOT YET CONSUMED by the engine material: this import

wires default-lit, so the mask is landed for the subsurface-profile pass and is honestly unused

today"* (import_char_0001_headasm.py L62-65). §2.4 consumes it.

0 refractive corneas and 0 apertures; the eyes are painted on a closed surface, and the record

says *"THE ROUTE DOES NOT SOLVE THIS AND WAS NEVER GOING TO"*

(CHAR_0001_FACE_PIVOT_RECORD.json /gaps_named_not_papered_over[0], quoted at

docs/pipeline_review/AAAAA_IMPROVEMENT_REGISTER_2026-08-06.md L87, register row 14). APP-C3 is

the one rubric check the generated route structurally cannot satisfy. **The graft named in row 14

is this spec's first execution step (§7).**

1.3 MISSING outright — no incumbent to reuse

finds LookAt only as camera-aim arithmetic in HumanityQACaptureSubsystem.cpp (L565, L608,

L688, L719) — a player-controller rotation, not an eye. §4 is built from zero.

from the engine rather than declared (GAME:QA/bench/char_0001_arrival_set_import_result.json;

quoted in the dossier at docs/pipeline_review/AAA_WORKFLOW_CORRESPONDENCE_2026-08-06.md

L558-559). The UE5 Mannequin's 89 bones carry no eye joints — MetaHuman's ≈342 do (dossier L537).

This is the load-bearing constraint on §4 and it is named rather than assumed.

---

2. THE MATERIAL STACK

Six surfaces, each with a stated job. **A term appears here only if it changes what a frame shows;

a stack that cannot be seen at the review distance is cost without appeal.**

2.1 CORNEA — clearcoat, and depth by parallax rather than refraction

tighter specular over the iris — the physical truth of a cornea over an aqueous humour, and the

thing the constant-white incumbent gets wrong by having only one lobe.

incumbent's 0.02 is the correct order and is kept as the starting value), metallic 0, base colour

black with the surface reading entirely through its specular and the shell behind it.

A true refractive cornea needs a translucent/refraction blend mode, which in UE 5.8 costs a

separate translucency pass per pixel and does not receive the same lighting path. The AAA route

for a game eye is parallax-offset iris under an opaque cornea: the cornea samples the iris map

with a view-dependent UV offset scaled by the anterior-chamber depth, which reproduces the

apparent iris displacement as the head turns at a fraction of the cost. Anterior-chamber depth is

already solved geometrically — cornea apex 0.03 cm behind the lid plane against a 1.14 cm eye

radius (CHAR_0001_HEAD_AUTHORED_RECORD.json) — so the parallax scalar is derived from the mesh,

never dialled by eye.

the true index-of-refraction term (1.376 for corneal tissue) is authored as a **cinematic-only

material variant** for the sequencer/portrait path, where the translucency cost is affordable and

a lookdev turntable will show the difference. It is judged against the parallax variant under the

W-LOOK standard (§6) before either is called finished.

lid-margin UV island that already exists. It is a roughness modulation on the cornea's outer

ring plus a narrow specular boost — never a separate transparent shell, because a second shell at

this scale is what produces the z-fighting shimmer at LOD1.

2.2 IRIS — parallax depth, limbus, and the aperture curve

(§1.1), so the parallax direction is radial by construction and needs no tangent frame beyond the

one the sphere already has. Depth is sampled from a dedicated T_EYE_IRIS_H height map (§3),

deepest at the pupil and rising to zero at the limbus — the physical shape of the iris's posterior

surface.

sin(theta * 46) modulated by fBm, a collarette ring lobe at t = 0.34, and a limbal ring rising

over the outer 20% of the iris radius at 0.86 strength (char_head_textures.py L406-440,

eye_map). Pupil radius 0.0619 and iris radius 0.1810 in UV, with both boundaries feathered so

no aliased ring survives at portrait resolution (same function, L436-440).

view-dependent Fresnel darkening at the limbus is the geometry — the limbal ring reads darker

and wider at grazing angles because the corneal edge is thicker there. The incumbent has the first

and not the second, and the second is what makes the eye read as a sphere rather than a disc when

the head turns.

refracted through the cornea onto the far iris wall — is faked as a scalar-parameter-driven

crescent multiplied into the iris albedo, its position derived from the dominant light vector.

It is declared OPTIONAL and its default is off: at gameplay camera distance it is invisible,

and an always-on caustic is exactly the kind of term that reads as a smudge in the general case.

It arms for the portrait/cinematic path only.

eye globe is nearly adult-sized while the palpebral aperture is small, so the visible iris fills a

much larger fraction of the visible eye than an adult's. That ratio is one of the strongest

age-read signals a face carries, and getting it wrong is a named failure mode on the record — the

age-8 tile read as *"the pick unaged with doll eyes"* and the age-11 tile as *"huge empty eyes"*

(docs/spine/DECISIONS_PENDING_JOSH.md L4404-4407, JOSH GRADES THE AGE LADDER). **The stage

therefore carries iris-to-aperture as a declared per-age value, not an emergent one**, keyed to

the four keystone ages 7/11/14/18 (L4435-4438) and interpolated between them the same way the

hair states are (docs/GROOM_STAGE_SPEC.md §4). The values are SET by the graded keystone plates

when they land; this spec fixes the mechanism and the age-7 anchor (globe radius 1.14 cm, IPD

5.44 cm) and refuses to invent the other three.

2.3 SCLERA — subsurface, vessels, and the corner shadow

default-lit sclera is the tell that reads as "plastic eye" at any distance. The profile runs a

short scatter radius with a warm-red tint, because what is scattering is blood.

iris radius at 0.30 strength, plus a graded darkening toward the corners

(char_head_textures.py L415-419). Vessel density is an authored per-character value, not a

constant — an old or a wounded character carries more, a child carries very few.

under 1.0 by construction, so no lighting rig can blow it to a flat disc. This is the same

discipline the hair atlas learned by measuring its own clipping (GROOM_STAGE_SPEC §2.3).

2.4 SKIN AROUND THE EYE — the landed mask, finally consumed

T_HEAD_SSS is a thin-tissue transmission mask covering ear, lid, lip and nasal ala

(import_char_0001_headasm.py L62-65). The eye stage is where the lid channel of it starts

doing work: the head material moves from default-lit to Subsurface Profile and reads that mask as

its opacity/transmission input, so a lit lid glows at its thin edge the way a real one does. **This

is a one-line change to the head material and it closes a named honest-gap that has been landed and

unused since the head assembly imported.** Register row 15 is the wider SSS/ORM/normal port

(AAAAA_IMPROVEMENT_REGISTER_2026-08-06.md L88); the eye stage takes only the lid half of it and

says so.

2.5 TEARLINE AND LACRIMAL CARUNCLE — new geometry, and the smallest shell in the character

margin UV island, with a high-gloss low-roughness material and a soft alpha falloff. Its job is

the wet contact line between lid and globe — the thing whose absence makes eyes look pasted on.

Budget: a single quad strip per lid, ~24 quads per eye.

canthus with the skin material and a caruncle-tinted albedo patch. Its absence is why a

bare-aperture eye reads as a cut hole at the inner corner.

2.6 OCCLUSION AND AO AT THE LIDS — the term that seats the eye in the head

An eye without contact shadow floats. Two mechanisms, and the spec picks one on measurement rather

than in advance:

globe carrying a baked gradient, multiplied into the sclera. Costs geometry; is view-stable.

aperture ring's own geometry. Costs no geometry; is fixed to the bind pose, so it does not follow

the globe as the eye rotates — which is the defect that decides it.

static aperture, so a baked-into-the-globe shadow would swing with the gaze and paint the shadow

onto the iris. The strongest objection is that it adds a fifth shell per eye to a mesh already

carrying seven material slots against a steam_deck_minimum material cap of 4 per garment piece

(register row 29, AAAAA_IMPROVEMENT_REGISTER_2026-08-06.md); the answer is that the AO shell

shares the cornea's material slot with a variant switch rather than minting a new one, and the

budget class it lands in is Lane B's to declare (§3.3).

---

3. THE TEXTURE INPUT CONTRACT

3.1 The map set

MapChannelsJobState today
T_EYE_BCRGB, sRGBiris + sclera albedo, concentric by constructionLANDED (char_head_textures.py L406-440)
T_EYE_IRIS_HR, lineariris height for the POM/parallax offsetNEW — authored from the same concentric grid
T_EYE_ORMR = AO, G = roughness, B = 0per-region roughness (sclera wetter than iris)NEW
T_EYE_NRGB, TC_NORMALMAPiris fibre relief; sclera flatNEW
T_HEAD_SSSR = lid, G = ear, B = lip/alathin-tissue transmissionLANDED, UNUSED (import_char_0001_headasm.py L62-65)
T_LASH_BCARGBA, sRGBlash and brow strands with real alphaLANDED

Every new map is authored by the same generator that authored T_EYE_BC, in the same file, against

the same UV pole. No eye map is ever painted by hand or lifted from a plate — that is the route

whose baked plate lighting is the named exemplar defect the W-LOOK de-light pass exists to catch

(docs/HANDOFF_2026-08-05_ACCOUNT_SWITCH.md L1030-1031).

3.2 Resolution, stated as a rule rather than a number

Eye maps are concentric and pole-centred, so texel density is wildly non-uniform in UV: the

pupil occupies the pole and the sclera occupies the outer annulus. The rule is therefore stated on

the *visible* quantity: **the iris annulus carries at least the same texels per centimetre as the

face skin at the same LOD**, measured on the rendered frame rather than declared in UV. At the

landed head's numbers that lands the eye maps one power of two below the head maps, and the exact

figure is a measured output of the first execution run, not a guess in this document.

3.3 Budget class — deferred to Lane B by name, not by number

The eye stage's triangle and material-slot cost is declared **against the spec-class taxonomy Lane B

is arming this wave**, by class name only: steam_deck_minimum / mid_range_pc / high_end_pc /

ultra (_source/01_Tier_1_Foundation/T1_Build_Pipeline_Contracts [ACTIVE v1.0].md §1.7, the

four-spec-class enum at L166 and the per-category budget shape at L185-188). **This spec states no

triangle number of its own.** Roster item 5 is explicit that budgets must be teeth rather than notes

(DECISIONS_PENDING_JOSH.md L4715-4717), and a second lane inventing a parallel number is how a

budget stops being one. The eye stage's obligation is to *declare its per-LOD counts into whatever

gate Lane B arms*, and §5 is written so those counts are derivable.

---

4. THE LOOK-AT RIG

*"The FF7R appeal at runtime is mostly eyes"* (roster item 2). A perfectly shaded eye that stares

through the player is worth less than a plain one that looks at them. **This is the half of the

stage that is missing outright (§1.3), and it is the half that changes a frame the most.**

4.1 The bone question, answered against the measured skeleton

The shipped skeleton is SK_Mannequin at 89 bones with no eye joints (§1.3). Three routes exist and

the spec picks one:

already enforced in the importer: update_skeleton_reference_pose stays False because

*"SK_Mannequin is shared with every animation asset in the project"*

(import_char_0001_headasm.py L25-26, L137). Editing the shared skeleton is not this stage's to

do.

leaves under head.** Appending leaf bones does not disturb the retarget chains or the root

motion contract, because retargeting maps limb chains and the eye joints belong to none of them

(the IK Rig / IK Retargeter model, dossier L530-533). Cost: the character carries its own

SKEL_ asset.

range: it slides a picture across a sphere instead of rotating one, so the specular highlight and

the parallax do not move with the gaze and the tell is immediate at portrait distance.

RECOMMENDATION: Route 2, with eye joints appended as leaves under head on a per-character

skeleton, and Route 3 retained as the crowd-tier implementation for the volume-NPC class where

no frame ever reaches portrait distance (roster item 6, THE VARIATION CAPABILITY,

DECISIONS_PENDING_JOSH.md L4718-4721). The strongest objection to Route 2 is that it forks

the skeleton the whole animation economy runs on, and a forked skeleton is how animation reuse dies.

The answer is that leaf-only appends under head preserve every retarget chain by construction and

are verifiable as such — a hierarchy diff against the 89-bone template that shows exactly two added

leaves and zero changed parents is the gate, and it is mechanical. **This routes to the cage verdict

because the winning cage's head partition determines where the eye joints sit; it is not settled

here.**

4.2 Convergence — the thing that separates a look-at rig from two rotating balls

angle is derived from the focus distance and the character's own IPD, which is a measured

per-age value (5.44 cm at age 7, char_head_author.py L143) and therefore changes across the age

ladder for free.

±45° adduction, ±25° elevation, ±30° depression). A focus point closer than the clamp allows

results in the eyes converging to the clamp and the HEAD turning the remainder — which is what

people do.

target, the interaction prompt, and an idle-interest selector all write to one focus-point

channel; the rig only consumes it. This keeps the rig one asset rather than one per system.

4.3 Lid follow, saccades, and idle behaviour

the lid comes with it. Without this, a downward gaze shows sclera above the iris and reads as a

stare. Implemented as a driven corrective on the lid bones (or lid morph, per §4.5), sourced from

the eye joint's own pitch so it can never desynchronise.

but it declares the contract: the blink drives the lid, the lid drives lid-follow's zero, and

a blink during a gaze change must not fight the follow. Named as the interface, not built here.

degree, a few times a second, with a random walk bounded to the current target. This is the

single cheapest term in the entire stage and it is the difference between "alive" and "animatronic"

at conversation distance.

in-world points of interest with a dwell distribution. **This is the behaviour that satisfies the

standing creature/NPC behavioural-completeness law** (DECISIONS_PENDING_JOSH.md L3755+) at the

eye level.

4.4 Per-age placement

Eye placement is not age-invariant. The globe reaches near-adult size early while the orbit and the

aperture keep growing, so IPD, set-back, and iris-to-aperture ratio all move across 7 → 18. The rig

therefore reads these as per-age values from the same keystone data the groom stage reads

(7/11/14/18 declared, 8-17 interpolated). The age-7 values are measured and landed (IPD 5.44 cm,

set-back 0.34 cm, globe radius 1.14 cm); the other three keystones' values are SET by the graded

keystone plates and the cage morphs, and this spec refuses to invent them.

4.5 UE 5.8 implementation path

AnimBP, containing the look-at solve and the lid-follow correctives. Reasons: it composes with

every existing animation without touching them, it is per-character rather than per-animation, it

survives retargeting, and it can be LOD-gated by the AnimBP's own LOD threshold (§5) with no extra

machinery.

sequencer shot can key the focus point directly. The spec's position is **both, with the AnimBP

layer as the runtime default and a Control Rig only where a cinematic needs hand-keyed gaze.**

/Game/Meshes/Characters/ carry the material parameters the rig's material-side terms (limbus

Fresnel, parallax scalar, caustic switch) are exposed through; the geometry the rig rotates is the

eye_l/eye_r shells with cornea_l/cornea_r parented to them. The parameter contract those

instances must satisfy is machine-checked by GAME:Tools/char/eye_material_contract.py (this

wave), so the rig can never be wired against a material that lacks the parameter it drives.

---

5. LOD AND AT-DISTANCE BEHAVIOUR

The eye is the most expensive appeal-per-pixel surface on a character at portrait distance and the

least valuable one at combat distance. The ladder says so.

LODCorneaIrisScleraTearline/caruncleAO shellLook-at
0clear coat + parallax + meniscusPOM + limbus FresnelSubsurface Profilepresentpresentfull: convergence, lid-follow, saccades
1clear coat, parallax onlyparallax offset, no POMSubsurface Profilepresentpresentconvergence + lid-follow, no saccades
2single specular lobeflat mapdefault lit, warm tintremovedremovedconvergence only
3merged into the head materialbaked into head albedobakedremovedremovedoff

distance (dossier L876-877), and each threshold is validated by walking the camera through it and

looking for the pop — the same gate the LOD stage already owes.

"look-at off" row above free rather than merely disabled. The dossier's finding stands: skeleton

LODs are absent on every asset today (L908), so this is a new capability the eye stage is the

first consumer of.

tris, cause proven by a topology-free control at 51,282 — register row 13). Named here so the eye

stage is not blamed for it and does not try to fix it: docs/GROOM_STAGE_SPEC.md §5 owns it.

---

6. THE REVIEW LAW — what "the eyes are finished" is allowed to mean

No eye claim counts unless it was made under the calibrated light. Roster item 4:

*"CALIBRATED LOOKDEV as the polish judge: the W-LOOK standard (declared HDRI set,

grey/chrome/Macbeth, de-light mandatory) becomes the light under which 'textured and polished' is

graded — polish claims under uncalibrated light are not claims"*

(DECISIONS_PENDING_JOSH.md L4712-4714). That standard is being built this same wave by the sibling

W-LOOK lane (docs/HANDOFF_2026-08-05_ACCOUNT_SWITCH.md L1025-1031) and **landed as

docs/LOOKDEV_STANDARD.md — THE CALIBRATED LOOKDEV STANDARD — while this spec was being

written; the eye stage consumes it and does not restate it.** If that path ever moves, find it by

its DOC_MAP row rather than by a path guessed here.

The eye-specific review ceremony on top of it:

a missing limbus Fresnel and a floating cornea both show), and an extreme close-up of one eye.

All four with the calibration geometry in frame, under the declared neutral HDRI.

clamp range. A static eye render is not a review of a look-at rig — the same reason a groom is

reviewed on a run cycle and not on a bust (dossier L490-492).

cornea tuned under one HDRI reads as glass under another; that is precisely the class of defect

the standard exists to catch (dossier L841-842).

sighted audit recorded first; a lane's gate table and its own eye-calls are inputs, never the pass

(DECISIONS_PENDING_JOSH.md L4416-4418).

L4558-4562).

---

7. THE EXECUTION ORDER, THE MOMENT THE TRIGGER CLEARS

Stated so the unblock is a start command rather than a planning session.

1. Read the cage verdict, and take from it the head partition's eye-socket region, the aperture

ring's topology, and the winning cage's UV block for the lid margin.

2. Graft the authored aperture + refractive cornea onto the winning route — register row 14,

scored 2.5, sized at a tooling-day, with both the geometry and the material slots already proven

through an engine import (AAAAA_IMPROVEMENT_REGISTER_2026-08-06.md L87).

3. Author the three new maps (T_EYE_IRIS_H, T_EYE_ORM, T_EYE_N) in

char_head_textures.py, against the existing UV pole.

4. Build the material graphs against the contract validated by

GAME:Tools/char/eye_material_contract.py, and import them into the existing

MI_CHAR_0001_Eye / MI_CHAR_0001_Cornea slots.

5. Consume T_HEAD_SSS in the head material — the landed-and-unused mask, lid channel first.

6. Build the look-at rig — per-character skeleton with two appended leaf joints, hierarchy diff

against the 89-bone template as the gate, post-process AnimBP layer, focus-point channel.

7. Run the review ceremony under W-LOOK, all four frames plus the gaze sweep plus the

multi-environment pass, imaged.

8. Declare the per-LOD counts into Lane B's budget gate, and let it fail loudly if they are over.

9. Cascade — companions, then NPCs, then creatures where the anatomy schema carries eyes,

per the class cascade (DECISIONS_PENDING_JOSH.md L4471-4474).

8. WHAT THIS SPEC DOES NOT CLAIM

unmake the first.

spec only declares the interface it needs from them.

geometry is the landed head's.

Generated by harness/site/structure_site.py — the URL path is the repo path. review root