Consensus flow list
On this page

How decisions are made

Harmonisation is a series of claims: this name belongs to this substance, this CAS number is correct, these two rows are the same flow. This page explains what evidence the project accepts for those claims, why several plausible-looking sources are not trusted on their own, and what happens when the evidence is not good enough.

If you want the step-by-step order in which these rules are applied, see Harmonisation steps.

The sources, and how far each is trusted

Source Used for Trusted for identity?
EF 3.1 The base flow list: names, CAS/EC, contexts, units, LCIA methods Yes — it is the starting point
ChEBI Synonyms, structures, cross-references Yes, with a formula check
CAS Common Chemistry Authoritative CAS ↔ name, structures Yes — highest quality for CAS, but see A name is not an identifier
ECHA EC inventory Official CAS ↔ EC correspondence Yes, for that correspondence
PubChem Structures, names, cross-references Only when confirmed elsewhere
OPSIN Parsing IUPAC names into structures Yes, when the name parses unambiguously
RDKit Deriving formula, mass, InChIKey from structure Yes — it is computation, not assertion
GLAD mappings EF 3.1 ↔ SimaPro flow correspondence Yes, as a stated mapping
ecoinvent An additional source list to merge Yes, as a source list

PubChem is the important exception. Its synonym and cross-reference data is crowd-sourced and contains errors, so it is never accepted as the sole basis for an identity claim. EF 3.1's own synonym lists appear to be drawn from PubChem, which is why they are not used either.

A name is not an identifier

Identifiers are ranked, and the ranking is not negotiable: a registry number outranks a name. A CAS number designates one substance by construction. A name designates whatever the person writing it meant, and common names are routinely generic where the substance is specific.

This is easy to state and was easy to get wrong, because the mistake does not look like trusting a name — it looks like trusting Common Chemistry, which is the most authoritative CAS source there is.

How a source list uses the two together

EF 3.1 pairs a readable common name with the registry number that says which substance is actually meant:

EF 3.1 name EF 3.1 CAS What that number designates
butanol 71-36-3 1-Butanol
ascorbic acid 50-81-7 L-ascorbic acid
carbon 7782-42-5 Graphite
iron oxide 1345-25-1 Ferrous oxide
pyrethrin 8003-34-7 Pyrethrins

None of these is an error. The name is the label a practitioner reads; the CAS is the identity. Carrying a generic name beside a specific number is exactly how a flow list stays readable without becoming ambiguous.

The failure

commonchem_cas_review looked up the flow's name in Common Chemistry and, on an exact match, replaced the flow's CAS with the one Common Chemistry returned. For the flows above, looking up the generic name returns Common Chemistry's generic registry entry:

Flow Name lookup returned Effect
butanol 35296-72-1 — unspecified butanol 71-36-3 discarded
ascorbic acid 62624-30-0 50-81-7 discarded
carbon 7440-44-0 — carbon 7782-42-5 discarded
pyrethrin 88108-26-3 — Pyrethrin 8003-34-7 discarded

Every one of those trades a specific number for a vaguer one, and discards the only field that said which substance was meant. In the August 2026 build this happened to 52 flow objects across 51 distinct registry numbers, and 51 of the 51 numbers discarded were valid registered CAS numbers that Common Chemistry itself knows.

The claim being made was never checked against the claim being used. "Common Chemistry says the name butanol maps to 35296-72-1" is true. "A flow named butanol carrying 71-36-3 is wrong about 71-36-3" does not follow from it.

The cost showed up downstream. EF's pyrethrins flow lost 8003-34-7, which is the number ecoinvent's six Pyrethrins rows ship — so those rows could no longer reach the substance they belong to by any identifier, and had candidates only through an EC number shared with something unrelated.

The rule

An exact name match fills in a CAS the flow does not have. It never replaces one the flow does have. Where the two disagree, the flow's number stands and the disagreement goes to the commonchem-name-cas queue with applied: false.

This is the same rule the mirror case already followed. When Common Chemistry knows a flow's CAS and calls it something else, nothing is changed and a report is filed — because "a name is not evidence of identity the way a CAS is". That is the same disagreement approached from the other side, and it cannot have two answers depending on which lookup happened to find it.

What this gives up

The old behaviour caught two genuine errors, both in the same build:

Flow CAS it carried What that number actually is
1,1,1-trichloroethane 79-00-5 1,1,2-Trichloroethane — the wrong isomer
1,3,5-triazine 121-82-4 RDX — an unrelated explosive

These are real findings and they are still reported; they are no longer applied automatically. That is the right trade. A rule that corrects two flows and damages forty-nine is not a correction rule, and neither error is safe to fix without someone looking — the flow may be mislabelled rather than mis-numbered, and only a curator can say which.

Implemented in transformers/commonchem_cas_review.py; see the review app for the queue.

The guards that stop bad merges

Each of these exists because a specific, reproducible failure was found in real data. They are worth understanding because they define what "matched" means in this project.

The CAS cross-check: don't trust a second-hand cross-reference

ChEBI IDs for a flow are resolved two ways. ChEBI-direct uses ChEBI's own CAS cross-references — the ChEBI record itself claims the CAS. PubChem-derived is a second hop: PubChem says "this compound has CAS Y and is also CHEBI:Z".

The second hop is unreliable. CAS 25013-16-5 (butylated hydroxyanisole, C₁₁H₁₆O₂) was mapped by PubChem to CHEBI:17688, which is (S)-nicotine, C₁₀H₁₄N₂. The two share no structural relationship, and the ChEBI record for nicotine does not list that CAS. Unguarded, all 105 of the nicotine record's cross-references — Beilstein IDs, PubMed articles, DrugBank, HMDB — would have been attached to butylated hydroxyanisole.

The rule: a PubChem-derived ChEBI ID is kept only if the ChEBI record's own CAS numbers overlap the CAS numbers being queried. No overlap, no match.

This guard also fixes a subtler problem. When related stereoisomers share a CAS family, PubChem may map all of them to one ChEBI entry — and that entry may carry stereochemistry-specific synonyms like (+)-(1S,3S,4R)-menthol. Without the cross-check, that name spreads to (−)-menthol, D-menthol, and racemic menthol, all of which are different substances.

The formula check: ChEBI is not infallible either

ChEBI-direct matches skip the cross-check, because ChEBI is asserting the CAS itself. But ChEBI records occasionally claim a CAS that belongs to a different substance. CHEBI:30146 (lithium hydride, HLi) lists CAS 7439-93-2, which is the CAS for lithium metal (CHEBI:30145, Li). Unguarded, lithium hydride's synonyms ("hydridolithium", "[LiH]", "hydrure de lithium") become synonyms of the lithium element, and its formula HLi contaminates the element's properties.

