The question a disclosure request actually asks
A tier-one customer or an OEM sends a supplier a substance request. It may cite the REACH candidate list of substances of very high concern, California's Proposition 65, the automotive industry's declarable substance list, or a full material disclosure format. Whatever the letterhead, the request reduces to one question per part: does any material in it contain a listed substance, and at what concentration?
For a stamping, plating or molding shop the evidence is the safety data sheet for each material, and the relevant part of each sheet is Section 3, the composition table. Somebody opens each sheet, reads the ingredient rows, types the CAS numbers and concentrations into a spreadsheet, and checks them against the lists. The typing is where the answer goes wrong, and nothing downstream knows it did.
Automating the reading does not change that. A reader that misreads a concentration produces a spreadsheet that looks exactly like a correct one. The problem to solve is verification, and the reading is only the first step of it.
What Section 3 holds, and the six ways it varies
A sixteen-section sheet in the GHS format puts composition in Section 3. For a mixture, each row gives a chemical name, an identifier, and a concentration. The variations below are all normal, and a reader that has not seen them will get them wrong.
- Ranges, bounds and exact values. A concentration may be printed as 10 to 20 percent, as less than 1 percent, or as 5 percent. A reader that stores one number per row loses the range, and the top of the range is the one a disclosure threshold cares about.
- Trade-secret rows. Some rows give a name and a concentration and no CAS number at all, because the identity is withheld. The row still has to be reported as present, and it can never be screened by number.
- EC numbers beside CAS numbers. Sheets prepared for the European market print an EC number next to the CAS number. The two look similar, both carry check digits, and the SVHC list is indexed by both.
- Footnote markers. An asterisk or a dagger after a name points to a note about the listing, and a reader that folds the marker into the name breaks the name match later.
- Section 3 on the second page. A long Section 2 pushes the table over the page break, and a reader that only looks at page one reports a sheet with no ingredients.
- Two layouts. Some sheets rule Section 3 as a grid; others print it as a borderless list of labels and values. Both are common, and a parser tuned to one is blind on the other.
The same identifiers appear on every list the request cites, which is what makes the request answerable at all. The CAS registry number is the join key between the sheet on your shelf and the list on the regulator's site.
Where automated reading fails
The failures below were observed in a measured run, described in the results section, on synthetic sheets that had been printed and scanned the way a sheet in a binder gets scanned. A born-digital PDF with a text layer has none of them; the office copy is where they live.
- Dropped decimal points. The commonest scan failure. A concentration of 0.5 percent reads as 5, and 22.5 reads as 20.5. When the ingredient is a listed substance, that single character is the difference between a customer notice and none.
- Missed rows. A row lost at a page break or to a faint rule line simply disappears from the output, and an absent row raises no error.
- A range collapsed to one end. A reader that stores one value per row records 1 to 1.9 percent as 1, and the threshold test is then run against the wrong number.
- A lost identifier. A CAS number dropped from an otherwise correct row. The row cannot be screened by number and, if nothing notices, it is screened by nothing.
- A wrong digit inside the number. Rarer, and the most dangerous when it happens, because a number with one wrong digit can match a different substance on the list, or none.
None of these makes the output look wrong. The spreadsheet has a number in every cell. That is the property that defines the problem, and it is why a second reading, an arithmetic check and a list rule have to be part of the design rather than a review step someone might get to.
The five checks, in the order they run
This is the design the practice runs on its live disclosure demo and measured on its bench. None of the five is a model. Each one catches a class of failure the previous one cannot, and the output of the chain is a worklist for a person, not a verdict.
- Check digit. The last digit of a CAS registry number is computed from the digits before it, and an EC number carries a check digit of its own. Every identifier is tested before anything else happens. A number that fails is never screened as if it were right, because a misread number can match the wrong substance.
- A second, independent read. Two reader classes extract Section 3 from the same page: a deterministic text reader, which is the document's own text layer on a clean PDF or an OCR engine on a scan, and a vision model reading the page image. They fail in different ways, which is the point. A value the two agree on has been read twice by methods that do not share a mistake.
- Disagreement routing. Any row where the readers differ, where only one reader found the row, where a reader reported that it was unsure, or where no concentration could be read goes to a person with both values printed beside the row and the page image next to it. The decision takes seconds. The row never reaches the answer on one reader's word.
- List screening by identifier first, name second. Each ingredient is matched to the SVHC candidate list and the Proposition 65 list by CAS number, then by EC number. A match by number is exact. Both lists also name families, such as lead and lead compounds, that have no single number, so a match by name is a rule applied to text and is always sent to a person to confirm rather than counted.
- The threshold, and a record of how each row was verified. A listed substance above 0.1 percent by weight carries an Article 33 communication duty, so the top of each concentration range is tested against that line. The emitted disclosure carries, on every row, which readers agreed, which check passed, and which list version was used, so the answer can be audited a year later without re-reading the sheet.
The order matters. Screening a number that failed its check digit produces a confident wrong match. Screening before the second read produces a confident match on a misread concentration. The chain is built so that a row has to earn its way past each step.
What a measured run found
The numbers below come from one archived run of the practice's bench on September 4, 2026: 22 synthetic sheets with 102 ingredient rows, each rendered as a clean PDF and as a print-and-scan copy. The sheets are synthetic on purpose. Their CAS numbers are real and checksum-verified at generation, their products and manufacturers are invented, and every Section 3 wrinkle above was planted so the answer key is exact. The lists were the official ECHA candidate list export and the OEHHA Proposition 65 list, pulled September 5, 2026. This is a small corpus and one run, and it is a measurement of the design, not a claim about anyone's filing cabinet.
| Reader | Copy | Values compared | Correct | Wrong | Abstained | Rows missed |
|---|---|---|---|---|---|---|
| Text reader | Clean PDF | 301 | 301 | 0 | 0 | 0 of 102 |
| Vision reader | Clean PDF | 301 | 301 | 0 | 0 | 0 of 102 |
| Text reader | Office scan | 295 | 289 | 4 | 2 | 2 of 102 |
| Vision reader | Office scan | 301 | 300 | 0 | 1 | 0 of 102 |
All four of the text reader's wrong values on the scans were dropped decimal points or a range collapsed to one end, and all four were flagged before they reached the answer, by disagreement with the vision reader. What the chain produced, on the scanned copies:
| Outcome on the scanned copies | Count |
|---|---|
| Values compared between the two readers | 295 |
| Rows sent to a person, with both readings beside them | 13 |
| Wrong values that entered the disclosure unflagged | 0 |
| Values both readers got wrong the same way | 0 |
| Ingredients matched to the SVHC candidate list | 12, nine by CAS number and three by EC number |
| Ingredients matched to Proposition 65 | 22, eighteen by CAS number and four by name, the four sent to a person |
| Listed substances above the 0.1 percent threshold | 10 |
| Vision reader cost for the whole run | $1.68 for 96 calls |
Two things in that table are the ones to carry away. The vision reader on its own was nearly perfect on scans, and a buyer might reasonably ask why the second reader is needed at all; the answer is that nearly perfect is a rate, and the one value it abstained on and the four the text reader got wrong were caught by the pair, not by either alone. And a screening count is only as good as the list version behind it: the candidate list export held 217 substances and 232 EC numbers that day, the Proposition 65 list 786 entries, and both grow, which is why the pull date is printed on the demo and recorded on every emitted row.
Before any of it writes to your ERP
A verified row is a row that has passed the five checks, and only a verified row should be allowed to change a record of yours. That sounds obvious and is routinely skipped, because the tool that reads the sheet is often the tool with write access, and a reassuring summary on its screen is not evidence that it changed only what it was allowed to.
The practice's engineering note on this sets out the acceptance test it would require of any build with write access: grade the actions the system attempted and the resulting state, not only its answer; keep extraction and writing under separate permissions; confirm that a permitted extraction still completes when a pre-action check is in the loop; and test that an instruction planted inside a supplier document cannot cause a write to anything unrelated, measured separately from whether a monitor would have noticed afterward. Prevention before the write and detection after it are two different properties, and a disclosure workflow needs both demonstrated, not assumed.
An acceptance checklist for any SDS reader, yours or a vendor's
Vendor-neutral, because the practice names no reader product and the design holds whichever readers are inside it. Run it on a sample of your own sheets, including the worst scans in the binder, before anything is connected to a system of record.
- Every CAS and EC number is tested against its check digit before screening, and a failing number is shown as failing, not screened.
- Two independent readers, and every disagreement is visible with both values, not resolved silently by a confidence score.
- A row found by only one reader is flagged, not dropped and not accepted.
- Concentration ranges are kept as ranges, and the threshold is tested against the top of the range.
- Trade-secret rows with no identifier are reported as present and marked as unscreenable.
- A list match by name is separated from a match by number and sent to a person.
- The list version and pull date are recorded on every emitted row.
- Each emitted row states how it was verified, so the disclosure can be audited without re-reading the sheet.
- Section 3 is found on whichever page it sits, and a sheet with no Section 3 found is reported as such rather than as empty.
- Nothing writes to the ERP or the customer answer until the row is verified, and write permission is separate from read permission.
Questions buyers ask
Can AI read safety data sheets accurately?
On a clean PDF, yes. In the measured run both reader classes got every one of 301 Section 3 values right on born-digital sheets. On office scans the text reader dropped decimal points and missed two rows, and the vision reader abstained on one value. The number that matters is not the accuracy of either reader but how many wrong values would have entered the disclosure unflagged, and with two readers, check digits and list screening that number was zero on this corpus.
What is a CAS check digit and why does it matter?
The last digit of a CAS registry number is computed from the digits before it, so a number with one misread digit almost always fails the check. EC numbers carry a check digit of their own. It is a free test that needs no model and no list, and a row whose number fails it must never be screened as if the number were right, because a wrong number can match the wrong substance.
Does a match by substance name count as a screening hit?
It counts as a question for a person, not as an answer. Both lists name families, such as lead and lead compounds or hexavalent chromium compounds, and a family entry has no single CAS number. A name match is a rule applied to text, so it is always sent to a person to confirm. A match by CAS number is exact and can stand on its own.
Why is GADSL not screened on the public demo?
The Global Automotive Declarable Substance List is licensed for non-commercial use, and a public page that screened against it would be redistributing it. The design screens GADSL in an engagement, where the list is used under its own terms. The SVHC candidate list and the Proposition 65 list are published by the regulators and are screened on the demo with their pull date shown.
How many rows will a person actually have to look at?
On the scanned half of the measured run, 13 of 295 values went to a person, which is one row in about 23, and each arrives with both readers' values beside it so the decision takes seconds. On clean PDFs none did. Every name match to a list family is added to that worklist by rule. The count on your own sheets depends on how they were scanned, and the honest way to find out is to run a sample of them.