Variants and handle groups
The failure that deletes a product and reports nothing.
Two similar products merged into one silently removes a product from your catalogue. One product split into two silently doubles it. Neither changes a row count, and neither raises an error.
Partly built, and this is the honest half
Grouping flat supplier rows into products is not built yet.
Grouping from flat rows is not built, and it is not a scheduling problem. Our acceptance bar requires a genuinely ambiguous real file to be surfaced for review rather than merged, and no file in the corpus has one. A fixture cannot be honestly invented for it, because inventing the case means inventing its answer. What IS built is the protection of groups that already exist: rows are classified, and an export never splits a handle group.
We would rather you read that here than discover it later. What follows is what the product does do about variants today, which is real and which is the part that protects a catalogue you already have.
What is built
Rows are classified on evidence
Every row is read as a product row, a variant row, or an image-only row, on what it actually carries rather than on where it sits in the file. That classification is what the rest of the pipeline is allowed to rely on.
A variant field is never conjured
A variant-scoped default is written only onto a row that already carries a variant. Writing one onto an image-only row would promote a photograph into a variant — because that is exactly the evidence the platform itself classifies on.
Exports never split a handle group
Large catalogues are chunked on file size, and the chunk boundary is always between handle groups, never inside one. A group split across two uploads becomes a merged product and a deleted variant.
Why the missing half is blocked on a file
Grouping has two halves and they are not equally hard. Normalising option values — Red S, RED Small, red-small, S — is deterministic work: case folding, separator handling, a curated synonym table. It is not an AI problem and we are not worried about it.
Deciding which rows are the same product is the dangerous half. Our bar for shipping it is that a genuinely ambiguous real file is surfaced for review rather than merged — we would rather ask than guess. No file in the test corpus contains an honestly ambiguous case, and one cannot be synthesised, because inventing the fixture means inventing the answer it is supposed to test.
So it waits on a real file. That is slower than shipping it and calling the corpus good enough, and given what a wrong grouping costs, it is the only defensible order to do it in.
What it will have to do
- Group on declared evidence — a parent SKU, a shared handle, a common title stem — and record which rule grouped each set.
- Carry a confidence per group. Below the threshold the rows stay ungrouped and are surfaced, not decided.
- Treat exceptions as output, not log lines: near-miss title stems, colliding option combinations, inconsistent option ordering.
- Let the model propose and never decide. A proposal is marked inferred and reviewed like any other.
Published because it is the specification we hold ourselves to, not because it is a schedule. There is no date on this page.
In the meantime, the report still tells you
The validator reads handle groups, so a file that would break them is named before you upload it — even though the pipeline cannot yet build the groups for you.
Read the failure modes we have documented, most of which the platform reports no error for, or see this stage in the pipeline.
Check a file against the grammar today.
Free, no account. It will tell you what it can, and say what it could not check.
Check a file free