The rule: when several ChEBI-direct records match one CAS and the flow has a known formula, candidates are scored for formula similarity and those below a similarity threshold are discarded. Li vs HLi scores about 0.50, below the 0.55 threshold, so lithium hydride is rejected for the lithium element. Identical formulae (stereoisomers) score 1.0 and are always kept. A record with no formula is kept — absence of data is not evidence against a match.

The flow's own formula comes from its molecular_formula property, and from what its name implies. That is the whole basis: there is no separate flow-level formula field, which is why the guard is silent for flows whose structure has not yet been enriched.

The primary-CAS rule: pick the compound that owns the number

A PubChem compound lists a primary CAS — the first in its own identifiers — plus secondary cross-references. When one CAS maps to several compounds, the one whose primary CAS matches is the right one.

CAS 7440-38-2 is elemental arsenic; CAS 7784-42-1 is arsine (arsane). PubChem lists both numbers on both compounds:

PubChem CID Substance Formula Primary CAS
23969 arsane AsH₃ 7784-42-1
5359596 arsenic As 7440-38-2

ChEBI has no CAS entry for either number, so the ChEBI cross-reference strategy fails and selection falls through to "first compound in PubChem's listing order" — which for 7440-38-2 is arsane. That produced a three-stage cascade: the arsenic flow was renamed "arsane"; then, because names from all compounds sharing a CAS were pooled into one candidate list, "arsenic" was available as a name for arsine and the readability scorer preferred it over "hydrogen arsenide", so arsine was renamed "arsenic"; then element enrichment matched elemental arsenic to the flow now labelled "arsenic" — the arsine flow — and enriched it with the wrong element's properties.

The rules: prefer the compound whose primary CAS equals the queried CAS; and propagate a compound's names only to its primary CAS, not to its secondary cross-references.

The curated-CAS gate: a vendor catalogue is not a registry

The primary-CAS rule above decides between compounds during consensus matching. The same question arises earlier, where structures and names are written onto a substance, and there it used to go unasked.

CAS numbers are looked up through PubChem's xref/RN cross-reference index. That index aggregates the CAS numbers of every substance record standardised onto a compound — and a substance record can be a chemical vendor's catalogue listing. A vendor that types the wrong number into its catalogue puts that number on a compound it does not belong to.

CAS 686-31-7 is tert-amyl peroxy-2-ethylhexanoate. xref/RN returns three compounds for it:

PubChem CID Formula Substance
102465 C₁₃H₂₆O₃ tert-amyl peroxy-2-ethylhexanoate
121489259 C₁₃H₂₆O₃ the same, (2R) enantiomer
106206 C₁₈H₁₂MgN₂O₂ magnesium bis(quinolin-8-olate)

The magnesium salt is there because two vendor listings carry 686-31-7 on it. The number appears nowhere on that compound's own page — not in its synonyms, not in its CAS section. It exists only in the cross-reference index.

Merged unchecked, the substance published two molecular formulas, three InChI, four SMILES and ten IUPAC names spanning two unrelated compounds. It was also typed ChemicalSalt, because semantic typing reads the first SMILES of a sorted list and the magnesium salt sorts first.

PubChem curates a CAS section on each compound, admitting only numbers a registry or regulator attests, with a reference per source. For CID 102465 it gives 686-31-7 from ten of them — AICIS, CAMEO Chemicals, CAS Common Chemistry, ChemIDplus, EPA CDR, EPA TSCA, EPA DSSTox, ECHA, FDA GSRS, NZ EPA. For CID 106206 it gives 67952-28-7 and 14639-28-2, and not 686-31-7.

The rule: a compound is dropped from a CAS lookup when its own curated CAS section does not list the number searched on. Two conditions keep this from overreaching:

  • Something better has to exist first. A compound is dropped only when another candidate for the same CAS is attested. Where no candidate is attested, all are kept and the substance stays as ambiguous as it was — the pipeline does not guess.
  • Silence is not denial. Where no curated record has been fetched for a compound, it is kept. Only a record that was retrieved and does not list the number counts as evidence against.

That second condition is why the identifier cache stores an empty record for a compound PubChem holds no registry identifiers for. "Asked, and there are none" and "never asked" are different answers, and only the first may drop a candidate.

Every CAS the gate narrowed is listed in the CAS links PubChem does not curate queue of the review application, with the compounds kept, dropped, and not asked about.

A semantic type can change without the substance having changed. Type assignment reads the first SMILES of a sorted list, so removing a candidate can change which structure it reads. Over a 400-flow verification run the gate narrowed 55 substances to a single structure, took the count carrying more than one from 135 to 80 — and moved 15 semantic types, 10 of them on substances that are still ambiguous and whose type was therefore already arbitrary. That arbitrariness is a known limitation, not something this rule introduced; the gate makes it visible by changing which arbitrary answer comes out.

The structure gate: a registry number need not denote a structure

The curated-CAS gate above decides which compound a CAS number means. It cannot help when a CAS number does not mean a compound at all.

Plenty of registry numbers name a UVCB, an unspecified isomer, or a commercial mixture. 1300-21-6 is "dichloroethane" with no isomer stated; 68475-60-5 is "alkanes, C4-5"; 8006-64-2 is gum turpentine. None of them denotes one molecule. PubChem answers all of them anyway, because its cross-reference index returns whatever compounds were standardised onto the number:

CAS Substance PubChem returns
1300-21-6 dichloroethane, isomer unstated CID 6365, 1,1-dichloroethane
68475-60-5 alkanes, C4-5 CID 8003, n-pentane
8006-64-2 gum turpentine CID 6506, triethyl citrate
111937-03-2 isononanoic acid, C16-18 esters CID 962, water

Each returns a single compound, which is why neither the curated-CAS gate nor the formula-similarity filter caught them: both treat one candidate as unambiguous, and an unopposed wrong answer is not ambiguous. The mixture then carried a specific molecule's structure, and collided under InChIKey with the substance it had borrowed it from — the 1300-21-6 flow object against the real 1,1-dichloroethane at 75-34-3.

CAS Common Chemistry is the source that can tell these apart, because it is the registry — but only partly, and the part it cannot is the reason this rule has a curated component. Its records come in four shapes:

75-34-3      1,1-Dichloroethane   C2H4Cl2       InChIKey=SCYULBFZEHDVBN-…
68475-60-5   Alkanes, C4-5        Unspecified   (no key)
1300-21-6    Dichloroethane       C2H4Cl2       (no key)
10028-15-6   Ozone                O3            (no key)

