// Package epoch formalizes the synchronization between binary-aligned // (2^b) and decimal-aligned (10^a) cadences in dendrite's subsystems. // // Binary and decimal are multiplicatively incommensurable: log2(10) is // transcendental, so no integer power of 2 exactly equals an integer // power of 10. When two subsystems operate at cadences from different // bases — binary for memory/crypto/lattice, decimal for metrics/timing/ // human interfaces — they drift apart at every step. The drift is the // phase angle θ = ln(2^b / 10^a), and it only resolves to zero at the // synchronization epoch: the product 10^a × 2^b. // // On the real line, the ratio 2^b / 10^a is an irreducible gap. // In the complex plane, the gap becomes a rotation: the binary and // decimal clocks trace circles of different periods, and the "missing" // alignment lives in the imaginary component of the complex logarithm. // The epoch is the point where both clocks return to the real axis // simultaneously. package epoch import ( "fmt" "git.smesh.lol/gnarl-hamadryad/ratio" ) // Epoch represents a synchronization period between a decimal cadence // (10^DecExp) and a binary cadence (2^BinExp). The synchronization // period is DecFactor × BinFactor = 10^DecExp × 2^BinExp. type Epoch struct { DecExp int // exponent of 10 BinExp int // exponent of 2 DecFactor int64 // 10^DecExp, precomputed BinFactor int64 // 2^BinExp, precomputed Period int64 // DecFactor × BinFactor } // New creates an Epoch from the decimal exponent a and binary exponent b. // The synchronization period is 10^a × 2^b. // Panics if either exponent is negative or the result overflows int64. func New(decExp, binExp int) Epoch { if decExp < 0 || binExp < 0 { panic("epoch: negative exponent") } dec := pow10(decExp) bin := pow2(binExp) // Overflow check: if Period / dec != bin, we overflowed. period := dec * bin if dec != 0 && period/dec != bin { panic("epoch: period overflow") } return Epoch{ DecExp: decExp, BinExp: binExp, DecFactor: dec, BinFactor: bin, Period: period, } } // Named epochs for dendrite subsystem synchronization. var ( // Colony is the generation synchronization epoch: 10^2 × 2^8 = 25600. // Binary-aligned logging every 256 steps, decimal-aligned crypto // verification every 100 steps. At step 25600 both clocks land on zero. Colony = New(2, 8) // EngineDissolveLCM is the tick synchronization epoch for concurrent // engine (2^4 = 16ms) and dissolve (10^2 = 100ms) loops. // 10^2 × 2^4 = 1600. The raw LCM(16, 100) = 400; the epoch is 4×LCM, // the smallest period expressible as a pure 10^a × 2^b product. EngineDissolveLCM = New(2, 4) // FitnessSampling is the epoch-aligned sample limit for binary // similarity: 10^2 × 2^8 = 25600. Replaces the ad-hoc 10000. FitnessSampling = New(2, 8) // CryptoWalk128 is the walk step count for Security128 (N=256=2^8): // 2^10 = 1024. Pure binary — the walk operates in a 2^8-dimensional // space, so the walk length shares the binary base. CryptoWalk128 = New(0, 10) // CryptoWalk192 is the walk step count for Security192 (N=384): // 10^2 × 2^4 = 1600. N=384=3×2^7 is not a pure power of 2, // so the epoch carries a decimal component. CryptoWalk192 = New(2, 4) // CryptoWalk256 is the walk step count for Security256 (N=512=2^9): // 10^3 × 2^1 = 2000. Already epoch-aligned. CryptoWalk256 = New(3, 1) // EWMACap is the denominator cap for EWMA rescaling: // 10^9 × 2^0 = 1_000_000_000. Pure decimal — the cap exists to // provide ~9 decimal digits of precision for human-readable output. EWMACap = New(9, 0) ) // OnBoundary reports whether step n falls on the epoch boundary. // Returns false for n <= 0. func (e Epoch) OnBoundary(n int64) bool { return n > 0 && n%e.Period == 0 } // OnDecimal reports whether step n falls on the decimal cadence boundary. // Returns false for n <= 0. func (e Epoch) OnDecimal(n int64) bool { return n > 0 && n%e.DecFactor == 0 } // OnBinary reports whether step n falls on the binary cadence boundary. // Returns false for n <= 0. func (e Epoch) OnBinary(n int64) bool { return n > 0 && n%e.BinFactor == 0 } // Phase returns the drift between the binary and decimal clocks at step n, // as an exact Ratio in [-1/2, 1/2]. // // At epoch boundaries, Phase returns 0/1. // At intermediate steps, Phase is the difference between the fractional // positions of the two clocks: // // Phase(n) = (n mod BinFactor)/BinFactor − (n mod DecFactor)/DecFactor // // This is the discrete analog of the transcendental phase angle // θ = ln(2^b / 10^a) that separates binary and decimal in the // complex plane. All arithmetic is exact rational. func (e Epoch) Phase(n int64) ratio.Ratio { binFrac := ratio.New(n%e.BinFactor, e.BinFactor) decFrac := ratio.New(n%e.DecFactor, e.DecFactor) return binFrac.Sub(decFrac) } // ComplexPhase holds the real and imaginary components of the // binary/decimal clock relationship at a step. type ComplexPhase struct { Re ratio.Ratio // drift: binFrac - decFrac Im ratio.Ratio // cross-correlation: binFrac * decFrac } // ImagPhase returns the cross-correlation between the binary and // decimal clocks at step n, as an exact Ratio in [0, 1/4]. // // The imaginary phase is the product of the two fractional positions: // // ImagPhase(n) = (n mod BinFactor)/BinFactor × (n mod DecFactor)/DecFactor // // This is maximal (1/4) when both clocks are at their midpoints // simultaneously, and zero at any factor boundary. It captures // the "when both clocks peak together" correlation that the real // Phase (their difference) cannot represent. // // On the complex plane: the real phase is the signed distance between // the two clock hands. The imaginary phase is their geometric mean // position — when both are high, the system is in a correlated state // that lives on the imaginary axis. func (e Epoch) ImagPhase(n int64) ratio.Ratio { binFrac := ratio.New(n%e.BinFactor, e.BinFactor) decFrac := ratio.New(n%e.DecFactor, e.DecFactor) return binFrac.Mul(decFrac) } // ComplexPhase returns both the real drift and imaginary cross-correlation // at step n. func (e Epoch) ComplexPhase(n int64) ComplexPhase { return ComplexPhase{ Re: e.Phase(n), Im: e.ImagPhase(n), } } // BinaryStepsPerDecimal returns the exact ratio BinFactor / DecFactor. // For Colony: 256/100 = 64/25 = 2.56. func (e Epoch) BinaryStepsPerDecimal() ratio.Ratio { return ratio.New(e.BinFactor, e.DecFactor) } // DecimalStepsPerBinary returns the exact ratio DecFactor / BinFactor. // For Colony: 100/256 = 25/64. func (e Epoch) DecimalStepsPerBinary() ratio.Ratio { return ratio.New(e.DecFactor, e.BinFactor) } // String returns "10^a×2^b=N" for debugging. func (e Epoch) String() string { return fmt.Sprintf("10^%d×2^%d=%d", e.DecExp, e.BinExp, e.Period) } // pow10 returns 10^n using integer multiplication. Panics on overflow. func pow10(n int) int64 { var r int64 = 1 for range n { next := r * 10 if next/10 != r { panic("epoch: 10^n overflow") } r = next } return r } // pow2 returns 2^n using bit shift. Panics if n >= 63. func pow2(n int) int64 { if n >= 63 { panic("epoch: 2^n overflow") } return 1 << n }