Verification is the product

Affinity is a factory with a gate at the exit. A build-time engine (ChemKernel) turns authored problem specs into machine-verified data; it refuses to emit anything that fails a check. Then a separate, pure-Node gate re-validates the committed output — so what deploys is proven twice, and the second layer runs no Python. Below is the whole verified surface as it stands, stated plainly: what is re-derived, and what is only sourced or disclosed.

Two layers

Emit-time (local)

ChemKernel parses formulas, balances by exact rational arithmetic, solves the extent — for a reaction driven to completion, or for a reversible reaction where the quotient equals K — and classifies from sourced rules. A failed check (unbalanced atoms, non-conserved charge, a negative amount, a contradicted rule) raises and writes nothing. Its own test suite additionally cross-checks the 118-element periodic dataset against an independent oracle.

Gate-time (CI)

On every push, seven Node gates re-validate the committed JSON from scratch — no Python in the loop. They re-derive the arithmetic, not merely re-read the answer: a claim survives only because a second, independent implementation reproduced it. The gates below are the second proof.

The seven gates

Run in order on every commit; the first failure stops the build.

validate:solutionsSchema + honesty cross-checks for every lesson

Ajv validates every derived lesson against its shape's strict schema (no stray fields allowed), then runs the honesty checks the schema can't express — dispatching each model-bearing shape to its own independent re-deriver (below).

validate:referenceThe Chemical Atlas re-derived

Every Atlas entry is schema-checked by kind; ids are unique; every concept link, wiki-link, and cited source id resolves. Then it re-derives the Valence Table (valence electrons from the group, every salt's name and subscripts by charge crossover, every flagged mistake re-proven wrong), each molecule's Lewis ledger, and every formula-sheet entry's dimensional homogeneity.

validate:gymsEvery drill re-solved from raw inputs

Each generated practice problem's answer is re-derived from its raw quantities (volume, molarity, mass, molar mass, rate constant, K…) — independent of the engine — and its answer format is checked: a categorical question is a one-correct menu, a numeric one is free entry whose distractors never collapse onto the answer.

check:ledgerThe species ledger and equation balance

The pivot object, re-proven: every amount is re-computed as initial + ν·ξ, and the reported result (precipitate moles, leftovers) is cross-checked against it. Each reaction's equation is independently re-balanced — every formula re-parsed, atoms and charge conserved on both sides — so a non-conserving coefficient can't slip through as an asserted flag.

check:parityThe browser's slider math matches the engine

For every interactive lesson, the JavaScript closed forms the browser runs to drive the sliders are re-evaluated at sample points and required to reproduce the engine's values across the whole range — including the point where the limiting reagent switches. The default slider setting must reproduce the committed static answer.

check:katexEvery formula renders

The build-time math renderer tolerates errors so a bad string would ship silently as an error node. This gate re-renders every LaTeX string in the committed data with errors turned into failures — so a formula that survives is known to render.

validate:scanNo course, exam, or board is named

Affinity is beginning chemistry, full stop. This gate greps every committed text file for the name of any specific course, exam, or standards body and fails the build on a hit — the public-language rule is enforced, not just intended.

Re-derived per lesson shape

The reaction lessons ride the ledger, balance, and parity gates above. The other six lesson shapes each carry their own independent re-derivation — dispatched from validate:solutions, re-run in pure Node — so the model-bearing lessons stand on the same footing as the precipitation ones.

machine-checkedEquilibrium (ICE table)

The ICE table is the species ledger with the extent solved from mass action, not driven to a limiting reagent. The gate re-derives every equilibrium concentration as c₀ + ν·x, re-solves the extent numerically to high precision by an independent method, and confirms the reaction quotient reproduces K (with its residual), the pH, and the percent ionization.

machine-checkedPrecipitation prediction (Q vs Ksp)

A snapshot, not a solve: mix two solutions, dilute each ion into the combined volume, compute the reaction quotient Q and compare it to Ksp. The gate re-derives the dilution, Q, and the does-it-precipitate verdict independently.

machine-checkedKinetics (the ledger in time)

One order-general engine over orders 0, 1, and 2. The gate re-derives the reaction balance, every point on the decay curve, the half-life relation, and the successive-half-life progression — constant, doubling, or shrinking — which is the machine-checked fingerprint of the order.

machine-checkedElectrochemistry (the electron ledger)

The ledger with electrons as the tracked quantity. The gate re-derives the oxidation numbers (rule hierarchy → sum to each species' charge), each half-reaction's atom, charge, and electron balance, the electron ledger (electrons lost = gained), the cell potential E°cell = E°(cathode) − E°(anode), and the free energy ΔG° = −nFE°.

machine-checkedStructure (the Lewis ledger)

The electron-counting counterpart of the species ledger. The gate re-derives the valence-electron total, every atom's octet (or duet for H) and formal charge and that they sum to the molecular charge, electron conservation, each bond's electronegativity difference and class, the VSEPR domain count, and that a molecule is polar exactly when its bonds and shape leave a net dipole.

machine-checkedComparison (a trend)

Several molecules ranked against a property. Each row reuses a verified molecule Atlas entry, the ordering is re-checked exactly, and the dominant intermolecular force must rise monotonically with the property — the corpus is refused if the trend is not clean.

What the badges mean — and what they don't claim

Not everything in chemistry can be proven from conservation laws; much of it is measured. The three badges keep the two apart, on every claim.

A fourth kind of claim — interpretive explanation (why one acid is stronger than another, what a shape "wants" to do) — is chemically useful but not machine-provable. Where it appears it wears the model-assumed badge with an interpretive marker: present, and labeled as story rather than proof.

Every lesson also carries a misconception register: the canonical wrong move, made to visibly fail in the ledger or particle view — never merely scolded. See the whole system at work in the lessons and the Chemical Atlas.