Diameter, thread, fitting: three sizing systems in one catalog
At one supplier the fitting is a 15x21. At the next it is a half-inch. On the third one's invoice it is a DN15. All three size the same part, in three systems that share neither origin nor unit. We ran the real spellings through our engine's plumbing pack: it isolates two of them, loses one, and on a thread it also produces an annotation that is false.
Three sizing systems, and the engine reads two and a half
A supply fitting is sized by its pipe thread, in French notation: 15x21, 20x27, 26x34. A pipe is sized by diameters, outer and inner: 14x16, 16x18, 22x24. A valve is sized by nominal diameter: DN20. And on top of all that, the imperial inch survives: 15x21 is a half-inch, and one supplier in three writes it that way.
The plumbing pack enumerates the threads value by value — 12x17, 15x21, 20x27, 26x34, 33x42, 40x49, 50x60 — and that is a list, not a character class. The difference is not cosmetic: the earlier version of the pattern wrote a class that generated 12x20, 12x21 and 15x20, three sizes that do not exist, and missed 12x17, which does. An enumeration written as a pattern can no longer be re-read. Fixed in the pack on 27 August 2026; the effect measured then, on the vertical's 3,000-product reference catalogue, is 678 thread annotations rising to 713, and the 35 new ones are exactly the 12x17s.
The measurement
In-house measurement. Labels run through the annotation cascade of the plomberie pack on 20 October 2026, engine at commit d25011d, each label run twice — Python cascade and production Rust core — with the same result on all seven.
| Product label | Annotations returned |
|---|---|
| Raccord laiton male 15x21 | FAM_RACCORD · FILET_15x21 · GENRE_MALE · MAT_LAITON · RACC_15x21 · TUBE_15X21 |
| Manchon 1/2 pouce laiton | FAM_RACCORD · MAT_LAITON · POUCE_1/2 |
| Manchon 1/2" laiton | FAM_RACCORD · MAT_LAITON |
| Tube cuivre 14x16 barre 4m | FAM_TUBE · MAT_CUIVRE · TUBE_14X16 · TUBE_MAT_CUIVRE |
| Tube multicouche 20x2 nu | FAM_TUBE · MAT_PER · TUBE_MAT_PER |
| Vanne a bille DN20 PN16 laiton | DN_20 · FAM_VANNE · MAT_LAITON · PN_16 · VANNE_DN_20 |
| Raccord MM cuivre 16 mm | FAM_RACCORD · GENRE_MALE · MAT_CUIVRE |
What this table says in the engine's favour, first. On the valve row, nominal diameter and nominal pressure are kept apart although they share exactly the same shape — two letters, a number. That is the distinction a plumber makes and a text search loses. On the last row, “MM” is read as the male-male gender and the “16 mm” that follows is not: the pattern requires that “mm” not follow a number.
That detail was expensive before it was settled. Across the reference catalogue's 3,000 products, “mm” preceded by a number — the millimetre — appears 662 times, and the “mm” of a male-male fitting 205 times: the spurious sense was three times more frequent than the intended one. Every pipe, elbow and coupling was therefore tagged male. Not a search that fails, a facet that lies: filtering on “male” returned half the catalogue. Fixed on 27 August 2026, with the effect measured on that same reference catalogue: 1,031 male-gender annotations, 34.4%, brought down to 466, 15.5%. The female gender stays at 560, unchanged, which bounds the effect to the defect being targeted.
What the engine loses, and what it wrongly asserts
The inch written with a quote mark is lost. Third and fourth rows of the table: “1/2 pouce” returns POUCE_1/2, “1/2"” returns nothing of the size. The rule does accept the quote mark. But the engine's normalisation only admits the period, the comma, the slash and the hyphen as internal separators: the quote mark disappears before the rule runs. The pattern provides for a spelling the tokeniser will never hand it. This is not a logic error — it is a rule written without knowing what normalisation lets through, and it is the third time in our packs, after the degree sign in wines and the foot mark in surfboards.
The multilayer pipe's dimension is lost. Fifth row: “Tube multicouche 20x2 nu” returns the family and the material, no dimension. The pipe-dimension pattern requires two digits on each side of the x. But multilayer and PEX pipe are noted “outer diameter × wall thickness”: 16x2, 20x2, 26x3. The second number has one digit. The pattern therefore covers copper and misses PEX and multilayer, which is to say most new installations for the past twenty years.
And a thread gets a false annotation. First row of the table: the 15x21 fitting carries FILET_15x21 — correct — and TUBE_15X21 — false, there is no pipe of dimension 15×21. Both patterns match the same string, the thread one by enumeration and the pipe one by “any pair of two digits”. This is not a silence like the two losses above: it is an assertion produced with the same confidence as the true one, and it enters the level-2 stream.
It shows up in search. Same protocol, five products indexed:
P1 Raccord laiton male 15x21
P2 Raccord laiton male 1/2 pouce
P3 Raccord laiton male 1/2"
P4 Raccord laiton male 20x27
P5 Tube cuivre 14x16 barre 4m
query “raccord 15x21” -> P1 52.0 P2 12.0 P3 12.0 P4 12.0
query “raccord 1/2 pouce” -> P2 38.0 P3 18.3 P1 12.0 P4 12.0
query “raccord 1/2"” -> P2 22.0 P3 22.0 P1 12.0 P4 12.0
query “tube 15x21” -> P1 19.5 P5 12.0
The last row is the whole defect: a search for a 15x21 pipe — a product that does not exist — returns a fitting first, ahead of the catalogue's only real pipe. The result explanation the engine returns names TUBE_15X21 among the things that counted for that ranking: the false annotation is not decoration, it carries weight.
The obvious fix is forbidden, and the reason is technical. A look-ahead excluding the seven threads works under Python's regular-expression engine, and the production Rust core refuses it — “look-around is not supported” — with no fallback. None of our packs can carry a look-ahead or look-behind. What would unblock it: the complete standardised series of copper, PEX and multilayer pipe, verified against a real catalogue. Then the enumeration gets written like the thread one. We do not have it, and inventing it would put plausible, unverified values into a production pack — exactly the defect the 27 August fix removed.
The limit we accept: 15x21 and 1/2" are not linked
The second row of the bench says it: on “raccord 1/2 pouce”, the 15x21 fitting lands at the same rank as a 20x27 fitting, which is a three-quarter inch. Yet 15x21 is the half-inch. The pack carries no synonym group — verified: neither the plumbing pack nor the electrical one declares any — and no rule translates a size from one system into the other. A rule recognises a shape; a conversion table is a different kind of object, and no pattern, however well written, produces one from text alone.
What to do about it
The remedy is the same as for the other losses, and it is measurable. The same fitting, twice, with the equivalence carried in the description of the second one:
P1 Raccord laiton male 15x21
P2 Raccord laiton male 15x21
description: “Filetage 15x21, soit 1/2 pouce”
query “raccord 1/2 pouce” -> P2 30.0 P1 12.0
query “raccord 15x21” -> P2 54.0 P1 52.0
One line of description, and the part is found through both sizing systems. The work is to write it once per thread family, not once per reference: seven values cover domestic supply.
If your catalogue already carries its nominal diameters, pressures, materials and genders, the pack reads them with no configuration — our Plumbing & sanitary page details the families and attributes it recognises. If it mixes the three sizing systems, an indexed field is what reunites them, not an engine release.