Skip to main content

wai_quantum/
quantum_cal.rs

1//! Deterministic autonomous qubit CALIBRATION — `wai.quantum.cal.rabi`
2//! (extensions/quantum-ops § Calibration engines).
3//!
4//! The quantum-control field (Q-CTRL, QuantrolOx, Qruise, Conductor …) sells one
5//! thing above all: **autonomous gate tune-up** — sweep a control parameter,
6//! measure the qubit, fit the response, set the optimum, no human in the loop.
7//! Those are *algorithms that run on measured data*, and the vendors develop and
8//! demo them against **simulators / digital twins** (Qruise ships one by name).
9//! This module is that algorithm — the canonical **Rabi π-pulse tune-up** — done
10//! the WAI way: a deterministic fixed-point device simulator + an autonomous
11//! calibrator, **byte-identical on every machine** (a portable tune-up hash), so
12//! a calibration run reproduces exactly and drops straight into a signed,
13//! joule-metered [`crate::quantum_ops::CalibrationReceipt`].
14//!
15//! Two honest boundaries: (1) it tunes a **simulated** device — we have no
16//! cryostat, exactly the surface a digital-twin demo runs on; (2) the physics
17//! model is a clean Rabi model, not a full transmon Hamiltonian. What is *not*
18//! approximate is the reproducibility: no float anywhere in the run, so the
19//! calibrated amplitude and the outcome hash are the same bytes everywhere — the
20//! property the float vendor stacks cannot offer, on top of which the receipt
21//! makes every run auditable.
22
23/// Fixed-point fractional bits. All amplitudes, probabilities and angles are i64
24/// at `2^CAL_FRAC`. Probabilities live in `[0, CAL_ONE]`.
25pub const CAL_FRAC: u32 = 20;
26/// `1.0` in fixed-point.
27pub const CAL_ONE: i64 = 1 << CAL_FRAC;
28/// `π · 2^CAL_FRAC` (integer constant — no float at runtime).
29const PI_FX: i64 = 3_294_199; // round(π · 2^20)
30
31#[inline]
32fn fmul(a: i64, b: i64) -> i64 {
33    ((a as i128 * b as i128) >> CAL_FRAC) as i64
34}
35
36/// Fixed-point sine via the Bhaskara-I rational approximation (max error ≈ 0.16%,
37/// pure integer). Reduced modulo `π`: callers square the result, and `sin²` has
38/// period `π`, so the sign dropped by the reduction is irrelevant. Deterministic
39/// by construction — the same bytes on every machine.
40pub fn sin2_fx(theta: i64) -> i64 {
41    let pi = PI_FX as i128;
42    let t = (theta as i128).rem_euclid(pi); // [0, π)
43    let p = t * (pi - t); // t(π−t) at 2^(2·CAL_FRAC)
44    let num = 16 * p;
45    let den = 5 * pi * pi - 4 * p;
46    let s = ((num << CAL_FRAC) / den) as i64; // sin(t) at 2^CAL_FRAC, in [0, ~CAL_ONE]
47    fmul(s, s) // sin²(t) at 2^CAL_FRAC
48}
49
50// ---------------------------------------------------------------------------
51// Deterministic device simulator
52// ---------------------------------------------------------------------------
53
54fn splitmix64(state: &mut u64) -> u64 {
55    *state = state.wrapping_add(0x9E37_79B9_7F4A_7C15);
56    let mut z = *state;
57    z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
58    z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
59    z ^ (z >> 31)
60}
61
62/// A single driven qubit under a Rabi model. The calibrator does not see
63/// `a_pi_fx` — it is the hidden truth the tune-up must discover.
64#[derive(Clone, Copy, Debug)]
65pub struct Device {
66    /// The true π-pulse amplitude (fixed-point) — hidden from the calibrator.
67    pub a_pi_fx: i64,
68    /// A per-device stream seed, so two devices with the same `a_pi` still shot-
69    /// noise independently but each reproducibly.
70    pub seed: u64,
71}
72
73impl Device {
74    /// Exact excited-state probability at drive amplitude `a`:
75    /// `P(a) = sin²(π·a / (2·a_π))`. Pure integer.
76    pub fn excited_prob(&self, a_fx: i64) -> i64 {
77        // θ = π·a / (2·a_π), fixed-point
78        let theta = ((PI_FX as i128 * a_fx as i128) / (2 * self.a_pi_fx as i128)) as i64;
79        sin2_fx(theta)
80    }
81
82    /// One "experiment": `shots` projective measurements at amplitude `a`, returning
83    /// the measured excited fraction (fixed-point). Deterministic Bernoulli sampling
84    /// via `splitmix64` keyed by `(seed, a)`, so the shot noise is real but portable.
85    pub fn measure(&self, a_fx: i64, shots: u32) -> i64 {
86        let p = self.excited_prob(a_fx);
87        let mut st = self
88            .seed
89            .wrapping_mul(0x1000_0001)
90            .wrapping_add(a_fx as u64);
91        let mut hits: u64 = 0;
92        for _ in 0..shots {
93            let r = (splitmix64(&mut st) >> (64 - CAL_FRAC)) as i64; // [0, CAL_ONE)
94            if r < p {
95                hits += 1;
96            }
97        }
98        ((hits as i128 * CAL_ONE as i128) / shots.max(1) as i128) as i64
99    }
100}
101
102// ---------------------------------------------------------------------------
103// Autonomous Rabi tune-up
104// ---------------------------------------------------------------------------
105
106/// Sweep + refinement schedule for [`calibrate_rabi`].
107#[derive(Clone, Copy, Debug)]
108pub struct TuneConfig {
109    /// Upper bound of the amplitude sweep (fixed-point). Choose ≳ 1.5× the
110    /// expected π-amplitude so the first Rabi lobe is contained.
111    pub a_max_fx: i64,
112    /// Coarse-sweep points across `[0, a_max]`.
113    pub n_coarse: u32,
114    /// Fine-sweep points around the coarse peak (± one coarse step).
115    pub n_fine: u32,
116    /// Shots per measurement.
117    pub shots: u32,
118}
119
120impl Default for TuneConfig {
121    fn default() -> Self {
122        TuneConfig { a_max_fx: 2 * CAL_ONE, n_coarse: 41, n_fine: 41, shots: 2000 }
123    }
124}
125
126/// The result of an autonomous tune-up. Deterministic given `(device, cfg)`.
127#[derive(Clone, Debug, PartialEq, Eq)]
128pub struct TuneResult {
129    /// The calibrated π-pulse amplitude (fixed-point).
130    pub a_pi_est_fx: i64,
131    /// Measured excited fraction at the calibrated amplitude — the tune-up's own
132    /// evidence of a good π rotation (`≈ CAL_ONE` is a clean π-pulse).
133    pub peak_prob_fx: i64,
134    /// Total measurements performed (the deterministic "work" of the run).
135    pub n_measurements: u32,
136    /// The full sweep: `(amplitude, measured_prob)` at `2^CAL_FRAC`, coarse then fine.
137    pub sweep: Vec<(i64, i64)>,
138}
139
140impl TuneResult {
141    /// BLAKE3 over the canonical outcome — a portable tune-up hash. Two machines
142    /// running the same `(device, cfg)` get this same hash.
143    pub fn hash(&self) -> [u8; 32] {
144        let mut h = blake3::Hasher::new();
145        h.update(b"wai:quantum-cal-rabi\x01");
146        h.update(&self.a_pi_est_fx.to_le_bytes());
147        h.update(&self.peak_prob_fx.to_le_bytes());
148        h.update(&(self.n_measurements as u64).to_le_bytes());
149        for (a, p) in &self.sweep {
150            h.update(&a.to_le_bytes());
151            h.update(&p.to_le_bytes());
152        }
153        *h.finalize().as_bytes()
154    }
155
156    /// Vendor-neutral artifacts for [`seal_artifacts`] — uniform with the other
157    /// routines' `artifacts()`.
158    pub fn artifacts(&self) -> CalArtifacts {
159        let mut ev = Vec::with_capacity(self.sweep.len() * 16 + 16);
160        ev.extend_from_slice(&self.a_pi_est_fx.to_le_bytes());
161        ev.extend_from_slice(&self.peak_prob_fx.to_le_bytes());
162        for (a, p) in &self.sweep {
163            ev.extend_from_slice(&a.to_le_bytes());
164            ev.extend_from_slice(&p.to_le_bytes());
165        }
166        CalArtifacts {
167            target: "1q_gate_amplitude".into(),
168            config_bytes: self.a_pi_est_fx.to_le_bytes().to_vec(),
169            evidence_kind: "rabi_amplitude_sweep".into(),
170            evidence_bytes: ev,
171            summary: format!("pi_amp={} peak_prob={} (2^{CAL_FRAC})", self.a_pi_est_fx, self.peak_prob_fx),
172        }
173    }
174}
175
176/// The autonomous calibrator: sweep the drive amplitude, then **fit the whole
177/// Rabi curve to the model** `P(a) = sin²(π·a/2a_π)` — searching the candidate
178/// π-amplitude that minimizes total error, coarse then fine. Whole-curve fitting
179/// (what real tune-ups do) is robust where an argmax fails: near a *flat* maximum
180/// shot noise moves the peak sample, but the model fit uses every point. Pure
181/// integer — byte-identical on every machine.
182pub fn calibrate_rabi(device: &Device, cfg: &TuneConfig) -> TuneResult {
183    let n = cfg.n_coarse.max(4);
184    let mut sweep = Vec::with_capacity(n as usize);
185    for i in 0..n {
186        let a = ((cfg.a_max_fx as i128 * i as i128) / (n - 1) as i128) as i64;
187        sweep.push((a, device.measure(a, cfg.shots)));
188    }
189
190    // Model-fit a_π over a candidate grid: minimize Σ|measured − sin²(π·a/2a_π)|.
191    let fit = |lo: i64, hi: i64, steps: u32| -> i64 {
192        let steps = steps.max(2);
193        let mut best = lo.max(1);
194        let mut best_err = i128::MAX;
195        for g in 1..=steps {
196            let a_pi = lo + ((hi - lo) as i128 * g as i128 / steps as i128) as i64;
197            if a_pi <= 0 {
198                continue;
199            }
200            let mut err = 0i128;
201            for &(a, p) in &sweep {
202                let theta = ((PI_FX as i128 * a as i128) / (2 * a_pi as i128)) as i64;
203                err += (p - sin2_fx(theta)).unsigned_abs() as i128;
204            }
205            if err < best_err {
206                best_err = err;
207                best = a_pi;
208            }
209        }
210        best
211    };
212    let coarse_step = cfg.a_max_fx / (n as i64 - 1);
213    let a_coarse = fit(coarse_step, cfg.a_max_fx, cfg.n_coarse.max(24));
214    let a_pi = fit((a_coarse - coarse_step).max(1), a_coarse + coarse_step, cfg.n_fine.max(24));
215
216    // A verification pulse at the calibrated amplitude — the π-rotation quality.
217    let peak = device.measure(a_pi, cfg.shots);
218    TuneResult { a_pi_est_fx: a_pi, peak_prob_fx: peak, n_measurements: n + 1, sweep }
219}
220
221// ---------------------------------------------------------------------------
222// Calibration → signed receipt
223// ---------------------------------------------------------------------------
224
225#[cfg(feature = "quantum_ops")]
226mod sealed {
227    use super::*;
228    use crate::quantum_ops::{content_hash, CalibrationReceipt, Evidence, GrantRef};
229    use ed25519_dalek::SigningKey;
230
231    /// Serialize the sweep to canonical bytes (the "raw dataset" the receipt
232    /// content-addresses — the analog of a vendor HDF5 tuning trace).
233    pub fn sweep_bytes(r: &TuneResult) -> Vec<u8> {
234        let mut o = Vec::with_capacity(r.sweep.len() * 16 + 16);
235        o.extend_from_slice(&r.a_pi_est_fx.to_le_bytes());
236        o.extend_from_slice(&r.peak_prob_fx.to_le_bytes());
237        for (a, p) in &r.sweep {
238            o.extend_from_slice(&a.to_le_bytes());
239            o.extend_from_slice(&p.to_le_bytes());
240        }
241        o
242    }
243
244    /// Run an autonomous Rabi tune-up and seal a `wai.quantum.calibration`
245    /// receipt over it: the config hash pins the calibrated amplitude, the
246    /// evidence content-addresses the full sweep, the joules are the run's
247    /// measured energy, and the grant authorizes it. The tune-up is byte-exact,
248    /// so a verifier re-running `(device, cfg)` reproduces the sealed evidence.
249    #[allow(clippy::too_many_arguments)]
250    pub fn calibrate_and_seal(
251        signer: &SigningKey,
252        signer_id: impl Into<String>,
253        device_id: impl Into<String>,
254        target: impl Into<String>,
255        device: &Device,
256        cfg: &TuneConfig,
257        joules_micro: u64,
258        grant: GrantRef,
259        parent: Option<[u8; 32]>,
260    ) -> (TuneResult, CalibrationReceipt) {
261        let r = calibrate_rabi(device, cfg);
262        // config = the tuned control parameter (the calibrated π-amplitude).
263        let config_hash = content_hash(&r.a_pi_est_fx.to_le_bytes());
264        // evidence = the sweep dataset + the achieved π-fidelity proxy.
265        let ev = vec![Evidence {
266            kind: "rabi_amplitude_sweep".into(),
267            blob_hash: content_hash(&sweep_bytes(&r)),
268            summary: format!(
269                "pi_amp={} peak_prob={} (fixed-point 2^{})",
270                r.a_pi_est_fx, r.peak_prob_fx, CAL_FRAC
271            ),
272        }];
273        let receipt = CalibrationReceipt::seal(
274            signer, signer_id, device_id, target, config_hash, ev, joules_micro, grant,
275            parent,
276        );
277        (r, receipt)
278    }
279}
280
281#[cfg(feature = "quantum_ops")]
282pub use sealed::{calibrate_and_seal, sweep_bytes};
283
284// ===========================================================================
285// Shared fixed-point machinery for the other routines
286// ===========================================================================
287
288const TWO_PI_FX: i64 = 6_588_397; // round(2π · 2^20)
289const HALF_PI_FX: i64 = 1_647_099; // round(π/2 · 2^20)
290const LN2_FX: i64 = 726_817; // round(ln2 · 2^20)
291
292/// Signed sine over a full period, `[-CAL_ONE, CAL_ONE]`, via Bhaskara on each half.
293pub fn sin_fx(theta: i64) -> i64 {
294    let two_pi = TWO_PI_FX as i128;
295    let mut t = (theta as i128).rem_euclid(two_pi); // [0, 2π)
296    let pi = PI_FX as i128;
297    let sign = if t >= pi {
298        t -= pi;
299        -1i64
300    } else {
301        1
302    };
303    let p = t * (pi - t);
304    let num = 16 * p;
305    let den = 5 * pi * pi - 4 * p;
306    let s = ((num << CAL_FRAC) / den) as i64;
307    sign * s
308}
309
310/// Signed cosine, `cos(x) = sin(x + π/2)`.
311pub fn cos_fx(theta: i64) -> i64 {
312    sin_fx(theta + HALF_PI_FX)
313}
314
315/// `exp(-x)` for `x ≥ 0`, fixed-point. Splits `x = k·ln2 + r`, a cubic on the
316/// small remainder, and `2^-k` by shift. Pure integer, deterministic.
317pub fn exp_neg_fx(x_fx: i64) -> i64 {
318    if x_fx <= 0 {
319        return CAL_ONE;
320    }
321    let k = x_fx / LN2_FX;
322    let r = x_fx - k * LN2_FX; // [0, ln2)
323    let r2 = fmul(r, r);
324    let r3 = fmul(r2, r);
325    let er = CAL_ONE - r + r2 / 2 - r3 / 6; // exp(-r)
326    if k >= 62 {
327        return 0;
328    }
329    (er >> k).max(0)
330}
331
332fn ratio_fx(a: i64, b: i64) -> i64 {
333    if b == 0 {
334        return 0;
335    }
336    (((a as i128) << CAL_FRAC) / b as i128) as i64
337}
338
339/// The vendor-neutral artifacts of any calibration run — what a receipt binds:
340/// the target, the calibrated parameter (`config`), and the evidence dataset.
341#[derive(Clone, Debug, PartialEq, Eq)]
342pub struct CalArtifacts {
343    pub target: String,
344    pub config_bytes: Vec<u8>,
345    pub evidence_kind: String,
346    pub evidence_bytes: Vec<u8>,
347    pub summary: String,
348}
349
350// ===========================================================================
351// Ramsey / T2* — dephasing + detuning
352// ===========================================================================
353
354/// A driven qubit under a Ramsey model: free-induction with an angular detuning
355/// `omega` and a dephasing time `t2`. The calibrator sees neither.
356#[derive(Clone, Copy, Debug)]
357pub struct RamseyDevice {
358    /// Angular detuning ω (rad per unit time, fixed-point) — hidden.
359    pub omega_fx: i64,
360    /// Dephasing time T2 (fixed-point) — hidden.
361    pub t2_fx: i64,
362    pub seed: u64,
363}
364
365impl RamseyDevice {
366    /// `P(τ) = ½(1 + cos(ω·τ)·exp(-τ/T2))`.
367    pub fn prob(&self, tau_fx: i64) -> i64 {
368        let c = cos_fx(fmul(self.omega_fx, tau_fx));
369        let env = exp_neg_fx(ratio_fx(tau_fx, self.t2_fx));
370        (CAL_ONE + fmul(c, env)) / 2
371    }
372    pub fn measure(&self, tau_fx: i64, shots: u32) -> i64 {
373        let p = self.prob(tau_fx);
374        let mut st = self.seed.wrapping_mul(0x2545_F491).wrapping_add(tau_fx as u64);
375        let mut hits = 0u64;
376        for _ in 0..shots {
377            let r = (splitmix64(&mut st) >> (64 - CAL_FRAC)) as i64;
378            if r < p {
379                hits += 1;
380            }
381        }
382        ((hits as i128 * CAL_ONE as i128) / shots.max(1) as i128) as i64
383    }
384}
385
386/// Ramsey autonomous fit — coarse search for the detuning ω (correlation) then
387/// the dephasing T2 (least model error), both over deterministic parameter grids.
388#[derive(Clone, Debug, PartialEq, Eq)]
389pub struct RamseyResult {
390    pub omega_est_fx: i64,
391    pub t2_est_fx: i64,
392    pub sweep: Vec<(i64, i64)>,
393    pub n_measurements: u32,
394}
395
396impl RamseyResult {
397    pub fn hash(&self) -> [u8; 32] {
398        let mut h = blake3::Hasher::new();
399        h.update(b"wai:quantum-cal-ramsey\x01");
400        h.update(&self.omega_est_fx.to_le_bytes());
401        h.update(&self.t2_est_fx.to_le_bytes());
402        for (a, b) in &self.sweep {
403            h.update(&a.to_le_bytes());
404            h.update(&b.to_le_bytes());
405        }
406        *h.finalize().as_bytes()
407    }
408    pub fn artifacts(&self) -> CalArtifacts {
409        let mut cfg = Vec::new();
410        cfg.extend_from_slice(&self.omega_est_fx.to_le_bytes());
411        cfg.extend_from_slice(&self.t2_est_fx.to_le_bytes());
412        let mut ev = Vec::new();
413        for (a, b) in &self.sweep {
414            ev.extend_from_slice(&a.to_le_bytes());
415            ev.extend_from_slice(&b.to_le_bytes());
416        }
417        CalArtifacts {
418            target: "dephasing".into(),
419            config_bytes: cfg,
420            evidence_kind: "ramsey_fringe".into(),
421            evidence_bytes: ev,
422            summary: format!("omega={} t2={} (2^{CAL_FRAC})", self.omega_est_fx, self.t2_est_fx),
423        }
424    }
425}
426
427/// `tau_max`, points, shots; `omega_max`/`t2_max` bound the fit search grids.
428#[derive(Clone, Copy, Debug)]
429pub struct RamseyConfig {
430    pub tau_max_fx: i64,
431    pub n_points: u32,
432    pub shots: u32,
433    pub omega_max_fx: i64,
434    pub t2_max_fx: i64,
435    pub n_grid: u32,
436}
437
438pub fn calibrate_ramsey(dev: &RamseyDevice, cfg: &RamseyConfig) -> RamseyResult {
439    let n = cfg.n_points.max(4);
440    let mut sweep = Vec::with_capacity(n as usize);
441    for i in 0..n {
442        let tau = ((cfg.tau_max_fx as i128 * i as i128) / (n - 1) as i128) as i64;
443        sweep.push((tau, dev.measure(tau, cfg.shots)));
444    }
445    // detuning: maximize |Σ (P−½)·cos(ω·τ)| over candidate ω
446    let ng = cfg.n_grid.max(4);
447    let mut best_omega = 0i64;
448    let mut best_score = -1i128;
449    for g in 1..ng {
450        let omega = ((cfg.omega_max_fx as i128 * g as i128) / ng as i128) as i64;
451        let mut acc = 0i128;
452        for &(tau, p) in &sweep {
453            acc += ((p - CAL_ONE / 2) as i128 * cos_fx(fmul(omega, tau)) as i128) >> CAL_FRAC;
454        }
455        let s = acc.abs();
456        if s > best_score {
457            best_score = s;
458            best_omega = omega;
459        }
460    }
461    // T2: minimize Σ |P − model(ω_est, T2)| over candidate T2
462    let mut best_t2 = cfg.t2_max_fx;
463    let mut best_err = i128::MAX;
464    for g in 1..=ng {
465        let t2 = ((cfg.t2_max_fx as i128 * g as i128) / ng as i128) as i64;
466        let probe = RamseyDevice { omega_fx: best_omega, t2_fx: t2, seed: 0 };
467        let mut err = 0i128;
468        for &(tau, p) in &sweep {
469            err += (p - probe.prob(tau)).unsigned_abs() as i128;
470        }
471        if err < best_err {
472            best_err = err;
473            best_t2 = t2;
474        }
475    }
476    RamseyResult { omega_est_fx: best_omega, t2_est_fx: best_t2, sweep, n_measurements: n }
477}
478
479// ===========================================================================
480// Randomized benchmarking — average gate fidelity
481// ===========================================================================
482
483/// A gate set with a per-gate depolarizing error `epsilon` — hidden.
484#[derive(Clone, Copy, Debug)]
485pub struct RbDevice {
486    pub epsilon_fx: i64,
487    pub seed: u64,
488}
489
490impl RbDevice {
491    /// Survival probability of a length-`m` Clifford sequence:
492    /// `P(m) = ½ + ½·p^m`, `p = 1 − 2ε`.
493    pub fn survival(&self, m: u32) -> i64 {
494        let p = CAL_ONE - 2 * self.epsilon_fx;
495        let mut pm = CAL_ONE;
496        for _ in 0..m {
497            pm = fmul(pm, p);
498        }
499        CAL_ONE / 2 + fmul(CAL_ONE / 2, pm)
500    }
501    /// `k` random sequences × `shots` each at length `m` — measured survival.
502    pub fn measure(&self, m: u32, k: u32, shots: u32) -> i64 {
503        let s = self.survival(m);
504        let mut st = self.seed.wrapping_mul(0x27D4_EB2F).wrapping_add(m as u64);
505        let mut hits = 0u64;
506        let total = (k.max(1) as u64) * shots.max(1) as u64;
507        for _ in 0..total {
508            let r = (splitmix64(&mut st) >> (64 - CAL_FRAC)) as i64;
509            if r < s {
510                hits += 1;
511            }
512        }
513        ((hits as i128 * CAL_ONE as i128) / total as i128) as i64
514    }
515}
516
517#[derive(Clone, Debug, PartialEq, Eq)]
518pub struct RbResult {
519    /// Fitted depolarizing parameter p.
520    pub p_est_fx: i64,
521    /// Average 1-qubit gate fidelity `F = 1 − (1−p)/2`.
522    pub fidelity_fx: i64,
523    pub curve: Vec<(u32, i64)>,
524}
525
526impl RbResult {
527    pub fn hash(&self) -> [u8; 32] {
528        let mut h = blake3::Hasher::new();
529        h.update(b"wai:quantum-cal-rb\x01");
530        h.update(&self.p_est_fx.to_le_bytes());
531        h.update(&self.fidelity_fx.to_le_bytes());
532        for (m, s) in &self.curve {
533            h.update(&m.to_le_bytes());
534            h.update(&s.to_le_bytes());
535        }
536        *h.finalize().as_bytes()
537    }
538    pub fn artifacts(&self) -> CalArtifacts {
539        let mut ev = Vec::new();
540        for (m, s) in &self.curve {
541            ev.extend_from_slice(&m.to_le_bytes());
542            ev.extend_from_slice(&s.to_le_bytes());
543        }
544        CalArtifacts {
545            target: "1q_gate".into(),
546            config_bytes: self.p_est_fx.to_le_bytes().to_vec(),
547            evidence_kind: "randomized_benchmarking".into(),
548            evidence_bytes: ev,
549            summary: format!("p={} fidelity={} (2^{CAL_FRAC})", self.p_est_fx, self.fidelity_fx),
550        }
551    }
552}
553
554#[derive(Clone, Copy, Debug)]
555pub struct RbConfig {
556    /// Sequence lengths to sample (inclusive powers/steps chosen by the caller).
557    pub lengths: [u32; 8],
558    pub k_sequences: u32,
559    pub shots: u32,
560    pub n_grid: u32,
561}
562
563pub fn calibrate_rb(dev: &RbDevice, cfg: &RbConfig) -> RbResult {
564    let curve: Vec<(u32, i64)> =
565        cfg.lengths.iter().map(|&m| (m, dev.measure(m, cfg.k_sequences, cfg.shots))).collect();
566    // fit p: minimize Σ |measured − (½ + ½·p^m)| over candidate p ∈ (0,1)
567    let ng = cfg.n_grid.max(8);
568    let mut best_p = CAL_ONE;
569    let mut best_err = i128::MAX;
570    for g in 1..ng {
571        let p = ((CAL_ONE as i128 * g as i128) / ng as i128) as i64;
572        let mut err = 0i128;
573        for &(m, s) in &curve {
574            let mut pm = CAL_ONE;
575            for _ in 0..m {
576                pm = fmul(pm, p);
577            }
578            let pred = CAL_ONE / 2 + fmul(CAL_ONE / 2, pm);
579            err += (s - pred).unsigned_abs() as i128;
580        }
581        if err < best_err {
582            best_err = err;
583            best_p = p;
584        }
585    }
586    let fidelity = CAL_ONE - (CAL_ONE - best_p) / 2;
587    RbResult { p_est_fx: best_p, fidelity_fx: fidelity, curve }
588}
589
590// ===========================================================================
591// Readout discrimination — GMM classification fidelity
592// ===========================================================================
593
594/// A dispersive readout projected onto its discrimination axis: `|0⟩ ~ N(s0,σ)`,
595/// `|1⟩ ~ N(s1,σ)`. The calibrator gets labeled shots and finds the threshold.
596#[derive(Clone, Copy, Debug)]
597pub struct ReadoutDevice {
598    pub s0_fx: i64,
599    pub s1_fx: i64,
600    pub sigma_fx: i64,
601    pub seed: u64,
602}
603
604impl ReadoutDevice {
605    fn gaussian(mean: i64, sigma: i64, st: &mut u64) -> i64 {
606        // sum of 12 U[0,1) − 6 ≈ N(0,1)
607        let mut acc = 0i64;
608        for _ in 0..12 {
609            acc += (splitmix64(st) >> (64 - CAL_FRAC)) as i64;
610        }
611        let z = acc - 6 * CAL_ONE;
612        mean + fmul(z, sigma)
613    }
614    /// `n` labeled shots per class: `(zeros, ones)` readout values.
615    pub fn dataset(&self, n: u32) -> (Vec<i64>, Vec<i64>) {
616        let mut st0 = self.seed ^ 0xA5A5;
617        let mut st1 = self.seed ^ 0x5A5A;
618        let zeros = (0..n).map(|_| Self::gaussian(self.s0_fx, self.sigma_fx, &mut st0)).collect();
619        let ones = (0..n).map(|_| Self::gaussian(self.s1_fx, self.sigma_fx, &mut st1)).collect();
620        (zeros, ones)
621    }
622}
623
624#[derive(Clone, Debug, PartialEq, Eq)]
625pub struct ReadoutResult {
626    pub threshold_fx: i64,
627    pub mean0_fx: i64,
628    pub mean1_fx: i64,
629    /// Assignment fidelity `1 − ½(P(1|0)+P(0|1))` at the fitted threshold.
630    pub fidelity_fx: i64,
631    pub n_shots: u32,
632}
633
634impl ReadoutResult {
635    pub fn hash(&self) -> [u8; 32] {
636        let mut h = blake3::Hasher::new();
637        h.update(b"wai:quantum-cal-readout\x01");
638        for v in [self.threshold_fx, self.mean0_fx, self.mean1_fx, self.fidelity_fx] {
639            h.update(&v.to_le_bytes());
640        }
641        h.update(&self.n_shots.to_le_bytes());
642        *h.finalize().as_bytes()
643    }
644    pub fn artifacts(&self) -> CalArtifacts {
645        let mut cfg = Vec::new();
646        cfg.extend_from_slice(&self.threshold_fx.to_le_bytes());
647        CalArtifacts {
648            target: "readout".into(),
649            config_bytes: cfg,
650            evidence_kind: "readout_gmm".into(),
651            evidence_bytes: {
652                let mut e = Vec::new();
653                for v in [self.mean0_fx, self.mean1_fx, self.fidelity_fx] {
654                    e.extend_from_slice(&v.to_le_bytes());
655                }
656                e.extend_from_slice(&self.n_shots.to_le_bytes());
657                e
658            },
659            summary: format!("threshold={} fidelity={} (2^{CAL_FRAC})", self.threshold_fx, self.fidelity_fx),
660        }
661    }
662}
663
664pub fn calibrate_readout(dev: &ReadoutDevice, n_per_class: u32) -> ReadoutResult {
665    let (zeros, ones) = dev.dataset(n_per_class);
666    let mean = |v: &[i64]| (v.iter().map(|&x| x as i128).sum::<i128>() / v.len().max(1) as i128) as i64;
667    let m0 = mean(&zeros);
668    let m1 = mean(&ones);
669    let threshold = (m0 + m1) / 2;
670    // classify: predict 1 if value is on the |1⟩ side of the threshold
671    let high1 = m1 >= m0;
672    let mis0 = zeros.iter().filter(|&&x| (x >= threshold) == high1).count();
673    let mis1 = ones.iter().filter(|&&x| (x >= threshold) != high1).count();
674    let n = n_per_class.max(1) as i128;
675    let err = ((mis0 as i128 * CAL_ONE as i128 / n) + (mis1 as i128 * CAL_ONE as i128 / n)) / 2;
676    ReadoutResult {
677        threshold_fx: threshold,
678        mean0_fx: m0,
679        mean1_fx: m1,
680        fidelity_fx: CAL_ONE - err as i64,
681        n_shots: n_per_class,
682    }
683}
684
685// ===========================================================================
686// Charge-stability tuning — silicon-spin double-dot autotuning
687// (Conductor Quantum / QuantrolOx origin capability): find the gate-voltage
688// operating point for a target charge configuration from a 2D charge-stability
689// scan. The honeycomb is a clean integer function of the *hidden* capacitance
690// model; the tuner discovers the operating point from the scan, byte-exactly —
691// exactly what a silicon-spin autotuner does, minus the float and plus a receipt.
692// ===========================================================================
693
694/// A double quantum dot under a constant-interaction capacitance model. Two
695/// plunger gates set the charge configuration `(n_L, n_R)`; cross-capacitance
696/// (`beta`) tilts the transitions into the classic honeycomb. The lever arms and
697/// offsets are the hidden truth the tuner never sees.
698#[derive(Clone, Copy, Debug)]
699pub struct ChargeDevice {
700    pub alpha_l_fx: i64,
701    pub alpha_r_fx: i64,
702    pub beta_lr_fx: i64,
703    pub beta_rl_fx: i64,
704    pub off_l_fx: i64,
705    pub off_r_fx: i64,
706}
707
708impl ChargeDevice {
709    /// The ground-state charge configuration `(n_L, n_R)` at gate voltages
710    /// `(v_l, v_r)` — what the charge sensor reads. Pure integer; the `>> CAL_FRAC`
711    /// is a floor (arithmetic shift), clamped to non-negative occupation.
712    pub fn charge_state(&self, v_l: i64, v_r: i64) -> (i32, i32) {
713        let e_l = fmul(self.alpha_l_fx, v_l) + fmul(self.beta_lr_fx, v_r) + self.off_l_fx;
714        let e_r = fmul(self.alpha_r_fx, v_r) + fmul(self.beta_rl_fx, v_l) + self.off_r_fx;
715        ((e_l >> CAL_FRAC).max(0) as i32, (e_r >> CAL_FRAC).max(0) as i32)
716    }
717}
718
719/// Scan window and resolution for [`tune_charge_state`].
720#[derive(Clone, Copy, Debug)]
721pub struct ChargeScanConfig {
722    pub v_max_fx: i64,
723    pub n_grid: u32,
724}
725impl Default for ChargeScanConfig {
726    fn default() -> Self {
727        ChargeScanConfig { v_max_fx: 8 * CAL_ONE, n_grid: 96 }
728    }
729}
730
731/// The result of an autonomous charge-state tune-up. Deterministic given
732/// `(device, target, cfg)`.
733#[derive(Clone, Debug, PartialEq, Eq)]
734pub struct ChargeResult {
735    /// The gate-voltage operating point — the centroid of the target charge cell.
736    pub v_l_op_fx: i64,
737    pub v_r_op_fx: i64,
738    pub target: (i32, i32),
739    pub found: bool,
740    pub n_grid: u32,
741    pub v_max_fx: i64,
742    /// Row-major `n_grid × n_grid` total-charge signal `n_L + n_R` (the honeycomb).
743    pub signal: Vec<i32>,
744}
745
746impl ChargeResult {
747    pub fn hash(&self) -> [u8; 32] {
748        let mut h = blake3::Hasher::new();
749        h.update(b"wai:quantum-cal-chargestab\x01");
750        h.update(&self.v_l_op_fx.to_le_bytes());
751        h.update(&self.v_r_op_fx.to_le_bytes());
752        h.update(&[self.target.0 as u8, self.target.1 as u8, self.found as u8]);
753        for s in &self.signal {
754            h.update(&s.to_le_bytes());
755        }
756        *h.finalize().as_bytes()
757    }
758    pub fn artifacts(&self) -> CalArtifacts {
759        let mut cfg = Vec::new();
760        cfg.extend_from_slice(&self.v_l_op_fx.to_le_bytes());
761        cfg.extend_from_slice(&self.v_r_op_fx.to_le_bytes());
762        let mut ev = Vec::with_capacity(self.signal.len() * 4);
763        for s in &self.signal {
764            ev.extend_from_slice(&s.to_le_bytes());
765        }
766        CalArtifacts {
767            target: format!("charge_state({},{})", self.target.0, self.target.1),
768            config_bytes: cfg,
769            evidence_kind: "charge_stability_scan".into(),
770            evidence_bytes: ev,
771            summary: format!(
772                "op=({},{}) target=({},{}) found={} (2^{CAL_FRAC})",
773                self.v_l_op_fx, self.v_r_op_fx, self.target.0, self.target.1, self.found
774            ),
775        }
776    }
777}
778
779/// Autonomously tune the double dot to a target charge configuration: scan the
780/// charge-stability diagram over `[0, v_max]²`, identify every grid point in the
781/// target cell, and return the operating point — its centroid (which lies inside
782/// the convex cell, so re-reading it yields the target). Pure integer,
783/// byte-identical everywhere. The tuner is blind to the capacitance model.
784pub fn tune_charge_state(
785    dev: &ChargeDevice,
786    target: (i32, i32),
787    cfg: &ChargeScanConfig,
788) -> ChargeResult {
789    let n = cfg.n_grid.max(2);
790    let mut signal = Vec::with_capacity((n * n) as usize);
791    let (mut sum_l, mut sum_r, mut count) = (0i128, 0i128, 0i128);
792    for iy in 0..n {
793        let v_r = ((cfg.v_max_fx as i128 * iy as i128) / (n - 1) as i128) as i64;
794        for ix in 0..n {
795            let v_l = ((cfg.v_max_fx as i128 * ix as i128) / (n - 1) as i128) as i64;
796            let (nl, nr) = dev.charge_state(v_l, v_r);
797            signal.push(nl + nr);
798            if (nl, nr) == target {
799                sum_l += v_l as i128;
800                sum_r += v_r as i128;
801                count += 1;
802            }
803        }
804    }
805    let found = count > 0;
806    let (v_l_op_fx, v_r_op_fx) =
807        if found { ((sum_l / count) as i64, (sum_r / count) as i64) } else { (0, 0) };
808    ChargeResult { v_l_op_fx, v_r_op_fx, target, found, n_grid: n, v_max_fx: cfg.v_max_fx, signal }
809}
810
811// ===========================================================================
812// Two-qubit cross-resonance gate calibration
813// (Q-CTRL / Qruise / Quantum Machines two-qubit tune-up). The target qubit's
814// Rabi rate depends on the CONTROL qubit's state; calibrate both conditional
815// π-amplitudes, whose difference is the ZX interaction. Model-fit, byte-exact.
816// ===========================================================================
817
818/// A cross-resonance pair: the target's π-amplitude differs by the control state
819/// (the ZX shift). Both amplitudes are the hidden truth.
820#[derive(Clone, Copy, Debug)]
821pub struct CrDevice {
822    pub a_pi0_fx: i64,
823    pub a_pi1_fx: i64,
824    pub seed: u64,
825}
826
827impl CrDevice {
828    /// Measured target excited fraction at amplitude `a` for a given control
829    /// state — a conditional Rabi experiment (deterministic shot noise).
830    pub fn measure(&self, a_fx: i64, control: bool, shots: u32) -> i64 {
831        let a_pi = if control { self.a_pi1_fx } else { self.a_pi0_fx };
832        Device { a_pi_fx: a_pi.max(1), seed: self.seed ^ (control as u64) }.measure(a_fx, shots)
833    }
834}
835
836#[derive(Clone, Copy, Debug)]
837pub struct CrConfig {
838    pub a_max_fx: i64,
839    pub n_points: u32,
840    pub shots: u32,
841    pub n_fit: u32,
842}
843impl Default for CrConfig {
844    fn default() -> Self {
845        CrConfig { a_max_fx: 2 * CAL_ONE, n_points: 41, shots: 2000, n_fit: 41 }
846    }
847}
848
849#[derive(Clone, Debug, PartialEq, Eq)]
850pub struct CrResult {
851    pub a_pi0_est_fx: i64,
852    pub a_pi1_est_fx: i64,
853    /// ZX interaction proxy: `|a_pi1 − a_pi0|` (the control-conditioned shift).
854    pub zx_shift_fx: i64,
855    pub sweep0: Vec<(i64, i64)>,
856    pub sweep1: Vec<(i64, i64)>,
857}
858
859impl CrResult {
860    pub fn hash(&self) -> [u8; 32] {
861        let mut h = blake3::Hasher::new();
862        h.update(b"wai:quantum-cal-cr\x01");
863        for v in [self.a_pi0_est_fx, self.a_pi1_est_fx, self.zx_shift_fx] {
864            h.update(&v.to_le_bytes());
865        }
866        for (a, p) in self.sweep0.iter().chain(self.sweep1.iter()) {
867            h.update(&a.to_le_bytes());
868            h.update(&p.to_le_bytes());
869        }
870        *h.finalize().as_bytes()
871    }
872    pub fn artifacts(&self) -> CalArtifacts {
873        let mut cfg = Vec::new();
874        cfg.extend_from_slice(&self.a_pi0_est_fx.to_le_bytes());
875        cfg.extend_from_slice(&self.a_pi1_est_fx.to_le_bytes());
876        let mut ev = Vec::new();
877        for (a, p) in self.sweep0.iter().chain(self.sweep1.iter()) {
878            ev.extend_from_slice(&a.to_le_bytes());
879            ev.extend_from_slice(&p.to_le_bytes());
880        }
881        CalArtifacts {
882            target: "cz(control,target)".into(),
883            config_bytes: cfg,
884            evidence_kind: "cross_resonance_sweep".into(),
885            evidence_bytes: ev,
886            summary: format!(
887                "a_pi0={} a_pi1={} zx_shift={} (2^{CAL_FRAC})",
888                self.a_pi0_est_fx, self.a_pi1_est_fx, self.zx_shift_fx
889            ),
890        }
891    }
892}
893
894/// Fit a Rabi π-amplitude by whole-curve model matching (shared with the
895/// single-qubit routine's approach): minimize `Σ|measured − sin²(π·a/2a_π)|`.
896fn fit_pi_amplitude(sweep: &[(i64, i64)], a_max: i64, coarse: u32, fine: u32) -> i64 {
897    let fit = |lo: i64, hi: i64, steps: u32| -> i64 {
898        let steps = steps.max(2);
899        let mut best = lo.max(1);
900        let mut best_err = i128::MAX;
901        for g in 1..=steps {
902            let a_pi = lo + ((hi - lo) as i128 * g as i128 / steps as i128) as i64;
903            if a_pi <= 0 {
904                continue;
905            }
906            let mut err = 0i128;
907            for &(a, p) in sweep {
908                let theta = ((PI_FX as i128 * a as i128) / (2 * a_pi as i128)) as i64;
909                err += (p - sin2_fx(theta)).unsigned_abs() as i128;
910            }
911            if err < best_err {
912                best_err = err;
913                best = a_pi;
914            }
915        }
916        best
917    };
918    let a_coarse = fit(a_max / coarse.max(2) as i64, a_max, coarse.max(24));
919    let step = a_max / coarse.max(2) as i64;
920    fit((a_coarse - step).max(1), a_coarse + step, fine.max(24))
921}
922
923/// Calibrate a cross-resonance two-qubit gate: sweep the drive amplitude with the
924/// control prepared in `|0⟩` and `|1⟩`, model-fit both conditional π-amplitudes,
925/// and report their difference (the ZX interaction). Pure integer, byte-exact.
926pub fn calibrate_cr(dev: &CrDevice, cfg: &CrConfig) -> CrResult {
927    let n = cfg.n_points.max(4);
928    let (mut sweep0, mut sweep1) = (Vec::with_capacity(n as usize), Vec::with_capacity(n as usize));
929    for i in 0..n {
930        let a = ((cfg.a_max_fx as i128 * i as i128) / (n - 1) as i128) as i64;
931        sweep0.push((a, dev.measure(a, false, cfg.shots)));
932        sweep1.push((a, dev.measure(a, true, cfg.shots)));
933    }
934    let a0 = fit_pi_amplitude(&sweep0, cfg.a_max_fx, cfg.n_points, cfg.n_fit);
935    let a1 = fit_pi_amplitude(&sweep1, cfg.a_max_fx, cfg.n_points, cfg.n_fit);
936    CrResult { a_pi0_est_fx: a0, a_pi1_est_fx: a1, zx_shift_fx: (a1 - a0).abs(), sweep0, sweep1 }
937}
938
939// ===========================================================================
940// Crosstalk characterization — the N×N drive-response matrix
941// (Q-CTRL / Conductor crosstalk mitigation, step one: measure the matrix).
942// ===========================================================================
943
944/// An `n`-qubit device with a hidden crosstalk matrix: driving qubit `i` at
945/// amplitude `a` rotates qubit `j` by `matrix[i*n+j]·a` (diagonal ≈ 1, off-
946/// diagonal small). Row-major, fixed-point.
947#[derive(Clone, Debug)]
948pub struct CrosstalkDevice {
949    pub n: usize,
950    pub matrix_fx: Vec<i64>,
951    pub seed: u64,
952}
953
954impl CrosstalkDevice {
955    /// Measured excited fraction of qubit `j` when driving qubit `i` at amplitude
956    /// `a`: `P = sin²(matrix[i,j]·a / 2)`.
957    pub fn measure(&self, i: usize, j: usize, a_fx: i64, shots: u32) -> i64 {
958        let theta = fmul(self.matrix_fx[i * self.n + j], a_fx);
959        let p = sin2_fx(theta / 2);
960        let mut st = self.seed.wrapping_mul(0x1000_0001).wrapping_add((i * 97 + j) as u64);
961        let mut hits = 0u64;
962        for _ in 0..shots {
963            if ((splitmix64(&mut st) >> (64 - CAL_FRAC)) as i64) < p {
964                hits += 1;
965            }
966        }
967        ((hits as i128 * CAL_ONE as i128) / shots.max(1) as i128) as i64
968    }
969}
970
971#[derive(Clone, Debug, PartialEq, Eq)]
972pub struct CrosstalkResult {
973    pub n: usize,
974    /// Recovered `n×n` crosstalk coefficients (row-major, fixed-point).
975    pub matrix_fx: Vec<i64>,
976    /// Worst off-diagonal coefficient (the crosstalk a mitigation must cancel).
977    pub worst_offdiag_fx: i64,
978}
979
980impl CrosstalkResult {
981    pub fn hash(&self) -> [u8; 32] {
982        let mut h = blake3::Hasher::new();
983        h.update(b"wai:quantum-cal-crosstalk\x01");
984        h.update(&(self.n as u64).to_le_bytes());
985        for v in &self.matrix_fx {
986            h.update(&v.to_le_bytes());
987        }
988        *h.finalize().as_bytes()
989    }
990    pub fn artifacts(&self) -> CalArtifacts {
991        let mut ev = Vec::new();
992        for v in &self.matrix_fx {
993            ev.extend_from_slice(&v.to_le_bytes());
994        }
995        CalArtifacts {
996            target: format!("crosstalk_{}x{}", self.n, self.n),
997            config_bytes: self.worst_offdiag_fx.to_le_bytes().to_vec(),
998            evidence_kind: "crosstalk_matrix".into(),
999            evidence_bytes: ev,
1000            summary: format!("n={} worst_offdiag={} (2^{CAL_FRAC})", self.n, self.worst_offdiag_fx),
1001        }
1002    }
1003}
1004
1005/// Characterize the crosstalk matrix: for each `(drive i, measure j)`, sweep a
1006/// small amplitude, and recover `matrix[i,j]` from the initial response slope
1007/// (`P ≈ (matrix·a/2)²` for small angle ⇒ `matrix ≈ 2·√P / a`). Pure integer.
1008pub fn characterize_crosstalk(dev: &CrosstalkDevice, probe_a_fx: i64, shots: u32) -> CrosstalkResult {
1009    let n = dev.n;
1010    let mut matrix = vec![0i64; n * n];
1011    // fit each coefficient by the whole-response model over a small sweep
1012    let sweeps = 12u32;
1013    for i in 0..n {
1014        for j in 0..n {
1015            let mut sweep = Vec::with_capacity(sweeps as usize);
1016            for s in 1..=sweeps {
1017                let a = (probe_a_fx as i128 * s as i128 / sweeps as i128) as i64;
1018                sweep.push((a, dev.measure(i, j, a, shots)));
1019            }
1020            // search coefficient c minimizing Σ|measured − sin²(c·a/2)|
1021            let mut best = 0i64;
1022            let mut best_err = i128::MAX;
1023            let c_max = 2 * CAL_ONE;
1024            for g in 0..=200 {
1025                let c = (c_max as i128 * g as i128 / 200) as i64;
1026                let mut err = 0i128;
1027                for &(a, p) in &sweep {
1028                    err += (p - sin2_fx(fmul(c, a) / 2)).unsigned_abs() as i128;
1029                }
1030                if err < best_err {
1031                    best_err = err;
1032                    best = c;
1033                }
1034            }
1035            matrix[i * n + j] = best;
1036        }
1037    }
1038    let worst = (0..n)
1039        .flat_map(|i| (0..n).filter(move |&j| i != j).map(move |j| (i, j)))
1040        .map(|(i, j)| matrix[i * n + j].abs())
1041        .max()
1042        .unwrap_or(0);
1043    CrosstalkResult { n, matrix_fx: matrix, worst_offdiag_fx: worst }
1044}
1045
1046// ===========================================================================
1047// DRAG / leakage pulse calibration — the pulse-shaping (optimal-control) primitive
1048// (Conductor / Q-CTRL leakage suppression). Optimize the DRAG coefficient β that
1049// minimizes leakage to |2⟩. A parabolic minimization — the simplest honest
1050// representative of the control-optimization layer (NOT full robust control).
1051// ===========================================================================
1052
1053/// A qubit whose leakage-to-`|2⟩` is minimized at a hidden DRAG coefficient
1054/// `beta_opt` (a parabola in β). `curvature` sets how sharply leakage rises.
1055#[derive(Clone, Copy, Debug)]
1056pub struct DragDevice {
1057    pub beta_opt_fx: i64,
1058    pub curvature_fx: i64,
1059    pub seed: u64,
1060}
1061
1062impl DragDevice {
1063    /// Measured leakage signal at DRAG coefficient `β`: `L = curvature·(β−β_opt)²`
1064    /// (clamped to `[0,1]`), with deterministic measurement noise.
1065    pub fn measure_leakage(&self, beta_fx: i64, shots: u32) -> i64 {
1066        let d = beta_fx - self.beta_opt_fx;
1067        let l = fmul(self.curvature_fx, fmul(d, d)).clamp(0, CAL_ONE);
1068        let mut st = self.seed.wrapping_mul(0x9E37).wrapping_add(beta_fx as u64);
1069        let mut hits = 0u64;
1070        for _ in 0..shots {
1071            if ((splitmix64(&mut st) >> (64 - CAL_FRAC)) as i64) < l {
1072                hits += 1;
1073            }
1074        }
1075        ((hits as i128 * CAL_ONE as i128) / shots.max(1) as i128) as i64
1076    }
1077}
1078
1079#[derive(Clone, Debug, PartialEq, Eq)]
1080pub struct DragResult {
1081    pub beta_opt_est_fx: i64,
1082    /// Residual leakage at the optimized β (`≈ 0` for a well-shaped pulse).
1083    pub residual_leakage_fx: i64,
1084    pub sweep: Vec<(i64, i64)>,
1085}
1086
1087impl DragResult {
1088    pub fn hash(&self) -> [u8; 32] {
1089        let mut h = blake3::Hasher::new();
1090        h.update(b"wai:quantum-cal-drag\x01");
1091        h.update(&self.beta_opt_est_fx.to_le_bytes());
1092        h.update(&self.residual_leakage_fx.to_le_bytes());
1093        for (b, l) in &self.sweep {
1094            h.update(&b.to_le_bytes());
1095            h.update(&l.to_le_bytes());
1096        }
1097        *h.finalize().as_bytes()
1098    }
1099    pub fn artifacts(&self) -> CalArtifacts {
1100        let mut ev = Vec::new();
1101        for (b, l) in &self.sweep {
1102            ev.extend_from_slice(&b.to_le_bytes());
1103            ev.extend_from_slice(&l.to_le_bytes());
1104        }
1105        CalArtifacts {
1106            target: "drag_beta".into(),
1107            config_bytes: self.beta_opt_est_fx.to_le_bytes().to_vec(),
1108            evidence_kind: "drag_leakage_sweep".into(),
1109            evidence_bytes: ev,
1110            summary: format!(
1111                "beta_opt={} residual_leakage={} (2^{CAL_FRAC})",
1112                self.beta_opt_est_fx, self.residual_leakage_fx
1113            ),
1114        }
1115    }
1116}
1117
1118/// Optimize the DRAG coefficient: sweep β over `[beta_min, beta_max]`, measure
1119/// leakage, and take the minimum (parabolic minimization — the pulse-shaping
1120/// optimization that suppresses leakage). Pure integer, byte-exact.
1121pub fn calibrate_drag(dev: &DragDevice, beta_min_fx: i64, beta_max_fx: i64, n: u32, shots: u32) -> DragResult {
1122    let n = n.max(4);
1123    let mut sweep = Vec::with_capacity(n as usize);
1124    let (mut best_b, mut best_l) = (beta_min_fx, i64::MAX);
1125    for i in 0..n {
1126        let b = beta_min_fx + ((beta_max_fx - beta_min_fx) as i128 * i as i128 / (n - 1) as i128) as i64;
1127        let l = dev.measure_leakage(b, shots);
1128        sweep.push((b, l));
1129        if l < best_l {
1130            best_l = l;
1131            best_b = b;
1132        }
1133    }
1134    // parabolic refinement around the discrete minimum
1135    let step = (beta_max_fx - beta_min_fx) / (n as i64 - 1);
1136    let refine = |lo: i64, hi: i64| -> (i64, i64) {
1137        let (mut bb, mut bl) = (lo, i64::MAX);
1138        for g in 0..=60 {
1139            let b = lo + ((hi - lo) as i128 * g as i128 / 60) as i64;
1140            let l = dev.measure_leakage(b, shots);
1141            if l < bl {
1142                bl = l;
1143                bb = b;
1144            }
1145        }
1146        (bb, bl)
1147    };
1148    let (beta, res) = refine((best_b - step).max(beta_min_fx), (best_b + step).min(beta_max_fx));
1149    DragResult { beta_opt_est_fx: beta, residual_leakage_fx: res, sweep }
1150}
1151
1152// ===========================================================================
1153// Robust optimal control — composite-pulse design (Q-CTRL Boulder Opal class).
1154// Numerically OPTIMIZE a control pulse to implement a π-gate that is robust to
1155// amplitude noise: minimize the worst-case gate error over an amplitude-error
1156// range. Bloch-sphere evolution in fixed-point, no float — the optimizer
1157// discovers the noise-robust composite (vs a fragile naive square pulse).
1158// ===========================================================================
1159
1160/// Rotate a Bloch vector `v` about the XY-plane axis `(cos φ, sin φ, 0)` by angle
1161/// `alpha` (Rodrigues' formula), fixed-point. The rotation axis phase `phi` is
1162/// the pulse phase; `alpha` the rotation angle (∝ amplitude·time).
1163fn bloch_rotate(v: [i64; 3], phi: i64, alpha: i64) -> [i64; 3] {
1164    let (n0, n1) = (cos_fx(phi), sin_fx(phi));
1165    let (c, s) = (cos_fx(alpha), sin_fx(alpha));
1166    let ndotv = fmul(n0, v[0]) + fmul(n1, v[1]); // n2 = 0
1167    let cross = [fmul(n1, v[2]), -fmul(n0, v[2]), fmul(n0, v[1]) - fmul(n1, v[0])];
1168    let n = [n0, n1, 0];
1169    let omc = CAL_ONE - c;
1170    let mut out = [0i64; 3];
1171    for k in 0..3 {
1172        out[k] = fmul(v[k], c) + fmul(cross[k], s) + fmul(n[k], fmul(ndotv, omc));
1173    }
1174    out
1175}
1176
1177/// Apply a composite pulse `[(phase, angle)…]` to `|0⟩` (Bloch `+z`) under a
1178/// fractional amplitude error `eps` (every angle scaled by `1+eps`), returning
1179/// the excited-state population `(1 − z)/2` — the population-transfer fidelity of
1180/// a π-gate. Clamped to `[0, 1]`.
1181pub fn apply_composite(segments: &[(i64, i64)], eps_fx: i64) -> i64 {
1182    let mut v = [0i64, 0, CAL_ONE];
1183    for &(phi, alpha) in segments {
1184        let a = alpha + fmul(alpha, eps_fx);
1185        v = bloch_rotate(v, phi, a);
1186    }
1187    ((CAL_ONE - v[2]) / 2).clamp(0, CAL_ONE)
1188}
1189
1190#[derive(Clone, Debug, PartialEq, Eq)]
1191pub struct RobustResult {
1192    /// Optimized symmetric composite `[(0,a1), (phi,a2), (0,a1)]`.
1193    pub a1_fx: i64,
1194    pub a2_fx: i64,
1195    pub phi_fx: i64,
1196    pub eps_axis_fx: Vec<i64>,
1197    /// Gate error `1 − P` vs `eps` for the naive single π-pulse.
1198    pub naive_infid_fx: Vec<i64>,
1199    /// Gate error vs `eps` for the optimized robust pulse.
1200    pub robust_infid_fx: Vec<i64>,
1201    pub worst_naive_fx: i64,
1202    pub worst_robust_fx: i64,
1203}
1204
1205impl RobustResult {
1206    pub fn hash(&self) -> [u8; 32] {
1207        let mut h = blake3::Hasher::new();
1208        h.update(b"wai:quantum-cal-robust\x01");
1209        for v in [self.a1_fx, self.a2_fx, self.phi_fx, self.worst_naive_fx, self.worst_robust_fx] {
1210            h.update(&v.to_le_bytes());
1211        }
1212        for v in self.naive_infid_fx.iter().chain(self.robust_infid_fx.iter()) {
1213            h.update(&v.to_le_bytes());
1214        }
1215        *h.finalize().as_bytes()
1216    }
1217    pub fn artifacts(&self) -> CalArtifacts {
1218        let mut cfg = Vec::new();
1219        for v in [self.a1_fx, self.a2_fx, self.phi_fx] {
1220            cfg.extend_from_slice(&v.to_le_bytes());
1221        }
1222        let mut ev = Vec::new();
1223        for v in self.naive_infid_fx.iter().chain(self.robust_infid_fx.iter()) {
1224            ev.extend_from_slice(&v.to_le_bytes());
1225        }
1226        CalArtifacts {
1227            target: "x_pi_robust".into(),
1228            config_bytes: cfg,
1229            evidence_kind: "robust_pulse_infidelity".into(),
1230            evidence_bytes: ev,
1231            summary: format!(
1232                "worst_naive={} worst_robust={} (2^{CAL_FRAC})",
1233                self.worst_naive_fx, self.worst_robust_fx
1234            ),
1235        }
1236    }
1237}
1238
1239/// Optimize a robust π-gate: search a symmetric 3-segment composite
1240/// `[(0,a1),(phi,a2),(0,a1)]` for the one that is a valid π-gate at nominal
1241/// amplitude AND minimizes the worst-case gate error over `eps ∈ [−err_max,
1242/// err_max]`. Pure integer — the optimizer's choice is byte-identical everywhere.
1243pub fn optimize_robust_pulse(err_max_fx: i64, n_eps: u32) -> RobustResult {
1244    let n_eps = n_eps.max(3);
1245    let eps_axis: Vec<i64> = (0..n_eps)
1246        .map(|i| -err_max_fx + (2 * err_max_fx as i128 * i as i128 / (n_eps - 1) as i128) as i64)
1247        .collect();
1248    let worst = |segs: &[(i64, i64)]| -> (Vec<i64>, i64) {
1249        let mut curve = Vec::with_capacity(eps_axis.len());
1250        let mut w = 0i64;
1251        for &e in &eps_axis {
1252            let inf = CAL_ONE - apply_composite(segs, e);
1253            w = w.max(inf);
1254            curve.push(inf);
1255        }
1256        (curve, w)
1257    };
1258
1259    let (naive_curve, worst_naive) = worst(&[(0, PI_FX)]);
1260
1261    let (mut best, mut best_w) = ((PI_FX / 2, PI_FX, 0i64), i64::MAX);
1262    let a1_lo = PI_FX / 4;
1263    let quarter = PI_FX / 2;
1264    for i in 0..=20 {
1265        let a1 = a1_lo + ((PI_FX - a1_lo) as i128 * i as i128 / 20) as i64;
1266        for j in 0..=20 {
1267            let a2 = quarter + ((3 * PI_FX / 2 - quarter) as i128 * j as i128 / 20) as i64;
1268            for k in 0..=24 {
1269                let phi = (TWO_PI_FX as i128 * k as i128 / 24) as i64;
1270                let segs = [(0, a1), (phi, a2), (0, a1)];
1271                if (CAL_ONE - apply_composite(&segs, 0)).abs() > CAL_ONE / 100 {
1272                    continue; // must be a valid π-gate at nominal amplitude
1273                }
1274                let (_, w) = worst(&segs);
1275                if w < best_w {
1276                    best_w = w;
1277                    best = (a1, a2, phi);
1278                }
1279            }
1280        }
1281    }
1282    let best_segs = [(0, best.0), (best.2, best.1), (0, best.0)];
1283    let (robust_curve, worst_robust) = worst(&best_segs);
1284    RobustResult {
1285        a1_fx: best.0,
1286        a2_fx: best.1,
1287        phi_fx: best.2,
1288        eps_axis_fx: eps_axis,
1289        naive_infid_fx: naive_curve,
1290        robust_infid_fx: robust_curve,
1291        worst_naive_fx: worst_naive,
1292        worst_robust_fx: worst_robust,
1293    }
1294}
1295
1296// ===========================================================================
1297// Generic seal — any routine's artifacts → wai.quantum.calibration receipt
1298// ===========================================================================
1299
1300#[cfg(feature = "quantum_ops")]
1301mod seal_any {
1302    use super::CalArtifacts;
1303    use crate::quantum_ops::{content_hash, CalibrationReceipt, Evidence, GrantRef};
1304    use ed25519_dalek::SigningKey;
1305
1306    /// Seal any calibration routine's [`CalArtifacts`] into a receipt: the config
1307    /// hash pins the calibrated parameter, the evidence content-addresses the
1308    /// dataset, the joules are the run's measured energy, the grant authorizes it.
1309    #[allow(clippy::too_many_arguments)]
1310    pub fn seal_artifacts(
1311        signer: &SigningKey,
1312        signer_id: impl Into<String>,
1313        device_id: impl Into<String>,
1314        art: &CalArtifacts,
1315        joules_micro: u64,
1316        grant: GrantRef,
1317        parent: Option<[u8; 32]>,
1318    ) -> CalibrationReceipt {
1319        let ev = vec![Evidence {
1320            kind: art.evidence_kind.clone(),
1321            blob_hash: content_hash(&art.evidence_bytes),
1322            summary: art.summary.clone(),
1323        }];
1324        CalibrationReceipt::seal(
1325            signer, signer_id, device_id, art.target.clone(),
1326            content_hash(&art.config_bytes), ev, joules_micro, grant, parent,
1327        )
1328    }
1329}
1330
1331#[cfg(feature = "quantum_ops")]
1332pub use seal_any::seal_artifacts;
1333
1334// ===========================================================================
1335// Calibration-graph orchestration — a bring-up campaign as a signed lineage
1336// (Quantum Machines' QUAlibrate differentiator, made superior: their node graph
1337// is unsigned; here each node's receipt CHAINS to the previous via
1338// parent_receipt_hash, so the whole campaign is one portable, verifiable lineage).
1339// ===========================================================================
1340
1341#[cfg(feature = "quantum_ops")]
1342mod campaign {
1343    use super::*;
1344    use crate::quantum_ops::{CalibrationReceipt, GrantRef};
1345    use ed25519_dalek::SigningKey;
1346
1347    /// One node of a calibration campaign — a routine plus its inputs. `run`
1348    /// dispatches to the deterministic engine and returns its receipt artifacts.
1349    #[allow(clippy::large_enum_variant)]
1350    #[derive(Clone, Debug)]
1351    pub enum CalStep {
1352        Rabi(Device, TuneConfig),
1353        Ramsey(RamseyDevice, RamseyConfig),
1354        Rb(RbDevice, RbConfig),
1355        Readout(ReadoutDevice, u32),
1356        Charge(ChargeDevice, (i32, i32), ChargeScanConfig),
1357    }
1358
1359    impl CalStep {
1360        fn run(&self) -> (CalArtifacts, &'static str) {
1361            match self {
1362                CalStep::Rabi(d, c) => (calibrate_rabi(d, c).artifacts(), "rabi"),
1363                CalStep::Ramsey(d, c) => (calibrate_ramsey(d, c).artifacts(), "ramsey"),
1364                CalStep::Rb(d, c) => (calibrate_rb(d, c).artifacts(), "rb"),
1365                CalStep::Readout(d, n) => (calibrate_readout(d, *n).artifacts(), "readout"),
1366                CalStep::Charge(d, t, c) => (tune_charge_state(d, *t, c).artifacts(), "charge"),
1367            }
1368        }
1369    }
1370
1371    /// A completed calibration campaign: the ordered receipts (each chained to the
1372    /// one before) and their routine kinds.
1373    #[derive(Clone, Debug)]
1374    pub struct Campaign {
1375        pub receipts: Vec<CalibrationReceipt>,
1376        pub kinds: Vec<String>,
1377    }
1378
1379    impl Campaign {
1380        /// A single portable id for the whole campaign — BLAKE3 over the ordered
1381        /// per-node receipt hashes.
1382        pub fn campaign_hash(&self) -> [u8; 32] {
1383            let mut h = blake3::Hasher::new();
1384            h.update(b"wai:quantum-cal-campaign\x01");
1385            for r in &self.receipts {
1386                h.update(&r.receipt_hash());
1387            }
1388            *h.finalize().as_bytes()
1389        }
1390
1391        /// The whole lineage is intact: every receipt verifies, and each node's
1392        /// `parent_receipt_hash` is exactly the previous node's `receipt_hash`
1393        /// (the first is a root). A third party confirms the bring-up ran in this
1394        /// order, each step authorized + metered — a signed calibration campaign.
1395        pub fn verify_chain(&self) -> bool {
1396            let mut prev: Option<[u8; 32]> = None;
1397            for r in &self.receipts {
1398                if !r.verify() || r.parent_receipt_hash != prev {
1399                    return false;
1400                }
1401                prev = Some(r.receipt_hash());
1402            }
1403            true
1404        }
1405    }
1406
1407    /// Run a calibration campaign: execute each step in order, sealing a
1408    /// `wai.quantum.calibration` receipt chained to the previous step. Every
1409    /// engine is deterministic, so the whole campaign — receipts and
1410    /// `campaign_hash` — is byte-identical on every machine.
1411    pub fn run_campaign(
1412        signer: &SigningKey,
1413        signer_id: &str,
1414        device_id: &str,
1415        joules_each: u64,
1416        grant: &GrantRef,
1417        steps: &[CalStep],
1418    ) -> Campaign {
1419        let mut receipts = Vec::with_capacity(steps.len());
1420        let mut kinds = Vec::with_capacity(steps.len());
1421        let mut parent: Option<[u8; 32]> = None;
1422        for step in steps {
1423            let (art, kind) = step.run();
1424            let r = seal_artifacts(signer, signer_id, device_id, &art, joules_each, grant.clone(), parent);
1425            parent = Some(r.receipt_hash());
1426            kinds.push(kind.to_string());
1427            receipts.push(r);
1428        }
1429        Campaign { receipts, kinds }
1430    }
1431}
1432
1433#[cfg(feature = "quantum_ops")]
1434pub use campaign::{run_campaign, CalStep, Campaign};
1435
1436#[cfg(test)]
1437mod tests {
1438    use super::*;
1439
1440    #[test]
1441    fn sine_is_accurate_enough() {
1442        // sin²(π/2) = 1, sin²(0) = 0, sin²(π/4) = 0.5
1443        assert_eq!(sin2_fx(0), 0);
1444        let at_half_pi = sin2_fx(PI_FX / 2);
1445        assert!((at_half_pi - CAL_ONE).abs() < CAL_ONE / 200, "sin²(π/2)≈1, got {at_half_pi}");
1446        let at_quarter = sin2_fx(PI_FX / 4);
1447        assert!((at_quarter - CAL_ONE / 2).abs() < CAL_ONE / 100, "sin²(π/4)≈0.5, got {at_quarter}");
1448    }
1449
1450    #[test]
1451    fn tune_up_finds_the_true_pi_amplitude() {
1452        // Hidden truth: π-pulse at amplitude 0.80. The calibrator must find it.
1453        let a_pi_true = (0.80 * CAL_ONE as f64) as i64;
1454        let device = Device { a_pi_fx: a_pi_true, seed: 0xCAFE };
1455        let cfg = TuneConfig { a_max_fx: (1.6 * CAL_ONE as f64) as i64, ..Default::default() };
1456        let r = calibrate_rabi(&device, &cfg);
1457        // within one fine step (~0.8%) of the hidden truth
1458        let tol = cfg.a_max_fx / (cfg.n_coarse as i64 - 1) / (cfg.n_fine as i64 - 1) + CAL_ONE / 50;
1459        assert!(
1460            (r.a_pi_est_fx - a_pi_true).abs() <= tol,
1461            "estimate {} vs true {} (tol {tol})",
1462            r.a_pi_est_fx, a_pi_true
1463        );
1464        // a clean π rotation: measured excited population ≈ 1
1465        assert!(r.peak_prob_fx > CAL_ONE - CAL_ONE / 20, "peak prob {} not ~1", r.peak_prob_fx);
1466    }
1467
1468    #[test]
1469    fn calibration_is_byte_exact_deterministic() {
1470        let device = Device { a_pi_fx: (0.73 * CAL_ONE as f64) as i64, seed: 7 };
1471        let cfg = TuneConfig::default();
1472        let a = calibrate_rabi(&device, &cfg);
1473        let b = calibrate_rabi(&device, &cfg);
1474        assert_eq!(a, b);
1475        assert_eq!(a.hash(), b.hash(), "same (device,cfg) must give the same tune-up hash");
1476    }
1477
1478    #[test]
1479    fn different_devices_tune_differently() {
1480        let d1 = Device { a_pi_fx: (0.5 * CAL_ONE as f64) as i64, seed: 1 };
1481        let d2 = Device { a_pi_fx: (1.1 * CAL_ONE as f64) as i64, seed: 1 };
1482        let cfg = TuneConfig { a_max_fx: 2 * CAL_ONE, ..Default::default() };
1483        let r1 = calibrate_rabi(&d1, &cfg);
1484        let r2 = calibrate_rabi(&d2, &cfg);
1485        assert!(r1.a_pi_est_fx < r2.a_pi_est_fx);
1486    }
1487
1488    #[cfg(feature = "quantum_ops")]
1489    #[test]
1490    fn calibrate_and_seal_produces_a_verifying_receipt() {
1491        use crate::quantum_ops::GrantRef;
1492        use ed25519_dalek::SigningKey;
1493        let device = Device { a_pi_fx: (0.9 * CAL_ONE as f64) as i64, seed: 0xABCD };
1494        let cfg = TuneConfig::default();
1495        let grant = GrantRef {
1496            grant_hash: [0u8; 32],
1497            capability: "quantum.calibrate".into(),
1498            joule_ceiling_micro: 10_000_000,
1499            funds_ceiling: None,
1500        };
1501        let (r, receipt) = calibrate_and_seal(
1502            &SigningKey::from_bytes(&[9u8; 32]), "did:key:lab", "sim:transmon:q0", "q0",
1503            &device, &cfg, 3_500_000, grant, None,
1504        );
1505        assert!(receipt.verify());
1506        // the evidence content-addresses the exact sweep the calibrator produced
1507        assert!(receipt.evidence_matches(0, &sweep_bytes(&r)));
1508        // and a re-run reproduces that sweep byte-for-byte (the superiority claim)
1509        let r2 = calibrate_rabi(&device, &cfg);
1510        assert!(receipt.evidence_matches(0, &sweep_bytes(&r2)));
1511    }
1512
1513    fn fx(x: f64) -> i64 {
1514        (x * CAL_ONE as f64) as i64
1515    }
1516
1517    #[test]
1518    fn ramsey_recovers_detuning_and_t2_deterministically() {
1519        let dev = RamseyDevice { omega_fx: fx(3.0), t2_fx: fx(3.0), seed: 0x1234 };
1520        let cfg = RamseyConfig {
1521            tau_max_fx: fx(6.0), n_points: 80, shots: 4000,
1522            omega_max_fx: fx(6.0), t2_max_fx: fx(6.0), n_grid: 60,
1523        };
1524        let r = calibrate_ramsey(&dev, &cfg);
1525        assert!((r.omega_est_fx - fx(3.0)).abs() < fx(0.4), "omega {} vs 3.0", r.omega_est_fx);
1526        assert!((r.t2_est_fx - fx(3.0)).abs() < fx(0.8), "t2 {} vs 3.0", r.t2_est_fx);
1527        // byte-exact determinism
1528        assert_eq!(r, calibrate_ramsey(&dev, &cfg));
1529        assert_eq!(r.hash(), calibrate_ramsey(&dev, &cfg).hash());
1530    }
1531
1532    #[test]
1533    fn rb_recovers_gate_fidelity_deterministically() {
1534        // 1% per-gate error → p = 0.98, F = 0.99.
1535        let dev = RbDevice { epsilon_fx: fx(0.01), seed: 0xBEEF };
1536        let cfg = RbConfig {
1537            lengths: [1, 2, 4, 8, 16, 32, 64, 128], k_sequences: 20, shots: 100, n_grid: 300,
1538        };
1539        let r = calibrate_rb(&dev, &cfg);
1540        assert!((r.p_est_fx - fx(0.98)).abs() < fx(0.02), "p {} vs 0.98", r.p_est_fx);
1541        assert!((r.fidelity_fx - fx(0.99)).abs() < fx(0.01), "F {} vs 0.99", r.fidelity_fx);
1542        assert_eq!(r, calibrate_rb(&dev, &cfg));
1543    }
1544
1545    #[test]
1546    fn readout_discriminates_well_separated_blobs_deterministically() {
1547        // 4σ separation → high assignment fidelity.
1548        let dev = ReadoutDevice { s0_fx: fx(-2.0), s1_fx: fx(2.0), sigma_fx: fx(1.0), seed: 42 };
1549        let r = calibrate_readout(&dev, 500);
1550        assert!(r.fidelity_fx > fx(0.9), "readout fidelity {} not > 0.9", r.fidelity_fx);
1551        assert!(r.mean0_fx < r.threshold_fx && r.threshold_fx < r.mean1_fx);
1552        assert_eq!(r, calibrate_readout(&dev, 500));
1553        assert_eq!(r.hash(), calibrate_readout(&dev, 500).hash());
1554    }
1555
1556    #[cfg(feature = "quantum_ops")]
1557    #[test]
1558    fn every_routine_seals_a_verifying_receipt() {
1559        use crate::quantum_ops::GrantRef;
1560        use ed25519_dalek::SigningKey;
1561        let signer = SigningKey::from_bytes(&[5u8; 32]);
1562        let grant = GrantRef::unbounded("quantum.calibrate");
1563
1564        let ram = calibrate_ramsey(
1565            &RamseyDevice { omega_fx: fx(2.0), t2_fx: fx(4.0), seed: 1 },
1566            &RamseyConfig { tau_max_fx: fx(8.0), n_points: 60, shots: 3000, omega_max_fx: fx(6.0), t2_max_fx: fx(8.0), n_grid: 50 },
1567        );
1568        let rb = calibrate_rb(
1569            &RbDevice { epsilon_fx: fx(0.005), seed: 2 },
1570            &RbConfig { lengths: [1, 2, 4, 8, 16, 32, 64, 128], k_sequences: 10, shots: 100, n_grid: 200 },
1571        );
1572        let ro = calibrate_readout(&ReadoutDevice { s0_fx: fx(-1.5), s1_fx: fx(1.5), sigma_fx: fx(1.0), seed: 3 }, 400);
1573
1574        for art in [ram.artifacts(), rb.artifacts(), ro.artifacts()] {
1575            let r = seal_artifacts(&signer, "did:key:lab", "sim:transmon:q0", &art, 1_000_000, grant.clone(), None);
1576            assert!(r.verify(), "receipt for {} must verify", art.evidence_kind);
1577            assert!(r.evidence_matches(0, &art.evidence_bytes));
1578        }
1579    }
1580
1581    fn dot() -> ChargeDevice {
1582        ChargeDevice {
1583            alpha_l_fx: fx(0.4), alpha_r_fx: fx(0.4),
1584            beta_lr_fx: fx(0.1), beta_rl_fx: fx(0.1),
1585            off_l_fx: 0, off_r_fx: 0,
1586        }
1587    }
1588
1589    #[test]
1590    fn charge_tune_is_byte_exact_deterministic() {
1591        let (d, cfg) = (dot(), ChargeScanConfig::default());
1592        let a = tune_charge_state(&d, (1, 1), &cfg);
1593        let b = tune_charge_state(&d, (1, 1), &cfg);
1594        assert_eq!(a, b);
1595        assert_eq!(a.hash(), b.hash());
1596    }
1597
1598    #[test]
1599    fn charge_tune_operating_point_reads_the_target() {
1600        let (d, cfg) = (dot(), ChargeScanConfig::default());
1601        for target in [(1, 1), (2, 1), (1, 2), (2, 2)] {
1602            let r = tune_charge_state(&d, target, &cfg);
1603            assert!(r.found, "target {target:?} not in the scan window");
1604            // the centroid lies inside the convex cell → re-reading yields the target
1605            assert_eq!(
1606                d.charge_state(r.v_l_op_fx, r.v_r_op_fx),
1607                target,
1608                "operating point for {target:?} reads the wrong charge state"
1609            );
1610        }
1611    }
1612
1613    #[test]
1614    fn charge_tune_higher_target_needs_higher_voltage() {
1615        let (d, cfg) = (dot(), ChargeScanConfig::default());
1616        let r1 = tune_charge_state(&d, (1, 1), &cfg);
1617        let r2 = tune_charge_state(&d, (2, 2), &cfg);
1618        assert!(r2.v_l_op_fx > r1.v_l_op_fx && r2.v_r_op_fx > r1.v_r_op_fx);
1619    }
1620
1621    #[cfg(feature = "quantum_ops")]
1622    #[test]
1623    fn charge_tune_seals_a_verifying_receipt() {
1624        use crate::quantum_ops::GrantRef;
1625        use ed25519_dalek::SigningKey;
1626        let r = tune_charge_state(&dot(), (1, 1), &ChargeScanConfig::default());
1627        let art = r.artifacts();
1628        let rec = seal_artifacts(
1629            &SigningKey::from_bytes(&[6u8; 32]), "did:key:lab", "sim:double-dot:d0",
1630            &art, 2_000_000, GrantRef::unbounded("quantum.calibrate"), None,
1631        );
1632        assert!(rec.verify());
1633        assert!(rec.evidence_matches(0, &art.evidence_bytes));
1634    }
1635
1636    #[cfg(feature = "quantum_ops")]
1637    #[test]
1638    fn campaign_chains_receipts_into_a_signed_lineage() {
1639        use crate::quantum_ops::GrantRef;
1640        use ed25519_dalek::SigningKey;
1641        let signer = SigningKey::from_bytes(&[7u8; 32]);
1642        let grant = GrantRef::unbounded("quantum.calibrate");
1643        let steps = vec![
1644            CalStep::Readout(
1645                ReadoutDevice { s0_fx: fx(-1.5), s1_fx: fx(1.5), sigma_fx: fx(1.0), seed: 1 },
1646                400,
1647            ),
1648            CalStep::Rabi(Device { a_pi_fx: fx(0.8), seed: 2 }, TuneConfig::default()),
1649            CalStep::Charge(dot(), (1, 1), ChargeScanConfig::default()),
1650        ];
1651        let camp = run_campaign(&signer, "did:key:lab", "sim:q0", 1_000_000, &grant, &steps);
1652        assert_eq!(camp.receipts.len(), 3);
1653        assert_eq!(camp.kinds, ["readout", "rabi", "charge"]);
1654        assert!(camp.verify_chain(), "the campaign lineage must verify");
1655        // deterministic: same steps → byte-identical campaign
1656        let camp2 = run_campaign(&signer, "did:key:lab", "sim:q0", 1_000_000, &grant, &steps);
1657        assert_eq!(camp.campaign_hash(), camp2.campaign_hash());
1658    }
1659
1660    #[cfg(feature = "quantum_ops")]
1661    #[test]
1662    fn campaign_tamper_breaks_the_chain() {
1663        use crate::quantum_ops::GrantRef;
1664        use ed25519_dalek::SigningKey;
1665        let steps = vec![
1666            CalStep::Rabi(Device { a_pi_fx: fx(0.8), seed: 2 }, TuneConfig::default()),
1667            CalStep::Rb(
1668                RbDevice { epsilon_fx: fx(0.005), seed: 3 },
1669                RbConfig { lengths: [1, 2, 4, 8, 16, 32, 64, 128], k_sequences: 8, shots: 80, n_grid: 150 },
1670            ),
1671        ];
1672        let mut camp = run_campaign(
1673            &SigningKey::from_bytes(&[8u8; 32]), "m", "d", 10,
1674            &GrantRef::unbounded("quantum.calibrate"), &steps,
1675        );
1676        // snap the lineage: re-point the 2nd node's parent
1677        camp.receipts[1].parent_receipt_hash = Some([0u8; 32]);
1678        assert!(!camp.verify_chain());
1679    }
1680
1681    #[test]
1682    fn cr_recovers_both_conditional_amplitudes() {
1683        let dev = CrDevice { a_pi0_fx: fx(0.70), a_pi1_fx: fx(0.95), seed: 11 };
1684        let cfg = CrConfig { a_max_fx: fx(1.8), ..Default::default() };
1685        let r = calibrate_cr(&dev, &cfg);
1686        assert!((r.a_pi0_est_fx - fx(0.70)).abs() < CAL_ONE / 20, "a0 {}", r.a_pi0_est_fx);
1687        assert!((r.a_pi1_est_fx - fx(0.95)).abs() < CAL_ONE / 20, "a1 {}", r.a_pi1_est_fx);
1688        assert!(r.zx_shift_fx > 0);
1689        assert_eq!(r, calibrate_cr(&dev, &cfg));
1690    }
1691
1692    #[test]
1693    fn crosstalk_recovers_the_matrix() {
1694        let dev = CrosstalkDevice {
1695            n: 2,
1696            matrix_fx: vec![fx(1.0), fx(0.12), fx(0.15), fx(1.0)],
1697            seed: 5,
1698        };
1699        let r = characterize_crosstalk(&dev, fx(3.0), 4000);
1700        for k in 0..4 {
1701            assert!(
1702                (r.matrix_fx[k] - dev.matrix_fx[k]).abs() < CAL_ONE / 10,
1703                "coeff {k}: got {} want {}",
1704                r.matrix_fx[k], dev.matrix_fx[k]
1705            );
1706        }
1707        assert!(r.worst_offdiag_fx > 0);
1708        assert_eq!(r, characterize_crosstalk(&dev, fx(3.0), 4000));
1709    }
1710
1711    #[test]
1712    fn drag_finds_the_leakage_minimum() {
1713        let dev = DragDevice { beta_opt_fx: fx(0.5), curvature_fx: fx(2.0), seed: 9 };
1714        let r = calibrate_drag(&dev, fx(-1.0), fx(2.0), 41, 3000);
1715        assert!((r.beta_opt_est_fx - fx(0.5)).abs() < CAL_ONE / 12, "beta {}", r.beta_opt_est_fx);
1716        assert!(r.residual_leakage_fx < CAL_ONE / 20, "residual {}", r.residual_leakage_fx);
1717        assert_eq!(r, calibrate_drag(&dev, fx(-1.0), fx(2.0), 41, 3000));
1718    }
1719
1720    #[cfg(feature = "quantum_ops")]
1721    #[test]
1722    fn new_routines_seal_verifying_receipts() {
1723        use crate::quantum_ops::GrantRef;
1724        use ed25519_dalek::SigningKey;
1725        let signer = SigningKey::from_bytes(&[4u8; 32]);
1726        let grant = GrantRef::unbounded("quantum.calibrate");
1727        let cr = calibrate_cr(&CrDevice { a_pi0_fx: fx(0.7), a_pi1_fx: fx(0.95), seed: 1 }, &CrConfig::default());
1728        let xt = characterize_crosstalk(&CrosstalkDevice { n: 2, matrix_fx: vec![fx(1.0), fx(0.12), fx(0.15), fx(1.0)], seed: 2 }, fx(3.0), 2000);
1729        let dg = calibrate_drag(&DragDevice { beta_opt_fx: fx(0.5), curvature_fx: fx(2.0), seed: 3 }, fx(-1.0), fx(2.0), 31, 2000);
1730        for art in [cr.artifacts(), xt.artifacts(), dg.artifacts()] {
1731            let r = seal_artifacts(&signer, "did:key:lab", "sim:q0", &art, 1_000_000, grant.clone(), None);
1732            assert!(r.verify(), "receipt for {} must verify", art.evidence_kind);
1733            assert!(r.evidence_matches(0, &art.evidence_bytes));
1734        }
1735    }
1736
1737    #[test]
1738    fn sin_cos_are_accurate() {
1739        assert!(sin_fx(0).abs() < CAL_ONE / 400);
1740        assert!((sin_fx(PI_FX / 2) - CAL_ONE).abs() < CAL_ONE / 200);
1741        assert!(sin_fx(PI_FX).abs() < CAL_ONE / 200);
1742        assert!((cos_fx(0) - CAL_ONE).abs() < CAL_ONE / 200);
1743        assert!((sin_fx(PI_FX + PI_FX / 2) + CAL_ONE).abs() < CAL_ONE / 200); // sin(3π/2) = −1
1744    }
1745
1746    #[test]
1747    fn naive_pi_pulse_transfers_at_nominal() {
1748        let p = apply_composite(&[(0, PI_FX)], 0);
1749        assert!((p - CAL_ONE).abs() < CAL_ONE / 50, "naive P(0) = {p}");
1750    }
1751
1752    #[test]
1753    fn robust_pulse_beats_naive() {
1754        let r = optimize_robust_pulse(fx(0.3), 13);
1755        // a naive π-pulse is fragile to 30% amplitude error
1756        assert!(r.worst_naive_fx > CAL_ONE / 12, "naive worst {} too low", r.worst_naive_fx);
1757        // the optimizer discovers a meaningfully more robust pulse
1758        assert!(
1759            r.worst_robust_fx * 2 < r.worst_naive_fx,
1760            "robust {} not better than naive {}",
1761            r.worst_robust_fx, r.worst_naive_fx
1762        );
1763        assert_eq!(r, optimize_robust_pulse(fx(0.3), 13)); // deterministic
1764    }
1765
1766    #[cfg(feature = "quantum_ops")]
1767    #[test]
1768    fn robust_pulse_seals_a_receipt() {
1769        use crate::quantum_ops::GrantRef;
1770        use ed25519_dalek::SigningKey;
1771        let r = optimize_robust_pulse(fx(0.3), 13);
1772        let art = r.artifacts();
1773        let rec = seal_artifacts(
1774            &SigningKey::from_bytes(&[3u8; 32]), "did:key:lab", "sim:q0", &art,
1775            5_000_000, GrantRef::unbounded("quantum.calibrate"), None,
1776        );
1777        assert!(rec.verify());
1778        assert!(rec.evidence_matches(0, &art.evidence_bytes));
1779    }
1780}