Skip to content

Periodic table complete through argon + a repaired basis-set foundation - #36

Open
abgnydn wants to merge 13 commits into
mainfrom
feat/periodic-table-expansion
Open

Periodic table complete through argon + a repaired basis-set foundation#36
abgnydn wants to merge 13 commits into
mainfrom
feat/periodic-table-expansion

Conversation

@abgnydn

@abgnydn abgnydn commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Twelve commits. The headline is that webgpu-q now supports every element from
hydrogen to argon — but the more important half is what building that validation
harness found in the code that was already shipped.

The defects this found

The run started by building a per-element PySCF comparison. It immediately went
red, and the reason was not the new elements.

defect worst measured impact
CCPVDZ_LI_2P coefficients + CCPVDZ_LI_2S_P exponent 1.293 mHa on LiH
CCPVDZ_BE_1S/2S/2P coefficients 0.367 mHa on BeH₂
aug-cc-pVDZ diffuse: only H and C were correct of 8 elements 0.171 mHa on HF
CCPVDZ_H non-canonical exponents ~5 µHa, but hydrogen is in almost everything
BECKE_XI missing fluorine; He/C/O off-by-one 0.64 µHa (measured, see below)
canonicalSymbol imported "Fe" as fluorine, silently wrong element, no error
LIMITATIONS.md advertised 6-31G* as "wired, spot-checked" it does not exist in src/
ccpvdz-firstrow.test.ts built NH₃ at 88° while its comment claimed 106.7° validated the wrong molecule

Lithium at 1.293 mHa breached this repo's own stated ≤0.5 mHa HF-vs-PySCF gate
by 2.6×, and is 81% of chemical accuracy. It survived 954 passing tests because
the tests covering those elements assert windows like -8.10 < E < -7.85 — a
250 mHa window around the error — under a header reading "verified vs PySCF".

Two independent paths agreed on the lithium number: a hand diff of the tables
measured 1.293 mHa, and a generator that reconstructs the constants from PySCF
independently measured −1.2927.

The aug-cc-pVDZ errors for N/O/F sat above the true HF energy (+0.09 to
+0.14 mHa). That is variationally impossible for a correct basis, and is the
tell that these were wrong data rather than an alternative convention.

What landed

Elements. H through Ar, all 18. tests/chemistry/elements/reference-agreement.test.ts
is 109 cells — 18 elements × 3 bases × both d-conventions, one real molecule each
(hydrides wherever one exists, so two-center integrals actually run) — all under
0.1 mHa against PySCF.

Zero engine work was required. The McMurchie–Davidson kernels were verified
against PySCF through L=5; row 3 tops out at L=2. heavyShellsRow3 is
deliberately a separate function rather than a generalisation of heavyShells,
so row 2 emits byte-identical shells and no pinned first-row number can move.

The curriculum unlock, which is the point of the exercise —
curriculum-molecules.test.ts verifies CH₃Cl (the SN2 substrate), CH₃SH, H₂S and
PH₃ all reproduce PySCF to better than 0.1 mHa, in ~1.2 s combined.

labs.html — three teaching labs computed live in the tab: bond dissociation
(RHF vs exact FCI on H₂), basis-set convergence, and the correlation ladder.
Nothing precomputed; the interpretation text is generated from the results.
Verified in a real browser against the built bundle.

Gradients. All 10 new elements match PySCF's own analytic RHF gradients to
≤4.8e-7 Ha/Bohr. Translational invariance holds to 3.6e-14.

Assertions tightened

Because the loose bars are what let this ship. Measured first, then set just
above the measurement — nothing was widened to pass:

  • H₂O cc-pVDZ MP2 correlation: 100 mHa window → 0.0001 mHa (10⁶×)
  • LiH/BeH₂/CH₄/NH₃/HF: 116–170 mHa windows → 0.01 mHa
  • hf-scf.test.ts gained a cc-pVDZ column that did not exist, and its references
    went from 4 decimals to 15
  • e2e/swarm-hf-anthracene-ccpvdz.spec.ts asserted -1500 < E < -100 while its
    own comment documented the run producing ≈−880 Ha against a literature ≈−537.
    A 343 Ha error was green on every nightly. Now split into an architecture
    test that claims only what is true, and a test.fail() physics test labelled
    as a documented expected failure pointing at LIMITATIONS.md §3.

