D1A is built on Kev by Jared Palmer, Copyright 2026 Jared Palmer, licensed under the Apache License 2.0. This file records where D1A's code came from and what D1A changed, as Apache-2.0 §4 asks.
| Upstream repository | https://github.com/jaredpalmer/kev |
| Upstream base commit | 0fe8fc97c2bcc247fa3efb6e5c32af4e99770e91 (0fe8fc9, jaredpalmer/kev main) |
| Fork commit the port starts from | 13374b3 (https://github.com/jonpol01/kev main: 0fe8fc9 + Gemma 4 support) |
| Import | merged with full history into this repository (the merge commit keeps every Kev commit and author) |
-
Ported from later upstream Kev: the suites mirror pin (kev-suites
cc4bac8, nowd1a/eval/suite.pyUPSTREAM_SUITES) from Kev commit6b1da9d(#198), which publishes thehard-v1anddocuments-v1training partitions. Every other partition is unchanged at that revision.PrefixCache.make_roomind1a/serving/serve.pyfrom Kev commit1d77363(#201): before a batch runs, the cache drops the states that batch's store would evict anyway, so an old long state no longer stays resident through the pass of the new one (#189).d1a/training/temperature_gate.py, whichd1a.training.calibrate --judge/--guard/--confirm/--lockedruns, ports Kev's validation of a refitted temperature:kev/rounds.pypooled_temperature_ci(Kev commite52f812, #168) as every fit's 90% bootstrap interval of its temperature;kev/rounds.pypaired(), the registered paired read overkev.metrics.paired_bootstrap(Kev1dc2fbc, #112: micro, 2,000 record-clustered resamples, seed 0, rows in (id, question) order), as the Brier interval; and round 28's registered temperature rule and confirmation stages (experiments/rounds/r28.jsonand PLAN.md, Kevebc8024, #199). A refitted temperature is written only when, on the judge rows pooled, its Brier score is lower with a 95% upper bound below 0 and its ECE is lower, no judge or guard panel's ECE rises by more than 0.005, and then, scored only once that passes, ECE falls on every--confirmfile (the tests stage) and Brier rises by at most 0.005 with accuracy identical on every--lockedfile (the locked stage). D1A's changes: panels are rows files given per call, not a registered spec; rows are keyed by their file, so two D1A partitions'custom/<line>ids never share a cluster, and each row is paired with itself at the other temperature, ordered by (id, question) and then by file, so the Brier interval equals Kev'spaired()wherever no source name spans two files (those are resampled as one stratum per file); the confirmation stages run in the same call, once the rule passes. Round 29, registered in the same Kev commit, is not ported: it selects among 9B checkpoints under round 24's audited rule, on accuracy, with a calibration guard of ECE at most the parent's + 0.01 and a locked stage of accuracy at least the parent's − 1 pp and Brier at most + 0.005. -
Gemma 4 support (from the jonpol01/kev fork, by John Soliva): Gemma 4 E2B / E4B bases in
d1a/backends/torch.pyandd1a/training/train.py(Gemma's reserved<unused0>–<unused4>tokens as delimiters with a leading<bos>, a packed mask for the sliding-window layers, text-only loading, re-admission of suite records under Gemma's tokenizer) with tests intests/test_encoding.py,tests/test_unit.pyandtests/test_model.py. -
Training robustness:
d1a/training/train.pywrites resume points for LoRA runs (--save_every_steps,--save_every_minutes,--resume; Kev had them for full-weight runs only; now D1A's ownd1a/training/resume.py), and a non-finite loss or gradient skips its micro-batch or step (up toMAX_NONFINITEin a row) instead of ending the run; tested intests/test_train.py(resumes, a NaN gradient) andtests/test_unit.py(a non-finite loss). -
MLX backend for Gemma 4 and MLX exports:
d1a/backends/mlx.pyruns Gemma 4 bases on Apple Silicon (row form on replicated plain and sliding-window caches, KV-shared layers) besides Kev's Qwen3.5 path, and writes merged, optionally quantized export folders (scripts/export_mlx.py) thatd1a/backends/checkpoint.pyloads fromd1a_config.jsonandd1a/serving/serve.pyserves;backend="auto"now picks MLX for Gemma 4 on Apple Silicon. Gemma 4's per-layer embeddings are read from the weight files per request (FlashEmbedding, #71) instead of held in memory. -
Default base:
d1a.training.traindefaults togoogle/gemma-4-E2Bat commitd29ff6b45f081a49ee2733a859c9c9c2d95d1a6f. Qwen bases, including the hybrid Qwen3.5 code paths, still work unchanged. -
Renames: the Python package
kevisd1a(python -m d1a.serving.serve,d1a.training.train,d1a.eval.benchmark, ..., all imports, pyproject name);KEV_*environment variables areD1A_*. -
Model names: the server lists only
d1a-latest(the oldkev-latestandjev-latestlistings were removed) and still answers any model name a request sends; requests, the benchmark's remote mode and the clients default tod1a-latest. -
Clients: D1A's dependency-free clients live in
clients/python(d1a-client, importd1a_client) andclients/js(d1a-client), so the named1abelongs to the main package. -
Removed (Kev's research record and its own deployments, not part of D1A; all still in the history):
runs/,experiments/(exceptsmoke.json, the Modal smoke plan;sft-v1-lengths.json, the SFT corpus token counts, went in #65: nothing read it),PLAN.md,space/(the Kev Hugging Face Space),.agents/,skills-lock.json,skills/(kev-deploy, kev-finetune), Kev'sAGENTS.mdanddocs/autoresearch.md,docs/claims.json+scripts/verify_claims.py, Kev's model cards and figures, and the release and round read-out scripts (release_confirm,release_numbers,round4_deltas,compare_night2,compare_q35,plot_family,plot_tweet,jevbench_paired,modal_retry_probe,publish_space.sh). Tests bound to them went too:tests/test_rounds.py,tests/test_skill_scripts.py, two registration checks intests/test_research.pyand the claims check intests/test_conventions.py. -
Removed later (Kev's research tooling that D1A never runs):
modal_app.py,d1a/anchors.py,autoresearch.py,compare.py,jev.py,plot.py,publish.py,study_v3.py, and the round, plot and audit scripts (base_mmlu_probe,breadth_reads,breadth_report,calibration_audit,chartstyle,checkpoint_average,compare_typesafe,longdoc_report,longstate_report,plot_calibration_audit,private_rows,reliability_head,review_calibration_screen,screen_longdoc_v1,screen_overlap,serving_bench,sft_probe,temperature_groups), with the tests that only exercised them. Then Kev's study harness,d1a/rounds.py,experiment.py,evaluate.py,budget.pyandmirror.py, with their tests: calibration became D1A's ownd1a/training/calibrate.py(same fitted temperature and the same in-distribution refusals as the script it replaces; the full-weight snapshot cap moved tod1a/full_ft.py). Then Kev's Next.jsplayground/and thetools/reviewlabel-review page, withJevPredictorind1a/eval/predictors.py(it ran the playground'sjev-evaluate.mjs) and its tests; the demo app is now jonpol01/d1a-playground, and removed-tools.md records what both tools did and how to restore them. Thend1a.training.train's research options that no D1A checkpoint used: label smoothing, the Brier and focal terms, the ordinal RPS, the permutation KL, anchoring, option isolation (also ind1a.backends.torch,d1a.serving.serve,d1a.backends.mlx; such checkpoints are refused at load) and delimiter-embedding training, with their tests; removed-tools.md describes each. Then full-weight training:d1a/full_ft.py(MasterAdamW, FSDP2 across GPUs under torchrun, snapshots),--full_ftand the snapshot options, loading full-weight checkpoints (now refused), and the two scripts that only served them,interpolate_checkpoint.pyandmerge_lora_checkpoint.py, with their tests. Training is single-process LoRA; resume points became D1A's ownd1a/training/resume.py. Then Kev's training-history suites (decision-v1,public-pool-v5/v6,round3-round15,sft-v1,sft-v2and itsr21-r26,transfer-v1,v3,v5,v6,v8) and the builders that only wrote them or the two below (build_long_states,build_soft_targets,build_night2_data,freeze_calibration_audit,freeze_semif,freeze_semif_external).external(semif-v1, typesafe-v1, wanli-v1, wanli-v2) andnight2moved, byte for byte, into D1A suites (evals/d1a/external,evals/d1a/night2, data in the private datasetJohnP1/d1a-evals). Then the builders of the suites D1A keeps frozen (build_hard_v1withhard_v1_common/_families/_numeric/_policy,build_breadth_v1,build_devtools_v1withdevtools_v1_licences.json,build_longdoc_v1withlongdoc_v1_synthetic,build_documents_v1/_v2,freeze_documents_v1,label_documents_v1,build_binding_diagnostic, andd1a/transfer_v9.py) with the tests that only exercised them; the suites stay as data pinned by sha256 (tests/test_frozen_suites.py), and removed-tools.md says where to rebuild them. Thend1a.eval.suite's own suite freezer (python -m d1a.eval.suite) withd1a/contrastive.pyand the record generator ofd1a/training/composition.py(its rule shapes stay ford1a.eval.suite.validate_training;paired_flipmoved tod1a/eval/benchmark.py), andtests/test_generators.py. Then thed1a/training/data.pyconverters only that freezer read (13 sources;build()keeps its six defaults) andscripts/longdoc_serving.py(CUDA long-document serving cost, run through the removed Modal app). -
Rewritten from scratch (no longer derived), one file per line in path order, so rewrites landing in parallel touch different lines; each behaviour-identical rewrite is checked by
scripts/equivalence/where one exists:d1a/core/api.py: the same schema, texts and answers; its tests aretests/test_system_one.py.d1a/eval/benchmark.py: the same rows, reports and files; its tests aretests/test_benchmark.py.d1a/training/calibrate.py: replaces Kev's calibration script;scripts/calibrate_checkpoint.pyis now a wrapper around it.d1a/backends/checkpoint.py: the same decisions, refusals and on-disk formats; its tests aretests/test_checkpoint.py.d1a/backends/shared_prefix.py: the same branch hidden states and gradients, bit for bit, on a tiny Qwen3.5 (eager and SDPA, padded and unpadded states, checkpointing on and off); checked byscripts/equivalence/shared_prefix.py; its tests aretests/test_shared_prefix.py.d1a/training/data.py: the same records from the same seeds (every draw in the same order); its tests aretests/test_data.py.d1a/eval/metrics.py: bit-identical results; its tests aretests/test_metrics.py.d1a/eval/predictors.py: the same predictions, requests, retries and rotation averages; checked byscripts/equivalence/predictors.py(local, remote and rotation-averaged predictors); its tests aretests/test_predictors.py, which withtests/test_encoding.pyreplaced Kev'stests/test_research.py.d1a/backends/torch.py(its encoding and pointer head now ind1a/core/encoding.pyandd1a/core/head.py, #60): the same encodings, masks, probabilities and training gradients, bit for bit, on Gemma 4 and Qwen3.5; its encoding, mask and pointer-head tests aretests/test_encoding.py.d1a/eval/suite.py: the same pins, partition checks, mirror rules and file formats; its tests aretests/test_suite.py.d1a/training/composition.py: the same shapes, splits, held-out keys and structure keys; checked byscripts/equivalence/composition.py.d1a/training/train.py: the same training, bit for bit on the CPU, resumes included; its tests aretests/test_train.py.tests/test_api.py: the same HTTP API checks and more (tighter sums, the confidence and expected-score formulas, 422s at both option limits, isolation for every question in any order); it now serves the tiny checkpoint in process.
-
Rewritten:
README.md,AGENTS.md,NOTICE,.gitignore. -
Kept as is: the frozen suites in
evals/(their large partitions download from D1A's copy of Kev's Hub datasetjaredpalmer/kev-suitesatcc4bac8, or from Kev's dataset for an account without access to the copy; #344), the suite builders inscripts/.
python scripts/kev_share.py compares each file with its Kev counterpart line by line and reports, per area, the lines
kept from Kev, changed and new. It counts text, not authorship. A file rewritten from scratch (d1a/core/api.py,
d1a/eval/metrics.py, d1a/eval/suite.py and the others listed above, checked by scripts/equivalence/ where one
exists) still matches Kev
wherever a constant, a formula, an argument name or a short idiom is the same by design: the same mask, pointer head and
metrics must give the same numbers. Those lines stay counted as kept, and the share will not reach 0% while D1A keeps
Kev's backbone, mask and head. The rest of the kept code is live, or on the Qwen and Qwen3.5 paths D1A keeps (#65,
2026-10-11: nothing Kev-only was left to prune).
Files taken from Kev and modified. Each carries the notice "Modified from Kev (...)" and a one-line summary of its
changes at the top; scripts/check_license.py checks that this list and the headers match exactly.
.github/workflows/ci.yml
.gitignore
d1a/backends/cuda_graphs.py
d1a/backends/fused_qwen35.py
d1a/backends/mlx.py
d1a/serving/serve.py
d1a/training/temperature_gate.py
pyproject.toml
scripts/mlx_parity.py
tests/test_conventions.py
tests/test_mlx.py
tests/test_model.py
tests/test_unit.py
Files taken from Kev and modified that cannot hold a comment (JSON, generated lockfiles).
scripts/golden_presets.json
uv.lock
Files carried over from Kev byte for byte (an entry ending in / covers a directory). The check fails if one of them
changes without moving to "Derived files".
evals/
.gitattributes
.python-version
LICENSE
d1a/backends/device.py
experiments/smoke.json