Part VI — Gauge Encryption · seven builds, seven receipts
The exercises for this chapter are Carol's clipboard, weaponized. Every build should produce a VerifyResult you can paste into a test log — a Verified payload, a named Rejected field with a delta, or a BundleMismatch caught before InvariantTuple::compute ever fires. The receipt class is the three-armed enum from src/invariant_verify.rs, not prose.
Run it live — GQL console
Point at the public read-only instance (no key needed) or your own engine
(start it with GIGI_CORS_ORIGIN=* for browser access — dev only).
—
E16.1Reproduce the three anchor tests cold
Build
Check out the engine at the Sprint N commit, run cargo test -p gigi --lib invariant_verify on a fresh clone with no other tests selected, and capture the three test names that fire from src/invariant_verify.rs.
Receipt
A green log showing honest_claim_verifies, tampered_k_is_rejected, and bundle_mismatch_caught_before_tuple_check all passing — the same three I anchored against BLD-CH16-VERIFY-TEST-HONEST, BLD-CH16-VERIFY-TEST-TAMPER, BLD-CH16-VERIFY-TEST-MISMATCH in § 16.7.
Bonus
Run the same fixtures under cargo test --release and confirm the verdicts are bitwise-identical to the debug build — the f64 walk should not drift across optimization levels.
E16.2Instrument the per-field walk with a forensic logger
Build
Fork verify_invariant_statement into a sibling verify_invariant_statement_traced that emits one line per slot — k, lambda1, holonomy_mean, record_count, beta_0, beta_1 — recording claimed, computed, delta, and whether the slot tripped.
Receipt
A trace from tiny_bundle() where the honest path emits six ok lines in canonical fingerprint order, and a tampered \(\beta_0\) run emits three ok lines (k, lambda1, holonomy_mean), then record_countok, then beta_0rejected — and no line for beta_1, proving the FIFO short-circuit from § 16.4 fires.
Bonus
Tamper \(K\) and \(\beta_1\) simultaneously and confirm the trace stops at \(K\) — the report names the first miss, never the worst one.
E16.3Stress the \(10^{-10}\) tolerance against gauge drift
Build
Take a tiny_bundle(), push it through each of the v0.2 gauge modes, and recompute \(\pi_{\mathrm{inv}}\) across all of them. Record the worst-case relative delta on the three f64 slots (\(K\), \(\lambda_1\), \(\overline{\mathrm{Hol}}\)).
Receipt
A three-row table of worst-case deltas confirming the \(\sim 10^{-11}\) relative drift I cited in the InvariantTolerances::default() doc-comment, with every f64 verdict still Verified at the default \(10^{-10}\) tolerance. If any row exceeds \(10^{-10}\), that is a bug — file it.
Bonus
Tighten the tolerance to \(10^{-12}\) and show which gauge mode breaks first — the failing field is the gauge mode's numerical weak link.
E16.4Forge a colliding-\(K\) tamper and confirm the full tuple catches it
Build
Construct two bundles with the same \(K\) (within \(10^{-10}\)) but different \(\beta_0\) — the BLD-CH16-HONESTY-CONCEPT-2 scenario where “an adversary can construct a different distribution that shares the same K.” Submit each as a claim against the other.
Receipt
VerifyResult::Rejected{field: "beta_0", …} on both directions — the curvature scalar alone would have let the forgery through, but the full canonical walk catches it on the integer slot. This is the receipt the honest-disclosure section in § 16.8 is paying off.
Bonus
Try to construct a bundle that collides on all three f64 slots simultaneously and report whether \(\beta_0\) or \(\beta_1\) catches it — empirical pressure on the open collision-resistance question.
E16.5Refute the API by trying to slip in a gauge key
Build
Read verify_invariant_statement's signature at src/invariant_verify.rs:162--173 and attempt to add a key: GaugeKey parameter. Patch the signature, see what the compiler says, and document the cascade of breakages.
Receipt
The patch refuses to compile cleanly against the existing call sites — the verifier API has no key-shaped hole because the contract from § 16.3 (“Verifier never receives the gauge key”) is enforced by the absence of a parameter, not by a runtime check. Write up the compiler errors as the receipt.
Bonus
Revert the patch and add a one-line compile_fail doctest to the module that pins this property — a key-bearing signature must never type-check against the public entry point.
E16.6Replay Carol's Appendix A.11 worked example end-to-end
Build
Construct an InvariantStatement with the published Appendix A.11 claim — \(K = 0.142\), \(\lambda_1 = 1.83\), \(\overline{\mathrm{Hol}} = 0.667\), \(\tau = 40\), \(\beta_0 = 2\), \(\beta_1 = 2\) — and run it against a bundle pinned to those values. Then run the tamper branch by mutating the underlying record so that recomputed \(K\) becomes \(0.151\).
Receipt
Branch one: Verified{computed} surfacing the full six-tuple. Branch two: Rejected{field: "k", claimed: 0.142, computed: 0.151, delta: 0.009} — the exact verbatim verdict from theory/encryption/paper_geometric_encryption_v0.1.tex:2008--2022 that I quoted in § 16.6.
Bonus
Vary the tamper magnitude from \(10^{-11}\) up through \(10^{-8}\) and chart where the verdict flips from Verified to Rejected — the transition is the tolerance boundary in practice.
E16.7Benchmark the Gap 1 fence against the walk
Build
Time verify_invariant_statement on three workloads: (a) matching bundle id, honest claim — the full walk runs; (b) mismatched bundle id, honest tuple — the early return fires; (c) matching bundle id, \(K\)-tampered claim — the walk fires and exits on slot one. Use criterion or a hand-rolled Instant::elapsed() over 10\,000 iterations.
Receipt
A three-bar chart showing case (b) at constant-time bundle-id length, case (c) at roughly one-sixth of case (a)'s walk cost — empirical evidence that the Gap 1 fix from § 16.5 saves the tuple computation, and that the FIFO short-circuit saves the downstream slots.
Bonus
Push the bundle-id length to 1\,KiB and confirm case (b) remains \(O(n)\) on string length and never enters InvariantTuple::compute — the fence in front of the arithmetic stays in front of the arithmetic.