scripts/check-basis-vs-pyscf.py is wired into CI as basis-digits — the only
gate that checks basis digits at the source rather than an energy that happens to
land close. It was itself covering only 8 of 18 elements when first wired; that
was caught by feeding it deliberately corrupted input, and it now fails on an
unclassifiable constant so a future element cannot be silently exempt.

Known gaps, stated plainly

docs/RUN-REPORT-2026-08-10.md leads with these:

  • All 108 reference cells are RHF only. No MP2/CCSD/CCSD(T)/DFT reference
    exists per-element for any new element.
  • The plan's Level-A bar of 1e-9 Ha is unreachableboys0 uses the
    Abramowitz–Stegun erf fit, measured worst case 2.66e-7 relative. That same
    floor is why the gradient bar is 1.5e-6 rather than 1e-6, documented with the
    evidence in the test header. Replacing erfApprox is the single change that
    would lift every finite-difference gate here.
  • Row-3 frozen core (5 orbitals) is implemented but untested, and interacts
    with a throw at rhf-auto.ts:452 for nFrozenCore > 0 on the exact-ERI path.
  • Reference geometries cannot be validated by a test that feeds identical
    coordinates to both engines.

BECKE_XI's repair is included with its measured impact (0.64 µHa) rather than
its dramatic description: the Becke partition is variationally insensitive to ξ,
so "every fluorine DFT number was computed on a mis-scaled grid" is literally
true and practically irrelevant.

Full suite: 142 files, 1107 passed, 1 skipped. tsc and eslint clean.

🤖 Generated with Claude Code

Ahmet Gunaydin and others added 13 commits August 10, 2026 09:11
…asis tables

Phase 0 of docs/RUN-PLAN-24H-ELEMENTS.md. Builds the validation harness
that the element-expansion run depends on, and immediately finds a real
defect in the existing basis data.

Gate 0.1 — d-convention, pinned with measurement. On H2O/cc-pVDZ PySCF
gives -76.02679870 (spherical, nao=24) vs -76.02713907 (mol.cart=True,
nao=25): a 0.340 mHa basis-convention gap, matching the note in
ccpvdz-spherical.test.ts. Our default Cartesian path lands 1.9 uHa from
cart-PySCF. The harness therefore compares each code path against its
MATCHING convention; crossing them would fake a ~0.34 mHa error on every
element carrying d functions. STO-3G is convention-free below the third
row (asserted).

Gate 0.2/0.3 — the finding. 49 cells (8 elements x 3 bases x 2
conventions, one hydride per element so two-center integrals actually
run): 38 pass, 11 fail.

  Li . LiH  . cc-pVDZ   1.293 / 1.300 mHa
  Li . LiH  . aug       1.144 / 1.145 mHa
  Be . BeH2 . cc-pVDZ   0.287 / 0.367 mHa
  Be . BeH2 . aug       0.119 mHa
  O  . H2O  . aug       0.122 / 0.141 mHa
  F  . HF   . aug       0.141 / 0.171 mHa

Shell counts are correct everywhere (nao matches); the numbers inside are
wrong. Li's cc-pVDZ p-shell carries coefficients (0.0223, 0.1117, 0.2403)
against PySCF's (0.0228, 0.1391, 0.5004) on identical exponents — not a
normalization convention, the ratios follow no power of alpha. Li at
1.29 mHa breaches the repo's own <= 0.5 mHa HF-vs-PySCF gate by 2.6x and
is 81% of chemical accuracy.

Why 954 tests missed it: ccpvdz.test.ts and aug-ccpvdz.test.ts only ever
run H2O, exercising H and O — two of the clean elements. The tests that
do cover Li/Be assert ballparks: ccpvdz-firstrow.test.ts allows
-8.10 < E_LiH < -7.85, a 250 mHa window ~200x wider than the error, under
a header claiming "verified vs PySCF"; aug-ccpvdz-firstrow.test.ts
asserts only variational ordering with no absolute reference at all.

