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