D1A models: what each can do (2026-10-14)
What each D1A model line can do today. "Decisions" means D1A's System One API (POST /v1/systemone): yes/no, choice and score questions over a document, answered in one pass with calibrated probabilities. Numbers are from each model's card; "not measured" means the card has no number yet.
Table with columns: D1A-E4B v0.6.1, D1A-E2B v0.6.1, D1A-E2B-it v0.6, D1A-12B | D1A-E4B v0.6.1 | D1A-E2B v0.6.1 | D1A-E2B-it v0.6 | D1A-12B |
|---|
| Base model (trunk) | Gemma 4 E4B (pretrained base) | Gemma 4 E2B (pretrained base) | Gemma 4 E2B-it (instruction-tuned) | Gemma 4 12B-it QAT; not trained yet (jonpol01/d1a#270, shelved) |
Decisions (/v1/systemone) | yes | yes | yes (experimental) | — |
| PR labeling, 487 PRs newer than all training: severity / change type | 79.1% / 90.6%; P0/P1 found 13 of 30 | 77.2% / 87.5%; P0/P1 0 of 30 | 72.9% / 87.3%; P0/P1 3 of 30 ("not a PR labeller") | — |
| Skill suites (hard, developer tools, long documents, transfer, Japanese JGLUE) | measured (card) | measured (card) | not measured | — |
Photos, voice and video (/v1/systemone/media, MLX builds with media/) | yes, zero-shot | yes; 25 of 28 demo answers match E4B | yes; 21 of 28 match E4B | — |
Routing temperature ("use_case": "routing") | yes, T 1.18 (from v0.6.1) | yes, T 0.95 (from v0.6.1) | no | — |
| Self-learning (outcome log, recalibration, learned flags) | yes, when served by d1a.serving.serve | yes | yes | — |
| Chat / text generation | no: base trunk; the MLX build has the adapter merged | no (same) | yes: build it with scripts/export_mlx.py --unmerged and serve it; with the adapter off it is Gemma 4 E2B-it (Enable chat, Chat with D1A). Also runs as an unmerged adapter in the Mieru iPhone app | planned: adapter off = Gemma 4 12B-it |
| Embeddings | — | — | from a GGUF embedder served beside it (D1A_EMBED_GGUF) | — |
| Builds | PyTorch JohnP1/d1a-e4b; MLX 8-bit JohnP1/d1a-e4b-mlx-q8 (7.6 GB with 1.0 GB of media encoders) and mirror mlx-community/d1a-e4b-8bit; Core ML int8 preview JohnP1/d1a-e4b-coreml (text only, ≤512 tokens) | PyTorch JohnP1/d1a-e2b; MLX 8-bit JohnP1/d1a-e2b-mlx-q8 (4.8 GB) and mirror mlx-community/d1a-e2b-8bit; Core ML int8 JohnP1/d1a-e2b-coreml (text only, ≤512 tokens) | PyTorch adapter JohnP1/d1a-e2b-it; MLX JohnP1/d1a-e2b-it-mlx-q8 (4.8 GB) and -mlx-q4 (3.6 GB), both merged; Core ML JohnP1/d1a-e2b-it-coreml and -coreml-4bit | 4-bit Q4_0 export ready (, ) |
| Calibration temperature | 1.95 | 1.45 | 1.41 | — |
| Where it runs | the Mac mini playground and the PR labeler (MLX 8-bit, v0.6.1) | — | the Mieru iPhone app | — |
Older single-purpose builds: JohnP1/d1a-e4b-pr-labeler-mlx-q8 (v1) and JohnP1/d1a-e4b-routing / -routing-mlx-q8 (v0.1), superseded by D1A-E4B v0.6.1.
Kept current in the D1A repository: docs/MODELS.md.
What's inside
A LoRA adapter (rank 16 on the attention and MLP projections: q, k, v, o, gate, up, down) and a small pointer head (256-dimensional) on google/gemma-4-E4B at revision 411aa17b. Each version continues training the previous one, so v0.6 contains every stage below:
Table with columns: Version, Stage, Training data, Settings| Version | Stage | Training data | Settings |
|---|
| v0.1 | General decisions | decision-v7 suite: ~12,500 records from public classification datasets plus generated policy and rule data | 2 epochs, lr 5e-5 |
| (v0.2) | Kev's later skills | dates and missing evidence (1,425), hard decisions, developer-tool decisions and long documents (hard-v1, devtools-v1, documents-v1 training partitions, states up to 4,096 tokens), decision-v7 replay 4,000 | 1 epoch, lr 2e-5 |
| v0.2 | Japanese and agent routing | Japanese decisions from JGLUE (JNLI, JCommonsenseQA, JSTS; 6,000), agent-factory and model-routing questions (2,745), decision-v7 replay 3,000 | 1 epoch, lr 5e-5 |
| v0.3 |
Before training, the v0.6 mix was screened against 47 evaluation partitions, the 487 newer PRs below included: none of their documents or PRs is in it.
Calibration: a single temperature, T = 1.95, fitted on pooled held-out rows (decision-v7 calibration split and PR-labeling development set; calibration error 0.093 before, 0.015 after, out of fold), stored in d1a_config.json (and in head.pt, which this release still writes for older loaders). v0.6 carries no per-use-case temperatures yet, so a request with "use_case": "routing" is read at 1.95 too; a refitted routing temperature is planned as v0.6.1.
Results
Pull requests newer than all training
487 hermes-agent pull requests created after every PR in v0.6's training, held back before v0.6 was trained (the test was registered in advance). All three models are MLX 8-bit at their served temperatures, with the serving context. Differences are paired over PRs, with 95% bootstrap intervals:
Table with columns: Question, Majority answer, v0.4, v0.5, v0.6, v0.6 − v0.5| Question | Majority answer | v0.4 | v0.5 | v0.6 | v0.6 − v0.5 |
|---|
| Severity (P0–P4) | 67.8% | 77.4% | 74.7% | 79.1% | +4.3 [+0.8, +7.8] (52 fixes, 31 breaks) |
| Change type | 51.5% | 86.4% | 86.7% | 90.6% | +3.9 [+1.2, +6.6] (31 fixes, 12 breaks) |
| P1 recall (23 PRs) |
Against v0.4, v0.6 is +1.6 [−0.8, +4.1] on severity and +4.1 [+1.4, +7.0] on change type. A cheaper alternative, v0.5 with outcome memory fitted on the same recent labels, reached 89.3% on change type but only 76.4% on severity (+1.6 [−1.0, +4.3]), with P1 recall 0.17, and failed its own bar.
Every suite, against v0.5
Held-out data only. Both models are MLX 8-bit (JohnP1/d1a-e4b-mlx-q8) at their served temperatures (v0.5 1.78, v0.6 1.95), scored with d1a.eval.benchmark through D1A's quality gate and scripts/decide.py. Differences are paired over questions, with 95% bootstrap intervals:
Table with columns: Set, v0.5, v0.6, Δ [95% CI], Calibration error, v0.5 → v0.6| Set | v0.5 | v0.6 | Δ [95% CI] | Calibration error, v0.5 → v0.6 |
|---|
| Hard decisions (hard-v1, 1,083 questions) | 71.5% | 68.8% | −2.7 [−4.9, −0.5] | 0.045 → 0.043 |
| Developer-tool decisions (devtools-v1, 1,074) | 69.8% | 70.1% | +0.3 [−1.4, +1.9] | 0.048 → 0.037 |
| Long documents (documents-v1, 920) | 87.5% | 89.5% | +2.0 [+0.1, +3.7] |
Pooled over all 21 lines, v0.6 − v0.5 = −0.20 [−0.98, +0.52]. Latency is unchanged: v0.6 over v0.5 on short requests 1.0009 [0.9991, 1.0035], within run-to-run noise (measured interleaved).
¹ These PR sets are older than the 487 above. v0.5's numbers here are its 8-bit build at T 1.78 over the full sets, so they differ a little from v0.5's own card, which scored PR labels on the bf16 PyTorch checkpoint.
² The PRs the owner's labeling job saw on 2026-10-06 and 07, labelled by the owner on the playground's review page.
Against Kev-4B's model card (fp32, development splits; an approximate comparison): hard decisions 78.6, developer tools 73.9, long documents 89.1, transfer 81.7. v0.6 is level with Kev-4B on long documents.
Calibration: v0.6's single temperature fits its calibration sets (0.015 out of fold), and its calibration error is lower than v0.5's on 15 of the 22 suites the gate scores (most on transfer-v4, agent factory and wanli-v2). It is higher on the other 7, most on dates (0.028 → 0.053), typesafe-v1 (0.104 → 0.129) and JGLUE (0.026 → 0.042).
Photos, voice and video
With the media extra, d1a.serving.serve answers questions about a photo, a voice clip or a video with this same model through Gemma 4 E4B's own vision and audio encoders, unchanged by the adapter (POST /v1/systemone/media). No media in training (zero-shot). On the playground's photo, voice and video examples, v0.6 changes 1 of 14 requests from v0.5 (one video example).
The questions it was trained for
PR labeling works best with these questions, worded exactly so, over a document of the form title / author / stats / body / files (one - status path +added/-deleted line per file):
type (choice): "Primary change type from files and body, not the title prefix." Options: type/bug, type/docs, type/feature, type/perf, type/refactor, type/security, type/test.
blast (choice): "How far a mistake in this PR spreads in production." Options: review:blast-contained (one module), -moderate (one subsystem), -broad (shared helper or config), -massive (auth, permissions, or all paths).
sev (choice): "How serious the problem this PR addresses is — not the risk of merging the diff as-is." Options P0 to P4.
The PR-labeler recipe has the exact wording, the document builder and the training and scoring scripts. The mix builder builds and screens mixes like v0.6's. Other questions about other documents work as in v0.2.
Run it
pip install "d1a[serve] @ git+https://github.com/jonpol01/d1a"python -m d1a.serving.serve --run JohnP1/d1a-e4b@v0.6.1 --port 8009
or in-process: from d1a import D1A; D1A.load("JohnP1/d1a-e4b@v0.6.1").decide(state, questions). On Apple Silicon the 8-bit MLX build, JohnP1/d1a-e4b-mlx-q8 v0.6, is faster and smaller. For hard-v1-style reasoning or the older PR-label conventions, load @v0.5.
Limits
- Hard decisions are 2.7 points below v0.5 (68.8% against 71.5%; the release exception above), and 10 below Kev-4B (78.6).
- Change type on older PRs is worse: 85.3% against 89.4% on the frozen English test set, and 72.5% against 76.2% on the Japanese one (all questions, 92 PRs). It calls more PRs type/bug than v0.5 did. On current PRs it is better (above).
- Blast radius on the owner's own repositories is worse: 67% against 74% on 39 hand-checked PRs (1 fix, 4 breaks). v0.6 was not trained for blast radius; on the larger frozen test set it is 62% against 58%.
- Severity: on the 487 newer PRs, P2 recall falls (0.55 against v0.5's 0.79) while P3 and P0 rise; P0 rests on 7 PRs. Severity on the older development set is 1.8 points lower.
- One temperature for every question except routing: from v0.6.1, requests sent with
"use_case": "routing" are served at T 1.18. Calibration error is higher than v0.5's on JGLUE, dates and typesafe-v1.
- Smaller losses against v0.5: decision-v7 −1.4, wanli-v1 −2.3, one of 45 hand-labelled routing questions.
- The recent PR labels come from one large open-source project and a few days of it; if its conventions move again, so will these numbers.
- Questions are in English; the documents can be English or Japanese.
Versions
Table with columns: Tag, What it adds| Tag | What it adds |
|---|
v0.1 | general decisions (decision-v7, 2 epochs, calibrated) |
v0.2 | Kev's later skills, Japanese, agent routing |
v0.3 | pull-request labeling, English and Japanese |
v0.4 | pull-request labeling round 2: severity, Japanese, less biased blast radius |
v0.5 | Kev's harder skills back (hard, developer-tool and long-document decisions), PR labels held |
|
Older tag names (v0.1-2epoch, v0.1.1-2epoch-calibrated, v0.2-hybrid) still work.
License and data
Apache-2.0. Base model: Gemma 4 by Google (Apache-2.0). Code: github.com/jonpol01/d1a, built on Kev by Jared Palmer (Apache-2.0). Japanese decision data derived from JGLUE by Yahoo Japan Corporation and Waseda University (CC BY-SA 4.0). Pull-request data from NousResearch/hermes-agent (MIT); the labeled PR dataset itself, including the recent PRs, is private.