This commit is deliberately RED on those 11 cells — the failing test is
the evidence, per the honest-negative discipline in RESEARCH.md. The
repair follows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
It was written up in CHANGELOG.md release notes but absent from
LIMITATIONS.md — the document that is supposed to enumerate what this
code cannot do. A reader auditing the project's limits would not have
found it.

The result deserves the prominence: on anthracene (C14H10, cc-pVDZ,
n=246) the damping recipe that rescues the default-DIIS +5352 Ha
divergence converges cleanly to E ~= -880 Ha against a literature
HF/cc-pVDZ value of ~-537 Ha. It reports converged: true and returns a
finite, plausible number. Being more negative than the true ground
state is the only tell.

Filed under section 3 (Known SCF / CC failure modes) and flagged as the
most dangerous entry there, because unlike the others it does not
announce itself — no automatic check catches it, since the SCF is
genuinely converged and only an external reference reveals the error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Turns the red 49-cell agreement test from the previous commit green.
Every correction is against pyscf.gto.basis.load, verified twice: by
hand-diffing the tables, and independently by a generator that
reconstructs the constants from PySCF and reproduces the same defect
list. The generator measured Li cc-pVDZ at -1.2927 mHa against the
hand-measured 1.293 mHa — three-digit agreement from two independent
paths.

cc-pVDZ:
  CCPVDZ_LI_2S_P  0.0285000 -> 0.0280500   (digit transposition)
  CCPVDZ_LI_2P.c  wholly wrong coefficients
  CCPVDZ_BE_1S.c  tail transcribed at reduced precision
  CCPVDZ_BE_2S.c  elements 4-8 substantively wrong (different source)
  CCPVDZ_BE_2P.c  last coefficient off by 5%
  CCPVDZ_N_1S.c   0.278722/0.448581 -> 0.278723/0.448540
  CCPVDZ_H_1S     non-canonical exponents 13.0107010/1.9622572/0.4445298
                  -> Dunning's published 13.01/1.962/0.4446
  CCPVDZ_H_2S     0.1219496 -> 0.1220000

aug-cc-pVDZ diffuse: of the eight elements only H and C were correct.
He, Li, Be, N, O and F all carried wrong exponents; all 16 values
replaced. Previous values are recorded in comments at each site.

Energy effect, worst cell per element (vs convention-matched PySCF):
  Li  1.293 mHa -> under 0.1    Be  0.367 -> under 0.1
  O   0.141    -> under 0.1     F   0.171 -> under 0.1
All 49 cells (8 elements x 3 bases x 2 d-conventions) now pass a
0.1 mHa bar; the previous ceiling was 1.29 mHa.

The aug diffuse errors on N/O/F sat ABOVE the true HF energy (+0.09 to
+0.14 mHa). That is variationally impossible for a correct basis and is
the tell that these were wrong data rather than an alternative
convention.

Full suite green: 140 files, 1003 passed, 1 skipped. No pinned number
downstream moved enough to break — the loose bars that hid this defect
also absorb its repair.

Adds scripts/gen-basis-tables.py, which emits these constants from
PySCF for all 18 elements so the remaining work is generated, not
transcribed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Phase 1a of docs/RUN-PLAN-24H-ELEMENTS.md: the pipeline proof. B and Ne
are structurally identical to C/N/O/F ([3s,2p,1d] in cc-pVDZ, 1s + an
L-shell in STO-3G), so they build through the existing `heavyShells` and
`heavyDiffuse` helpers unchanged. A failure here would have meant a
broken harness rather than a hard element. There was no failure: all 12
new cells passed on the first run, and the element agreement test is now
61/61 green across 10 elements x 3 bases x 2 d-conventions.

Basis constants are generated by scripts/gen-basis-tables.py from PySCF,
not transcribed. New reference molecules: BH3 (planar D3h, 1.19 A) and
atomic Ne.

Per-element data landed in every table that needed it. Two of these are
string-keyed with silent fallbacks and would have produced wrong physics
with no error at all:
  geometry.ts COVALENT_RADIUS_ANGSTROM  (?? 1.0 -> wrong bond detection)
  geometry.ts ATOMIC_MASS               (?? 0   -> zero mass, garbage
                                         centre-of-mass and rotational
                                         constants)