The second is unambiguous: CAS is saying the number has no definite composition at all. The third and fourth are identical in the record and opposite in meaning — an isomer family, and a single molecule Common Chemistry simply holds no key for. 319 of the 836 answered-with-no-key records are that shape, and they include ozone, nitric oxide, nitrogen dioxide, chlorine dioxide and doramectin. Reading them all as non-specific would strip ozone's structure.

The rule, in three parts:

  • A number with no composition lends no structure. molecularFormula: "Unspecified" is CAS stating there is nothing definite to give, so neither PubChem nor ChEBI is consulted through that number, however many or few candidates it has. 517 cached records. The number itself is still published and still links to its Common Chemistry and ECHA pages — only the structure is withheld.
  • A number with a formula and no key changes nothing, unless a curator has ruled on it. The default is to do nothing, so a substance is only ever denied a structure by an explicit entry in commonchemistry-structure-decisions.json, each carrying a mandatory comment saying why the number is ambiguous. An entry without one is ignored.
  • Where Common Chemistry does give a structure, the candidate matching it wins. One-sided in the same way as the curated-CAS gate: a contradicted compound is dropped only when another candidate is confirmed. Common Chemistry is strong evidence and not an oracle — for metaldehyde, CAS 9002-91-9, it publishes acetaldehyde's InChIKey where our tetramer is the better answer — so a contradiction with nothing better to replace it goes to the queue rather than deleting a structure.

An empty cache record is neither answer. It means a 404 or a request that failed after its retries, and 286 of the 7,409 cached entries are that shape. Only a named record counts; an unnamed one changes nothing. A gap in the cache must never withhold a structure, which is the same rule the curated-CAS gate follows for compounds it never asked about.

Comparisons ignore the standard/non-standard flag — the 14th character of an InChIKey's second block — when the keys agree. Common Chemistry publishes non-standard keys freely and every other source here publishes standard ones, so …-CDRYSYESSA-N and …-CDRYSYESNA-N are the same molecule. 22 flow objects agree with Common Chemistry only once that character is disregarded.

When the keys disagree, that flag decides whether they disagreed at all. A non-standard InChI is computed under options the key does not record, and CAS reaches for them exactly when standard InChI cannot say what it needs — most often /s2, relative stereochemistry, which standard InChI has no layer for:

Trans-4-tert-butylcyclohexanol   CAS  CCOQPGVQAWPUPE-KYZUINATNA-N
                                      InChI=1/C10H20O/…/t8-,9-
(2RS,4SR)-2-methyl-4-propyl-     CAS  GKGOLPMYJJXRGD-HGXVMFPFNA-N
  1,3-oxathiane                       InChI=1/C8H16OS/…/t7-,8+/s2

40 of the 75 non-standard keys in the cache carry /s2. No standard key can ever equal one of them, so a difference against one is not the registry contradicting a structure — it is two hashes of different things. Those get a third verdict, incomparable, and the candidate is kept exactly as an uncached CAS's candidates are: nothing was said against it. A skeleton difference is still a contradiction whatever the flags say, because no InChI option moves the connectivity hash.

Against the 2026-08-07 build, with 33 seeded rulings, the gate withholds a structure from 181 flow objects carrying 2,286 elementary flows, and dissolves 49 of the 105 InChIKey collisions described in the identity limitations. Every CAS it acts on is listed in the CAS publishes no structure queue of the review application.

The stereochemistry gate: a flat registration is a statement

The gate above asks which substance a number means. This one asks which isomer of it, and it is the one rule here that is not comparative.

CAS registers 4170-30-3 as Crotonaldehyde with a flat InChIKey — MLUCVPSAIODCQM-UHFFFAOYSA-N, no stereo layer — and registers the trans isomer separately as 123-73-9. The flat key is not a gap in the record. It is the registry saying which of the two substances the number denotes:

CAS Substance Key
542-75-6 1,3-Dichloropropene UOORRWUZONOOLO-UHFFFAOYSA-N
10061-01-5 cis-1,3-dichloropropene UOORRWUZONOOLO-YFHOEESVSA-N
4170-30-3 Crotonaldehyde MLUCVPSAIODCQM-UHFFFAOYSA-N
123-73-9 trans-crotonaldehyde MLUCVPSAIODCQM-BUHFOSPRSA-N

Every source a structure is looked up in disagrees, and all in the same direction. ChEBI's entry for a common name is usually the stereo-defined natural isomer; PubChem's CAS index answers with a compound it has a record for — and a substance whose stereochemistry is unstated is not a compound either of them holds. The flow object got the trans key, and then collided under InChIKey with trans-2-butenal, a different substance with its own number.

None of the gates above can catch that, and it is not an oversight in them. They weigh candidates against each other and act only when one is better. Here there is no better candidate: in 20 of the 33 affected flow objects PubChem and ChEBI hand back the same stereo-specific structure, so nothing is contradicted and nothing is confirmed, and the narrowing gate returns early exactly as designed. Waiting for a source to disagree is waiting forever.

The rule: where Common Chemistry publishes a flat key for a number, from a standard InChI, a candidate structure that shares its skeleton and carries stereochemistry is refused — from PubChem and from ChEBI alike, however many sources offer it, and with no better candidate required. All three conditions are needed. A flat candidate agrees and is untouched, which is the overwhelming majority: 5,726 of the 6,300 keyed numbers in the cache are flat. A different skeleton is a different substance and a different problem, left to the gates above. And a flat non-standard key states nothing, because those options can suppress stereochemistry the substance really has.

Because the refusal can empty the candidate list, the structure CAS does publish is put back in its place — the key, the InChI and the formula, under enrich_references.commonchemistry_semantic. This is the only place Common Chemistry is a source of structure rather than a referee of other sources' structures, and it earns that here because it is the only source that holds the answer. Withholding alone would trade one defect for another: a flow object with no chemical identity at all. No SMILES is invented, because a value computed from the InChI belongs to the stage that computes it.

On the 2026-08-12 build the gate acts on 90 registry numbers, withholding 27 PubChem compounds and 70 ChEBI records across 100 flow objects. The "stereo invented" band of #281 goes from 33 flow objects to nought, and all 33 now publish the key CAS registers and no other. Its "lost" and "conflict" bands are untouched, as is every one of the skeleton disagreements — this rule reaches only the isomer question.

No flow object lost its structure: all 100 still publish an InChIKey, an InChI and a SMILES. The collisions the invented stereochemistry manufactured are gone — Crotonaldehyde now holds MLUCVPSAIODCQM-UHFFFAOYSA-N against Trans-2-butenal's -NSCUHMNNSA-N, and 1,3-dichloropropene UOORRWUZONOOLO-UHFFFAOYSA-N against the (Z)-isomer's -UPHRSURJSA-N.

