Source the conformance corpus from JVM Clojure; retire the prelude gate

corpus.edn :expected is now the value reference JVM Clojure produces, set by the
new test/conformance/regen-corpus.clj (one JVM process, per-row thread watchdog).
167 rows moved to the JVM value: ratios (/ 1 2)=>1/2, doubles (double 3)=>3.0,
shared-heap concurrency (the future/pmap/agent cases), clojure.math doubles. The
JVM is the spec; jolt is measured against it.

known-divergences.edn shrinks to the rows whose JVM value is an opaque host object
that can't round-trip to source (Java arrays, transients, atoms, beans, proxies,
chunks all print as #object[..@addr]) plus (fn* foo) and a few racy concurrency
cases (:flaky). The zero-janet gate's allowlist becomes the set of host gaps vs the
JVM spec (no Class/array/BigDecimal, :jolt reader, jolt's own printing).

Math/clojure.math sqrt/pow/floor/trig now return doubles (Chez returns exact for
exact args, e.g. (sqrt 9)=>3); JVM always returns a double.

extract-corpus.janet no longer writes corpus.edn unless asked (the test runner
imported it and was silently overwriting the JVM corpus with the spec sources'
placeholder answers). The prelude parity gate is deleted — the zero-janet spine +
certify.clj are the oracles.

zero-janet 2678 (0 new divergences), certify 0 new / 0 stale, emit-test 330/330.
This commit is contained in:
Yogthos 2026-06-21 01:45:04 -04:00
parent 467ad75ff7
commit da775802d6
13 changed files with 435 additions and 823 deletions

View file

@ -10,15 +10,17 @@ read one data file, run each case, compare, report.
| File | Role | Generated by |
|------|------|--------------|
| `test/chez/corpus.edn` | **The spec.** ~2900 cases of `{:suite :label :expected :actual}`. | `test/chez/extract-corpus.janet` |
| `test/chez/corpus.edn` | **The spec.** ~2900 cases of `{:suite :label :expected :actual}`, `:expected` **sourced from reference JVM Clojure**. | `test/conformance/regen-corpus.clj` |
| `test/conformance/profile.edn` | Per-case **feature classification** — which non-portable cases need which host capability. | `certify.clj --profile` |
| `test/conformance/known-divergences.edn` | Curated allowlist of cases whose `:expected` deliberately differs from JVM Clojure (+ tracked bugs). | hand-maintained |
| `test/conformance/known-divergences.edn` | The few rows whose JVM value is an opaque host object that can't round-trip to readable source (Java arrays/transients/atoms/beans/proxies print as `#object[..@addr]`), so the corpus keeps jolt's value. | `regen-corpus.clj` leftovers, hand-checked |
| `test/conformance/regen-corpus.clj` | Sources every `:expected` from reference **JVM Clojure** in one process. | — |
| `test/conformance/certify.clj` | Certifies `:expected` against reference **JVM Clojure**; gates on new/stale divergences; emits the profile. | — |
The corpus is *generated* from `test/spec/*-spec.janet` and the inline cases in
`test/integration/conformance-test.janet` — those are the authoring convenience.
**`corpus.edn` is the canonical contract**: it is what every runtime consumes, and
what `certify.clj` certifies. A new runtime never needs to read Janet.
`corpus.edn` is **JVM-sourced**: `regen-corpus.clj` evaluates each case's `:actual`
on reference JVM Clojure and writes the JVM value as `:expected`. The case *list*
(the `:actual` strings) comes from `test/spec/*-spec.janet` via `extract-corpus.janet`,
but the *answers* are the JVM's. **`corpus.edn` is the canonical contract**: it is
what every runtime consumes and what `certify.clj` certifies.
## Row schema