Download docs/rust-migration/PARITY_MATRIX.md from staccs/ds4-winhip: direct link, hf CLI and curl.
- Browser
- Download file 35.5 kB
-
https://huggingface.co/staccs/ds4-winhip/resolve/main/docs/rust-migration/PARITY_MATRIX.md
- Command line
-
hf download hf://staccs/ds4-winhip/docs/rust-migration/PARITY_MATRIX.md
-
curl -L -o PARITY_MATRIX.md https://huggingface.co/staccs/ds4-winhip/resolve/main/docs/rust-migration/PARITY_MATRIX.md
Parity matrix
Frozen migration evidence. Preserve its fixture definitions and recorded results; use the v0.1.0 ledger for current release qualification. Passing this historical matrix is not a new candidate pass.
Recorded result (2026-08-31 KST): the complete
v0.6.5-dfmlive matrix is green ateb4ba77: PASS 57 + PASS* 3 (C-shared E-2, E-3, E-6), FAIL 0, BLOCKED 0. The final host-only fix and 13/13 cheap/parity re-audit are green atd126e56. Qwen Q5+Sidecar owns the campaign's only two-hour soak; DeepSeek retains its ordinary functional, KV, API, proof, and performance cells.
Qwen v0.6.5 delta re-stamp (8006198)
Full identities, artifact scope, commands, hashes, and raw-evidence paths are recorded in QWEN_V065_RESTAMP_2026-08-31.md.
| Axis | Result |
|---|---|
| Numerical | Q5 loader, SSD-PLE, QSA, MoE, GDN, two-bank batch, embedded MTP, and shared MMQ gates PASS |
| Token | Qwen tokenizer goldens PASS; C→Rust→Rust→C text and image outputs are exact |
| KV | same-image reuse, changed-pixel rejection, cross-worker disk restore, two-bank disk/partial-fork lifecycle PASS |
| Wire/API | image Chat, Responses, and Anthropic PASS; continuous width 2, static width 2, serial fallback, /v1/models, and /v1/stats PASS |
| Performance | text ABBA: prefill 99.97%, decode 100.00%, TTFT +0.95%, worker VmHWM +4.40%, GPU residency exact; image prefill 100.20%, TTFT +0.32%; exact-262K prefill 99.64% |
| Hard gates | 7,202.3-second Qwen soak: 3,610/3,610 requests, 158 barriers, 79 images, RSS drift 0.0011%/0.0%, swap 0; 262K direct: 248,320 finite logits, argmax 198 exact, f32 mismatches 0; KV 4-way, MTP 1.01→2.00 tok/step with exact output, forced static route 2/2 PASS |
This is the requested Q5 main GGUF plus shared Sidecar scope. Safetensors, resident BF16, Q6, and their reference gates were intentionally not loaded.
Current v0.6.5 full re-stamp (eb4ba77 + d126e56)
Evidence root:
scratch/rust-host-live/v065-full-restamp-20260831-184200/. The classified
live ledger is gates-results.txt; the final host/parity audit is under
final-audit-d126e56/.
| Group | Logical result |
|---|---|
| G0 cheap/parity/shared kernels | 13 PASS |
| G1 DeepSeek KV/API/proof | 23 PASS |
| G2 Motif family/shutdown/barrier/ABBA | 9 PASS; E-4/E-5 fixed and re-run green |
| G3 Solar | 8 PASS + 1 PASS*(E-3) |
| G4 K-EXAONE | 2 PASS + 1 PASS*(E-2) |
| G5 dots3-note | 2 PASS + 1 PASS*(E-6) |
All three PASS* cells were re-run against a C control in this campaign. E-2
and E-6 used exact v0.6.5-dfm sm_121a test binaries; E-3 reproduced in the
frozen C server. The candidate and exact-tag Dots3 runs produced identical
first=63594/63594, batch_cos=0.98607464, and
batch_nrmse=0.201895. No C-pass/Rust-fail cell remains.
The current Motif ABBA ratios are 99.90% prefill, 99.33% decode, +1.07% TTFT,
and +1.03% host VmHWM, with exact GPU residency and zero swap. The proof set
passes smoke 2/2, captured/eager long 6/6, tracked v0.6.5 OPP-C 5/5, and
C→Rust OPP-C 5/5. After the host-only socket compatibility fix, all 13 G0
cells, clippy, final default/C builds, and ds4-eval --self-test-extractors
pass at d126e56.
The detailed incremental evidence below is retained for provenance. Statements that a later phase was “pending” describe the named historical commit only and are superseded by this current re-stamp.
Historical post-promote §10 (cb11c0b)
Evidence: .omo/evidence/task-53-rerun-cb11c0b.txt.
PASS 55 + PASS* 5 (E-2..E-6) + FAIL 0 + BLOCKED 0.
| Axis | Result |
|---|---|
| Numerical | family kernels + mmq PASS; family IMA/decode gaps = E-2..E-6 (C-shared) |
| Token | DeepSeek logprob vectors PASS; Motif batch expected-vector miss = E-4 |
| KV | DeepSeek 4-way ordinary/continued/tool-map/periodic/evict/partial PASS; Motif shutdown 4-way PASS |
| Wire/API | DeepSeek 4 surfaces × serial/cont/static PASS (C=ds4-server-c, Rust=ds4-server); barrier width=2 PASS |
| Performance | Motif ABBA PASS (prefill 99.95%, decode 100%, TTFT +1.1%, HWM +1.0%); proofs smoke/long/opp-c/rust-opp-c PASS |
The historical two-hour mixed DeepSeek soak is not repeated. This campaign's only long soak was the now-green Qwen Q5+Sidecar two-bank gate; DeepSeek still runs the ordinary functional, parity, proof, and performance cells.
“Rust works” is not cargo build. A host change is accepted only
when all five axes that it can affect are green. CUDA optimization
commits already require a correctness proof and a speed proof
(AGENTS.md). The same bar applies to migration commits.
Five axes
| Contract | Requirement | Oracle |
|---|---|---|
| Numerical | logits / fixtures stay inside existing tolerances | family CUDA fixtures, test-mmq-parity, test-model-family-kernels, CPU-vs-GPU refs where they exist |
| Token | deterministic path emits the same token ids | greedy / temp-0 benches, tokenizer goldens, motif/solar sentinels |
| KV | save / restore / reuse / prefix / eviction identical | KVC 4-way matrix; ds4_session_save_payload / load; bank restore |
| Wire/API | schema, event automaton, route engagement, semantic equivalence | docs/ds4-api-surface-matrix.md + ds4_test --server |
| Performance | no unexplained regression vs C on GB10 | BASELINE.md thresholds; AB/BA or ABBA |
Live sampled HTTP bodies are not a byte oracle. Continuous temp-0 can jitter. Live gates check schema, automata, routing, and semantic equivalence — the same rule the API matrix already records.
Do not refresh goldens to hide a Rust miss.
Phase gates
Phase 1 — workspace + FFI skeleton
cargo check -p ds4-sys(and empty member crates) succeeds- Header exists; no bindgen of
ds4.h - No production binary replaced
Phase 3 — FFI shadow (ds4-rs / ds4-bench-rs / ds4-agent-rs, historical)
Same model, same arguments, C vs Rust wrapper around the same C core:
| Check | Pass |
|---|---|
| Token output | Fixed-seed sampled C/Rust stdout is byte-identical (ae12f463...); post-port greedy stdout is also exact (a12b7cb4...). Fixed-seed non-TTY thinking output is exact in both modes (--think: 292 bytes, ad6d107f...; --nothink: 52 bytes, ae12f463...). Same-prompt server pair returned Hi. / stop / 13+2 |
| KV behavior | save/load round-trip matches C (synthetic). Live Rust benchmark restored the 64-token frontier before incrementally syncing to 128; checkpoint sizes were 18,632,800 and 24,556,624 bytes |
| Prefill / decode tok/s | Local C/Rust benchmark ABBA is green below; full production-path performance remains pending |
| Memory | sequential; C server peak nvidia-smi 102833 MiB, Rust server 99077 MiB; teardown + clear_cache returned ~115 GiB available |
| Agent shadow | make test-agent-parity is green: the 7,579-byte built-in prompt, fixed-input datetime message, selected non-TTY projector tapes, both supported DSML openers, and the 393,216-token high-thinking boundary are covered. The release binary links over the existing native core; live generation, transcript token tape, streaming, malformed/in-think DSML, tools, KV, MTP, and distributed paths remain pending |
If FFI alone regresses performance, stop. Do not port subsystems on a dirty seam.
Phase 4 — KV store (historical incremental evidence; current gate green)
Preserve magic KVC, file version 1, payload ABI 2
(ds4_kvstore.c), 48-byte fixed header, endianness, key = rendered
byte prefix SHA, eviction and prefix policy, trailer hooks.
Hard gate (all four):
C save → Rust load
Rust save → C load
Rust save → Rust load
C save → C load
No new checkpoint format.
The isolated seams are green for metadata-only KVC indexing (including a
sparse 4 GiB payload fixture), bounded text-prefix comparison, embedded DSV4
range validation, and a file-backed Rust payload writer. The writer stages the
complete stream before eviction, protects a replaced destination, preserves
the C-compatible O(trailer) fast path, and produces payload/trailer bytes read
exactly by the C oracle. The no-GPU C oracle also proves nonzero seek, exact
length, EOF rejection, and uint64 overflow rejection.
The ordinary serial Motif-3 no-think/no-tools slice is now live-green under the
policy both servers implement (cold=0, continued=0). In
scratch/rust-host-live/rust-kv-no-think-final-IHtJue/, C and Rust generated
the same 301,972,392-byte
5522739e3318261231ec3ddd49a24da9e66a5118.kv; visible text and payload bytes
were exact, apart from volatile header counters/timestamps after reads. All four
restart cells returned RESTORED_OK with 6,896 cached prompt tokens and 15
new prompt tokens:
C save → Rust load PASS
Rust save → C load PASS
Rust save → Rust load PASS
C save → C load PASS
Request SHA-256 values were a765063d149094c6542f42e7156735a8d466cc7f4eab1eac71e0fc40a7cbadbb
(A), 083ab2beb504500ee28dafe0d8184b53d7795d6958712c78b1c045cdf2c3d827
(evict), and 4ae9a992140aa7cd98a7ec0467b299c66ffcb4154c2429ca202239caa8cc9d4b
(restore). The 94,162,541,472-byte GGUF was
Motif-3-MQ87-88-FIT.gguf. The C binary was
04f25a86040940674984c35160d2e4eec7f6c6d4e30313815ce10309cd57e662
and the Rust four-way binary was
dae70ae2f909fe6c0713a609a285c272db8d1b6ec0e2856a70bd361753625ff4.
The common launch contract was serial (DS4_SERVER_COALESCE_MAX=1 /
--cont-width 0), ctx 8192, max output 128, disk budget 2048 MiB, and minimum
checkpoint 512 tokens; C additionally set both unimplemented policy knobs to
zero. Follow-up e5830c218361ec2288e98992cd388be1a5a24a04 corrected the Rust
timing porcelain so a live Rust cache hit now reports
prefill_tokens=15 and prefill_cached_tokens=6896, matching C (post-fix
binary 52471e49c4c22bde2f1abb063755847ff5d738da705896e925e8b7468b8ec197).
The initial comparable single cells exposed a real lifecycle regression: C was
879--934 ms TTFT while Rust was 1,590--1,715 ms because the Rust server opened
with deferred boot prewarm and never called it. Commit f4a632e added the
opaque prewarm call after batch placement, preserving C's placement contract.
The same model, request C, KVC, serial lane, and cache-clear protocol then gave:
C 880.9 ms
Rust 836.0 ms
Rust 860.4 ms
C 897.5 ms
C mean was 889.2 ms and Rust mean 848.2 ms (-4.61%), so the scoped restore TTFT
gate is green. All four cells returned RESTORED_OK, 6,896 cached tokens, and
15 computed tokens. Commit 4fc8ef4 then matched C's reported prefill timing
scope (computed suffix sync only): live Rust was 69.2 tok/s versus C
68.2--69.0, with TTFT still 840.4 ms. The ABBA binary SHA-256 was
00da345a5e09887d82b514c80b4674aa37311e0903ad50ff9cae82b1db3a34b3;
the timing-scope binary was
ea714d4d7ae4e2618bf052aa842d40e290cd978ac404ac1f39aa15f5d76779f9.
The C-default ordinary cold slice (cold_max=30000, trim 32, align 2048) is
live-green for this fixture under
scratch/rust-host-live/rust-cold-default-0IeCd9/. For the 6,782-token Motif
fixture, both hosts selected the same 6,144-token prefix. The rendered text
SHA-256 was
ebd540ec7d9b9059649a1066c222dae4b02ca54bed54570da6fda0b81fd66f5e
and the payload SHA-256 was
0f0af1d1e189561aee24534cb4918bc292ef68a418522a51e615ac0bfade5862
for both C and Rust. Rust→Rust, Rust→C, and C→Rust restart cells restored the
prefix and emitted the same 106-token output
(49b5f8a8b7c4e3aa2f768fd3afd29ad33a1d2cc327fe0361a0cd6d2c21afcdd9)
at 2,038.4/2,078.9/2,018.0 ms TTFT. Header timestamps and hit counters remain
intentionally volatile; the text and payload bodies are exact. These cells are
a correctness/cross-read gate, not a cold-policy ABBA performance claim.
The ordinary serial continued final-sync call/order is CPU-green, while the
decode frontier is live-green under
scratch/rust-host-live/continued-fourway-oJTYrf/. C and Rust used ctx 8,192,
cold=0, continued=6800, trim 0, align 1, and request A
(a765063d...). Both wrote
411e439f9951c2df3addaa93e73cabee465bf0b2.kv, 300,423,338 bytes,
reason 2, ext 0, model 3, tokens 6,800, ctx 8,192. The rendered-text SHA-256
was 025231236a8afc77532eeecdb6ea16b3f94b51456641e29224438813605764ae
and payload SHA-256 was
be4d59a936d236809bfeae3953408b067df3a5dac86212b85df21ecf98550838
for both hosts; their 114-token answer was exact.
The first restart fixture was intentionally retained as a negative oracle:
Motif live generation contains <think></think>, while a closed no-think
assistant history drops that empty pair in both C and Rust. It therefore
misses the record by construction. The positive fixture prepends the same
empty pair to the assistant replay (SHA-256 6bbd72ee...) so its rendered
bytes preserve the live KVC prefix. Four isolated/cross-host loader cells
then passed:
C save → Rust load PASS cached=6800 computed=111 output=4
Rust save → C load PASS cached=6800 computed=111 output=4
Rust save → Rust load PASS cached=6800 computed=111 output=4
C save → C load PASS cached=6800 computed=111 output=4
All returned RESTORED_OK with semantic response SHA-256 f61bf763....
The C binary was 04f25a86...; the live-tested Rust binary was
beadabe4.... The subsequent cheap-frontier build 42a1ddfb... removes the
non-due token-vector copy and passed the full CPU/parity/link gates; it did not
need another 100 GiB live matrix because checkpoint bytes and ordering are
unchanged. Teardown and clear_cache ran between resident models, and the
final host had no compute application or listener. These cells prove
decode-frontier continued correctness and cross-read; the final-sync
call/order is covered by the CPU integration test. Neither is a performance
gate.
The scoped ordinary-serial DeepSeek tool-map slice is live-green under
scratch/rust-host-live/tool-fourway-20260825/ at cc1bf0f. The producer
fixture used OpenAI Chat, no-think, pair_values(a: integer, b: integer), and
asserted finish_reason=tool_calls; literal tool_choice=required was not
used because that path ends in the same tool parse error on the C oracle. C
and Rust both sampled arguments {"a":1,"b":2} with 365 prompt + 59 output
tokens, then an unrelated EVICT_OK request saved the live state.
Both hosts wrote a 25,851,198-byte record named
29cf875c11df369237f528cb8155b8d1979f5b32.kv: reason 3, ext flags 1,
model 0, payload ABI 2, 424 tokens, 1,913 text bytes, 25,848,936 payload bytes,
and a valid one-entry 297-byte KTM\x01 trailer. The rendered-text SHA-256 is
20e492de0058ac24efd1bc22b72b7467caad69d7cec8d3d0468b1bde2ddb7c11
and the payload SHA-256 is
f427f9263acf8316bf9bd9de03467a52cb77909ae16882e5316148f33cbf9c8e
for both producers. The 244-byte sampled DSML occurs in the checkpoint text
and in each trailer. The trailers differ only in the process-unique tool ID;
header timestamps are run-specific:
call_361e9fbdea60bfa15a23be22020fede1 for C and
call_aefef96b236c98f22ce68ef16d907c57 for Rust.
Each loader ran in a fresh process against an isolated copy of the selected
record. Its assistant-history arguments were deliberately reordered to
{"b":2,"a":1}, so a canonical re-render cannot match the saved prefix
without KTM restoration:
C save → Rust load PASS cached=424 computed=28 output=5 TTFT=436.9 ms
Rust save → C load PASS cached=424 computed=28 output=5 TTFT=493.1 ms
Rust save → Rust load PASS cached=424 computed=28 output=5 TTFT=435.8 ms
C save → C load PASS cached=424 computed=28 output=5 TTFT=485.8 ms
Every cell returned RESTORED_OK, finish stop, prompt tokens 452,
prefill_cached_tokens=424, and the serial OpenAI Chat route. C binary
SHA-256 was 04f25a86040940674984c35160d2e4eec7f6c6d4e30313815ce10309cd57e662;
Rust binary SHA-256 was
6e920f1d46e79ac5f733ce3243c5b1799091d80f885d57025d0fb143bf6975ef.
The complete process was sequential; every resident exited before
clear_cache, and the final host had no GPU compute application.
Intermediate-prefill continued checkpoint
The scoped DeepSeek ordinary-serial gate is live-green under
scratch/rust-host-live/intermediate-prefill-fourway-40gDCF/ at 8361116.
The deterministic OpenAI Chat/no-think producer request SHA-256 is
efecb01d300f7e4f0e67420a7e9ce3be286d9665d716c55662aaa67e0ce79fd7:
6,778 raw user tokens plus four chat-framing tokens made a 6,782-token prompt.
With ctx 8,192, cold=0, continued=4096, trim 0, and align 1, the 4,096
frontier is reached inside prefill and the final prompt plus output stays below
the next 8,192 frontier. Both producers returned PREFILL_OK, finish stop,
and the serial route.
C and Rust wrote the same
af7f4f7b6cc1a33c0ca93d55f7dc11bb08c0c507.kv:
size: 41,956,589 bytes
reason/ext: 2 / 0
model/ABI: 0 / 2
tokens/ctx: 4,096 / 8,192
text/payload: 14,617 / 41,941,920 bytes
text SHA-256: 2dfc39c82411c86cadeabdfc517d0450054a0cba7c32bf4afb2b5f197dea9384
payload SHA: 00d8719acee5341f3e92feb45347a43fa41d11f0102148c1775feffcdd318f1c
Each loader was a fresh process with an isolated copy of that one record and
continued=0. The loader request SHA-256 is
6f29e35888928f2ac2228046695f3859c2c0d816301e6574c56bcb5e3beb3443:
C save → Rust load PASS cached=4096 computed=2686 output=5 TTFT=3642.8 ms
Rust save → C load PASS cached=4096 computed=2686 output=5 TTFT=3656.3 ms
Rust save → Rust load PASS cached=4096 computed=2686 output=5 TTFT=3644.0 ms
C save → C load PASS cached=4096 computed=2686 output=5 TTFT=3729.4 ms
All cells returned RESTORED_OK, finish stop, prompt tokens 6,782, matching
prefill usage/timing counts, and the serial route; normalized semantic
SHA-256 is
7f0f6d75bd5f83e33fbd25eb224ced322825960f7e94a9467eca8ce71a125dcd.
The 86,720,111,488-byte DeepSeek V4 Flash IQ2XXS/w2Q2K model was shared.
Its SHA-256 is
ca22ae2f838e14077c22bc1c1417b71b45b5e5a3687bd96c2ac6e17fdb6261c0.
C binary SHA-256 was
04f25a86040940674984c35160d2e4eec7f6c6d4e30313815ce10309cd57e662;
Rust binary SHA-256 was
3fd0e40320d06eae6891c5399fe622df16b9dfdfa081d92dd1df1519ff003736.
Every resident exited before clear_cache; final inspection found no GPU
compute application or listener and 117 GiB available. This is a correctness
and cross-read gate, not an ABBA performance claim, and it does not itself
cover Motif/Solar callback semantics or the separately green width-1 bank lane.
Width-1 continuous-bank shutdown checkpoint
The scoped Motif-3 OpenAI Chat, no-think/no-tools bank lane is live-green under
scratch/rust-host-live/bank-fourway-20260825-093322/. e9dfd77 exposes
opaque native bank snapshots and bounded payload save/load, 0e4a178 adds the
strict-suffix bank candidate, and 15b016c owns width-1 host metadata/policy,
warm/disk admit, retirement, checkpoint/evict/shutdown persistence, and
graceful shutdown ordering. CPU/oracle/link gates at that commit were
make test-kv-parity (38 unit + 11 cross-language),
make test-server-parity (88 unit + all integration matrices), and
make ds4-server-rs. The native rolling scheduler and opaque bank payload
remain C.
The live fixture used the 94,162,541,472-byte
Motif-3-MQ87-88-FIT.gguf, ctx 8,192, max output 128, temperature 0,
thinking disabled, no tools, disk budget 2,048 MiB, minimum checkpoint 512,
cold=0, continued=0, and DS4_SERVER_BANK_CHECKPOINT=0. The C oracle
allocated two banks while Rust used --cont-width 1; every cell admitted one
request into bank 0, so this is not multi-bank evidence. Producer and loader
request SHA-256 values were a765063d... and 14042672....
C and Rust graceful-shutdown producers wrote the same
3faf064c1bf3e92ef70f356f5c1c7baeb0dd62bc.kv:
size: 301,972,407 bytes
reason/ext: 8 / 16 (bank-shutdown / EXT_BANK_REPLAY_V1)
quant/model: 2 / 3
tokens/ctx: 6,896 / 8,192
text/payload: 24,591 / 301,947,764 bytes
trailer: 0 bytes
text SHA-256: bb9a55e900337c73272f430fc3b66efa01966e6ba70fe31ec01a4e60aea9856c
payload SHA: df417b44399e62795a644431dafa537c5780a5753ab4d193d73f4c43208044c2
Each loader was a fresh process with an isolated copy of the selected record:
C save → Rust load PASS cached=6896 computed=15 output=4
Rust save → C load PASS cached=6896 computed=15 output=4
Rust save → Rust load PASS cached=6896 computed=15 output=4
C save → C load PASS cached=6896 computed=15 output=4
All four returned RESTORED_OK, finish stop, prompt tokens 6,911, and the
continuous OpenAI Chat route. The C binary SHA-256 was 04f25a86...; the Rust
four-way/ABBA binary was 287c821a... at 15b016c.
The same C-produced bank record then drove a 114-token C→Rust→Rust→C restore
ABBA. The request SHA-256 was d68b6990..., and all completion text was exact
(faf7c021...):
| Cell | Prefill tok/s | Decode tok/s | TTFT ms | Device census GiB |
|---|---|---|---|---|
| C #1 | 76.0 | 14.9 | 375.0 | 99.15 |
| Rust #1 | 76.4 | 14.8 | 388.4 | 98.82 |
| Rust #2 | 76.1 | 14.7 | 387.4 | 98.82 |
| C #2 | 76.1 | 14.9 | 398.7 | 99.15 |
C/Rust means were 76.05/76.25 tok/s prefill, 14.90/14.75 tok/s decode (-1.01%), and 386.85/387.90 ms TTFT (+0.27%), inside the provisional gate. Peak host RSS was not captured, so this is not full memory-performance closure.
Commit 98d81b9 then passed native continuous decode duration/token/step
through the opaque callback; CUDA execution and bank behavior did not change.
Its bridge/core/server/KV/link gates are green. A post-fix C→Rust short loader
cell used Rust binary 6c25d952... and returned RESTORED_OK with
cached/computed/output 6,896/15/4, 12.3 decode tok/s, and 1.25 tok/step. That
matches the C loader cells' 12.0--12.1 tok/s and 1.25 tok/step and closes the
short-response timing-porcelain discrepancy. The 114-token ABBA was not
repeated after this timing-only commit; its 15b016c binary provenance remains
explicit above.
At that historical snapshot this was not the whole Phase 4 gate. Live default configured 10,000-token/effective aligned 10,240-token reason-bank-checkpoint, live reason-bank-evict, full default-policy ABBA, multi-bank fork/partial and pin/claim behavior, bank tool/thinking/extension integration, other families and surfaces, and peak host-RSS/soak evidence remain pending. Intermediate-prefill and tool-map replay retain their separately scoped limitations above.
Phase 5 — web utility
Resource ownership (OwnedFd, TcpStream, Child, Vec<u8>)
without changing the subprocess/search contract. No Tokio.
Phase 6 — distributed
Explicit integer codecs. Wire bytes match C. Do not serialize
#[repr(C)] Rust structs.
Runtime is production-integrated through blocking Rust coordinator/worker orchestration: CLI/route, HELLO/WORK/RESULT, receive prefetch, hop relay, reconnect, and snapshot gather/scatter ordering are host-owned. Layer-slice evaluation and opaque GPU snapshot bytes stay native.
Phase 7 — server shadow
route_decide + request_compute_needs are the routing oracle.
The HTTP door (reader, native error envelopes, schema-format refusal,
/v1/models porcelain), the four JSON parsers (chat / completion /
Anthropic / Responses, tokenize/render cut off), the four tape
stream projectors plus buffered finals and incremental live DSML tool stream (OpenAI + Anthropic; Responses has no incremental tool stream in C),
enqueue/shed + job-id mint, the host-owned /metrics /v1/stats
porcelain including the memgov census format (live CUDA census +
observation via ds4_bridge_mem_*_snap when an engine is open;
absence-not-zero when unsupported), family
render including tool-schema / invoke reconstruct
(DSML / Motif / EXAONE / dots3 / Solar C oracle),
NULL-handle tokenize/sample FFI, the serial decode driver
(scripted tape, no GGUF), generated-message tool parse
(DSML / Hermes / dots3 / Solar C goldens), SemAccum stop /
no-tools cut / DSML tool_calls verdict, and finalize
tool_calls / tool_use wire, the Inc 5a/5b/5c
continuation registry (publish / resolve / hold / pin / TTL /
bank claim + serial 503/409), and corrective recovery retry
(decode_again / model-visible tool error + tag-completion
repair) are make test-server-parity.
The loaded-engine shadow now accepts and parses in client threads,
then routes jobs through a bounded FIFO to one non-Send inference
owner. Stable continuation pins, queue-inclusive TTFT, ordered
terminal publication, nonblocking bounded sends, real TCP disconnect,
slow-reader, and exactly-once settlement regressions are green at
6545d44 (make test-server-parity).
Live Motif generate: content/finish/usage-count/cache_write_tokens
match. Live CUDA census: census_supported=1 epoch=1636
weight_artifact 86.07 GiB (scratch/rust-host-live/).
Serial buffered responses emit a C-shaped timings object.
Live serial/continuous/static routing, width-2 barriers, multi-bank
fork/partial/evict/shutdown, four surfaces, tool/continuation/KV extensions,
disconnect/slow-reader handling, and the smoke/long/OPP-C proof harness are
green in the current 60-cell matrix. Qwen additionally covers image requests,
MTP, exact/configured 262K, and the two-hour soak.
Do not improve the table.
All four surfaces:
POST /v1/chat/completions
POST /v1/completions
POST /v1/messages
POST /v1/responses
plus /v1/models, /v1/stats, /metrics.
Preserve ID formats (including the documented Anthropic
chatcmpl-N quirk), finish_reason mapping, native error
envelopes, stream event order, continuation / trust-domain
semantics, chunked bodies, typed schema-format refusal (v0.6.3).
Replay the ds4_test --server fixture inventory listed in the API
matrix. Live gates follow that document, not byte dumps.
Phase 8 — ds4.c leaves
| Slice | Gate |
|---|---|
| Model metadata | enum/shape values match g_ds4_shape / catalog — green (make test-catalog-parity) |
| GGUF catalog | mmap; no full-file Vec<u8>; first-shard split.count identity — green on synthetic v3; host weights_bind name catalog + bind-plan check/match + host tensor-dir apply (skip parse_tensors when installed) + host config_validate / apply shape+compress (skip C validate when installed) + host bind map (skip C name walk when installed) + host weights_validate_layout (skip C main-model layout when bind map installed) + host MTP/DSpark sibling name/layout catalogs + sibling BindPlan resolve/validate + sibling bind map FFI (native swaps the sibling map around its own open+bind window and skips that sibling's C layout check; live DSpark drafter 81/81 + Rust --dspark decode green) + host-table clear before sibling model_open green; sibling pointer assignment / CUDA upload still native |
| Tokenizer | encode/decode/special/template/stop exact token ids — green on synthetic GGUF (make test-tokenizer-parity); family chat transcript framing is exact for DeepSeek, Motif-3, Solar Open2, EXAONE, and Dots3 across none/low/high/max think modes, with byte payload and malformed-control errors covered; host vocab apply (skip C vocab_load when installed) + Model host tokenize green; live Motif specials + encode hi→8320 |
| Session | ownership + sync/eval/rewind/payload — ledger + DSV4 prefix green (make test-session-parity: rewrite/prefix/plan/rewind/generation + header/token tapes); GPU/logits tail / CUDA eval still native |
| Backend dispatch | CUDA path unchanged; no extra dynamic dispatch on the hot path |
Proof harness (any phase that can touch CUDA execution)
make proof-cuda-smoke
make proof-cuda-long
make proof-cuda-opp-c
make proof-rust-cuda-opp-c
proof-cuda-opp-c remains the native-drift gate against a tracked
golden. A persisted CUDA_ARCH=sm_121 build selects the GB10 snapshot
validated against the v0.6.5-dfm/Qwen C cut; the older v0.6.3 snapshot is
retained under its own namespace. Other builds keep their original generic
snapshot and require separate architecture approval. proof-rust-cuda-opp-c
is the separate host-parity gate: it writes a temporary snapshot with the
current C oracle, then checks the Rust binary through the same stable runner
path. Its artifacts remain under /tmp/ds4_proof/proof-rust-cuda-opp-c.*
for audit; it does not rewrite or replace either tracked native golden.
Both OPP-C gates must be green before the Rust execution path becomes default. Long-context captured-vs-eager stays a release gate.
Phase 9 / split
See work instruction §26. SPLIT_READINESS.md is now green because Runtime,
Correctness, Performance, and Architecture (unsafe confined to reviewed
FFI/native/OS adapters) passed the current audit.
rg -n 'unsafe \{' crates/
Almost every hit must sit in crates/ds4-sys or a native adapter.
Family regression set (must stay green)
Makefile variables, not flags:
| Family | Targets |
|---|---|
| Motif-3 | test-motif3-{loader,reference,tokenizer,cuda,resident,batch} |
| Solar | test-solar-{loader,tokenizer,forward,session,kda,kda-prefill,kda-chunk,gates,kv} |
| K-EXAONE | test-exaone-{ref,kernels,batch} |
| dots3-note | test-dots3-{loader,tokenizer,resident} |
| Qwen3.8 Flash Next | test-qwen4exp-{loader,tokenizer,ple,ple-cuda,primitives,hc-forward,ple-compute,qsa,qsa-forward,moe,moe-forward,gdn,gdn-forward,batch} on Q5+Sidecar |
| Shared | test-model-family-kernels, test-mmq-parity |
Resident tests load real weights. Use tmux + workspace-local
../scripts/guarded-run.sh (outside this repository).
One resident model at a time.
Performance protocol
Same host, same artifact, clocks recorded.
Minimum order:
C → Rust → Rust → C
or ABBA. Publish SHA + GGUF identity + command/env with the numbers. Unexplained 2–3% is a fail even if it sits inside the provisional percent table.
Recorded ABBA (2026-08-31, Qwen Q5+Sidecar)
Candidate 6ca85c8, C Qwen cut 4d40d97, Q5 three-shard main GGUF plus the
shared four-file SSD-PLE Sidecar, ctx 196,608, two banks, prefill chunk 8,192,
embedded MTP draft 2, temperature 0. Every cell used a fresh owner/worker pair;
C and Rust were never resident together, and clear_cache ran only after both
PIDs exited.
All text cells returned the same 64-token output (SHA-256 3ab21f93...):
| Cell | Prefill tok/s | Decode tok/s | TTFT ms | Worker VmHWM KiB | Worker GPU MiB |
|---|---|---|---|---|---|
| C #1 | 519.7 | 14.4 | 7,954.7 | 1,852,404 | 23,471 |
| Rust #1 | 518.6 | 14.5 | 8,044.9 | 1,933,444 | 23,471 |
| Rust #2 | 518.8 | 14.4 | 8,041.3 | 1,929,004 | 23,471 |
| C #2 | 518.0 | 14.5 | 7,979.9 | 1,847,240 | 23,471 |
Rust/C means were 99.97% prefill, 100.00% decode, +0.95% TTFT, +4.40%
worker VmHWM, and identical GPU residency. All four image cells returned
MEN WALK ON MOON (SHA-256 991530ac...); Rust/C means were 100.20% image
prefill and +0.32% image TTFT. The six-token image decode sample is not used
as a performance gate.
Recorded ABBA (2026-08-24, cross-lane)
Host SHA 9463b3c (+ scratch runner scratch/rust-host-live/abba.sh),
GGUF Motif-3-MQ87-88-FIT.gguf, ctx 8192, cold 6782-token prompt,
114 decode tokens, temp 0, thinking disabled, sequential loads with
teardown + clear_cache between cells:
| Cell | Lane | prefill tok/s | decode tok/s | ttft ms | peak GPU MiB |
|---|---|---|---|---|---|
| C #1 | continuous | 633.4 | 14.8 | 10755 | 112145 |
| Rust #1 | serial | 579.8 | 15.4 | 11834 | 102357 |
| Rust #2 | serial | 577.5 | 15.5 | 11877 | 102357 |
| C #2 | continuous | 633.0 | 14.8 | 10780 | 114529 |
All four completions are byte-identical greedy text (SHA1
4d34f24352e7) — the Token axis passes across hosts and lanes.
Pair spreads are ≤0.4%. The −8.6% prefill / +4.4% decode delta was
attributed to the lane difference and re-measured after the
continuous port (below).
Recorded ABBA (2026-08-24, same lane: both continuous)
Same protocol, ds4-server-rs --cont-width 2 routing
openai_chat_continuous, all four completions byte-identical
(same SHA1 4d34f24352e7):
| Cell | Lane | prefill tok/s | decode tok/s | ttft ms |
|---|---|---|---|---|
| C #1 | continuous | 579.2 | 14.9 | 11767 |
| Rust #1 | continuous | 590.8 | 14.8 | 11521 |
| Rust #2 | continuous | 592.9 | 14.7 | 11480 |
| C #2 | continuous | 633.9 | 14.9 | 10751 |
Rust pair spread 0.4%; the C pair spread is 9.0% (579/634 — the cross-lane run's C pair sat at 633.4/633.0), so the −2.4% Rust mean prefill delta is inside the C cell noise; decode is within 1%. No unexplained regression. At that recorded snapshot Rust continuous still had one active job: client ingress is concurrent behind the FIFO, but the sole owner runs each job to completion. The rolling scheduler, bank admit, per-seq eos, and engine usage split are the same native path; live multi-client width and the Anthropic/Responses cont promotion are follow-ups.
Recorded ABBA (2026-08-24, local benchmark shadow)
Host commit a9ba7b38cbf683f03c21e2604e055356ec2a2ad2
(v0.6.3-dfm), NVIDIA GB10, driver 610.43.02, CUDA 13.3. C binary
SHA-256 3c0af3d1d860cf3d2800261d51e729c3ca96aae3d048551ed721ed717aed0f8c;
Rust binary SHA-256
a66d97c48755af0e54178c57a5d70765019eade45cb9a038ccfd5615c940dae3.
Model artifact:
DeepSeek-V4-Flash-IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8-chat-v2-imatrix-0731.gguf
(86,720,111,488 bytes; model label DeepSeek V4 Flash, revision label
0731-chat-v2, quant label IQ2XXS-w2Q2K-AProjQ8-SExpQ8-OutQ8).
Order was C → Rust → Rust → C with teardown and clear_cache between
cells. Both binaries used the same raw prompt, frontiers 1024→2048,
ctx_alloc=2081, 32 decode tokens, width 1, and default packed FP8 KV
- FP4 index; no
DS4_*override was set. Logs and CSVs are underscratch/rust-host-live/bench-abba-20260824/.
$BIN --cuda -m "$MODEL" --prompt-file tests/long_context_essay_prompt.txt \
--ctx-start 1024 --ctx-max 2048 --ctx-alloc 2081 --step-incr 1024 \
--gen-tokens 32 --csv "$CELL.csv"
| Cell | Frontier | Prefill tok/s | Decode tok/s | Steady decode tok/s | First decode token s | Host max RSS KiB | KV bytes |
|---|---|---|---|---|---|---|---|
| C #1 | 1024 | 838.58 | 22.78 | 22.94 | 0.0531 | 8,972,888 | 28,482,336 |
| C #1 | 2048 | 945.37 | 23.10 | 23.10 | 0.0433 | 8,972,888 | 32,968,864 |
| Rust #1 | 1024 | 850.48 | 22.83 | 22.96 | 0.0517 | 9,024,668 | 28,482,336 |
| Rust #1 | 2048 | 953.26 | 23.10 | 23.10 | 0.0433 | 9,024,668 | 32,968,864 |
| Rust #2 | 1024 | 845.62 | 22.88 | 23.01 | 0.0518 | 9,025,144 | 28,482,336 |
| Rust #2 | 2048 | 954.29 | 22.93 | 22.92 | 0.0433 | 9,025,144 | 32,968,864 |
| C #2 | 1024 | 843.66 | 22.91 | 23.06 | 0.0523 | 8,972,584 | 28,482,336 |
| C #2 | 2048 | 947.30 | 23.10 | 23.11 | 0.0439 | 8,972,584 | 32,968,864 |
Rust/C mean ratios were 100.82% / 100.79% prefill and 100.04% / 99.63% decode at the two frontiers. Rust host max RSS was +0.58%; KV bytes matched exactly. This passes the Phase 3 FFI-overhead thresholds. GPU resident peak was not sampled, so this is not the full pre-split performance gate.
Status of this matrix
The superseded subsystem status is available as an archived snapshot. Current release gates belong in the v0.1.0 ledger.