
The same body is a 29 in one jean and a 28 in another. I built the fit engine that explains why a size chart can't tell them apart.
I built this demo to settle an argument I kept having with myself, and it took one dropdown to end it. I had a synthetic shopper I called Riley, a fixed set of body measurements, and a catalog of eight synthetic jeans. I put Riley in front of the Ironside, a 14oz raw selvedge straight jean, rigid, zero stretch, and the engine came back with Size 29, 95% confidence, comfortable at every zone. Then I changed nothing about Riley, swapped the garment to the Driftwood, a stretch slim jean that looks almost identical in a product photo, and the correct size dropped to 28.
Same body. Same measurements. Two different correct sizes. And a waist-only size chart, the thing almost every apparel site actually uses today, would have printed the exact same number for both jeans and been wrong on one of them.

The product I ended up with is called Contour, and you can run this exact comparison yourself at https://veriprajna.com/demos/ai-fit-prediction-fashion. But the thing I want to talk about is not the recommendation. It is the reason the recommendation changed when nothing about the body did, because that reason is the whole argument for building this the way I built it.
Fashion has been trying to fix returns with better pictures
I started this project believing, like most people in this space, that the returns problem was an imaging problem. Apparel returns are dominated by fit, and the fit-related share runs somewhere between 53 and 67 percent, with about 63 percent of shoppers admitting they bracket, ordering two sizes and sending one back (Veriprajna WP34 research, 2026). The reverse logistics eat the margin. The industry's answer has been to make the picture better: richer size charts, then 3D avatars, then generative virtual try-on that renders the garment onto a photo of your body.
I spent a while convinced a good enough try-on would close the gap, and then I sat with what a try-on actually shows you. It shows you the jeans on a body. It does not show you whether those jeans will fit that body. A generative image can drape a fabric convincingly and have no idea that when Riley sits down, the thigh circumference exceeds what that specific denim can stretch to. The picture looks right. The seam is under load the render never computed.
A virtual try-on can show you the jeans on your body and still have no idea whether they will fit.
That was the sentence that reframed the project for me. A size chart is four one-dimensional numbers pretending to describe a three-dimensional body, and a try-on image is a pretty two-dimensional render pretending to be fit data. They share the same blindness. Neither of them can feel the fabric. Whether a garment fits is not a visual question. It is a mechanical one: the circumferential strain at each body zone measured against that fabric's elastic limit. And that is why Riley is a 29 in raw selvedge and a 28 in stretch denim even when the size chart is identical.

Why did I stop trusting the model to pick the size?
I let a language model choose the size once, early on, and watching it be confidently wrong is the reason the architecture looks the way it does now. My first instinct was the obvious one: feed the model the body, feed it the garment, ask it for a size. It answered instantly and fluently and, on the rigid fabrics, it was often wrong in the most dangerous way, wrong with high confidence. It had learned the shape of a plausible sizing answer without doing the one calculation that decides the truth.
So I pulled the decision out of the model entirely. In Contour, the size is computed in plain, unit-tested Python. For each candidate size the engine calculates zone_strain = (body_circumference − garment_finished_circumference) / garment_finished_circumference at every zone, compares it to the fabric's elastic comfort limit, and picks the size with the lowest total per-zone regret. Eight unit tests pin that physics in place. There is no model anywhere in the path that decides your size. The language model still has a job, reading messy vendor copy into a structured fabric spec, and phrasing the result into "snug at hip, relaxed at thigh." It advises. It never decides.
Agents advise, code decides. The moment the model gets a vote on the number, you have lost the thing that made the number trustworthy.
This is also the part of the thesis that does not age out, and it is the answer I give the engineers who ask why I did not just wait for a better model. A perfect language model still would not remove the need for the fabric mechanics, the body geometry, the per-zone strain calc, and the abstain policy. Even a flawless advisor has to be checked against a computed quantity to be safe at checkout. The model is one swappable advisor inside the machine. The machine is the product.
The size it refuses to guess
I almost shipped a version that never says "I don't know," and I am glad a stubborn test case talked me out of it. The shopper was Jordan, on that same rigid Ironside selvedge. I ran the fit check expecting a clean number and instead the engine surfaced a genuine conflict: at the smaller sizes the thigh blows past the fabric's stretch limit, and at the larger sizes the waist runs loose. On a zero-stretch denim there is simply no size that clears every zone. The waist-only chart, meanwhile, prints a confident 28 and moves on.

