# garment-qa — chromakey garment-clipping QA (T-1089) Automatically detects clothing clip-through with a **two-pass depth-proximity** chromakey. Per view (clips × sampled frames × 4 camera yaws), the capture scene renders the SAME frozen animation frame twice: **pass A** paints the body segments a garment *claims to cover* (coverage.json `hides`) flat **unshaded magenta**, garment + head/hands normal; **pass B** is identical except the garment is flat **cyan** and every garment vertex is nudged `clip_epsilon_m` (default 3 cm) **toward the camera**. A body-key pixel that is magenta in A but cyan in B means the ε-shifted cloth now covers it — the body sat within ε *in front of* the cloth = poking through. This separates a true clip from a limb merely crossing in front of the torso, an open collar, or a bare arm over background (all of which stay magenta because the cloth behind them is > ε away). **Run:** `tooling/garment-qa/run-garment-qa [config.json]` (defaults to `configs/peasant.json`). It launches Godot (`~/bin/godot4`, `opengl3`, `xvfb-run` when headless) on the capture scene, then runs the analyzer. **Config** (path passed to the scene via `GARMENT_QA_CONFIG`): `garments` (`{item_id,slot}` catalogue items, or `{glb,covers[]}` for a raw WIP garment), `body_types`, `clips`, `frames_per_clip`, `yaws`, `head_id/hair_id/eyebrow_id/skin_tone`, `out_dir`. **Read the report:** `/report.json` — the same summary prints to stdout. Two metrics per capture: - **`clip_through_pixels`** / `largest_clip_component` — key pixels the ε-shifted cloth covers (skin ≤ ε in front of cloth). **This is the real defect and it gates:** a capture `fail`s when its largest connected clip blob ≥ `--min-pixels` (default 8, tolerating AA edges). `clip_through_failures` + the `by_group` `clipfail`/`worstClip` columns roll it up. - **`exposed_skin_pixels`** — key pixels the shift did NOT cover (skin well in front of any cloth: collar/sleeve/ankle gaps, a limb crossing the torso). Informational; does not gate. Tune sensitivity with `clip_epsilon_m` in the config (smaller = only tighter pokes count) and `--min-pixels` on the analyzer. Failing/flagged frames are copied to `/failures/*_HL.png` with **exposed_skin lime**, **clip_through filled red**, and each clip blob boxed. **Note:** the Godot scene lives at `client/tools/garment_qa/chromakey_scene.gd` (not here) because Godot `res://` paths cannot leave the client project root.