Skip to content

Sources & data

The question this answers: what this project was built from, and what the built application is actually fed today.

The short version of the second half needs stating carefully, because it changed and this page said otherwise until 2026-09-20.

In either repository, every piece of chemical content is fixture text — most of it carrying the words FIXTURE TEXT — not from any safety data sheet inside the string, so that a screenshot of a test run can never be mistaken for a screenshot of the product. That remains true and is worth keeping true.

The database is a different matter. The Corpus lives in Postgres, not in either checkout, and it holds five curated documents — Acetone, Sulphuric Acid, Toluene, IPA and MEK, all Loba Chemie Pvt. Ltd. — with 79 Source Spans of real Thai SDS text between them. None carries the fixture marker. Their Provenance reads provided by The Plant safety office, with revision dates from 2022 to 2024.

This needs an owner's ruling, not an edit

ADR-0016 rules a proxy corpus of public SDS while plant access is pursued, and names Acetone, IPA and Toluene. The stored Provenance says these came from The Plant rather than from a public source, which is a different claim about a different set of documents. Either the Provenance is wrong, or plant access was obtained and ADR-0016's premise has lapsed without a ruling saying so. That question is the owner's; this page records the discrepancy rather than resolving it.

Seam 1's gate reports only what it looked at — no Corpus snapshot on disk, so there is nothing here to check — and that is a statement about an exported file, never about whether anything has been curated.

What the design was derived from

SourceWhat it isWhere it was read
chemical-safety-assisant-docs.pdfThe original one-page project postersource-poster.md
poster.pdfA revised poster, which wins where the two disagreeposter-v2.md
Two public manufacturer SDS, plus a third consulted opportunisticallyThe curation spike — read end to end, to measure what admitting one document costscuration-spike.md
The sibling work-permit repositoriesStack conventions, and the traps in inheriting themstack-conventions-frontend.md, stack-conventions-backend.md

Those five notes declare 112 numbered R- findings, and every ruling in docs/adr/ cites the findings it rests on. The COVERAGE gate is what keeps that honest in one direction — a finding claimed by no ruling shows up as a problem. It reports none as of 2026-09-20: 332 declared ids, all mapped downstream. Read the count from ./init.sh rather than from here — see Current state.

Nothing in the design was derived from a chemical the project holds, because it holds none. That is the whole of blocker 1.

What the application is fed today

DataWhere it livesReal or fixture
Chemical Records, Source Spans, SDS SectionsPostgres via Prisma on the server; IndexedDB on the deviceFixture only. The schema is real and asserted; no document has been curated into it
The Corpus snapshot the device syncsGET /api/v1/corpus/snapshotThe endpoint is built and tested. The database holds four snapshots, one of them published, so what it answers now depends on the store rather than on there being nothing — what an unpublished Corpus refuses with, and what that refusal may never be confused with, is ADR-0057
Curated ExplanationsThe same snapshot, its own IndexedDB storeFixture only. Whether an explanation already written may be authored again is ADR-0073
Curated Escalation — hotline 1669, evacuate, seek medical attentionShips with the application shell, not the CorpusHotline 1669 alone, unsigned (ADR-0049). The evacuate and seek-medical steps are The Plant's procedure and wait for a named site authority; a build carrying them unsigned fails
Escalation Trigger phrase listA module constant in the clientWritten, and provisional — see below
Routing ThresholdA module constant in the clientA placeholder, and says so
Routing FixtureA test fixture with 15 curated casesWritten against fixture chemicals
The sixteen GHS Section headings, Thai and EnglishA constant held once in the api and gated across both repositories by a golden fixtureWritten, and unsourced in Thai — see below

Three artifacts the glossary calls Corpus data that the Corpus has no room for

The Escalation Trigger phrase list, the Routing Threshold and the Routing Fixture are each described as a Corpus artifact — written and fixed by a person at Curation — and the Corpus snapshot carries a field for none of them. All three are therefore module constants in the client, each with a TODO(spec) saying so.

One would be an oversight. Three of the same shape is a gap in the snapshot schema, or a glossary calling something a Corpus artifact that is not one. It is recorded rather than resolved by quietly making the code match the words.

The sixteen Section headings, and the half of them with no source

The GHS Section headings are carried as a constant rather than curated per document, and both languages ship in the application today. The ruling that makes them a constant, and the ruling that decides the shape they reach a device in, are ADR-0060 and ADR-0072.

What this page has to record is where the strings came from, and for the Thai half the answer is nowhere. GHS Annex 4 fixes the sixteen English headings; the Thai wording comes from a Thai ministerial notification, and no artifact in this repository names it. All sixteen Thai strings are therefore uncited, on a surface a Handler reads. This is a /research pass, not a curation task — the headings are a property of the format rather than of any document — and it is open.

What is missing, and what it blocks

MissingBlocks
The Plant's SDS binderEverything. The application has no content to show without it
The Study Area, and The Plant's chemical listWhich documents are curated, and therefore the schedule
A named site authority for the Curated EscalationThe one screen that must work when everything else has failed
Photographs of real drum labelsThe camera Identification spike, and therefore that route
A provider key, a spend cap and a per-address bucket sizeThe Query Intent endpoint, which is deferred by ruling until there is a Corpus to route over — ADR-0055
A citation for the sixteen Thai Section headingsNothing yet; the strings ship uncited, which is the section above

The application does not degrade quietly in the meantime. A device with no Corpus answers Corpus Unavailable — a statement about the device, never about a supplier's document — which is settled in ADR-0032 and is one of the four states the content split keeps apart.

Where the data model itself is described

Field by field, with the rulings that shaped each decision, in Data model. How a document becomes Corpus content is Curation; how it reaches a device and what happens when it is evicted is The Corpus lifecycle.