Third flake found in the same hunt. `timing variance stays bounded across
mismatch positions` took two single measurements of 50 000 iterations each and
compared their ratio, which is one GC pause away from a false alarm — it failed
about one run in fourteen on a loaded machine.
Two things were wrong with the measurement, not the property:
The first loop through that code pays for JIT compilation the second one does
not, so whichever side ran first was biased upward. The old comment admitted it
— "allow 2x variance for JIT/noise" — which is a tolerance covering a
measurement artefact rather than the thing under test. There is a warm-up now.
And a single pair has no defence against a scheduler hiccup. Five interleaved
pairs compared by median throw the pause out instead of the property.
The threshold is unchanged at 3, deliberately. An early-exit compare takes
~256x longer to reach a mismatch in the last byte than the first, on every
round; nothing here weakens what the test catches.
Verified that it still catches what it is for: with `constantTimeEqual`
temporarily replaced by an early-exit loop the test fails, and passes again
with the real one restored. A security test nobody has watched fail is a
security test nobody knows works.
A security test that cries wolf under load is worse than none — it teaches
people to re-run until green, and then a real regression looks like the noise.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014489bKUtUEY1Zgs9xN9mt7
V3.1 → V3.12 consolidated and tagged for the first GA release. Wire
format unchanged from 0.4.x — 4.0 peers interoperate with 0.4.x peers
byte-for-byte. The version bump is semantic: audit-cycle complete,
opt-in surface fully exposed, threat model refreshed for every new
surface.
Highlights:
- All 24 @shade/* packages bumped to 4.0.0 in lockstep.
- CHANGELOG 4.0.0 section is the canonical manifest of what landed.
- THREAT-MODEL extended (§10 fingerprint gates, §11 WebRTC P2P, §12
Web-Worker boundary) + residual-risks table refreshed.
- OpenAPI now covers all 27 routes: prekey, transfer, KT, inbox,
bridge, observer, /metrics, /healthz, /ready.
- MIGRATION 0.3.x → 4.0 documented + smoke-tested against
shade migrate-storage on a real SQLite DB.
- docs/audit/REVIEW-BUNDLE.md + SCOPE.md ready for external reviewer.
- scripts/soak.ts harness for the GA-stable 2-week soak window.
- All V*.md plans archived under docs/archive/ with Status: Done.
- Voice/Video carved out into V5.0; 4.0 audit focuses on the frozen
non-realtime stack.
Tests: TS 1000/1000 + Kotlin 11/11 cross-platform vectors green.
Docker: gt.zyon.no/stian/shade-prekey:4.0.0 builds and reports
version 4.0.0 on /health.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>