Skip to main content

memra_cli/
lib.rs

1use memra_gguf::GgufFile;
2use memra_gguf::config::{HfConfig, ModelConfig};
3use memra_gguf::model_packs::{self, Gate, ModelPack, TokenizerSource};
4use memra_gguf::placement::{LayerPlacementCost, PlacementRequest, plan_contiguous_stages};
5use memra_gguf::safetensors::{
6    StInfo, StModel, parse_header_json_checked, parse_index_weight_map_json_checked,
7};
8#[cfg(test)]
9use memra_gguf::source::canonical_hf_name;
10use memra_gguf::source::{
11    Hy3RepackSource, TensorCensusRecord, TensorSource, census_from_gguf,
12    census_from_safetensors_headers,
13};
14use memra_gguf::tensor_contract::{
15    BoundTensorContract, CheckpointDialect, ContractOptions, OutputHead, TensorId, TensorOwner,
16};
17use memra_reference::{deterministic_fixture, execute, execute_multimodal, execute_vision};
18use sha2::{Digest, Sha256};
19use std::collections::BTreeMap;
20use std::fmt::Write as _;
21use std::io::Write as _;
22use std::path::{Path, PathBuf};
23use std::process::{Command, Output, Stdio};
24
25const MAX_TEXT_BYTES: usize = 100_000_000;
26
27pub struct InspectRequest {
28    pub source: String,
29    pub against: String,
30    pub out_dir: PathBuf,
31}
32
33pub struct InspectSummary {
34    pub family: &'static str,
35    pub tensor_count: usize,
36    pub out_dir: PathBuf,
37}
38
39pub struct ScaffoldRequest {
40    pub family: String,
41    pub out_dir: PathBuf,
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45pub enum VerifyStage {
46    Config,
47    Tiny,
48    Checkpoint,
49    Rewrite,
50    Serve,
51}
52
53pub struct VerifyRequest {
54    pub stage: VerifyStage,
55    pub source: String,
56    pub against: String,
57    pub out_dir: Option<PathBuf>,
58    pub oracle: Option<PathBuf>,
59    pub native_runner: Option<PathBuf>,
60}
61
62pub struct VerifySummary {
63    pub family: &'static str,
64    pub stage: VerifyStage,
65}
66
67pub fn verify_model(request: VerifyRequest) -> Result<VerifySummary, Box<dyn std::error::Error>> {
68    match request.stage {
69        VerifyStage::Config => {
70            let pack = model_packs::by_alias(&request.against)
71                .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
72            let config = load_config_only(&request.source)?;
73            pack.compile_plan(&config)?;
74            Ok(VerifySummary {
75                family: pack.family,
76                stage: VerifyStage::Config,
77            })
78        }
79        VerifyStage::Checkpoint => {
80            let pack = model_packs::by_alias(&request.against)
81                .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
82            let out_dir = request.out_dir.ok_or("verify checkpoint requires --out")?;
83            let summary = inspect_model(InspectRequest {
84                source: request.source.clone(),
85                against: request.against.clone(),
86                out_dir: out_dir.clone(),
87            })?;
88            write_hf_oracle_bundle(&request.source, &out_dir)?;
89            let gate = pack.checkpoint_parity.ok_or_else(|| {
90                format!(
91                    "model pack {} has no checkpoint parity threshold; capture bundle written to {} and no fallback is allowed",
92                    pack.family,
93                    out_dir.display()
94                )
95            })?;
96            let oracle_path = request.oracle.ok_or_else(|| {
97                format!(
98                    "checkpoint tensor contract passed; run {} offline, then repeat with --oracle <hf-oracle.tsv>; no fallback is allowed",
99                    out_dir.join("capture-hf-oracle.py").display()
100                )
101            })?;
102            let runner = request
103                .native_runner
104                .or_else(|| std::env::var_os("MEMRA_NATIVE_CHECKPOINT_RUNNER").map(PathBuf::from))
105                .ok_or("checkpoint parity requires --native-runner or MEMRA_NATIVE_CHECKPOINT_RUNNER; no fallback is allowed")?;
106            let native_path = out_dir.join("native-oracle.tsv");
107            run_native_checkpoint(&runner, &request.source, &native_path)?;
108            let runner_hash = hex_sha256(&std::fs::read(&runner)?);
109            let expected = parse_checkpoint_oracle(&std::fs::read_to_string(&oracle_path)?)?;
110            let actual = parse_checkpoint_oracle(&std::fs::read_to_string(&native_path)?)?;
111            let receipt = match compare_checkpoint_oracles(&expected, &actual, gate) {
112                Ok(receipt) => receipt,
113                Err(error) => {
114                    write_atomic(
115                        &out_dir.join("checkpoint-parity.tsv"),
116                        format!(
117                            "status\tfailed\nerror\t{}\n",
118                            lock_value(&error.to_string())
119                        )
120                        .as_bytes(),
121                    )?;
122                    write_atomic(
123                        &out_dir.join("gates.txt"),
124                        format_gate_results_with_receipts(
125                            pack,
126                            &out_dir,
127                            &[Gate::Config, Gate::TokenizerTemplate, Gate::TensorCensus],
128                            &[Gate::CheckpointParity],
129                        )
130                        .as_bytes(),
131                    )?;
132                    return Err(error);
133                }
134            };
135            let artifact_lock = std::fs::read(out_dir.join("artifact.lock"))?;
136            let receipt = format!(
137                "{receipt}artifact_lock_sha256\t{}\nnative_runner_sha256\t{runner_hash}\n",
138                hex_sha256(&artifact_lock)
139            );
140            write_atomic(&out_dir.join("checkpoint-parity.tsv"), receipt.as_bytes())?;
141            write_atomic(
142                &out_dir.join("gates.txt"),
143                format_gate_results_with_receipts(
144                    pack,
145                    &out_dir,
146                    &[
147                        Gate::Config,
148                        Gate::TokenizerTemplate,
149                        Gate::TensorCensus,
150                        Gate::CheckpointParity,
151                    ],
152                    &[],
153                )
154                .as_bytes(),
155            )?;
156            Ok(VerifySummary {
157                family: summary.family,
158                stage: VerifyStage::Checkpoint,
159            })
160        }
161        VerifyStage::Tiny => {
162            let pack = model_packs::by_alias(&request.against)
163                .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
164            if pack.support.is_none() {
165                return Err(format!(
166                    "model pack {} is inspect-only and has no native support state",
167                    pack.family
168                )
169                .into());
170            }
171            let out_dir = request.out_dir.ok_or("verify tiny requires --out")?;
172            let plan = pack.compile_tiny_plan()?;
173            let fixture = deterministic_fixture(&plan)?;
174            let first = execute(&plan, &fixture.weights, &fixture.token_ids)?;
175            let second = execute(&plan, &fixture.weights, &fixture.token_ids)?;
176            if first != second {
177                return Err("native reference fixture is not bit-deterministic".into());
178            }
179            let vision = fixture
180                .vision
181                .as_ref()
182                .map(|input| {
183                    let first = execute_vision(&plan, &fixture.weights, input)?;
184                    let second = execute_vision(&plan, &fixture.weights, input)?;
185                    if first != second {
186                        return Err(ReferenceVisionError::Nondeterministic);
187                    }
188                    Ok(first)
189                })
190                .transpose()
191                .map_err(|error| -> Box<dyn std::error::Error> { error.into() })?;
192            let multimodal = match (
193                fixture.multimodal_token_ids.as_ref(),
194                fixture.vision.as_ref(),
195            ) {
196                (Some(token_ids), Some(input)) => {
197                    let first = execute_multimodal(&plan, &fixture.weights, token_ids, input)?;
198                    let second = execute_multimodal(&plan, &fixture.weights, token_ids, input)?;
199                    if first != second {
200                        return Err(
201                            "native multimodal reference fixture is not bit-deterministic".into(),
202                        );
203                    }
204                    Some(first)
205                }
206                (None, None) | (None, Some(_)) if plan.multimodal.is_none() => None,
207                _ => {
208                    return Err(
209                        "multimodal plan is missing its combined tiny fixture inputs".into(),
210                    );
211                }
212            };
213            std::fs::create_dir_all(&out_dir)?;
214            write_atomic(
215                &out_dir.join("tiny-fixture.txt"),
216                format_tiny_fixture(&plan, &fixture).as_bytes(),
217            )?;
218            write_atomic(
219                &out_dir.join("reference-oracle.tsv"),
220                format_reference_oracle(&first).as_bytes(),
221            )?;
222            if let Some(vision) = vision.as_ref() {
223                write_atomic(
224                    &out_dir.join("reference-vision-oracle.tsv"),
225                    format_reference_vision_oracle(vision).as_bytes(),
226                )?;
227            }
228            if let Some(multimodal) = multimodal.as_ref() {
229                write_atomic(
230                    &out_dir.join("reference-multimodal-oracle.tsv"),
231                    format_reference_oracle(&multimodal.language).as_bytes(),
232                )?;
233            }
234            write_atomic(
235                &out_dir.join("tiny-gate.tsv"),
236                format!("status\tpassed\nfamily\t{}\n", pack.family).as_bytes(),
237            )?;
238            write_atomic(
239                &out_dir.join("gates.txt"),
240                format_gate_results_with_receipts(
241                    pack,
242                    &out_dir,
243                    &[Gate::Config, Gate::TinyParity],
244                    &[],
245                )
246                .as_bytes(),
247            )?;
248            Ok(VerifySummary {
249                family: pack.family,
250                stage: VerifyStage::Tiny,
251            })
252        }
253        VerifyStage::Rewrite => {
254            let pack = model_packs::by_alias(&request.against)
255                .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
256            let out_dir = request
257                .out_dir
258                .ok_or("verify rewrite requires --out; no fallback is allowed")?;
259            verify_rewrite_receipt(pack, Path::new(&request.source), &out_dir)?;
260            Ok(VerifySummary {
261                family: pack.family,
262                stage: VerifyStage::Rewrite,
263            })
264        }
265        VerifyStage::Serve => {
266            let pack = model_packs::by_alias(&request.against)
267                .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
268            let out_dir = request
269                .out_dir
270                .ok_or("verify serve requires --out; no fallback is allowed")?;
271            let runner = request
272                .native_runner
273                .or_else(|| std::env::var_os("MEMRA_NATIVE_SERVE_RUNNER").map(PathBuf::from))
274                .ok_or("verify serve requires --native-runner or MEMRA_NATIVE_SERVE_RUNNER; no fallback is allowed")?;
275            verify_native_serve(pack, &request.source, &out_dir, &runner)?;
276            Ok(VerifySummary {
277                family: pack.family,
278                stage: VerifyStage::Serve,
279            })
280        }
281    }
282}
283
284fn verify_rewrite_receipt(
285    pack: &ModelPack,
286    receipt_path: &Path,
287    out_dir: &Path,
288) -> Result<(), Box<dyn std::error::Error>> {
289    let artifact_lock = std::fs::read_to_string(out_dir.join("artifact.lock"))?;
290    let artifact_lock_sha256 = hex_sha256(artifact_lock.as_bytes());
291    if !artifact_lock
292        .lines()
293        .any(|line| line == format!("family={}", pack.family))
294    {
295        return Err("rewrite receipt family does not match artifact.lock".into());
296    }
297    let manifest = std::fs::read_to_string(out_dir.join("execution-rewrites.tsv"))?;
298    let receipt = std::fs::read_to_string(receipt_path)?;
299    let mut fields = BTreeMap::new();
300    for line in receipt.lines() {
301        let Some((key, value)) = line.split_once('\t') else {
302            return Err(format!("malformed rewrite receipt line {line:?}").into());
303        };
304        if fields.insert(key, value).is_some() {
305            return Err(format!("duplicate rewrite receipt field {key}").into());
306        }
307    }
308    for (key, expected) in [
309        ("format", "memra-rewrite-parity-v1"),
310        ("status", "passed"),
311        ("first_violation", "none"),
312    ] {
313        if fields.get(key).copied() != Some(expected) {
314            return Err(format!("rewrite receipt requires {key}={expected}").into());
315        }
316    }
317    match fields.get("value_kind").copied() {
318        Some("logits-f32") if fields.get("require_argmax").copied() == Some("true") => {}
319        Some("token-ids-u32") if fields.get("require_argmax").copied() == Some("false") => {}
320        _ => return Err("rewrite receipt has an invalid value_kind/argmax policy".into()),
321    }
322    let rewrite_id = *fields.get("rewrite").ok_or("rewrite receipt has no id")?;
323    let row = manifest
324        .lines()
325        .skip(1)
326        .find(|line| line.split('\t').next() == Some(rewrite_id))
327        .ok_or_else(|| format!("rewrite {rewrite_id} is absent from execution manifest"))?;
328    let columns: Vec<_> = row.split('\t').collect();
329    if columns.len() != 8 || columns[4] != "true" {
330        return Err(format!("rewrite {rewrite_id} is not eligible in this artifact").into());
331    }
332    for (field, expected) in [
333        ("surface", columns[1]),
334        ("implementation", columns[2]),
335        ("plan_sha256", columns[3]),
336    ] {
337        if fields.get(field).copied() != Some(expected) {
338            return Err(format!("rewrite receipt {field} does not match manifest").into());
339        }
340    }
341    if fields.get("artifact_lock_sha256").copied() != Some(artifact_lock_sha256.as_str()) {
342        return Err("rewrite receipt does not match artifact.lock".into());
343    }
344    let reference = fields
345        .get("reference_sha256")
346        .ok_or("rewrite receipt has no reference hash")?;
347    let candidate = fields
348        .get("candidate_sha256")
349        .ok_or("rewrite receipt has no candidate hash")?;
350    let parse_nonnegative = |field: &str| -> Result<f32, Box<dyn std::error::Error>> {
351        let value = fields
352            .get(field)
353            .ok_or_else(|| format!("rewrite receipt has no {field}"))?
354            .parse::<f32>()?;
355        if !value.is_finite() || value < 0.0 {
356            return Err(format!("rewrite receipt {field} is not finite and nonnegative").into());
357        }
358        Ok(value)
359    };
360    let atol = parse_nonnegative("atol")?;
361    let rtol = parse_nonnegative("rtol")?;
362    let max_abs = parse_nonnegative("max_abs")?;
363    let _max_rel = parse_nonnegative("max_rel")?;
364    if atol == 0.0 && rtol == 0.0 && (max_abs != 0.0 || reference != candidate) {
365        return Err("exact rewrite receipt has nonzero error or different stream hashes".into());
366    }
367    for field in [
368        "implementation_sha256",
369        "reference_sha256",
370        "candidate_sha256",
371    ] {
372        let value = fields[field];
373        if value.len() != 64
374            || !value
375                .bytes()
376                .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
377        {
378            return Err(format!("rewrite receipt {field} is not a lowercase SHA-256").into());
379        }
380    }
381    if fields
382        .get("values")
383        .and_then(|value| value.parse::<usize>().ok())
384        .is_none_or(|values| values == 0)
385    {
386        return Err("rewrite receipt compared no values".into());
387    }
388    let receipt_hash = hex_sha256(receipt.as_bytes());
389    let receipt_dir = out_dir.join("rewrite-receipts");
390    std::fs::create_dir_all(&receipt_dir)?;
391    write_atomic(
392        &receipt_dir.join(format!("{rewrite_id}.tsv")),
393        receipt.as_bytes(),
394    )?;
395    let index_path = out_dir.join("rewrite-receipts.tsv");
396    let mut index = BTreeMap::new();
397    if let Ok(existing) = std::fs::read_to_string(&index_path) {
398        for line in existing.lines().skip(1) {
399            let columns: Vec<_> = line.split('\t').collect();
400            if columns.len() == 4 {
401                index.insert(
402                    columns[0].to_string(),
403                    (
404                        columns[1].to_string(),
405                        columns[2].to_string(),
406                        columns[3].to_string(),
407                    ),
408                );
409            }
410        }
411    }
412    index.insert(
413        rewrite_id.to_string(),
414        (columns[3].to_string(), receipt_hash, "passed".to_string()),
415    );
416    let mut index_text = String::from("rewrite\tplan_sha256\treceipt_sha256\tstatus\n");
417    for (rewrite, (plan, hash, status)) in index {
418        writeln!(index_text, "{rewrite}\t{plan}\t{hash}\t{status}").unwrap();
419    }
420    write_atomic(&index_path, index_text.as_bytes())?;
421    write_atomic(
422        &out_dir.join("gates.txt"),
423        format_gate_results_with_receipts(pack, out_dir, &[], &[]).as_bytes(),
424    )?;
425    Ok(())
426}
427
428fn verify_native_serve(
429    pack: &ModelPack,
430    source: &str,
431    out_dir: &Path,
432    runner: &Path,
433) -> Result<(), Box<dyn std::error::Error>> {
434    if !Path::new(source).exists() {
435        return Err("verify serve requires a local model artifact; no fallback is allowed".into());
436    }
437    let checkpoint_receipt = out_dir.join("checkpoint-parity.tsv");
438    let artifact_lock_path = out_dir.join("artifact.lock");
439    let artifact_lock = std::fs::read_to_string(&artifact_lock_path).map_err(|error| {
440        format!(
441            "verify serve requires {} from inspect/checkpoint first: {error}; no fallback is allowed",
442            artifact_lock_path.display()
443        )
444    })?;
445    if !artifact_lock
446        .lines()
447        .any(|line| line == format!("source={}", lock_value(source)))
448        || !artifact_lock.lines().any(|line| line == "binding=passed")
449        || !artifact_lock.lines().any(|line| line == "tokenizer=passed")
450    {
451        return Err(
452            "verify serve artifact.lock does not match this source with binding/tokenizer passed; no fallback is allowed"
453                .into(),
454        );
455    }
456    let checkpoint = std::fs::read_to_string(&checkpoint_receipt).map_err(|error| {
457        format!(
458            "verify serve requires a passed {} first: {error}; no fallback is allowed",
459            checkpoint_receipt.display()
460        )
461    })?;
462    if !checkpoint.lines().any(|line| line == "status\tpassed") {
463        return Err(
464            "verify serve requires status=passed checkpoint parity; no fallback is allowed".into(),
465        );
466    }
467    let lock_hash = hex_sha256(artifact_lock.as_bytes());
468    if !checkpoint
469        .lines()
470        .any(|line| line == format!("artifact_lock_sha256\t{lock_hash}"))
471    {
472        return Err(
473            "verify serve checkpoint receipt does not match artifact.lock; no fallback is allowed"
474                .into(),
475        );
476    }
477    std::fs::create_dir_all(out_dir)?;
478    let listener = std::net::TcpListener::bind("127.0.0.1:0")?;
479    let port = listener.local_addr()?.port();
480    drop(listener);
481    let address = format!("127.0.0.1:{port}");
482    let api_key = "memra-onboarding-verify";
483    let log_path = out_dir.join("serve.log");
484    let log = std::fs::File::create(&log_path)?;
485    let mut child = Command::new(runner)
486        .env("MEMRA_MODELS", format!("verify={source}"))
487        .env("MEMRA_REWRITE_BUNDLE", out_dir)
488        .env("MEMRA_ADDR", &address)
489        .env("MEMRA_API_KEY", api_key)
490        .stdin(Stdio::null())
491        .stdout(Stdio::from(log.try_clone()?))
492        .stderr(Stdio::from(log))
493        .spawn()?;
494    let result = (|| -> Result<String, Box<dyn std::error::Error>> {
495        let timeout = std::env::var("MEMRA_SERVE_VERIFY_TIMEOUT_S")
496            .ok()
497            .and_then(|value| value.parse::<u64>().ok())
498            .unwrap_or(180);
499        let started = std::time::Instant::now();
500        loop {
501            if let Some(status) = child.try_wait()? {
502                return Err(format!(
503                    "native server exited before readiness with {status}; inspect {}",
504                    log_path.display()
505                )
506                .into());
507            }
508            let ready = Command::new("curl")
509                .args([
510                    "--fail",
511                    "--silent",
512                    "--output",
513                    "/dev/null",
514                    &format!("http://{address}/readyz"),
515                ])
516                .status();
517            if ready.is_ok_and(|status| status.success()) {
518                break;
519            }
520            if started.elapsed() >= std::time::Duration::from_secs(timeout) {
521                return Err(format!(
522                    "native server did not become ready within {timeout}s; inspect {}",
523                    log_path.display()
524                )
525                .into());
526            }
527            std::thread::sleep(std::time::Duration::from_millis(250));
528        }
529        let response = Command::new("curl")
530            .args([
531                "--fail",
532                "--silent",
533                "--show-error",
534                "--header",
535                &format!("Authorization: Bearer {api_key}"),
536                "--header",
537                "Content-Type: application/json",
538                "--data",
539                r#"{"model":"verify","prompt":"Hello","max_tokens":1,"temperature":0}"#,
540                &format!("http://{address}/v1/completions"),
541            ])
542            .output()?;
543        if !response.status.success() {
544            return Err(format!(
545                "native completion failed with {}: {}",
546                response.status,
547                String::from_utf8_lossy(&response.stderr)
548            )
549            .into());
550        }
551        let response = String::from_utf8(response.stdout)?;
552        if !response.contains("\"choices\"") || response.contains("\"error\"") {
553            return Err(format!("native completion response is not successful: {response}").into());
554        }
555        Ok(response)
556    })();
557    let _ = child.kill();
558    let _ = child.wait();
559    let response = result?;
560    let runner_hash = hex_sha256(&std::fs::read(runner)?);
561    write_atomic(&out_dir.join("serve-response.json"), response.as_bytes())?;
562    write_atomic(
563        &out_dir.join("serve-gate.tsv"),
564        format!(
565            "status\tpassed\nfamily\t{}\nmodel\tverify\nendpoint\t/v1/completions\nartifact_lock_sha256\t{lock_hash}\nnative_runner_sha256\t{runner_hash}\n",
566            pack.family,
567        )
568        .as_bytes(),
569    )?;
570    write_atomic(
571        &out_dir.join("gates.txt"),
572        format_gate_results_with_receipts(
573            pack,
574            out_dir,
575            &[
576                Gate::Config,
577                Gate::TokenizerTemplate,
578                Gate::TensorCensus,
579                Gate::CheckpointParity,
580                Gate::Serve,
581            ],
582            &[],
583        )
584        .as_bytes(),
585    )?;
586    Ok(())
587}
588
589#[derive(Debug, Clone, PartialEq)]
590struct CheckpointOracle {
591    engine: String,
592    numeric_class: String,
593    tokens: Vec<u32>,
594    vocab: usize,
595    logits: Vec<f32>,
596}
597
598fn write_hf_oracle_bundle(source: &str, out_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
599    let tokens = [1u32, 2, 3, 4];
600    let (model, revision) = if Path::new(source).exists() {
601        (source.to_string(), None)
602    } else {
603        let (model, revision) = parse_pinned_hf_source(source)?;
604        (model.to_string(), Some(revision.to_string()))
605    };
606    let request = format!(
607        "format\tmemra-checkpoint-request-v1\nsource\t{}\nrevision\t{}\nnumeric_class\tsource-weights-float32-accumulation\ntokens\t{}\n",
608        lock_value(&model),
609        revision.as_deref().unwrap_or("local"),
610        tokens
611            .iter()
612            .map(u32::to_string)
613            .collect::<Vec<_>>()
614            .join(",")
615    );
616    write_atomic(&out_dir.join("oracle-request.tsv"), request.as_bytes())?;
617    let model_literal = format!("{model:?}");
618    let revision_literal = revision
619        .as_ref()
620        .map(|revision| format!("{revision:?}"))
621        .unwrap_or_else(|| "None".to_string());
622    let script = format!(
623        r#"#!/usr/bin/env python3
624import argparse
625import struct
626import torch
627import transformers
628from transformers import AutoModelForCausalLM
629
630MODEL = {model_literal}
631REVISION = {revision_literal}
632TOKENS = [1, 2, 3, 4]
633
634parser = argparse.ArgumentParser(description="Offline HF correctness oracle for Memra onboarding")
635parser.add_argument("--out", default="hf-oracle.tsv")
636args = parser.parse_args()
637
638model = AutoModelForCausalLM.from_pretrained(
639    MODEL,
640    revision=REVISION,
641    dtype=torch.float32,
642    trust_remote_code=False,
643)
644device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
645model = model.to(device).eval()
646with torch.no_grad():
647    logits = model(input_ids=torch.tensor([TOKENS], device=device)).logits[0, -1].float().cpu()
648
649with open(args.out, "w", encoding="utf-8") as f:
650    f.write("format\tmemra-checkpoint-oracle-v1\n")
651    f.write("engine\thf-transformers-fp32\n")
652    f.write("numeric_class\tsource-weights-float32-accumulation\n")
653    f.write(f"transformers_version\t{{transformers.__version__}}\n")
654    f.write(f"torch_version\t{{torch.__version__}}\n")
655    f.write("tokens\t" + ",".join(map(str, TOKENS)) + "\n")
656    f.write(f"vocab\t{{logits.numel()}}\n")
657    for index, value in enumerate(logits.tolist()):
658        bits = struct.unpack("<I", struct.pack("<f", value))[0]
659        f.write(f"logit\t{{index}}\t{{bits:08x}}\n")
660"#
661    );
662    write_atomic(&out_dir.join("capture-hf-oracle.py"), script.as_bytes())?;
663    Ok(())
664}
665
666fn run_native_checkpoint(
667    runner: &Path,
668    source: &str,
669    output: &Path,
670) -> Result<(), Box<dyn std::error::Error>> {
671    if !Path::new(source).is_dir() {
672        return Err(
673            "native checkpoint parity requires a local safetensors directory; inspect may use a pinned remote header, execution may not"
674                .into(),
675        );
676    }
677    let result = Command::new(runner)
678        .arg(source)
679        .args(["1", "2", "3", "4"])
680        .env("MEMRA_FULL_PREC", "1")
681        .env("MEMRA_ORACLE_OUT", output)
682        .output()?;
683    if !result.status.success() {
684        return Err(format!(
685            "native checkpoint runner failed ({}): stdout={} stderr={}",
686            result.status,
687            String::from_utf8_lossy(&result.stdout),
688            String::from_utf8_lossy(&result.stderr)
689        )
690        .into());
691    }
692    if !output.is_file() {
693        return Err(format!(
694            "native checkpoint runner did not create {}",
695            output.display()
696        )
697        .into());
698    }
699    Ok(())
700}
701
702fn parse_checkpoint_oracle(text: &str) -> Result<CheckpointOracle, Box<dyn std::error::Error>> {
703    let mut format_ok = false;
704    let mut engine = None;
705    let mut numeric_class = None;
706    let mut tokens = None;
707    let mut vocab = None;
708    let mut logits = BTreeMap::new();
709    for line in text.lines() {
710        let fields: Vec<_> = line.split('\t').collect();
711        match fields.as_slice() {
712            ["format", "memra-checkpoint-oracle-v1"] => format_ok = true,
713            ["engine", value] => engine = Some((*value).to_string()),
714            ["numeric_class", value] => numeric_class = Some((*value).to_string()),
715            ["tokens", value] => {
716                tokens = Some(
717                    value
718                        .split(',')
719                        .map(str::parse)
720                        .collect::<Result<Vec<u32>, _>>()?,
721                )
722            }
723            ["vocab", value] => vocab = Some(value.parse::<usize>()?),
724            ["logit", index, bits] => {
725                let index = index.parse::<usize>()?;
726                let bits = u32::from_str_radix(bits, 16)?;
727                if logits.insert(index, f32::from_bits(bits)).is_some() {
728                    return Err(format!("duplicate oracle logit index {index}").into());
729                }
730            }
731            _ => {}
732        }
733    }
734    if !format_ok {
735        return Err("oracle is missing format=memra-checkpoint-oracle-v1".into());
736    }
737    let vocab = vocab.ok_or("oracle is missing vocab")?;
738    if logits.len() != vocab || (0..vocab).any(|index| !logits.contains_key(&index)) {
739        return Err(format!(
740            "oracle has {} logits, expected contiguous {vocab}",
741            logits.len()
742        )
743        .into());
744    }
745    Ok(CheckpointOracle {
746        engine: engine.ok_or("oracle is missing engine")?,
747        numeric_class: numeric_class.ok_or("oracle is missing numeric_class")?,
748        tokens: tokens.ok_or("oracle is missing tokens")?,
749        vocab,
750        logits: (0..vocab).map(|index| logits[&index]).collect(),
751    })
752}
753
754fn compare_checkpoint_oracles(
755    expected: &CheckpointOracle,
756    actual: &CheckpointOracle,
757    gate: model_packs::CheckpointParityGate,
758) -> Result<String, Box<dyn std::error::Error>> {
759    if expected.numeric_class != actual.numeric_class {
760        return Err(format!(
761            "oracle numeric class mismatch: expected={} native={}",
762            expected.numeric_class, actual.numeric_class
763        )
764        .into());
765    }
766    if expected.tokens != actual.tokens || expected.vocab != actual.vocab {
767        return Err(format!(
768            "oracle identity mismatch: expected tokens={:?} vocab={}, native tokens={:?} vocab={}",
769            expected.tokens, expected.vocab, actual.tokens, actual.vocab
770        )
771        .into());
772    }
773    let mut max_abs = 0.0f32;
774    let mut max_rel = 0.0f32;
775    let mut worst = 0usize;
776    let mut first_violation = None;
777    for (index, (&reference, &native)) in expected.logits.iter().zip(&actual.logits).enumerate() {
778        if !reference.is_finite() || !native.is_finite() {
779            return Err(format!("non-finite checkpoint logit at token {index}").into());
780        }
781        let absolute = (reference - native).abs();
782        let relative = absolute / reference.abs().max(1e-6);
783        if absolute > max_abs {
784            max_abs = absolute;
785            worst = index;
786        }
787        max_rel = max_rel.max(relative);
788        let allowed = gate.max_abs + gate.max_rel * reference.abs();
789        if absolute > allowed && first_violation.is_none() {
790            first_violation = Some((index, absolute, allowed));
791        }
792    }
793    let reference_argmax = stable_argmax(&expected.logits);
794    let native_argmax = stable_argmax(&actual.logits);
795    if let Some((index, absolute, allowed)) = first_violation {
796        return Err(format!(
797            "checkpoint parity failed at token {index}: abs={absolute} exceeds atol+rtol*abs(reference)={allowed}; observed max_abs={max_abs} at token {worst}, max_rel={max_rel}"
798        )
799        .into());
800    }
801    if gate.require_argmax && reference_argmax != native_argmax {
802        return Err(format!(
803            "checkpoint parity argmax mismatch: reference={reference_argmax} native={native_argmax}"
804        )
805        .into());
806    }
807    Ok(format!(
808        "status\tpassed\nreference_engine\t{}\nnative_engine\t{}\nnumeric_class\t{}\ntokens\t{}\nvocab\t{}\nmax_abs\t{max_abs}\nmax_rel\t{max_rel}\nreference_argmax\t{reference_argmax}\nnative_argmax\t{native_argmax}\n",
809        expected.engine,
810        actual.engine,
811        expected.numeric_class,
812        expected
813            .tokens
814            .iter()
815            .map(u32::to_string)
816            .collect::<Vec<_>>()
817            .join(","),
818        expected.vocab,
819    ))
820}
821
822fn stable_argmax(values: &[f32]) -> usize {
823    values
824        .iter()
825        .enumerate()
826        .max_by(|(left_index, left), (right_index, right)| {
827            left.total_cmp(right)
828                .then_with(|| right_index.cmp(left_index))
829        })
830        .map(|(index, _)| index)
831        .unwrap_or(0)
832}
833
834#[derive(Debug)]
835enum ReferenceVisionError {
836    Reference(memra_reference::ReferenceError),
837    Nondeterministic,
838}
839
840impl std::fmt::Display for ReferenceVisionError {
841    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
842        match self {
843            Self::Reference(error) => error.fmt(f),
844            Self::Nondeterministic => write!(
845                f,
846                "native vision reference fixture is not bit-deterministic"
847            ),
848        }
849    }
850}
851
852impl std::error::Error for ReferenceVisionError {}
853
854impl From<memra_reference::ReferenceError> for ReferenceVisionError {
855    fn from(value: memra_reference::ReferenceError) -> Self {
856        Self::Reference(value)
857    }
858}
859
860pub fn scaffold_model_pack(request: ScaffoldRequest) -> Result<(), Box<dyn std::error::Error>> {
861    validate_family_name(&request.family)?;
862    if request.out_dir.exists() && request.out_dir.read_dir()?.next().is_some() {
863        return Err(format!(
864            "refusing to scaffold into non-empty directory {}",
865            request.out_dir.display()
866        )
867        .into());
868    }
869    std::fs::create_dir_all(&request.out_dir)?;
870    write_atomic(
871        &request.out_dir.join("pack.toml"),
872        format!(
873            "family = {:?}\nconfig_layout = \"pending\"\nsupport = \"pending\"\n\n[checkpoint_parity]\nmax_abs = \"pending\"\nmax_rel = \"pending\"\nrequire_argmax = true\n",
874            request.family
875        )
876        .as_bytes(),
877    )?;
878    write_atomic(
879        &request.out_dir.join("aliases.txt"),
880        format!("{}\n", request.family).as_bytes(),
881    )?;
882    write_atomic(
883        &request.out_dir.join("config-normalization.txt"),
884        b"# source field\tcanonical field\ttransform\n",
885    )?;
886    write_atomic(
887        &request.out_dir.join("tensor-schema.tsv"),
888        b"semantic_id\tcheckpoint_pattern\tshape\townership\ttransform\tquant_layout\n",
889    )?;
890    write_atomic(
891        &request.out_dir.join("tokenizer-template.txt"),
892        b"tokenizer_source=pending\ntemplate=artifact-required\n",
893    )?;
894    write_atomic(
895        &request.out_dir.join("gates.txt"),
896        format_gates(&[
897            Gate::Config,
898            Gate::TokenizerTemplate,
899            Gate::TensorCensus,
900            Gate::TinyParity,
901            Gate::CheckpointParity,
902            Gate::RewriteParity,
903            Gate::Serve,
904        ])
905        .as_bytes(),
906    )?;
907    Ok(())
908}
909
910struct SourceData {
911    label: String,
912    revision: String,
913    dialect: CheckpointDialect,
914    config: ModelConfig,
915    config_bytes: Vec<u8>,
916    tensors: Vec<TensorCensusRecord>,
917    shards: Vec<String>,
918    tokenizer: Result<TokenizerEvidence, String>,
919}
920
921struct TokenizerEvidence {
922    source: TokenizerSource,
923    tokenizer_sha256: String,
924    template_sha256: String,
925    template_bytes: usize,
926}
927
928pub fn inspect_model(
929    request: InspectRequest,
930) -> Result<InspectSummary, Box<dyn std::error::Error>> {
931    let pack = model_packs::by_alias(&request.against)
932        .ok_or_else(|| format!("unknown model pack {:?}", request.against))?;
933    let source = load_source(&request.source)?;
934    let plan = pack.compile_plan(&source.config)?;
935    let output_head = if source
936        .tensors
937        .iter()
938        .any(|row| row.entry.name == "lm_head.weight" || row.entry.name == "output.weight")
939    {
940        OutputHead::Separate
941    } else {
942        OutputHead::TiedToEmbedding
943    };
944    let entries: Vec<_> = source.tensors.iter().map(|row| row.entry.clone()).collect();
945    std::fs::create_dir_all(&request.out_dir)?;
946    // A reused inspection directory must never retain a valid-looking placement from an older
947    // checkpoint/plan when the current tensor contract cannot bind or has fewer legal stages.
948    for stages in 2..=4 {
949        let path = request
950            .out_dir
951            .join(format!("placement-checkpoint-{stages}.tsv"));
952        match std::fs::remove_file(path) {
953            Ok(()) => {}
954            Err(error) if error.kind() == std::io::ErrorKind::NotFound => {}
955            Err(error) => return Err(error.into()),
956        }
957    }
958    let config_hash = hex_sha256(&source.config_bytes);
959    let census = format_census(&source.tensors);
960    let census_hash = hex_sha256(census.as_bytes());
961    let plan_text = format!("{plan:#?}\n");
962    let plan_hash = hex_sha256(plan_text.as_bytes());
963    let rewrites = memra_gguf::execution_manifest::execution_rewrites(&plan);
964    debug_assert!(
965        rewrites
966            .iter()
967            .all(|rewrite| rewrite.plan_sha256 == plan_hash)
968    );
969    let rewrite_manifest = format_execution_rewrites(&rewrites);
970    let rewrite_hash = hex_sha256(rewrite_manifest.as_bytes());
971    write_atomic(
972        &request.out_dir.join("tensor-census.tsv"),
973        census.as_bytes(),
974    )?;
975    write_atomic(
976        &request.out_dir.join("model-plan.txt"),
977        plan_text.as_bytes(),
978    )?;
979    write_atomic(
980        &request.out_dir.join("execution-rewrites.tsv"),
981        rewrite_manifest.as_bytes(),
982    )?;
983    let (binding, binding_error) = match pack.compile_tensor_contract(
984        &source.config,
985        &plan,
986        source.dialect,
987        ContractOptions { output_head },
988    ) {
989        Ok(contract) => match contract.bind(&entries) {
990            Ok(binding) => (Some(binding), None),
991            Err(error) => (None, Some(error.to_string())),
992        },
993        Err(error) => (None, Some(error.to_string())),
994    };
995    if let Some(binding) = binding.as_ref() {
996        write_checkpoint_placement_candidates(&request.out_dir, &plan, binding, &plan_hash)?;
997    }
998    let tokenizer_error = match &source.tokenizer {
999        Ok(evidence) if pack.tokenizer_sources.contains(&evidence.source) => None,
1000        Ok(evidence) => Some(format!(
1001            "model pack {} does not accept tokenizer source {:?}",
1002            pack.family, evidence.source
1003        )),
1004        Err(error) => Some(error.clone()),
1005    };
1006    if let Ok(evidence) = &source.tokenizer {
1007        write_atomic(
1008            &request.out_dir.join("tokenizer-contract.tsv"),
1009            format!(
1010                "status\tpassed\nsource\t{:?}\ntokenizer_sha256\t{}\ntemplate_sha256\t{}\ntemplate_bytes\t{}\n",
1011                evidence.source,
1012                evidence.tokenizer_sha256,
1013                evidence.template_sha256,
1014                evidence.template_bytes,
1015            )
1016            .as_bytes(),
1017        )?;
1018    }
1019    write_atomic(
1020        &request.out_dir.join("artifact.lock"),
1021        format_lock(
1022            pack,
1023            &source,
1024            &config_hash,
1025            &census_hash,
1026            &plan_hash,
1027            &rewrite_hash,
1028            if binding_error.is_some() {
1029                "failed"
1030            } else {
1031                "passed"
1032            },
1033        )
1034        .as_bytes(),
1035    )?;
1036    let error_path = request.out_dir.join("contract-error.txt");
1037    let tokenizer_error_path = request.out_dir.join("tokenizer-error.txt");
1038    let mut passed = vec![Gate::Config];
1039    let mut failed = Vec::new();
1040    if tokenizer_error.is_some() {
1041        failed.push(Gate::TokenizerTemplate);
1042    } else {
1043        passed.push(Gate::TokenizerTemplate);
1044    }
1045    if binding_error.is_some() {
1046        failed.push(Gate::TensorCensus);
1047    } else {
1048        passed.push(Gate::TensorCensus);
1049    }
1050    write_atomic(
1051        &request.out_dir.join("gates.txt"),
1052        format_gate_results_with_receipts(pack, &request.out_dir, &passed, &failed).as_bytes(),
1053    )?;
1054    if let Some(error) = binding_error.as_ref() {
1055        write_atomic(&error_path, format!("{error}\n").as_bytes())?;
1056    } else {
1057        match std::fs::remove_file(&error_path) {
1058            Ok(()) => {}
1059            Err(error) if error.kind() == std::io::ErrorKind::NotFound => {}
1060            Err(error) => return Err(error.into()),
1061        }
1062    }
1063    if let Some(error) = tokenizer_error.as_ref() {
1064        write_atomic(&tokenizer_error_path, format!("{error}\n").as_bytes())?;
1065    } else {
1066        match std::fs::remove_file(&tokenizer_error_path) {
1067            Ok(()) => {}
1068            Err(error) if error.kind() == std::io::ErrorKind::NotFound => {}
1069            Err(error) => return Err(error.into()),
1070        }
1071    }
1072    match (binding_error, tokenizer_error) {
1073        (Some(binding), Some(tokenizer)) => {
1074            return Err(
1075                format!("tensor contract: {binding}; tokenizer contract: {tokenizer}").into(),
1076            );
1077        }
1078        (Some(error), None) | (None, Some(error)) => return Err(error.into()),
1079        (None, None) => {}
1080    }
1081
1082    Ok(InspectSummary {
1083        family: pack.family,
1084        tensor_count: source.tensors.len(),
1085        out_dir: request.out_dir,
1086    })
1087}
1088
1089fn load_source(source: &str) -> Result<SourceData, Box<dyn std::error::Error>> {
1090    let path = Path::new(source);
1091    if path.exists() {
1092        return load_local(path);
1093    }
1094    let (repo, revision) = parse_pinned_hf_source(source)?;
1095    load_remote(repo, revision)
1096}
1097
1098fn load_config_only(source: &str) -> Result<ModelConfig, Box<dyn std::error::Error>> {
1099    let path = Path::new(source);
1100    if path.is_file() {
1101        return Ok(ModelConfig::from_gguf(&GgufFile::open(path)?));
1102    }
1103    if path.is_dir() {
1104        let bytes = std::fs::read(path.join("config.json"))?;
1105        return Ok(ModelConfig::from_hf(&HfConfig::parse(std::str::from_utf8(
1106            &bytes,
1107        )?)));
1108    }
1109    let (repo, revision) = parse_pinned_hf_source(source)?;
1110    let url = format!("https://huggingface.co/{repo}/resolve/{revision}/config.json");
1111    let config = http_text(&url)?.ok_or("pinned model has no config.json")?;
1112    Ok(ModelConfig::from_hf(&HfConfig::parse(&config)))
1113}
1114
1115fn load_local(path: &Path) -> Result<SourceData, Box<dyn std::error::Error>> {
1116    if path.is_file() {
1117        let gguf = GgufFile::open(path)?;
1118        let tokenizer = inspect_gguf_tokenizer(&gguf);
1119        let config = ModelConfig::from_gguf(&gguf);
1120        let tensors = census_from_gguf(&gguf).tensors;
1121        let config_bytes = format!("{config:#?}").into_bytes();
1122        return Ok(SourceData {
1123            label: path.display().to_string(),
1124            revision: "local".to_string(),
1125            dialect: CheckpointDialect::Gguf,
1126            config,
1127            config_bytes,
1128            tensors,
1129            shards: (0..gguf.n_shards())
1130                .map(|index| gguf.shard_path(index).display().to_string())
1131                .collect(),
1132            tokenizer,
1133        });
1134    }
1135
1136    if path.join("manifest.json").is_file() {
1137        let source = Hy3RepackSource::open(path)?;
1138        let config = source.try_config().map_err(std::io::Error::other)?;
1139        let census = source.tensor_census().map_err(std::io::Error::other)?;
1140        let tokenizer_dir = source.source_dir().unwrap_or(path);
1141        let tokenizer = inspect_hf_tokenizer_dir(tokenizer_dir);
1142        return Ok(SourceData {
1143            label: path.display().to_string(),
1144            revision: "local-repack".to_string(),
1145            dialect: census.dialect,
1146            config_bytes: format!("{config:#?}").into_bytes(),
1147            config,
1148            tensors: census.tensors,
1149            shards: vec!["manifest.json".to_string()],
1150            tokenizer,
1151        });
1152    }
1153
1154    let config_bytes = std::fs::read(path.join("config.json"))?;
1155    let config_text = std::str::from_utf8(&config_bytes)?;
1156    let config = ModelConfig::from_hf(&HfConfig::parse(config_text));
1157    let tokenizer = inspect_hf_tokenizer_dir(path);
1158    let model = StModel::open(path)?;
1159    let shards = local_shards(path)?;
1160    let revision = local_hf_revision(path, &shards).unwrap_or_else(|| "local".to_string());
1161    let headers = model
1162        .names()
1163        .map(|name| {
1164            let info = model.info(name).expect("StModel name must resolve");
1165            (name.clone(), info.clone())
1166        })
1167        .collect();
1168    Ok(SourceData {
1169        label: path.display().to_string(),
1170        revision,
1171        dialect: CheckpointDialect::HfSafetensors,
1172        config,
1173        config_bytes,
1174        tensors: census_from_safetensors_headers(&headers)?.tensors,
1175        shards,
1176        tokenizer,
1177    })
1178}
1179
1180fn load_remote(repo: &str, revision: &str) -> Result<SourceData, Box<dyn std::error::Error>> {
1181    let base = format!("https://huggingface.co/{repo}/resolve/{revision}");
1182    let config_bytes = http_text(&format!("{base}/config.json"))?
1183        .ok_or("pinned model has no config.json")?
1184        .into_bytes();
1185    let config = ModelConfig::from_hf(&HfConfig::parse(std::str::from_utf8(&config_bytes)?));
1186    let tokenizer = inspect_remote_hf_tokenizer(&base);
1187    let index = http_text(&format!("{base}/model.safetensors.index.json"))?;
1188    let shards: Vec<String> = if let Some(index) = index {
1189        let mut files: Vec<_> = parse_index_json(&index)?.into_values().collect();
1190        files.sort();
1191        files.dedup();
1192        files
1193    } else {
1194        vec!["model.safetensors".to_string()]
1195    };
1196    let mut headers = BTreeMap::new();
1197    for shard in &shards {
1198        validate_remote_filename(shard)?;
1199        let url = format!("{base}/{shard}");
1200        let prefix = http_range(&url, 0, 7)?;
1201        if prefix.len() != 8 {
1202            return Err(format!("{shard}: expected 8-byte safetensors prefix").into());
1203        }
1204        let header_len = u64::from_le_bytes(prefix.try_into().unwrap()) as usize;
1205        if header_len == 0 || header_len > MAX_TEXT_BYTES {
1206            return Err(format!("{shard}: invalid safetensors header length {header_len}").into());
1207        }
1208        let bytes = http_range(&url, 8, 7 + header_len)?;
1209        if bytes.len() != header_len {
1210            return Err(format!(
1211                "{shard}: range returned {} header bytes, expected {header_len}",
1212                bytes.len()
1213            )
1214            .into());
1215        }
1216        let parsed = parse_header(std::str::from_utf8(&bytes)?)?;
1217        for (name, info) in parsed {
1218            if headers.insert(name.clone(), info).is_some() {
1219                return Err(format!("tensor {name} occurs in multiple safetensors shards").into());
1220            }
1221        }
1222    }
1223    Ok(SourceData {
1224        label: repo.to_string(),
1225        revision: revision.to_string(),
1226        dialect: CheckpointDialect::HfSafetensors,
1227        config,
1228        config_bytes,
1229        tensors: census_from_safetensors_headers(&headers)?.tensors,
1230        shards,
1231        tokenizer,
1232    })
1233}
1234
1235fn inspect_gguf_tokenizer(gguf: &GgufFile) -> Result<TokenizerEvidence, String> {
1236    let model = gguf
1237        .metadata
1238        .get("tokenizer.ggml.model")
1239        .and_then(|value| value.as_str())
1240        .ok_or_else(|| "GGUF is missing tokenizer.ggml.model".to_string())?;
1241    let tokens = gguf
1242        .metadata
1243        .get("tokenizer.ggml.tokens")
1244        .and_then(|value| value.as_str_array())
1245        .ok_or_else(|| "GGUF is missing tokenizer.ggml.tokens".to_string())?;
1246    if tokens.is_empty() {
1247        return Err("GGUF tokenizer.ggml.tokens is empty".to_string());
1248    }
1249    let template = gguf
1250        .metadata
1251        .get("tokenizer.chat_template")
1252        .and_then(|value| value.as_str())
1253        .filter(|template| !template.trim().is_empty())
1254        .ok_or_else(|| "GGUF is missing tokenizer.chat_template".to_string())?;
1255    let mut hasher = Sha256::new();
1256    hasher.update(model.as_bytes());
1257    if let Some(pre) = gguf
1258        .metadata
1259        .get("tokenizer.ggml.pre")
1260        .and_then(|value| value.as_str())
1261    {
1262        hasher.update([0]);
1263        hasher.update(pre.as_bytes());
1264    }
1265    for token in tokens {
1266        hasher.update([0]);
1267        hasher.update(token.as_bytes());
1268    }
1269    Ok(TokenizerEvidence {
1270        source: TokenizerSource::GgufMetadata,
1271        tokenizer_sha256: hasher
1272            .finalize()
1273            .iter()
1274            .map(|byte| format!("{byte:02x}"))
1275            .collect(),
1276        template_sha256: hex_sha256(template.as_bytes()),
1277        template_bytes: template.len(),
1278    })
1279}
1280
1281fn inspect_hf_tokenizer_dir(path: &Path) -> Result<TokenizerEvidence, String> {
1282    let tokenizer_path = path.join("tokenizer.json");
1283    let tokenizer = std::fs::read(&tokenizer_path)
1284        .map_err(|error| format!("read {}: {error}", tokenizer_path.display()))?;
1285    let template = local_hf_template(path)?;
1286    Ok(TokenizerEvidence {
1287        source: TokenizerSource::TokenizerJson,
1288        tokenizer_sha256: hex_sha256(&tokenizer),
1289        template_sha256: hex_sha256(template.as_bytes()),
1290        template_bytes: template.len(),
1291    })
1292}
1293
1294fn local_hf_template(path: &Path) -> Result<String, String> {
1295    let config_path = path.join("tokenizer_config.json");
1296    if let Ok(config) = std::fs::read_to_string(&config_path)
1297        && let Some(template) = template_from_tokenizer_config(&config)
1298    {
1299        return Ok(template);
1300    }
1301    let template_path = path.join("chat_template.jinja");
1302    std::fs::read_to_string(&template_path)
1303        .map_err(|error| format!("read {}: {error}", template_path.display()))
1304        .and_then(nonempty_template)
1305}
1306
1307fn inspect_remote_hf_tokenizer(base: &str) -> Result<TokenizerEvidence, String> {
1308    let tokenizer = http_text(&format!("{base}/tokenizer.json"))
1309        .map_err(|error| error.to_string())?
1310        .ok_or_else(|| "pinned HF model has no tokenizer.json".to_string())?;
1311    let config =
1312        http_text(&format!("{base}/tokenizer_config.json")).map_err(|error| error.to_string())?;
1313    let template = config
1314        .as_deref()
1315        .and_then(template_from_tokenizer_config)
1316        .or_else(|| {
1317            http_text(&format!("{base}/chat_template.jinja"))
1318                .ok()
1319                .flatten()
1320        })
1321        .ok_or_else(|| {
1322            "pinned HF model has neither tokenizer_config chat_template nor chat_template.jinja"
1323                .to_string()
1324        })
1325        .and_then(nonempty_template)?;
1326    Ok(TokenizerEvidence {
1327        source: TokenizerSource::TokenizerJson,
1328        tokenizer_sha256: hex_sha256(tokenizer.as_bytes()),
1329        template_sha256: hex_sha256(template.as_bytes()),
1330        template_bytes: template.len(),
1331    })
1332}
1333
1334fn template_from_tokenizer_config(config: &str) -> Option<String> {
1335    let config = memra_gguf::config::JsonObj::parse(config);
1336    config
1337        .string("chat_template")
1338        .filter(|value| !value.trim().is_empty())
1339}
1340
1341fn nonempty_template(template: String) -> Result<String, String> {
1342    if template.trim().is_empty() {
1343        Err("chat template is empty".to_string())
1344    } else {
1345        Ok(template)
1346    }
1347}
1348
1349fn parse_pinned_hf_source(source: &str) -> Result<(&str, &str), Box<dyn std::error::Error>> {
1350    let (repo, revision) = source
1351        .rsplit_once('@')
1352        .ok_or("remote sources must be pinned as hf-id@40-char-sha")?;
1353    if repo.split('/').count() != 2
1354        || repo.split('/').any(|part| part.is_empty())
1355        || !repo
1356            .bytes()
1357            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'/' | b'-' | b'_' | b'.'))
1358        || repo.contains("..")
1359    {
1360        return Err("HF model id must be namespace/repository".into());
1361    }
1362    if revision.len() != 40 || !revision.bytes().all(|byte| byte.is_ascii_hexdigit()) {
1363        return Err("HF revision must be a full 40-character commit SHA".into());
1364    }
1365    Ok((repo, revision))
1366}
1367
1368fn validate_family_name(family: &str) -> Result<(), Box<dyn std::error::Error>> {
1369    if family.is_empty()
1370        || !family
1371            .bytes()
1372            .all(|byte| byte.is_ascii_lowercase() || byte.is_ascii_digit() || byte == b'_')
1373    {
1374        return Err(
1375            "family must contain only lowercase ASCII letters, digits, and underscores".into(),
1376        );
1377    }
1378    Ok(())
1379}
1380
1381fn validate_remote_filename(name: &str) -> Result<(), Box<dyn std::error::Error>> {
1382    if name.is_empty()
1383        || name.starts_with('/')
1384        || name.split('/').any(|part| part.is_empty() || part == "..")
1385        || !name
1386            .bytes()
1387            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'/' | b'-' | b'_' | b'.'))
1388    {
1389        return Err(format!("unsafe shard filename {name:?}").into());
1390    }
1391    Ok(())
1392}
1393
1394fn http_text(url: &str) -> Result<Option<String>, Box<dyn std::error::Error>> {
1395    let mut command = curl_command();
1396    command.args([
1397        "--silent",
1398        "--show-error",
1399        "--location",
1400        "--max-filesize",
1401        &MAX_TEXT_BYTES.to_string(),
1402        "--write-out",
1403        "\n%{http_code}",
1404        url,
1405    ]);
1406    let output = curl_output(command)?;
1407    if !output.status.success() {
1408        return Err(format!(
1409            "curl failed for {url}: {}",
1410            String::from_utf8_lossy(&output.stderr)
1411        )
1412        .into());
1413    }
1414    let split = output
1415        .stdout
1416        .iter()
1417        .rposition(|byte| *byte == b'\n')
1418        .ok_or("curl response omitted HTTP status")?;
1419    let status = std::str::from_utf8(&output.stdout[split + 1..])?.trim();
1420    match status {
1421        "200" => Ok(Some(String::from_utf8(output.stdout[..split].to_vec())?)),
1422        "404" => Ok(None),
1423        other => Err(format!("HTTP {other} for {url}").into()),
1424    }
1425}
1426
1427fn http_range(url: &str, start: usize, end: usize) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
1428    let mut command = curl_command();
1429    command.args([
1430        "--fail",
1431        "--silent",
1432        "--show-error",
1433        "--location",
1434        "--max-filesize",
1435        &MAX_TEXT_BYTES.to_string(),
1436        "--range",
1437        &format!("{start}-{end}"),
1438        url,
1439    ]);
1440    let output = curl_output(command)?;
1441    if !output.status.success() {
1442        return Err(format!(
1443            "range request failed for {url}: {}",
1444            String::from_utf8_lossy(&output.stderr)
1445        )
1446        .into());
1447    }
1448    Ok(output.stdout)
1449}
1450
1451fn curl_command() -> Command {
1452    Command::new("curl")
1453}
1454
1455fn curl_output(mut command: Command) -> std::io::Result<Output> {
1456    let token = std::env::var("HF_TOKEN").ok();
1457    if token.is_none() {
1458        return command.output();
1459    }
1460    command
1461        .args(["--header", "@-"])
1462        .stdin(Stdio::piped())
1463        .stdout(Stdio::piped())
1464        .stderr(Stdio::piped());
1465    let mut child = command.spawn()?;
1466    let mut stdin = child.stdin.take().expect("piped curl stdin");
1467    writeln!(stdin, "Authorization: Bearer {}", token.unwrap())?;
1468    drop(stdin);
1469    child.wait_with_output()
1470}
1471
1472fn local_shards(path: &Path) -> Result<Vec<String>, Box<dyn std::error::Error>> {
1473    let index = path.join("model.safetensors.index.json");
1474    if index.exists() {
1475        let mut shards: Vec<_> = parse_index_json(&std::fs::read_to_string(index)?)?
1476            .into_values()
1477            .collect();
1478        shards.sort();
1479        shards.dedup();
1480        Ok(shards)
1481    } else {
1482        Ok(vec!["model.safetensors".to_string()])
1483    }
1484}
1485
1486fn local_hf_revision(path: &Path, shards: &[String]) -> Option<String> {
1487    let metadata = path.join(".cache/huggingface/download");
1488    let mut files = Vec::with_capacity(shards.len() + 1);
1489    files.push("config.json");
1490    files.extend(shards.iter().map(String::as_str));
1491    let revisions: Option<Vec<_>> = files
1492        .into_iter()
1493        .map(|file| {
1494            let text = std::fs::read_to_string(metadata.join(format!("{file}.metadata"))).ok()?;
1495            let revision = text.lines().next()?;
1496            (revision.len() == 40 && revision.bytes().all(|byte| byte.is_ascii_hexdigit()))
1497                .then(|| revision.to_ascii_lowercase())
1498        })
1499        .collect();
1500    let revisions = revisions?;
1501    let first = revisions.first()?;
1502    revisions
1503        .iter()
1504        .all(|revision| revision == first)
1505        .then(|| first.clone())
1506}
1507
1508fn format_census(rows: &[TensorCensusRecord]) -> String {
1509    let mut output =
1510        String::from("semantic_name\tphysical_name\tdtype\tshape\tstorage\tphysical_bytes\n");
1511    for row in rows {
1512        writeln!(
1513            output,
1514            "{}\t{}\t{}\t{:?}\t{:?}\t{}",
1515            row.entry.name,
1516            row.physical_name,
1517            row.dtype,
1518            row.entry.shape,
1519            row.entry.storage,
1520            row.entry.physical_bytes,
1521        )
1522        .unwrap();
1523    }
1524    output
1525}
1526
1527fn placement_first_stage_tensor(id: &TensorId) -> bool {
1528    match id {
1529        TensorId::TokenEmbedding | TensorId::RopeFactors | TensorId::Vision { .. } => true,
1530        TensorId::QuantAux { tensor, .. } => placement_first_stage_tensor(tensor),
1531        _ => false,
1532    }
1533}
1534
1535fn write_checkpoint_placement_candidates(
1536    out_dir: &Path,
1537    plan: &memra_gguf::model_plan::ModelPlan,
1538    binding: &BoundTensorContract,
1539    plan_hash: &str,
1540) -> Result<(), Box<dyn std::error::Error>> {
1541    let mut layers = vec![LayerPlacementCost::default(); plan.layers.len()];
1542    let mut first_fixed = 0u64;
1543    let mut last_fixed = 0u64;
1544    for (id, tensor) in &binding.tensors {
1545        match tensor.owner {
1546            TensorOwner::Layer(layer) if (layer as usize) < layers.len() => {
1547                let cost = &mut layers[layer as usize];
1548                cost.weight_bytes = cost
1549                    .weight_bytes
1550                    .checked_add(tensor.physical_bytes)
1551                    .ok_or("layer checkpoint byte total overflows u64")?;
1552            }
1553            // Some legacy contracts retain the physical MTP layer index instead of rewriting
1554            // its owner to TensorOwner::Mtp. It executes with the tail/head stage either way.
1555            TensorOwner::Layer(_) => {
1556                last_fixed = last_fixed
1557                    .checked_add(tensor.physical_bytes)
1558                    .ok_or("head-stage checkpoint byte total overflows u64")?;
1559            }
1560            TensorOwner::Vision(_) => {
1561                first_fixed = first_fixed
1562                    .checked_add(tensor.physical_bytes)
1563                    .ok_or("first-stage checkpoint byte total overflows u64")?;
1564            }
1565            TensorOwner::Global if placement_first_stage_tensor(id) => {
1566                first_fixed = first_fixed
1567                    .checked_add(tensor.physical_bytes)
1568                    .ok_or("first-stage checkpoint byte total overflows u64")?;
1569            }
1570            TensorOwner::Global | TensorOwner::Mtp(_) => {
1571                last_fixed = last_fixed
1572                    .checked_add(tensor.physical_bytes)
1573                    .ok_or("head-stage checkpoint byte total overflows u64")?;
1574            }
1575        }
1576    }
1577
1578    for stages in 2..=4.min(layers.len()) {
1579        let devices: Vec<usize> = (0..stages).collect();
1580        let mut fixed = vec![0u64; stages];
1581        fixed[0] = first_fixed;
1582        fixed[stages - 1] = fixed[stages - 1]
1583            .checked_add(last_fixed)
1584            .ok_or("head-stage checkpoint byte total overflows u64")?;
1585        let candidate = plan_contiguous_stages(PlacementRequest {
1586            layers: &layers,
1587            fixed_stage_bytes: &fixed,
1588            context_tokens: 0,
1589            devices: &devices,
1590            legal_boundaries: &plan.partition_boundaries,
1591        });
1592        let mut output = String::new();
1593        writeln!(output, "basis\tcheckpoint_physical_bytes")?;
1594        writeln!(output, "plan_sha256\t{plan_hash}")?;
1595        writeln!(output, "context_tokens\t0")?;
1596        writeln!(
1597            output,
1598            "warning\tnot exact HBM: loader expansions, repacks, mirrors, KV and workspaces require runtime planning"
1599        )?;
1600        match candidate {
1601            Ok(candidate) => {
1602                let cuts = candidate
1603                    .stages
1604                    .iter()
1605                    .take(candidate.stages.len() - 1)
1606                    .map(|stage| stage.layers.end.to_string())
1607                    .collect::<Vec<_>>()
1608                    .join(",");
1609                writeln!(output, "status\tpassed")?;
1610                writeln!(output, "MEMRA_PP_STAGES\t{stages}")?;
1611                writeln!(
1612                    output,
1613                    "MEMRA_PP_DEVICES\t{}",
1614                    devices
1615                        .iter()
1616                        .map(usize::to_string)
1617                        .collect::<Vec<_>>()
1618                        .join(",")
1619                )?;
1620                writeln!(output, "MEMRA_PP_SPLITS\t{cuts}")?;
1621                writeln!(output, "max_stage_bytes\t{}", candidate.max_stage_bytes)?;
1622                writeln!(
1623                    output,
1624                    "stage\tdevice\tlayers\tweight_bytes\tfixed_bytes\ttotal_bytes"
1625                )?;
1626                for (stage, placement) in candidate.stages.iter().enumerate() {
1627                    writeln!(
1628                        output,
1629                        "{stage}\t{}\t{}..{}\t{}\t{}\t{}",
1630                        placement.device,
1631                        placement.layers.start,
1632                        placement.layers.end,
1633                        placement.cost.weight_bytes,
1634                        placement.cost.fixed_bytes,
1635                        placement.cost.total_bytes,
1636                    )?;
1637                }
1638            }
1639            Err(error) => {
1640                writeln!(output, "status\tfailed")?;
1641                writeln!(output, "error\t{error}")?;
1642            }
1643        }
1644        write_atomic(
1645            &out_dir.join(format!("placement-checkpoint-{stages}.tsv")),
1646            output.as_bytes(),
1647        )?;
1648    }
1649    Ok(())
1650}
1651
1652fn format_execution_rewrites(
1653    rewrites: &[memra_gguf::execution_manifest::ExecutionRewrite],
1654) -> String {
1655    let mut output = String::from(
1656        "rewrite\tsurface\timplementation\tplan_sha256\teligible\tblockers\toperations\treceipt\n",
1657    );
1658    for rewrite in rewrites {
1659        let blockers = rewrite
1660            .blockers
1661            .iter()
1662            .map(|operation| format!("{operation:?}"))
1663            .collect::<Vec<_>>()
1664            .join(",");
1665        let mut unique_operations = Vec::new();
1666        for operation in &rewrite.canonical_operations {
1667            if !unique_operations.contains(operation) {
1668                unique_operations.push(*operation);
1669            }
1670        }
1671        let operations = unique_operations
1672            .iter()
1673            .map(|operation| format!("{operation:?}"))
1674            .collect::<Vec<_>>()
1675            .join(",");
1676        writeln!(
1677            output,
1678            "{}\t{}\t{}\t{}\t{}\t{}\t{}\tpending",
1679            rewrite.id,
1680            rewrite.surface.as_str(),
1681            rewrite.implementation,
1682            rewrite.plan_sha256,
1683            rewrite.eligible(),
1684            blockers,
1685            operations,
1686        )
1687        .unwrap();
1688    }
1689    output
1690}
1691
1692fn format_lock(
1693    pack: &ModelPack,
1694    source: &SourceData,
1695    config: &str,
1696    census: &str,
1697    plan: &str,
1698    rewrites: &str,
1699    binding: &str,
1700) -> String {
1701    let mut output = String::from("format_version=2\n");
1702    writeln!(output, "source={}", lock_value(&source.label)).unwrap();
1703    writeln!(output, "revision={}", lock_value(&source.revision)).unwrap();
1704    writeln!(output, "family={}", pack.family).unwrap();
1705    match pack.support {
1706        Some(support) => writeln!(output, "support={support:?}").unwrap(),
1707        None => writeln!(output, "support=unsupported").unwrap(),
1708    }
1709    if let Some(gate) = pack.checkpoint_parity {
1710        writeln!(output, "checkpoint_atol={}", gate.max_abs).unwrap();
1711        writeln!(output, "checkpoint_rtol={}", gate.max_rel).unwrap();
1712        writeln!(output, "checkpoint_require_argmax={}", gate.require_argmax).unwrap();
1713    }
1714    writeln!(output, "config_sha256={config}").unwrap();
1715    writeln!(output, "census_sha256={census}").unwrap();
1716    writeln!(output, "plan_sha256={plan}").unwrap();
1717    writeln!(output, "rewrite_manifest_sha256={rewrites}").unwrap();
1718    writeln!(output, "binding={binding}").unwrap();
1719    match &source.tokenizer {
1720        Ok(evidence) if pack.tokenizer_sources.contains(&evidence.source) => {
1721            writeln!(output, "tokenizer=passed").unwrap();
1722            writeln!(output, "tokenizer_source={:?}", evidence.source).unwrap();
1723            writeln!(output, "tokenizer_sha256={}", evidence.tokenizer_sha256).unwrap();
1724            writeln!(output, "template_sha256={}", evidence.template_sha256).unwrap();
1725        }
1726        Ok(_) | Err(_) => writeln!(output, "tokenizer=failed").unwrap(),
1727    }
1728    writeln!(output, "tensor_count={}", source.tensors.len()).unwrap();
1729    for shard in &source.shards {
1730        writeln!(output, "shard={}", lock_value(shard)).unwrap();
1731    }
1732    output
1733}
1734
1735fn parse_header(
1736    json: &str,
1737) -> Result<std::collections::HashMap<String, StInfo>, Box<dyn std::error::Error>> {
1738    parse_header_json_checked(json).map_err(Into::into)
1739}
1740
1741fn parse_index_json(
1742    json: &str,
1743) -> Result<std::collections::HashMap<String, String>, Box<dyn std::error::Error>> {
1744    parse_index_weight_map_json_checked(json).map_err(Into::into)
1745}
1746
1747fn lock_value(value: &str) -> String {
1748    value
1749        .replace('\\', "\\\\")
1750        .replace('\n', "\\n")
1751        .replace('\r', "\\r")
1752}
1753
1754fn format_gates(gates: &[Gate]) -> String {
1755    format_gate_results(gates, &[], &[])
1756}
1757
1758fn format_gate_results(gates: &[Gate], passed: &[Gate], failed: &[Gate]) -> String {
1759    let mut output = String::new();
1760    for gate in gates {
1761        let status = if passed.contains(gate) {
1762            "passed"
1763        } else if failed.contains(gate) {
1764            "failed"
1765        } else {
1766            "pending"
1767        };
1768        writeln!(output, "{gate:?}={status}").unwrap();
1769    }
1770    output
1771}
1772
1773fn all_eligible_rewrites_have_receipts(out_dir: &Path) -> bool {
1774    let Ok(manifest) = std::fs::read_to_string(out_dir.join("execution-rewrites.tsv")) else {
1775        return false;
1776    };
1777    let Ok(index_text) = std::fs::read_to_string(out_dir.join("rewrite-receipts.tsv")) else {
1778        return false;
1779    };
1780    let mut index = BTreeMap::new();
1781    for line in index_text.lines().skip(1) {
1782        let columns: Vec<_> = line.split('\t').collect();
1783        if columns.len() != 4 || columns[3] != "passed" {
1784            return false;
1785        }
1786        index.insert(columns[0], (columns[1], columns[2]));
1787    }
1788    let mut eligible = 0usize;
1789    for line in manifest.lines().skip(1) {
1790        let columns: Vec<_> = line.split('\t').collect();
1791        if columns.len() != 8 {
1792            return false;
1793        }
1794        if columns[4] != "true" {
1795            continue;
1796        }
1797        eligible += 1;
1798        let Some(&(plan, receipt_hash)) = index.get(columns[0]) else {
1799            return false;
1800        };
1801        if plan != columns[3] {
1802            return false;
1803        }
1804        let Ok(receipt) = std::fs::read(
1805            out_dir
1806                .join("rewrite-receipts")
1807                .join(format!("{}.tsv", columns[0])),
1808        ) else {
1809            return false;
1810        };
1811        if hex_sha256(&receipt) != receipt_hash {
1812            return false;
1813        }
1814    }
1815    eligible > 0
1816}
1817
1818fn format_gate_results_with_receipts(
1819    pack: &ModelPack,
1820    out_dir: &Path,
1821    passed: &[Gate],
1822    failed: &[Gate],
1823) -> String {
1824    let mut passed = passed.to_vec();
1825    let artifact_lock = std::fs::read(out_dir.join("artifact.lock")).ok();
1826    let lock_hash = artifact_lock.as_ref().map(|bytes| hex_sha256(bytes));
1827    if let Some(lock) = artifact_lock
1828        .as_deref()
1829        .and_then(|bytes| std::str::from_utf8(bytes).ok())
1830        .filter(|lock| {
1831            lock.lines().any(|line| line == "format_version=2")
1832                && lock
1833                    .lines()
1834                    .any(|line| line == format!("family={}", pack.family))
1835        })
1836    {
1837        for (gate, evidence) in [
1838            (Gate::Config, None),
1839            (Gate::TokenizerTemplate, Some("tokenizer=passed")),
1840            (Gate::TensorCensus, Some("binding=passed")),
1841        ] {
1842            if evidence.is_none_or(|line| lock.lines().any(|candidate| candidate == line))
1843                && !passed.contains(&gate)
1844                && !failed.contains(&gate)
1845            {
1846                passed.push(gate);
1847            }
1848        }
1849    }
1850    let receipt_passes = |name: &str, family_bound: bool, lock_bound: bool| {
1851        let Ok(receipt) = std::fs::read_to_string(out_dir.join(name)) else {
1852            return false;
1853        };
1854        if !receipt.lines().any(|line| line == "status\tpassed") {
1855            return false;
1856        }
1857        if family_bound
1858            && !receipt
1859                .lines()
1860                .any(|line| line == format!("family\t{}", pack.family))
1861        {
1862            return false;
1863        }
1864        if lock_bound
1865            && !lock_hash.as_ref().is_some_and(|hash| {
1866                receipt
1867                    .lines()
1868                    .any(|line| line == format!("artifact_lock_sha256\t{hash}"))
1869            })
1870        {
1871            return false;
1872        }
1873        true
1874    };
1875    for (gate, name, family_bound, lock_bound) in [
1876        (Gate::TinyParity, "tiny-gate.tsv", true, false),
1877        (Gate::CheckpointParity, "checkpoint-parity.tsv", false, true),
1878        (Gate::Serve, "serve-gate.tsv", true, true),
1879    ] {
1880        if receipt_passes(name, family_bound, lock_bound)
1881            && !passed.contains(&gate)
1882            && !failed.contains(&gate)
1883        {
1884            passed.push(gate);
1885        }
1886    }
1887    if all_eligible_rewrites_have_receipts(out_dir)
1888        && !passed.contains(&Gate::RewriteParity)
1889        && !failed.contains(&Gate::RewriteParity)
1890    {
1891        passed.push(Gate::RewriteParity);
1892    }
1893    format_gate_results(pack.gates, &passed, failed)
1894}
1895
1896fn format_tiny_fixture(
1897    plan: &memra_gguf::model_plan::ModelPlan,
1898    fixture: &memra_reference::ReferenceFixture,
1899) -> String {
1900    let mut output = format!("tokens={:?}\nplan={plan:#?}\n", fixture.token_ids);
1901    for (id, tensor) in &fixture.weights {
1902        let mut bytes = Vec::with_capacity(tensor.data.len() * 4);
1903        for value in &tensor.data {
1904            bytes.extend_from_slice(&value.to_bits().to_le_bytes());
1905        }
1906        writeln!(
1907            output,
1908            "tensor={id:?}\tshape={:?}\tsha256={}",
1909            tensor.shape,
1910            hex_sha256(&bytes)
1911        )
1912        .unwrap();
1913    }
1914    if let Some(vision) = fixture.vision.as_ref() {
1915        let mut bytes = Vec::with_capacity(vision.patches.data.len() * 4);
1916        for value in &vision.patches.data {
1917            bytes.extend_from_slice(&value.to_bits().to_le_bytes());
1918        }
1919        writeln!(
1920            output,
1921            "vision_patches={:?}\tsha256={}\tpositions={:?}\toutput_tokens={}",
1922            vision.patches.shape,
1923            hex_sha256(&bytes),
1924            vision.positions,
1925            vision.output_tokens,
1926        )
1927        .unwrap();
1928    }
1929    if let Some(token_ids) = fixture.multimodal_token_ids.as_ref() {
1930        writeln!(output, "multimodal_tokens={token_ids:?}").unwrap();
1931    }
1932    output
1933}
1934
1935fn format_reference_oracle(output: &memra_reference::ReferenceOutput) -> String {
1936    let mut text = String::from("stream\tposition\ttoken\tlogit_f32_bits\n");
1937    append_oracle_rows(
1938        &mut text,
1939        "main",
1940        &output.logits,
1941        output.tokens,
1942        output.vocab,
1943    );
1944    for mtp in &output.mtp {
1945        append_oracle_rows(
1946            &mut text,
1947            &format!("mtp:{}", mtp.depth),
1948            &mtp.logits,
1949            output.tokens,
1950            output.vocab,
1951        );
1952    }
1953    if let Some(draft) = output.draft.as_ref() {
1954        append_oracle_rows(
1955            &mut text,
1956            "dspark",
1957            &draft.logits,
1958            draft.block_size,
1959            output.vocab,
1960        );
1961        for (position, (&token, &confidence)) in draft
1962            .output_ids
1963            .iter()
1964            .skip(1)
1965            .zip(&draft.confidence)
1966            .enumerate()
1967        {
1968            writeln!(
1969                text,
1970                "dspark-confidence\t{position}\t{token}\t{:08x}",
1971                confidence.to_bits()
1972            )
1973            .unwrap();
1974        }
1975    }
1976    text
1977}
1978
1979fn append_oracle_rows(
1980    text: &mut String,
1981    stream: &str,
1982    logits: &[f32],
1983    tokens: usize,
1984    vocab: usize,
1985) {
1986    for position in 0..tokens {
1987        for token in 0..vocab {
1988            writeln!(
1989                text,
1990                "{stream}\t{position}\t{token}\t{:08x}",
1991                logits[position * vocab + token].to_bits()
1992            )
1993            .unwrap();
1994        }
1995    }
1996}
1997
1998fn format_reference_vision_oracle(output: &memra_reference::ReferenceVisionOutput) -> String {
1999    let mut text = String::from("stream\tposition\tchannel\tf32_bits\n");
2000    for (stream, values, rows, width) in [
2001        (
2002            "vision-encoder",
2003            output.encoder_hidden.as_slice(),
2004            output.patch_count,
2005            output.hidden_size,
2006        ),
2007        (
2008            "vision-pooled",
2009            output.pooled_hidden.as_slice(),
2010            output.output_tokens,
2011            output.hidden_size,
2012        ),
2013        (
2014            "vision-projected",
2015            output.projected_hidden.as_slice(),
2016            output.output_tokens,
2017            output.projection_size,
2018        ),
2019    ] {
2020        for position in 0..rows {
2021            for channel in 0..width {
2022                writeln!(
2023                    text,
2024                    "{stream}\t{position}\t{channel}\t{:08x}",
2025                    values[position * width + channel].to_bits()
2026                )
2027                .unwrap();
2028            }
2029        }
2030    }
2031    text
2032}
2033
2034fn hex_sha256(bytes: &[u8]) -> String {
2035    let digest = Sha256::digest(bytes);
2036    digest.iter().map(|byte| format!("{byte:02x}")).collect()
2037}
2038
2039fn write_atomic(path: &Path, bytes: &[u8]) -> std::io::Result<()> {
2040    let temporary = path.with_extension(format!("tmp-{}", std::process::id()));
2041    std::fs::write(&temporary, bytes)?;
2042    std::fs::rename(temporary, path)
2043}
2044
2045#[cfg(test)]
2046mod tests {
2047    use super::*;
2048
2049    #[test]
2050    fn local_glm_fixture_generates_deterministic_onboarding_artifacts() {
2051        let root = std::env::temp_dir().join(format!("memra-cli-inspect-{}", std::process::id()));
2052        let model = root.join("model.gguf");
2053        let output = root.join("out");
2054        std::fs::create_dir_all(&root).unwrap();
2055        memra_gguf::micro_gguf::write_glm_dsa_micro(&model, 0x434c_4901).unwrap();
2056        let verified = verify_model(VerifyRequest {
2057            stage: VerifyStage::Config,
2058            source: model.display().to_string(),
2059            against: "glm_dsa".to_string(),
2060            out_dir: None,
2061            oracle: None,
2062            native_runner: None,
2063        })
2064        .unwrap();
2065        assert_eq!(verified.stage, VerifyStage::Config);
2066        let first = inspect_model(InspectRequest {
2067            source: model.display().to_string(),
2068            against: "glm_dsa".to_string(),
2069            out_dir: output.clone(),
2070        })
2071        .unwrap();
2072        assert_eq!(first.family, "glm_dsa");
2073        assert!(first.tensor_count > 0);
2074        let lock = std::fs::read(output.join("artifact.lock")).unwrap();
2075        std::fs::write(output.join("placement-checkpoint-3.tsv"), "stale\n").unwrap();
2076        std::fs::write(output.join("placement-checkpoint-4.tsv"), "stale\n").unwrap();
2077        inspect_model(InspectRequest {
2078            source: model.display().to_string(),
2079            against: "glm_dsa".to_string(),
2080            out_dir: output.clone(),
2081        })
2082        .unwrap();
2083        assert_eq!(std::fs::read(output.join("artifact.lock")).unwrap(), lock);
2084        for artifact in [
2085            "artifact.lock",
2086            "tensor-census.tsv",
2087            "model-plan.txt",
2088            "execution-rewrites.tsv",
2089            "placement-checkpoint-2.tsv",
2090            "gates.txt",
2091        ] {
2092            assert!(output.join(artifact).is_file(), "missing {artifact}");
2093        }
2094        let placement = std::fs::read_to_string(output.join("placement-checkpoint-2.tsv")).unwrap();
2095        assert!(placement.contains("basis\tcheckpoint_physical_bytes"));
2096        assert!(placement.contains("warning\tnot exact HBM"));
2097        assert!(placement.contains("MEMRA_PP_STAGES\t2"));
2098        assert!(!output.join("placement-checkpoint-3.tsv").exists());
2099        assert!(!output.join("placement-checkpoint-4.tsv").exists());
2100        std::fs::remove_dir_all(root).unwrap();
2101    }
2102
2103    #[test]
2104    fn pinned_source_and_wrapper_normalization_fail_closed() {
2105        assert!(parse_pinned_hf_source("org/model@main").is_err());
2106        let sha = "a".repeat(40);
2107        assert_eq!(
2108            parse_pinned_hf_source(&format!("org/model@{sha}")).unwrap(),
2109            ("org/model", sha.as_str())
2110        );
2111        assert_eq!(
2112            canonical_hf_name("model.language_model.layers.1.self_attn.q_proj.weight"),
2113            "model.layers.1.self_attn.q_proj.weight"
2114        );
2115    }
2116
2117    #[test]
2118    fn local_repack_inspect_routes_metadata_census_into_placement() {
2119        use memra_gguf::tensor_contract::TensorMatch;
2120
2121        let root =
2122            std::env::temp_dir().join(format!("memra-cli-repack-inspect-{}", std::process::id()));
2123        let output = root.join("out");
2124        std::fs::create_dir_all(&root).unwrap();
2125        let config_json = r#"{"model_type":"qwen3","num_hidden_layers":2,"hidden_size":8,
2126            "num_attention_heads":2,"num_key_value_heads":1,"head_dim":4,
2127            "intermediate_size":16,"vocab_size":32,"max_position_embeddings":32,
2128            "rms_norm_eps":0.000001}"#;
2129        std::fs::write(root.join("config.json"), config_json).unwrap();
2130        std::fs::write(root.join("tokenizer.json"), "{}").unwrap();
2131        std::fs::write(
2132            root.join("tokenizer_config.json"),
2133            r#"{"chat_template":"{{ messages }}"}"#,
2134        )
2135        .unwrap();
2136        let config = ModelConfig::from_hf(&HfConfig::parse(config_json));
2137        let pack = model_packs::by_alias("qwen3").unwrap();
2138        let plan = pack.compile_plan(&config).unwrap();
2139        let contract = pack
2140            .compile_tensor_contract(
2141                &config,
2142                &plan,
2143                CheckpointDialect::Gguf,
2144                ContractOptions {
2145                    output_head: OutputHead::Separate,
2146                },
2147            )
2148            .unwrap();
2149        let mut tensors = BTreeMap::<String, Vec<u64>>::new();
2150        for requirement in contract.requirements {
2151            if !requirement.required {
2152                continue;
2153            }
2154            let names: Vec<_> = match requirement.match_mode {
2155                TensorMatch::OneOf => requirement.names.into_iter().take(1).collect(),
2156                TensorMatch::All => requirement.names,
2157            };
2158            for name in names {
2159                tensors.insert(name, requirement.shape.clone());
2160            }
2161        }
2162        let mut blob = Vec::new();
2163        let mut fields = Vec::new();
2164        for (name, shape) in tensors {
2165            let bytes = shape.iter().product::<u64>() as usize * 4;
2166            let offset = blob.len();
2167            blob.resize(offset + bytes, 0);
2168            fields.push(format!(
2169                "{name:?}:{{\"file\":\"weights.bin\",\"offset\":{offset},\"qtype\":\"F32\",\"ne\":{:?},\"bytes\":{bytes}}}",
2170                shape,
2171            ));
2172        }
2173        std::fs::write(root.join("weights.bin"), blob).unwrap();
2174        std::fs::write(
2175            root.join("manifest.json"),
2176            format!(
2177                "{{\"format\":\"memra-repack-v1\",\"tensors\":{{{}}}}}",
2178                fields.join(",")
2179            ),
2180        )
2181        .unwrap();
2182
2183        let summary = inspect_model(InspectRequest {
2184            source: root.display().to_string(),
2185            against: "qwen3".to_string(),
2186            out_dir: output.clone(),
2187        })
2188        .unwrap();
2189        assert_eq!(summary.family, "qwen3");
2190        assert!(summary.tensor_count > 0);
2191        assert!(output.join("placement-checkpoint-2.tsv").is_file());
2192        std::fs::remove_dir_all(root).ok();
2193    }
2194
2195    #[test]
2196    fn scaffold_is_deterministic_and_refuses_non_empty_targets() {
2197        let root = std::env::temp_dir().join(format!("memra-cli-scaffold-{}", std::process::id()));
2198        scaffold_model_pack(ScaffoldRequest {
2199            family: "new_family".to_string(),
2200            out_dir: root.clone(),
2201        })
2202        .unwrap();
2203        for artifact in [
2204            "pack.toml",
2205            "aliases.txt",
2206            "config-normalization.txt",
2207            "tensor-schema.tsv",
2208            "tokenizer-template.txt",
2209            "gates.txt",
2210        ] {
2211            assert!(root.join(artifact).is_file(), "missing {artifact}");
2212        }
2213        assert!(
2214            scaffold_model_pack(ScaffoldRequest {
2215                family: "new_family".to_string(),
2216                out_dir: root.clone(),
2217            })
2218            .is_err()
2219        );
2220        assert!(validate_family_name("Bad-Family").is_err());
2221        std::fs::remove_dir_all(root).unwrap();
2222    }
2223
2224    #[test]
2225    fn unimplemented_verify_stages_refuse_without_fallback() {
2226        {
2227            let stage = VerifyStage::Serve;
2228            let error = verify_model(VerifyRequest {
2229                stage,
2230                source: "unused".to_string(),
2231                against: "qwen3".to_string(),
2232                out_dir: None,
2233                oracle: None,
2234                native_runner: None,
2235            })
2236            .err()
2237            .unwrap()
2238            .to_string();
2239            assert!(error.contains("no fallback is allowed"));
2240        }
2241    }
2242
2243    #[test]
2244    fn supported_packs_write_deterministic_native_oracles() {
2245        let root = std::env::temp_dir().join(format!("memra-cli-tiny-{}", std::process::id()));
2246        let request = || VerifyRequest {
2247            stage: VerifyStage::Tiny,
2248            source: "unused".to_string(),
2249            against: "qwen3".to_string(),
2250            out_dir: Some(root.clone()),
2251            oracle: None,
2252            native_runner: None,
2253        };
2254        verify_model(request()).unwrap();
2255        let fixture = std::fs::read(root.join("tiny-fixture.txt")).unwrap();
2256        let oracle = std::fs::read(root.join("reference-oracle.tsv")).unwrap();
2257        verify_model(request()).unwrap();
2258        assert_eq!(
2259            std::fs::read(root.join("tiny-fixture.txt")).unwrap(),
2260            fixture
2261        );
2262        assert_eq!(
2263            std::fs::read(root.join("reference-oracle.tsv")).unwrap(),
2264            oracle
2265        );
2266        for pack in model_packs::PACKS {
2267            if pack.family == "qwen3" {
2268                continue;
2269            }
2270            let result = verify_model(VerifyRequest {
2271                stage: VerifyStage::Tiny,
2272                source: "unused".to_string(),
2273                against: pack.family.to_string(),
2274                out_dir: Some(root.join(pack.family)),
2275                oracle: None,
2276                native_runner: None,
2277            });
2278            if pack.support.is_some() {
2279                result.unwrap();
2280                assert!(
2281                    root.join(pack.family)
2282                        .join("reference-oracle.tsv")
2283                        .is_file()
2284                );
2285                if pack.family.starts_with("gemma4") {
2286                    assert!(
2287                        root.join(pack.family)
2288                            .join("reference-vision-oracle.tsv")
2289                            .is_file()
2290                    );
2291                    assert!(
2292                        root.join(pack.family)
2293                            .join("reference-multimodal-oracle.tsv")
2294                            .is_file()
2295                    );
2296                }
2297            } else {
2298                assert!(result.is_err());
2299            }
2300        }
2301        std::fs::remove_dir_all(root).unwrap();
2302    }
2303
2304    #[test]
2305    fn checkpoint_oracle_bundle_is_pinned_and_parity_is_fail_closed() {
2306        let root = std::env::temp_dir().join(format!(
2307            "memra-cli-checkpoint-oracle-{}",
2308            std::process::id()
2309        ));
2310        std::fs::create_dir_all(&root).unwrap();
2311        let sha = "0123456789abcdef0123456789abcdef01234567";
2312        write_hf_oracle_bundle(&format!("org/model@{sha}"), &root).unwrap();
2313        let request = std::fs::read_to_string(root.join("oracle-request.tsv")).unwrap();
2314        let script = std::fs::read_to_string(root.join("capture-hf-oracle.py")).unwrap();
2315        assert!(request.contains(&format!("revision\t{sha}")));
2316        assert!(script.contains(&format!("REVISION = \"{sha}\"")));
2317        assert!(script.contains("trust_remote_code=False"));
2318        assert!(script.contains("dtype=torch.float32"));
2319        assert!(script.contains("source-weights-float32-accumulation"));
2320
2321        let oracle = |engine: &str, values: &[f32]| {
2322            let mut text = format!(
2323                "format\tmemra-checkpoint-oracle-v1\nengine\t{engine}\nnumeric_class\tsource-weights-float32-accumulation\ntokens\t1,2,3,4\nvocab\t{}\n",
2324                values.len()
2325            );
2326            for (index, value) in values.iter().enumerate() {
2327                writeln!(text, "logit\t{index}\t{:08x}", value.to_bits()).unwrap();
2328            }
2329            parse_checkpoint_oracle(&text).unwrap()
2330        };
2331        let reference = oracle("hf-transformers", &[0.0, 1.0, -1.0]);
2332        let native = oracle("memra-native", &[0.0, 1.001, -1.001]);
2333        let gate = model_packs::CheckpointParityGate {
2334            max_abs: 0.01,
2335            max_rel: 2.0,
2336            require_argmax: true,
2337        };
2338        assert!(compare_checkpoint_oracles(&reference, &native, gate).is_ok());
2339        let failing = oracle("memra-native", &[2.0, 1.0, -1.0]);
2340        assert!(compare_checkpoint_oracles(&reference, &failing, gate).is_err());
2341        std::fs::remove_dir_all(root).unwrap();
2342    }
2343
2344    #[test]
2345    fn rewrite_verifier_binds_manifest_plan_and_exact_streams() {
2346        let root =
2347            std::env::temp_dir().join(format!("memra-cli-rewrite-receipt-{}", std::process::id()));
2348        std::fs::create_dir_all(&root).unwrap();
2349        let config = ModelConfig::from_hf(&HfConfig::parse(
2350            r#"{"model_type":"qwen3","num_hidden_layers":2,"hidden_size":64,
2351            "num_attention_heads":2,"num_key_value_heads":1,"head_dim":32,
2352            "intermediate_size":128,"vocab_size":16,"max_position_embeddings":128}"#,
2353        ));
2354        let plan = memra_gguf::model_plan::ModelPlan::compile(&config).unwrap();
2355        let rewrites = memra_gguf::execution_manifest::execution_rewrites(&plan);
2356        let rewrite = rewrites
2357            .iter()
2358            .find(|rewrite| {
2359                rewrite.surface == memra_gguf::execution_manifest::RewriteSurface::DecodeBatch
2360            })
2361            .unwrap();
2362        let artifact_lock = b"format_version=2\nfamily=qwen3\n";
2363        std::fs::write(root.join("artifact.lock"), artifact_lock).unwrap();
2364        std::fs::write(
2365            root.join("execution-rewrites.tsv"),
2366            format_execution_rewrites(&rewrites),
2367        )
2368        .unwrap();
2369        let receipt = rewrite
2370            .verify_logits(
2371                &"00".repeat(32),
2372                &[0.0, 1.0, -1.0],
2373                &[0.0, 1.0, -1.0],
2374                memra_gguf::execution_manifest::RewriteParityPolicy {
2375                    max_abs: 0.0,
2376                    max_rel: 0.0,
2377                    require_argmax: true,
2378                },
2379            )
2380            .unwrap()
2381            .bind_artifact_lock(artifact_lock)
2382            .to_tsv();
2383        let receipt_path = root.join("receipt.tsv");
2384        std::fs::write(&receipt_path, &receipt).unwrap();
2385        verify_rewrite_receipt(
2386            model_packs::by_alias("qwen3").unwrap(),
2387            &receipt_path,
2388            &root,
2389        )
2390        .unwrap();
2391        assert!(
2392            std::fs::read_to_string(root.join("rewrite-receipts.tsv"))
2393                .unwrap()
2394                .contains("decode-batch.v1")
2395        );
2396
2397        let wrong = receipt.replace(&rewrite.plan_sha256, &"11".repeat(32));
2398        std::fs::write(&receipt_path, wrong).unwrap();
2399        assert!(
2400            verify_rewrite_receipt(
2401                model_packs::by_alias("qwen3").unwrap(),
2402                &receipt_path,
2403                &root,
2404            )
2405            .is_err()
2406        );
2407        std::fs::remove_dir_all(root).unwrap();
2408    }
2409
2410    #[cfg(unix)]
2411    #[test]
2412    fn native_serve_gate_launches_readiness_and_completion_on_real_http() {
2413        use std::os::unix::fs::PermissionsExt;
2414
2415        let root =
2416            std::env::temp_dir().join(format!("memra-cli-serve-gate-{}", std::process::id()));
2417        let model = root.join("model");
2418        std::fs::create_dir_all(&model).unwrap();
2419        let artifact_lock = format!(
2420            "source={}\nbinding=passed\ntokenizer=passed\n",
2421            lock_value(model.to_str().unwrap())
2422        );
2423        std::fs::write(root.join("artifact.lock"), &artifact_lock).unwrap();
2424        std::fs::write(
2425            root.join("checkpoint-parity.tsv"),
2426            format!(
2427                "status\tpassed\nartifact_lock_sha256\t{}\n",
2428                hex_sha256(artifact_lock.as_bytes())
2429            ),
2430        )
2431        .unwrap();
2432        let runner = root.join("fake-memra-server.py");
2433        std::fs::write(
2434            &runner,
2435            r#"#!/usr/bin/env python3
2436import json, os
2437from http.server import BaseHTTPRequestHandler, HTTPServer
2438host, port = os.environ["MEMRA_ADDR"].rsplit(":", 1)
2439class Handler(BaseHTTPRequestHandler):
2440    def log_message(self, *args): pass
2441    def do_GET(self):
2442        self.send_response(200 if self.path == "/readyz" else 404)
2443        self.end_headers()
2444        self.wfile.write(b"ready")
2445    def do_POST(self):
2446        length = int(self.headers.get("content-length", "0"))
2447        self.rfile.read(length)
2448        body = json.dumps({"choices":[{"text":"ok"}]}).encode()
2449        self.send_response(200)
2450        self.send_header("content-type", "application/json")
2451        self.send_header("content-length", str(len(body)))
2452        self.end_headers()
2453        self.wfile.write(body)
2454HTTPServer((host, int(port)), Handler).serve_forever()
2455"#,
2456        )
2457        .unwrap();
2458        let mut permissions = std::fs::metadata(&runner).unwrap().permissions();
2459        permissions.set_mode(0o755);
2460        std::fs::set_permissions(&runner, permissions).unwrap();
2461        verify_native_serve(
2462            model_packs::by_alias("qwen3").unwrap(),
2463            model.to_str().unwrap(),
2464            &root,
2465            &runner,
2466        )
2467        .unwrap();
2468        assert!(root.join("serve-response.json").is_file());
2469        assert!(
2470            std::fs::read_to_string(root.join("gates.txt"))
2471                .unwrap()
2472                .contains("Serve=passed")
2473        );
2474        std::fs::remove_dir_all(root).unwrap();
2475    }
2476}