Every number it acts on goes to the review queue: the registry's flat key is the whole of the evidence, and where the isomers are not separately registered a curator should be able to call it a gap rather than a statement. Three of the 100 are flows whose name asserts a stereochemistry — a racemate, a reaction mass, and one whose own source InChI is flat and so agrees with the registry against its name. All three are in the queue, which is where that judgement belongs.

Reading the structure, not the fingerprint

The gate above answers one question — does this number have a stereochemistry at all — and it answers it from CAS's InChIKey. That is a fingerprint of a structure, not the structure, and a fingerprint records how it was taken. CAS takes many of its fingerprints a different way from every other source here, and two taken differently cannot be held up against each other. For those numbers the honest answer used to be "no comparable answer", and a real defect and a false alarm looked exactly alike.

But CAS also publishes the structure itself, alongside the fingerprint. A structure can be read and written out again — and then a fingerprint taken our way, which can be compared:

trans-4-tert-butylcyclohexanol, 21862-63-5
    CAS publishes    CCOQPGVQAWPUPE-KYZUINATNA-N
    read and retaken CCOQPGVQAWPUPE-KYZUINATSA-N
                                    ^^^^^^^^ the same stereochemistry, all along

On the 2026-08-12 build that answers 22 of the 56 substance-and-number pairs where CAS states a stereochemistry the list does not match — and for a loss it does more than answer, because the corrected value is exactly what was just computed. Seven of the ten losses now arrive at the review queue with the key the substance should carry, rather than only the news that it is wrong.

The other 34 must stay unanswered, and that is the part to be careful about. CAS reaches for its own way of taking a fingerprint mostly to say something standard chemistry notation cannot: a relative stereochemistry — "these two centres are arranged so with respect to each other, in either mirror image". RDKit does not refuse such a structure. It reads it and hands back one of the two mirror images, with nothing in the answer saying a choice was made:

(2RS,4SR)-2-methyl-4-propyl-1,3-oxathiane, 59323-76-1
    CAS says       GKGOLPMYJJXRGD-HGXVMFPFNA-N   either mirror image
    RDKit returns  GKGOLPMYJJXRGD-JGVFFNPUSA-N   one specific mirror image

Accepting that would invent a stereochemistry the registry never claimed, which is the defect this whole section exists to stop. So the relative and racemic cases are detected before any conversion is attempted, and return nothing.

Two further notes for anyone extending this. Enhanced stereochemistry — RDKit's model for "either mirror image" — holds the meaning correctly in memory but produces the same fingerprint as the absolute form, so it is no way round the problem. And a fingerprint showing no stereochemistry has two causes it writes identically: a molecule with nothing to state, and a molecule whose arrangement was not stated. Counting stereocentres tells them apart, and anything deciding whether a substance has lost its stereochemistry needs that difference, or it reports every simple molecule in the list.

How a stereochemistry difference is decided

flowchart TD
    A["CAS publishes a structure for this number"]
    A -->|"no"| Z["Nothing to say"]
    A --> P{"Same skeleton, and the same number of hydrogen ions?"}
    P -->|"a different skeleton"| X["A different substance — #261 and #264, not a question about shape"]
    P -->|"same skeleton, different charge"| Q["<b>protonation</b> — an acid and its ion. Not a question about shape either"]
    P -->|"both the same"| Y{"Does its key already agree with ours?"}
    Y -->|"yes"| Z2["Nothing to say. Equal stereo hashes are the same structure whatever computed them, so no conversion can change this"]
    Y -->|"no"| B["Read the structure CAS published"]
    B --> C{"Can it be re-expressed as a standard InChI?"}
    C -->|"no"| D["No comparable answer exists. Report as <b>incomparable</b>, <i>saying which of the three reasons applied</i>, and ask a curator"]
    C -->|"yes"| E["Take a fingerprint our way, so the two can be compared"]
    E --> F{"How does it compare with what the substance publishes?"}
    F -->|"the same"| Z
    F -->|"substance has none, CAS has one"| G["<b>lost</b> — the corrected key is the one just computed, and is published"]
    F -->|"substance has one, CAS has none"| H["<b>invented</b> — refuse the stereoisomer and publish what CAS registers"]
    F -->|"both have one, and they differ"| M{"Is one record the other with some arrangements left undetermined?"}
    M -->|"the registry's is"| N["<b>cas-undetermined</b> — a gap in the registry's drawing. Our record stands"]
    M -->|"ours is"| O["<b>ours-undetermined</b> — our key names a broader substance than the number does. Fill it from the registry"]
    M -->|"neither"| I["<b>conflict</b> — a real disagreement on a valid comparison. Ask a curator"]
    G --> J{"Does the substance publish a stereochemistry-bearing key for this skeleton elsewhere?"}
    J -->|"yes"| K["Not a loss — the flat key is the deliberate simplification"]
    J -->|"no"| L["A genuine loss"]

Agreement is asked first, and it costs nothing. Two keys with the same stereo hash describe the same structure whatever computed them — that is the half of

281's warning about the standard flag that was always right, and it means a