Sources: NIST most-abundant-isotope masses, Pauling electronegativity
(null for Ne, as for He), Pyykko-Atsumi covalent radii (matching the
file's stated source, not Cordero), Bondi/Mantina vdW, Grimme 2006 D2
C6 and R_r.

Widening AtomSymbol makes every Record<AtomSymbol,...> table a compile
error until filled — the desired loud failure. Five separate copies of
ATOMIC_MASS and four independent element lists exist across the repo;
all were updated, but the duplication is a standing drift hazard worth
consolidating later.

tests/chemistry/xyz.test.ts used Boron as its "unsupported element"
example, which this commit invalidates — it now uses Krypton, well away
from the basis tables, with B and Ne round-trip tests added alongside.

Full suite: 140 files, 1017 passed, 1 skipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… uHa)

BECKE_XI sets the per-atom radial scaling for the Becke-partitioned DFT
grid. Four entries disagreed with the Bragg-Slater table the scheme is
defined on (pyscf.dft.radi.BRAGG_RADII):

  F   MISSING -> 0.50   silently hit the `?? 1.0` fallback at grid.ts:80
  He  0.35    -> 1.40   0.35 is hydrogen's value
  C   0.65    -> 0.70   0.65 is nitrogen's value
  O   0.65    -> 0.60   nitrogen's value again

H stays at 0.5 — that deviation is deliberate and documented in place.
Noble gases really are anomalously large here (He 1.40, Ne 1.50); that is
the table, not a typo. I initially flagged Ne 1.50 as implausible and was
wrong.

MEASURED IMPACT, so nobody inherits an overstatement: LDA/cc-pVDZ,
spherical, before vs after —

  HF   -99.780846416 -> -99.780847054   (0.64 uHa)
  H2O  -75.854562755 -> -75.854562750   (0.005 uHa)

Sub-microhartree. The Becke partition is variationally insensitive to
xi: it redistributes quadrature points rather than changing the
integrand, and the existing grid was already dense enough to converge
regardless. So "every fluorine DFT number was computed on a mis-scaled
radial grid" is literally true and practically irrelevant. This commit
is correctness hygiene — it removes a silent fallback and realigns with
the cited source — not a repair of a meaningful error.

Full suite green: 140 files, 1017 passed, 1 skipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Phase 1b of docs/RUN-PLAN-24H-ELEMENTS.md. webgpu-q now supports every
element from hydrogen to argon. The element agreement test is 109/109
green: 18 elements x 3 bases x 2 d-conventions, one real molecule each
(hydrides wherever one exists, so two-center integrals actually run),
all under a 0.1 mHa bar against PySCF.

This is the unlock the run was for. Cl gives SN2, the single most-taught
mechanism in undergraduate organic; S gives thiols and H2S; P gives
phosphates and PH3.

Structure is uniform across the row, so atoms.ts needed one row-3 code
path rather than eight:
  STO-3G   3s + 2p        ->  9 Cartesian
  cc-pVDZ  4s + 3p + 1d   -> 19 Cartesian / 18 spherical
  aug      +1s +1p +1d
STO-3G's M-shell (3s/3p) coefficients are a genuinely new universal set,
identical across all eight elements exactly as the L-shell constants are
across Li-Ne; 3s and 3p share one exponent set.

`heavyShellsRow3` is deliberately a SEPARATE function rather than a
generalisation of `heavyShells`. Row 2 therefore emits byte-identical
shells and no pinned first-row number can move. The d-set stays a
contiguous canonical 6-tuple, which buildSphericalDTransform requires.

Frozen core is 5 for Na-Ar (the full neon core, 1s2s2p), not 1.

ZERO engine work was needed. The McMurchie-Davidson kernels were
verified against PySCF through L=5 (f/g/h agree to ~1e-14); row 3 tops
out at L=2, which is production-proven.

Also fixed here, because this change made it worse:
`canonicalSymbol` in import-formats.ts truncated an unsupported 2-char
symbol to 1 char unconditionally, so "Fe" imported as FLUORINE — silent,
and a real wrong element rather than an error. Adding P and S as
supported single letters made "Pd"/"Pt" -> P and "Sc"/"Se"/"Sn"/"Sr" ->
S newly wrong ("Na" -> N was already wrong). The truncation is only ever
correct for PDB atom names (cols 13-16, where "CA" is alpha-carbon), so
it is now opt-in and passed only from that path. Regression tests cover
both directions.