The tempting move, the one that makes your headline accuracy look better, is to always print the least-bad size and call it a recommendation. I wrote that version. Then I made the engine abstain instead: it names the least-bad size, drops the confidence to 0.58, and says out loud, "bracket, or speak to a stylist." Across the full evaluation it does this on 33 of 105 body-by-garment pairs rather than guess. An honest "no single size is clean here" is worth more to a shopper than a confident wrong 28, because the confident wrong 28 is exactly how you get a return. Refusing to answer turned out to be a feature I had to fight my own benchmark instincts to keep.
The vendor copy that can't be true
I have a garment in the catalog that exists only to be rejected, and it came out of a real irritation with how product copy is written. The Maverick is described by its own vendor as "100% cotton raw selvedge denim with 4-way stretch." That claim is physically incoherent. A rigid woven raw selvedge cannot also be four-way stretch. But a naive extractor reads "4-way stretch," happily assumes the fabric forgives everything, and hands you a dangerously wrong size with a smile.
So between the extraction and the decision I put an adversarial critic. It checks the extracted fabric spec against physical constraints, and when the copy contradicts itself, it blocks the inference and routes to human review. No size recommendation is issued. The deterministic rules have the final say, not the model that read the copy.

I keep this example on screen because it is the honest version of "AI safety" for this problem. The failure mode is not the model being creative. It is the model being obediently wrong about a garment whose own description lies. A system that always answers will answer here too, and it will be exactly as confident about the Maverick as it was about a jean whose copy was true. The whole point is to have a layer that can say "these two facts cannot both hold," and stop.
What the numbers actually say, and what they don't
I care about the benchmark, and I care even more about stating its scope honestly, because the honest number is the durable one. On a labeled 105-pair synthetic golden set, 15 bodies against 7 scored garments, Contour's engine scores 100 percent against the waist-only size chart's 60 percent. It eliminates bracketing on 67.6 percent of pairs, meaning the shopper gets one high-confidence size and does not need to order two, and it catches 39 fit conflicts, cases where the chart's waist-match picks a size the strain model proves fails at another zone.

Here is the part I refuse to round off. That golden set is synthetic, and its labels use the same measurable fabric-stretch figures the engine uses, so it is not a fully independent oracle. The 100 percent is a property of this constructed set, not a promise of perfect fit prediction in the open world, and I will not let anyone quote it as one. The number I actually stand behind is the +40-point lift over the real incumbent method, the waist-only chart that most stores run today, measured on the same labels. That advantage is largest exactly where it should be: on the rigid selvedge and tailoring, where the chart falls to 33 percent, because a rigid fabric punishes a wrong size and a stretchy knit forgives it. Where the physics bites hardest is where a picture helps least, and where this engine earns its keep.
The honest headline is not "100% accurate." It is "40 points better than the chart your store already trusts, and most of that gap is in denim."
Every one of those recommendations also writes a replayable JSON receipt: the extracted fabric spec with the exact source phrases that drove each parameter, the full per-size strain matrix, and the final decision. So the answer is not just a number. It is a number you can open up and cross-examine, and the same payload is served at an /api/fit endpoint an AI shopping agent can call directly. As commerce moves toward agents that transact for us, the sizing signal they consume has to be machine-readable, confidence-scored, and auditable. A report, not a picture.
The question I keep coming back to
I went into this thinking I was building a better guesser, and I came out convinced I had built something closer to an instrument. The interesting work was never predicting a size. It was deciding what the system is allowed to claim, when it has to abstain, which contradictions it must refuse, and how it proves each answer after the fact. When I flip that dropdown from the rigid jean to the stretch one and watch the correct size change under a body that did not, the thing I feel is not "the model is smart." It is "the physics is real, and we finally stopped hiding it behind a picture." You can flip that same dropdown at https://veriprajna.com/demos/ai-fit-prediction-fashion and watch it happen.
And if you would rather see it than read me describe it, here is the whole thing running end to end.
The question I keep turning over, and the one I would genuinely like other builders to argue with me about, is where else we are papering over a mechanical fact with a prettier image. Fashion reached for better pictures for a decade while the answer sat in a strain calculation any engineer could unit-test. So in your own domain, what is the mechanical fact underneath the thing everyone keeps trying to render, and would you trust a picture of it over a number you could check?