conversion cannot change the answer where the keys already agree. Asking it second is how Zinc-65 came to be reported as an impossible comparison against a key identical to its own (#349).

A refusal names its own reason. Re-expressing CAS's structure declines for three different reasons, and reporting the wrong one is a defect in its own right:

Reason What it means Where it comes from
relative A relative or racemic arrangement, which standard InChI cannot write down. Converting would pick one mirror image and not say so 40 of the 75 non-standard keys in the cache
altered The structure did not survive the round trip, so it cannot be trusted. RDKit's InChI reader drops the isotopic layer of a lone labelled atom — InChI=1S/Zn/i1+0 comes back as InChI=1S/Zn every isotope-labelled single atom
unreadable Empty, or RDKit would not parse it

The middle one is the guard working, not a stereochemistry. It used to be reported as the first, which is how a queue row came to describe a single zinc atom as having a relative stereochemistry.

The branch marked invented is the gate described above. conflict is reported and left alone: both sides state a shape, the comparison was valid, and nothing here can say which is right. The final question — whether a flat key sits beside a specific one — is what separates a real loss from the simplification the list publishes on purpose, and is #334.

The two questions at the top are asked first on purpose, and the charge one is #348: see an acid and its ion below.

A gap is not a contradiction

"Both sides state a shape and the shapes differ" turned out to be three findings wearing one label, and the split matters because two of the three are not disagreements at all (#350).

α-cyclodextrin is a ring of six glucose units, and each unit has five corners whose arrangement matters, so the molecule has thirty of them. Our record describes all thirty; the registry's describes twenty-nine and leaves one blank:

ours   …,22-,23-,24-,25-,…      corner 24: pointing this way
CAS    …,22-,23-,24?,25-,…      corner 24: not determined

Every corner both records describe, they describe identically. But a fingerprint is computed over the whole set of corners at once, so one blank in thirty produces a completely different result — as different as inverting all thirty would give:

ours   HFHDHCJBZVLPGP-RWMJIURBSA-N
CAS    HFHDHCJBZVLPGP-FXNRASGISA-N

A fingerprint does not degrade gracefully, so nothing comparing these two records by fingerprint can tell "the same substance, described once fully and once with a gap" from "two different substances". Fifteen rows arrived in the review queue labelled identically for that reason.

The question is answered by construction rather than by reading the layers off. Take the fuller record, mark as undetermined exactly what the sparser one leaves undetermined, and ask InChI for the fingerprint of what remains. If that is the sparser record's fingerprint, the sparser record is the fuller one with those corners unstated, and the two agree everywhere both speak.

Comparing the arrangement layers directly is the obvious approach and it is wrong, in a way that matters for two of the fifteen:

chloralose   ours  /t2?,3-,4+,5+,6?,7+/m0/s1
             CAS   /t2-,3+,4-,5-,6-,7-/m1/s1

Every assigned corner differs, and so does the flag saying which mirror image the record was written for. That reads as a flat contradiction and is not one: blank corners 2 and 6 in the registry's record and the rest re-canonicalises to exactly ours. The mirror flag records which of two mirror images the corner list describes, and which one that is depends on the set of corners being listed — so the two layers cannot be compared element-wise across records that describe different sets. Taking the fingerprint again is what avoids the trap.

The three answers want three different things:

Kind What it means What happens
cas-undetermined The registry leaves blank what we describe, and agrees everywhere else Nothing. Our fuller record stands — a record that assigns every corner is not contradicted by one that leaves some undetermined. Reported at INFO so the next reader does not rediscover it
ours-undetermined We leave blank what the registry describes The same repair as a lost shape, below. Where it cannot be applied, the row stays open with the fuller key named in it
conflict Each record states an arrangement the other contradicts Reported at BLOCKING. Nothing here can say which side is right

On the 2026-08-12 build the twenty conflict rows become seven cas-undetermined, one ours-undetermined, five repairs and eight conflicts, across 13 flow objects and 168 elementary flows. Where a structure cannot be read at all the answer stays conflict, because that is the status quo and the answer that sends a person to look.

Restoring a stereochemistry no source holds

A genuine lost is repaired from the registry's structure. It is the only place in the pipeline where evidence is used to add a structural claim rather than to refuse one, so it is a step of its own, under its own provenance name — enrich_references.commonchemistry_stereochemistry — rather than part of a gate's write.

The reason it is safe here and nowhere else is that the registry is the only source that can answer. 21862-63-5 is trans-4-tert-butylcyclohexanol; the trans form is not a compound PubChem or ChEBI holds a record for, so both answer the number with the shape-free structure, and the flow object publishes CCOQPGVQAWPUPE-UHFFFAOYSA-N — which is also plain 4-tert-butylcyclohexanol's key, so the two substances collide on it. Waiting for a source to disagree is waiting forever, exactly as in the invented direction.

Five conditions, and each refuses a case that would otherwise be wrong:

Condition What it stops
The registry's structure re-expresses as a standard key A relative or racemic registration, where reading the structure back invents an absolute arrangement
The registry's structure states a shape at all, asked of the InChI and not the key Zinc-65, whose key looks stereo-specific because the second block hashes isotopes too — the shape being copied would be an isotope label (#349)
Every candidate on the skeleton has a gap the registry fills — shape-free, or shape-incomplete in the sense above Overwriting an answer a source did supply; a redundant flat key beside it is #334's business
Same skeleton A different substance, which is #261 and #264
Same protonation An acid and its ion, which is #348

The partial case — a record missing part of its shape rather than all of it — is the same repair, and it is the safer of the two, which is worth saying because it looks like the bolder one. Filling a wholly shape-free record rests on the registry alone: there is nothing in the candidate to agree or disagree with. Filling a partial one rests on the registry having been checked against the candidate first and found to state the same arrangement at every corner the candidate describes. A record that contradicts ours at one corner and completes it at another fails that test and stays a conflict.

β-Endosulfan is why it is worth doing. Five corners, of which the published record describes two; the registry describes all five and agrees on the two. α- and β-endosulfan are distinct regulated pesticides, and what distinguishes them is exactly the corners left blank — so the published fingerprint was not merely different from the registry's, it named a broader substance than the registry number does. On the 2026-08-12 build the partial repair fires on 5 flow objects across 65 elementary flows.

The key published is the converted one, not the registry's own. Six of the seven wholly-lost numbers this fires on are registered with a non-standard InChI whose key cannot be compared with anything else in the list, and the InChI is published alongside it from the same conversion so that the two agree with each other. No formula is written: stereochemistry does not change one.

Nothing is done silently. Each repair appears in the stereo-disagreement queue as a restored row at INFO, saying which key was replaced and by what. Where the replaced key carried part of a shape rather than none, its withdrawal is folded into that same row rather than reported again as a discarded claim: one event, one row.

When the registry breaks a tie between two sources

A flow object can also end up with two stereochemistry-bearing keys on the same skeleton — one from ChEBI, one from PubChem, with nothing in the pipeline reconciling the two lookup paths against each other. Pyrethrin I publishes both ROVGZAWFACYCSP-VUMXUWRFSA-N and ROVGZAWFACYCSP-NEWSRXKRSA-N, and anything using an InChIKey as an identity sees two substances where there is one.

Where one of those keys is the structure CAS registers for the number, the others are withdrawn. That is a weaker claim than it sounds, and deliberately so: nothing is being chosen on Common Chemistry's authority. One of the object's own keys has been independently reproduced by the registry, which means the others describe something the registry does not call by this number.

The restraint is what makes it safe:

  • A group where no key matches the registry is left entirely alone. That is the conflict band and the two undetermined bands above, which are settled or repaired rather than tie-broken — #350.
  • A group where the registry has no comparable answer — a relative or racemic registration — is left alone for the same reason.
  • A flat key in the group survives. It states nothing the specific key contradicts, and it is #334's.
  • Skeleton and protonation must match, so a different substance or a different ionisation state is never in the group at all.

On the 2026-08-12 build this withdraws a key from 8 flow objects across 106 elementary flows. Six are the pyrethrin esters — Pyrethrin I and II, Cinerin II, Jasmolin I and II — where the withdrawn key is the surviving one with the double-bond geometry left out. Because a structure claim is being discarded rather than added, each withdrawal is reported at REVIEW, naming both the key that went and the one that stayed.

One of the eight runs the other way, and the split above now says so out loud. Oxymetholone's withdrawn key states a double-bond geometry the registry does not state at all, so the same number carries a cas-undetermined row beside its superseded one: our record described more, and the tie-break took it. Keeping it instead would mean asserting a geometry the registry does not, on one source's word, and leaving two identities on the object — which is the defect the tie-break exists to remove. So the rule stays uniform and the row stays REVIEW, which is what a curator is being asked to look at.

An acid and its ion are two substances, not two shapes

An InChIKey's last block records how many hydrogen ions the substance is carrying. N is the neutral form; M, L, K are one, two and three ions removed; O, P, Q are one, two and three added. It is the only block that moves when an acid gives away a hydrogen ion, and the shape hash in the middle does not move at all:

(2R,3R)-2,3-dihydroxybutanedioic acid, 87-69-4
    published    FEWJPZIEWOKRBE-JCYAYHJZSA-N    tartaric acid, C4H6O6
    published    FEWJPZIEWOKRBE-JCYAYHJZSA-L    tartrate, C4H4O6, two ions gone
    CAS says     FEWJPZIEWOKRBE-JCYAYHJZSA-N    the acid, as (+)-Tartaric acid
                                ^^^^^^^^ the same shape in all three

Both of those keys were on one flow object, one from ChEBI and one from PubChem, in the field that says what the substance is. And because the comparison against the registry reported a difference — correctly; a charge difference is a real difference — the shape classifier read that answer as being about shape, and filed the object at blocking as "same skeleton, different stereochemistry, both specific" over two keys whose shape hashes are identical character for character. A curator sent to settle a shape question would have found there was no shape question to settle.

Charge is therefore tested before shape. The order is what fixes it: the answer to "is this a shape disagreement?" was already decided by something that is not a shape. Testing charge first also gets the question right when both differ, because the last block is not touched by the InChI options the shape hash depends on — so the charge comparison is valid on a pair where the shape comparison could only shrug, and the row reports what can be reported.

Where the charge differs, the two keys are two substances in one identity field, and the tie is broken exactly where the previous section breaks it: only where one of the object's own keys is the structure the registry publishes for the number. Nothing is chosen on Common Chemistry's authority; one key has been independently reproduced by the registry, so the other describes something the registry does not call by this number, and it is withdrawn.

The procedure, per registry number the object was reached through:

Step What it does
1 Re-express the registry's structure as a standard key, as everywhere else here. No comparable answer — a relative or racemic registration, or one that does not survive the round trip — and the object is left alone
2 Take the object's keys with the same skeleton, the same shape hash and the same InChI version. A different skeleton or a different shape is a different question, and has its own band
3 Is the registry's own charge among them? If not, stop: the registry has not reproduced anything, and choosing which ionisation state the object is for is a curator's judgement
4 Withdraw the rest, and report the removal at review, naming the key that went and the one that stayed

Worked through on the example above: step 1 gives FEWJPZIEWOKRBE-JCYAYHJZSA-N; step 2 keeps both published keys, since they differ only in the last block; step 3 finds -N among them; step 4 withdraws -L and leaves the object publishing tartaric acid alone, with a review row saying tartrate was taken out and the acid stayed.

Step 2 is also why this needs no isotope guard, unlike the tie-break above: block 2 hashes isotopic labelling as well as shape, so radium-226 and radium-224 differ in it and never reach step 3 together. Two keys that do reach it carry the same label as well as the same arrangement (#349).

Unlike its stereochemistry sibling this asks nothing about shape, so a pair with no shape at all is treated the same way — SLXKOJJOQWFEFD-UHFFFAOYSA-N and -M, 6-aminohexanoic acid and its anion, are two substances for the same reason. Those were reported nowhere before: the classifier handed a number registered without stereochemistry straight to the shape gate, which has nothing to say about charge.

Only the identity field is settled by this. The object above also publishes two formulas, C4H6O6 and C4H4O6; two SMILES; two charges, 0 and -2; and two masses. Those fields accumulate their candidates on purpose — a list there states the ambiguity where a single value would hide it, which is #127 — so withdrawing the key does not touch them, and a reader joining on formula still sees both substances.

On the 2026-08-12 build 15 flow objects publish two keys differing only in charge. The registry's own answer is among the keys for 4 of them — the tartaric acid above, Enoxolone, Nadide and Aminocaproic Acid — and those are the withdrawals, across 52 elementary flows. The other 11 are mostly salts the registry answers with a different skeleton altogether, so nothing is reproduced and nothing is touched.

Two objects are reported as their own protonation rows at blocking, because the registry does hold a key for the number and what the object publishes for it is the ionised form: Cupferron (135-20-6), which is one of the 11, and the ammonium salt of 34274-28-7, which is not — it publishes the ion and nothing else, so it has no clash of its own. The remaining objects clash without the registry saying anything either way. Finding those needs no registry lookup at all, since two keys on one object differing only in the last character is always this situation, and that check is what #348 leaves open.

The cross-object synonym strip: a name belongs to one substance

Two cleanup passes remove synonyms that create false equivalences:

  • Any synonym matching the preferred name of a different flow object is removed. A substance cannot legitimately be called by another substance's preferred name. Flows of the same substance in different contexts share a preferred name and never trigger this.
  • Element symbols (Rn, [Rn]) belong exclusively to the pure element. When they appear on isotopes or compounds they are wrong. The pure element is identified by having exactly one molecular formula value equal to the bare symbol — isotopes carry extra values like ["Rn", "[222Rn]"] and so are not mistaken for it.
Flow object Preferred name Synonyms before After
fo-37b9… Radon Rn, [Rn], niton, … unchanged — this is the element
fo-3320… Radon-222 (222)Rn, [Rn], Alphatron, … [Rn] removed

Both run before consensus matching, so the scoring step sees cleaned label sets.

The catalogue strip: a product code is not a name

Common Chemistry and ChEBI file every string anyone has attached to a CAS number, and nothing in either payload separates chemistry from commerce. Along with octadecanoic acid, stearic acid arrives carrying F 1000, S 300, Prifrac 2981, Radiacid 0152 and NSC 147337. 18.3% of published alternative labels — 368,720 of 2,012,182 — are one of three shapes:

Shape Examples Rows
Supplier grade S 100, A 1, F 1000, P-30 243,048
Trade name and product number Garlon 480, Polytal 4641, Dow Corning 777 80,357
Database accession NSC 147337, AKOS000118800, C.I. 77120, UN 3077 45,315

These are not merely noise. A grade code is shared between unrelated products: a merge once resolved Propylene Carbonate to Talc, because both carried a K 3 alternative label and a label index cannot weigh what it cannot read.

Removing them costs little. The filter takes 368,720 labels and leaves 104 flows with none at all, out of 89,045 carrying any.

Why shape rather than agreement

The obvious alternative is the rule used everywhere else on this page: publish only what two sources agree on. It was measured against a full build and rejected.

Rule Alternative labels kept Flows left with none
Publish everything a source supplies 2,012,182 0
Require Common Chemistry and ChEBI 127,358 (6.3%)
Require any 2 of Common Chemistry / ChEBI / PubChem 160,243 (8.0%) 31,002
Shape filter (what runs) 1,643,462 (81.7%) 104

Agreement fails here for a reason specific to names. Common Chemistry and ChEBI agree on 5.8% of published strings — not because the other 94% are wrong, but because one ships CAS-index inversions and trade names while the other ships IUPAC and biochemical shorthand. The rule therefore removes oxidane, trans-2,4-hexadienal, H(2)O and Common Chemistry's own primary name for a substance alongside the grade codes, and would add 2,598 back.

Consensus measures whether two registries share a vocabulary. It does not measure whether a string is a name. For identity claims — which substance, which CAS — agreement is the right instrument and is used. For labels, shape is.

When the shape test is wrong

It is a heuristic, and there are two ways to overrule it.

A whole convention belongs in the patterns, in transformers/strip_catalogue_altlabels.py. Two are already exempt:

  • Refrigerant, halocarbon and halon designations — HFC-134a, Halon 1211, Fluorocarbon 113, R-600a. EF 3.1 identifies 55 flows by designation alone, with no CAS, no formula and no structure (#202); deleting these would be a data loss. R-600a with a hyphen is isobutane as a refrigerant, so R is admitted only hyphenated — R 300 with a space is a grade of stearic acid.
  • Congener numbering — PCB 118, BDE 47. None appear in the current build; the exemption is pre-emptive.

A single string belongs in the keep list, altlabel-keep-list.json, which is data rather than code:

{
  "keep": [
    {"value": "Some Label 400", "comment": "why this is a name and not a grade"}
  ]
}

Matching is case- and whitespace-insensitive, an entry applies to every flow carrying that label, and comment is mandatory — an entry without one is ignored and logged, because an unexplained exemption is one nobody can re-evaluate later. The file ships empty: when it was written, no string the filter removes was any flow object's preferred name, so nothing was known to need overruling.

The strip step also names every value it removes in its change-log comment, so /changes filtered to strip_catalogue_altlabels is where you find a label worth keeping.

Some cases neither mechanism can fix, and the patterns are deliberately shy about them. The trade-name test requires a three-digit product number, so Tween 80 survives — it is a brand, but so is the form of Pigment Yellow 74 and Vitamin B12, and no shape test tells those apart.

When the evidence is not in the label

Silicon Dioxide published 4,003 synonyms after the shape filter had taken 38% of what Common Chemistry supplied, and they were almost entirely commercial: 173 beginning Snowtex, 126 Aerosil, 75 Nipsil (#242). Snowtex 30 is shorter than the trade-name pattern requires and matches no registry prefix, and no prefix list will ever hold it — brand tokens are open-ended.

The signal is repetition on one object. 173 labels sharing a leading token is a supplier catalogue; a chemical vocabulary does not behave that way. Two formulations of the gate were measured against the build and failed:

Gate Why it fails
Leading token is a chemical word Methyl Violet 10B, Pigment Blue 15:3 lead with chemical words and are product codes
Token appears on few other objects Nissan spans 56 objects; R (103), S (74), A (73) are grade prefixes, not vocabulary

What separates them is what the number is doing. In a name the digits are bound into the chemistry — Sodium 2-mercaptopyridine 1-oxide. In a product code they dangle — Snowtex 30. A hyphen between digits is a catalogue range (Cataloid S 1-50), so only adjacency to lower-case chemistry counts.

The rule runs only above 100 alternative labels. The median object carries 9 and the mean 17, while the 96 above 100 hold 23.9% of every synonym in the list — so the gate buys the concentrated part of the problem without exposing Tween 80 to a rule it would fail. It removes 8,643 labels from 69 objects.

Where shape genuinely cannot decide, a register does. Ponceau 4R is a name and Acetoquinone Blue R is a product, and the strings are the same shape; ChEBI is consulted at run time and the public part of the Colour Index ships as data. This is agreement used as an exemption — it may only keep a label, never publish one — which is what makes it safe here after being rejected as the primary filter above. It rescues 13 labels, Ponceau 4R, Tween 20, Polysorbate 20, Laureth 4 and Laureth 9 among them.

The documented gap is Methyl Violet 10B. It appears in no open register — not ChEBI, not Wikidata, and Colour Index International itself is subscription-only — so it survives on the size gate alone, crystal violet carrying 96 labels against a threshold of 100. The keep list is the mechanism for a string in that position.

Structure is computed, not asserted

Names and registry numbers come from sources and may be wrong. Molecular formula, mass, and InChIKey can be derived from a structure, which is arithmetic rather than testimony.

Where a flow's IUPAC name parses unambiguously with OPSIN, its SMILES and InChI are replaced with values derived from that parse. RDKit then recomputes formula, masses, and InChIKey from the resulting InChI — but only for flows whose identity is unambiguous: exactly one IUPAC name, no origin qualifier, and an InChIKey unique across all non-qualified flows. When those conditions do not hold, the existing values are left alone.

This is why the eligibility conditions are strict. Computed values are only better than asserted ones when you are certain what you are computing from.

Salts: the formula and the structure do not say the same thing

Nickel(II) acetate is a nickel atom carrying a charge of two, with two acetate ions beside it. That is C4H6NiO4.

Here is how CAS registers it, under 373-02-4:

  name                Nickel acetate
  molecular formula   C2H4O2 · 1/2 Ni
  molecular mass      178.80

That reads as acetic acid, with half a nickel for each acetic acid — which is the same thing said the other way round. Two acetic acids to one nickel. It is the long-standing way chemical registries write a salt down: name the acid, because the acid is the part with a name, then say how much metal goes with it as a ratio. The mass confirms it: 178.80 is two acetic acids plus one nickel.

The composition is correct. The trouble starts when it is turned into a drawing.

Half an atom cannot be drawn

The two standard ways of writing a structure down — SMILES and InChI — describe one specific assembly of atoms. Neither has any way to write "half a nickel". So when the registry converts its own formula into a structure, the fraction has nowhere to go, and the ratio quietly becomes one-to-one:

  the formula      C2H4O2 · 1/2 Ni     two acetic acids to one nickel
  the SMILES       [Ni].O=C(O)C        one acetic acid  to one nickel
  the InChI        InChI=1S/C2H4O2.Ni/c1-2(3)4;/h1H3,(H,3,4);
  the InChIKey     XMOKRCSXICGIDD-UHFFFAOYSA-N

That last key is not a mistake anybody made. It is the registry's own, computed from the registry's own structure, and it describes the right substance with its ratio rounded off. PubChem holds the same key, having taken it from the same place, and publishes the rounded formula C2H4NiO2 — the 1/2 having been lost one step earlier.

This is not one substance's quirk. 274 of the registry records this project has fetched carry a ratio that a structure cannot hold — 77 written as a fraction and 197 as a whole-number multiplier:

  62-54-4     Calcium acetate           C2H4O2 · 1/2 Ca
  553-72-0    Zinc benzoate             C7H6O2 · 1/2 Zn
  14644-61-2  Zirconium sulfate         H2O4S  · 1/2 Zr
  14807-96-6  Talc                      H2O3Si · 3/4 Mg
  7758-16-9   Disodium pyrophosphate    H4O7P2 · 2 Na
  1113-38-8   Ammonium oxalate          C2H2O4 · 2 H3N

Every one of those looks, to a program comparing structures, like the registry describing something other than the salt. It is describing the salt, in a notation that lost the ratio on the way out.

What this project does about it

Ask what the substance is made of, not what it looks like. The formula is the field where the ratio survives, so the formula is the field to compare.

This is the third way one object ends up publishing two identities, after the flat key beside a specific one and the acid beside its ion. The rule for a charge difference is An acid and its ion are two substances, not two shapes above, and it compares keys directly, because there the two keys share a skeleton. Here they do not: rounding the ratio off changes the skeleton as well as the charge, so that rule sees two unrelated structures and correctly declines. Comparing compositions is what reaches the cases it cannot.

Comparing has to allow for two things that are not disagreements:

  • The ratio is multiplied out first. C2H4O2 · 1/2 Ni becomes C4H8NiO4 before anything is compared, because half a nickel alongside one acetic acid is one nickel alongside two.
  • Hydrogen is ignored. A salt is its acid with the acidic hydrogens gone, and the registry names the acid: C4H8NiO4 for the registry, C4H6NiO4 for the salt. Ignore hydrogen and both are four carbons, four oxygens and one nickel — one substance, described from two ends.

Where a substance publishes two formulas and the registry backs one of them, the other is withdrawn, and so is every structure that came with it. That is step 19 of the chain.

The same test, pointing the other way

It would be easy to read the above as "the salt's own chemistry wins over the registry", and that reading is wrong. The test is about composition, and it cuts both ways.

1,4-diazabicyclooctane — DABCO — is a small cage of two nitrogens bridged three ways, C6H12N2. Its name is properly written 1,4-diazabicyclo[2.2.2]octane; the [2.2.2] says how long the three bridges are, and without it the name does not describe a molecule. The name-reading software does not refuse it. It reads bicyclo as "two of", and returns a completely different molecule, C14H28N2.

The registry says C6H12N2 for 280-57-9, and so do ChEBI and PubChem. So the same comparison that keeps the name-derived answer for nickel acetate withdraws it for DABCO. Nothing is decided on which part of the pipeline produced a value — only on whether the registry's stated composition backs it.

What is deliberately left alone

  • A substance publishing one formula is never touched, even where the registry disagrees with it. A substance with no formula at all is worse than one whose formula is disputed, and the dispute is already reported.
  • Where the registry agrees with nothing the substance publishes, nothing is withdrawn. That disagreement is real and belongs to a curator. On the build of 17 August 2026 there were ten such substances, mostly borates and vanadates whose published formulas disagree among themselves as well.
  • Ignoring hydrogen is allowed here and nowhere else. It makes ethane and ethene indistinguishable, which would be intolerable if this were deciding whether two substances are the same. It is not: it asks only whether a second value on one record contradicts what the registry registered.

When the evidence is not enough

The consensus matching step applies updates only under explicit confidence rules — typically several independent sources agreeing. When they do not agree, it does not guess. Instead the case goes into a queue in review_queue, and /queue/<name> is where a human decides it:

Situation Queue
Common Chemistry disagrees with the flow's name for a CAS commonchem-cas-name-differences
Common Chemistry gives a different CAS for the flow's name commonchem-name-cas
A CAS resolves to several ChEBI records ambiguously cas-ambiguous
An EC number fails its check digit and cannot be corrected ec-malformed
CAS ↔ EC pairing contradicts the ECHA inventory ec-cross-check
Consensus matching found no confident answer consensus-match
A preferred-label rename is awaiting a ruling undecided-label-replacement
Two live flows share a substance, a context and a unit, and a comment is all that separates them elementary-flow-collision
A ChEBI record's formula diverges from the flow's formula_mismatches table
An element has no flow object element_coverage table
An ecoinvent flow matched no consensus flow object merge_outcomes table

Declining to act is a normal outcome, not a failure. See The review application for how to work through these queues.

Every value carries its provenance

Two independent records are kept:

  • Field-level provenance — for a data value, which source asserted it, recorded as a structured PROV record rather than free text. Carried on the value itself, and traced across the run by provenance_activities.
  • Which source stands behind which value. Where a field holds several values, the provenance list above covers the field as a whole and cannot say which source gave which value: DABCO's InChIKey field held two keys and three provenance entries with nothing joining them. A companion attested_by records, per value, which steps wrote or confirmed it. It is what lets the salt rule above withdraw the InChIKey that came from the same place as the formula it withdrew. A value nothing attests reads as unknown, never as unsupported, so an older record is never withdrawn for its silence.
  • The change log — for each field the pipeline wrote, which processing step wrote it, the old value, the new value, and the reason. The changelog table, keyed by flow object id, with changelog_flows naming the elementary flows each edit landed on. One row per edit: the biggest fields in the log belong to the substance, and an edit to a substance reaches every flow that shares it, so a row per flow said the same thing a dozen times over. /changes shows all of it; /flows/<uuid>/changes shows one flow's, on demand.

Both are written by every run. They were optional JSON files until the review application was consolidated onto the database, which meant the record of why a value is what it is normally did not exist.

A value the pipeline declined to write is the same kind of fact. When two flows are collapsed into one and both of them published a characterisation factor for the same method, only one number can be published, and the other used to disappear without trace — so nothing told a reader that the number they were looking at had been chosen at all. The number not published is now kept on the factor that superseded it, in superseded_values, with its own provenance naming the flow that published it.

No processing step mutates a flow directly; each proposes changes that the engine applies and logs. That is what makes the change log complete rather than best-effort. Where several steps write the same field, the last one wins, and the log shows the sequence.

Keyboard

?
Show or hide this map
Esc
Close

More as the sections are built.