Corrections to the run plan, for the record:
  - Na and Mg carry d functions in cc-pVDZ, so the Cartesian/spherical
    convention difference applies from Na, not from Al as written.
  - STO-3G row 3 is 9 Cartesian functions, not 13.

Full suite: 140 files, 1065 passed, 1 skipped. tsc clean, lint clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…unlock

Phase 3 of docs/RUN-PLAN-24H-ELEMENTS.md. The report leads with what
could NOT be verified, per the plan, because on a run this size that
section is worth more than the list of what shipped.

Unverified, in short: Level A of the two-level scheme was never built
(only Level B exists, so wrong-data and wrong-integrals are not
separable); its 1e-9 Ha bar is unreachable anyway because boys0 uses an
Abramowitz-Stegun erf fit with a measured 2.66e-7 relative floor; all
108 reference cells are RHF only, so no correlated method is validated
for any new element; the row-3 frozen-core path (5 orbitals) is
implemented but untested and interacts with a known throw at
rhf-auto.ts:452; gradients were not hardened; and reference geometries
cannot be validated by a test that feeds identical coordinates to both
engines.

LIMITATIONS.md basis coverage rewritten. It claimed 6-31G* was "wired,
spot-checked" for H/C/N/O — the string "6-31g" appears nowhere in src/
and BasisName has only three members. That claim was never true, and it
was sitting in the document whose entire job is honest disclosure. The
section also cited ccpvdz-firstrow.test.ts as its precision evidence at
"~10 mHa"; that test's real slack is 116-170 mHa and it failed to catch
Li/Be being wrong by 1.29 mHa. Precision claims now rest on the element
agreement test instead.

curriculum-molecules.test.ts checks what the run was actually for:
CH3Cl (the SN2 substrate), CH3SH, H2S and PH3 all reproduce PySCF to
better than 0.1 mHa at STO-3G, in ~1.2 s combined. Element coverage is
only interesting if it unlocks chemistry people teach.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… tab

The education deliverable. Three standard undergraduate computational
chemistry labs, each running real SCF / MP2 / CCSD / CCSD(T) in a Web
Worker on the reader's machine. Nothing is precomputed and no number is
hard-coded into the page; the interpretation text is generated FROM the
results, so a student reads their own run rather than a promise about
one.

  Lab 1  Bond dissociation — RHF vs exact FCI on H2 across 14 bond
         lengths. The teaching moment is c_g / c_u going 0.994 / -0.113
         at equilibrium to 0.707 / -0.707 at 5 A: two configurations
         contributing equally is static correlation, and it is why
         single-reference theory fails there and why CASSCF exists.
  Lab 2  Basis-set convergence — H2O at STO-3G / cc-pVDZ / aug-cc-pVDZ.
         Minimal to double-zeta buys 1064 mHa; adding diffuse functions
         buys 14.8 mHa for 18 more basis functions. Diminishing returns,
         measured rather than asserted.
  Lab 3  The correlation ladder — HF to MP2 to CCSD to CCSD(T) on H2O.
         MP2 recovers 71.7% of the correlation CCSD(T) finds, CCSD
         99.7%. STO-3G runs in seconds; cc-pVDZ is selectable and is the
         calculation a methods course actually assigns.

Verified in a real browser against the built bundle, not just in unit
tests. Lab 3's STO-3G numbers (MP2 -74.998420, CCSD -75.012287) match
the repo's own full-precision PySCF artifact
(experiments/results/2026-07-06/level-6/E34-pyscf.json: -74.99842043,
-75.01228678) exactly. Lab 2's aug-cc-pVDZ value is -76.041983 against
PySCF's -76.0419832 — that agreement is new this session; before the
oxygen diffuse-function repair it read -76.041842.

The worker treats a non-converged SCF or CCSD amplitude set as an ERROR
and the page says so explicitly. That is deliberate: an earlier attempt
at Lab 1 printed unconverged CCSD numbers as data, and a teaching page
that does this teaches the opposite of what it should.

Honest scoping, stated on the page: the exact curve in Lab 1 is a 16
determinant full CI specific to H2 in STO-3G. There is no general FCI
solver here, so this lab does not generalise to N2.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A page nothing links to does not exist. Added to both nav bars in
index.html and to the learn and viz navs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…k into CI

Two problems, one theme: gates that report green without checking anything.

1. e2e energy assertions

`swarm-hf-anthracene-ccpvdz` asserted only `-1500 < E < -100` while its own
comment recorded that the run lands at ~-880 Ha against a literature
anthracene HF/cc-pVDZ value of ~-537 Ha. A 343 Ha error was certified green
on every nightly, with `converged: true` and a plausible-looking number —
the most dangerous failure mode in the repo (LIMITATIONS.md section 3).

Split into a serial pair sharing one 20-minute SCF:
  - "architecture ..." asserts what is actually true (runs end to end,
    converges, no +5352 Ha divergence) and makes NO energy claim;
  - "physics ... [EXPECTED FAILURE: wrong-basin SCF]" is marked test.fail()
    and asserts the literature value. If the SCF is ever fixed with MOM /
    SOSCF / SAD, it passes, Playwright reports "expected to fail but passed",
    and CI goes red until the annotation is removed.

New e2e/lib/energy-gate.ts replaces hand-picked windows with a derived,
size-extensive sanity band (-40.0 to -20.0 Ha per carbon, anchored on this
repo's own ladder) applied to hexacene / heptacene / octacene. It is named so
it cannot be read as validation: it detects wrong-basin collapse and broken
integrals, not method error. The floor is the tight side because variational
collapse always goes down; the ceiling stays slack because those specs report
the last iterate of a non-converged SCF, which is a diagnostic, not a value.

naphthalene-capstone (+-3 Ha) and swarm-gpu (+-1 Ha) already reject the
wrong-basin signature, so their numbers are unchanged — only relabelled, so a
reader cannot mistake a feasibility window for a validated energy.

2. scripts/check-basis-vs-pyscf.py had no runner

It is the only artifact that checks basis digits at the source rather than
checking an energy that happens to land close, and it ran from no workflow,
no npm script and no test. Wired up as `npm run check:basis` and a
`basis-digits` job in ci.yml.

It exited non-zero on the correct tree because Li STO-3G is deliberately
s-only. Added ALLOWED_DEVIATIONS, which excuses a cell only when the diff is
exactly the documented one (matched by exponent), so a bad digit elsewhere in
that same cell still fails. Coverage also went from 8 elements to all 18 that
the repo ships (24 -> 54 cells, 83 -> 235 constants; the other 152 constants
were previously classified as "note:" and compared against nothing), and an
unclassified constant is now a failure so a newly-added element cannot be
silently exempt.

Verified: exits 0 on the current tree; exits 1 for a perturbed digit in the
allowlisted Li cell, a perturbed digit in a newly-covered element, and an
unclassifiable constant. tsc, eslint and ruff clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Phase 2. No gradient bug: our analytic gradient matches PySCF's own
analytic RHF gradient to <= 4.77e-7 Ha/Bohr across all 15 comparable
molecules. Translational invariance — a property of the analytic
expression alone — holds to 3.6e-14 per axis. Ne and Ar give identically
zero gradients in both bases and both d-conventions.

The FD bar is 1.5e-6, not the 1e-6 the run plan proposed, and that is a
deliberate accepted widening rather than a rescue. Evidence, all in the
file header: the FD is not noisy (flat plateau from h=3e-4 down to 1e-5);
our analytic gradient sits 2.56e-7 from PySCF on PH3 while the central FD
of our OWN energy sits 1.50e-6 from PySCF — the analytic result is ~6x
closer to truth than the reference scoring it; and the eight elements
that were already PySCF-validated before this branch fall in the same
band under the identical harness (F/HF at 7.06e-7 is worse than 8 of the
10 new elements). Nothing is new-element-specific.

Root cause named: our SCF energy carries 1e-7-8e-7 Ha of integral
precision error, and differentiating the energy differentiates that
error. That traces to boys0 using the Abramowitz-Stegun 7.1.26 rational
fit for erf, measured worst case 2.66e-7 relative. It is the same floor
that makes the run plan's Level-A 1e-9 Ha bar unreachable. Replacing
erfApprox with an f64-accurate erf is the single change that would let
every FD-based gradient gate here — HF, DFT and CPHF — go below 1e-6.

25/25 passing, tsc and eslint clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The chemistry suites asserted far looser bounds than their comments
claimed, which is how the Li/Be cc-pVDZ table defect (up to 1.29 mHa)
shipped with 954 tests green. Re-source every headline reference from
the repo's own full-precision artifacts and set each bar just above the
measured delta.

Sources (read, not retyped, where the file allows):
  tests/chemistry/elements/pyscf-reference.json  (PySCF 2.13, 1e-12)
  experiments/results/2026-07-06/level-6/E34-pyscf.json (PySCF 2.13.0)
Values not present in either artifact at the geometry under test
(CH4 @ 1.09 A, LiH @ 1.595, BeH2 @ 1.34 in cc-pVDZ) were regenerated
with PySCF 2.13.1; the exact call is recorded in the file.

  aug-ccpvdz       -76.041358 +/-5e-4  -> fixture row, bar 0.001 mHa
                   (old literal was 0.070 mHa off the repo's own fixture)
  ccpvdz           cartesian run vs SPHERICAL ref inside 1 mHa
                   -> each convention vs its own ref, bar 0.001 mHa,
                      plus an explicit test that the 0.340 mHa
                      Cartesian-vs-spherical gap is reproduced
  ccsd             -75.0117 +/-1.5 mHa -> E34 -75.01228678295575, 0.001 mHa
  mp2              -74.999  +/-2 mHa   -> E34 -74.99842042839526, 0.001 mHa
  ccpvdz-firstrow  116-170 mHa windows -> fixture rows + nao, 0.01 mHa
  aug-ccpvdz-first ordering only       -> absolute refs both bases, 0.01 mHa
  hf-scf           4-decimal refs, 0.5 mHa, no cc-pVDZ row
                   -> full precision, 0.01 mHa, cc-pVDZ column added

The first-row suites now take their geometries from the fixture rows
too, so reference and test always describe the same molecule; this also
fixes an NH3 construction that built an 88 deg HNH angle while its
comment claimed 106.7 deg. Variational-ordering checks are kept as
supplementary. No bar was loosened.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The labs page previously used hydrogen and oxygen only: it demonstrated
nothing that this branch added. This is the lab that does.

Identity SN2, Cl- + CH3Cl -> ClCH3 + Cl-. The canonical gas-phase
benchmark and the mechanism every introductory organic course teaches.
Chlorine was the single element blocking it. 11 points along the
reaction coordinate, ~20 s in a Web Worker, charge -1 (44 electrons).

Three things the table shows, none of them asserted by the page — all of
them computed:

  - The umbrella angle sweeps 72 deg -> 90 deg -> 108 deg. Ninety degrees
    is planar, and that is the transition state. It is the Walden
    inversion, visible as a column of numbers.
  - The profile is exactly symmetric, E(s) = E(-s) to 1e-9. An identity
    reaction MUST be symmetric, so this is a free correctness check on
    the integrals, the geometry and the SCF — asserted in the test.
  - The barrier comes out at 33.4 kcal/mol in STO-3G against 14.6 in
    cc-pVDZ and ~13 in the literature. The minimal basis is wrong by more
    than 2x, in the direction that would make you predict the reaction is
    far slower than it is.

That last one is the lesson, and it is why the lab is worth running: the
shape is right and the number is not. A minimal basis is enough to see a
mechanism and nowhere near enough to predict a rate.

Caveats are on the page, not buried: the path is a straight-line
interpolation rather than an optimized reaction path (a real study would
locate the saddle and verify a single imaginary frequency), and anions
genuinely want diffuse functions that neither basis here provides.

Geometry lives in src/labs/sn2-geometry.ts and is imported by BOTH the
worker and tests/chemistry/elements/sn2-profile.test.ts, so the page and
its validation cannot describe different molecules. That is deliberate:
ccpvdz-firstrow.test.ts spent months validating an NH3 built at 88 deg
while its comment claimed 106.7 deg, because the geometry was written
twice.

Endpoint and transition-state energies are pinned against PySCF
(charge=-1, cart=True, conv_tol 1e-11) to better than 0.1 mHa.

Full suite: 143 files, 1110 passed, 1 skipped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant