keys.go raw

   1  // Package memory provides persistent cross-generation knowledge storage
   2  // using Badger v4 with composite binary keys and vector table indexes.
   3  //
   4  // Key schema follows the ORLY relay pattern: 3-byte ASCII prefixes,
   5  // fixed-width binary components, nil-value secondary indexes, and
   6  // sorted range iteration for graph traversal.
   7  package memory
   8  
   9  import (
  10  	"crypto/sha256"
  11  	"encoding/binary"
  12  )
  13  
  14  // 3-byte ASCII prefixes for each index table.
  15  var (
  16  	PrefixGen  = [3]byte{'g', 'e', 'n'} // generation metadata
  17  	PrefixTyp  = [3]byte{'t', 'y', 'p'} // type signature snapshots
  18  	PrefixBnd  = [3]byte{'b', 'n', 'd'} // bond events
  19  	PrefixMis  = [3]byte{'m', 'i', 's'} // missing site records
  20  	PrefixCon  = [3]byte{'c', 'o', 'n'} // connectivity statistics
  21  	PrefixFit  = [3]byte{'f', 'i', 't'} // fitness scores
  22  	PrefixHlt  = [3]byte{'h', 'l', 't'} // health snapshots
  23  	PrefixHex  = [3]byte{'h', 'e', 'x'} // hexagram operation counts
  24  	PrefixLck  = [3]byte{'l', 'c', 'k'} // lock-in depth distribution
  25  	PrefixMnd  = [3]byte{'m', 'n', 'd'} // mindsicle snapshots
  26  	PrefixEwm  = [3]byte{'e', 'w', 'm'} // EWMA detector state
  27  	PrefixAdr  = [3]byte{'a', 'd', 'r'} // ADSR phase distribution
  28  	PrefixFsc  = [3]byte{'f', 's', 'c'} // file accretion scores
  29  	PrefixWlk  = [3]byte{'w', 'l', 'k'} // walker checkpoint (singleton)
  30  	PrefixOrc  = [3]byte{'o', 'r', 'c'} // oracle state per generation
  31  	PrefixOhx  = [3]byte{'o', 'h', 'x'} // oracle reading history
  32  	PrefixOsr  = [3]byte{'o', 's', 'r'} // oracle directive results
  33  	PrefixPrf  = [3]byte{'p', 'r', 'f'} // recognition profile snapshots
  34  	PrefixMdl  = [3]byte{'m', 'd', 'l'} // model fingerprint spores
  35  	PrefixCvg  = [3]byte{'c', 'v', 'g'} // convergence state
  36  )
  37  
  38  // Fitness dimension constants.
  39  const (
  40  	DimSource  byte = 0
  41  	DimBinary  byte = 1
  42  	DimBehav   byte = 2
  43  	DimOverall byte = 3
  44  )
  45  
  46  // TagHash produces a truncated 8-byte SHA-256 hash of a tag string.
  47  // Same principle as ORLY's PubHash/IdHash: deterministic, fixed-width,
  48  // collision-acceptable (used for key prefix, not identification).
  49  func TagHash(tag string) [8]byte {
  50  	h := sha256.Sum256([]byte(tag))
  51  	var out [8]byte
  52  	copy(out[:], h[:8])
  53  	return out
  54  }
  55  
  56  // --- Key builders ---
  57  // All keys are built by concatenating: prefix(3) + components.
  58  // Generation number is always uint32 big-endian (4 bytes).
  59  
  60  // GenKey builds: gen | gen(4)
  61  func GenKey(gen uint32) []byte {
  62  	k := make([]byte, 3+4)
  63  	copy(k, PrefixGen[:])
  64  	binary.BigEndian.PutUint32(k[3:], gen)
  65  	return k
  66  }
  67  
  68  // TypKey builds: typ | tag_hash(8) | count(4) | gen(4)
  69  func TypKey(tagHash [8]byte, count uint32, gen uint32) []byte {
  70  	k := make([]byte, 3+8+4+4)
  71  	copy(k, PrefixTyp[:])
  72  	copy(k[3:], tagHash[:])
  73  	binary.BigEndian.PutUint32(k[11:], count)
  74  	binary.BigEndian.PutUint32(k[15:], gen)
  75  	return k
  76  }
  77  
  78  // TypPrefix builds the seek prefix for a specific tag: typ | tag_hash(8)
  79  func TypPrefix(tagHash [8]byte) []byte {
  80  	k := make([]byte, 3+8)
  81  	copy(k, PrefixTyp[:])
  82  	copy(k[3:], tagHash[:])
  83  	return k
  84  }
  85  
  86  // BndKey builds: bnd | tag_hash(8) | gen(4) | site_id(4)
  87  func BndKey(tagHash [8]byte, gen uint32, siteID uint32) []byte {
  88  	k := make([]byte, 3+8+4+4)
  89  	copy(k, PrefixBnd[:])
  90  	copy(k[3:], tagHash[:])
  91  	binary.BigEndian.PutUint32(k[11:], gen)
  92  	binary.BigEndian.PutUint32(k[15:], siteID)
  93  	return k
  94  }
  95  
  96  // BndPrefix builds the seek prefix for bonds of a tag: bnd | tag_hash(8)
  97  func BndPrefix(tagHash [8]byte) []byte {
  98  	k := make([]byte, 3+8)
  99  	copy(k, PrefixBnd[:])
 100  	copy(k[3:], tagHash[:])
 101  	return k
 102  }
 103  
 104  // BndGenPrefix builds: bnd | tag_hash(8) | gen(4) for counting bonds in a gen.
 105  func BndGenPrefix(tagHash [8]byte, gen uint32) []byte {
 106  	k := make([]byte, 3+8+4)
 107  	copy(k, PrefixBnd[:])
 108  	copy(k[3:], tagHash[:])
 109  	binary.BigEndian.PutUint32(k[11:], gen)
 110  	return k
 111  }
 112  
 113  // MisKey builds: mis | tag_hash(8) | gen(4) | count(4)
 114  func MisKey(tagHash [8]byte, gen uint32, count uint32) []byte {
 115  	k := make([]byte, 3+8+4+4)
 116  	copy(k, PrefixMis[:])
 117  	copy(k[3:], tagHash[:])
 118  	binary.BigEndian.PutUint32(k[11:], gen)
 119  	binary.BigEndian.PutUint32(k[15:], count)
 120  	return k
 121  }
 122  
 123  // MisPrefix builds: mis | tag_hash(8)
 124  func MisPrefix(tagHash [8]byte) []byte {
 125  	k := make([]byte, 3+8)
 126  	copy(k, PrefixMis[:])
 127  	copy(k[3:], tagHash[:])
 128  	return k
 129  }
 130  
 131  // ConKey builds: con | tag_hash(8) | gen(4)
 132  func ConKey(tagHash [8]byte, gen uint32) []byte {
 133  	k := make([]byte, 3+8+4)
 134  	copy(k, PrefixCon[:])
 135  	copy(k[3:], tagHash[:])
 136  	binary.BigEndian.PutUint32(k[11:], gen)
 137  	return k
 138  }
 139  
 140  // FitKey builds: fit | dimension(1) | gen(4)
 141  func FitKey(dim byte, gen uint32) []byte {
 142  	k := make([]byte, 3+1+4)
 143  	copy(k, PrefixFit[:])
 144  	k[3] = dim
 145  	binary.BigEndian.PutUint32(k[4:], gen)
 146  	return k
 147  }
 148  
 149  // FitDimPrefix builds: fit | dimension(1)
 150  func FitDimPrefix(dim byte) []byte {
 151  	k := make([]byte, 3+1)
 152  	copy(k, PrefixFit[:])
 153  	k[3] = dim
 154  	return k
 155  }
 156  
 157  // HltKey builds: hlt | gen(4)
 158  func HltKey(gen uint32) []byte {
 159  	k := make([]byte, 3+4)
 160  	copy(k, PrefixHlt[:])
 161  	binary.BigEndian.PutUint32(k[3:], gen)
 162  	return k
 163  }
 164  
 165  // HexKey builds: hex | operation(1) | gen(4)
 166  func HexKey(op byte, gen uint32) []byte {
 167  	k := make([]byte, 3+1+4)
 168  	copy(k, PrefixHex[:])
 169  	k[3] = op
 170  	binary.BigEndian.PutUint32(k[4:], gen)
 171  	return k
 172  }
 173  
 174  // LckKey builds: lck | bucket(1) | gen(4)
 175  func LckKey(bucket byte, gen uint32) []byte {
 176  	k := make([]byte, 3+1+4)
 177  	copy(k, PrefixLck[:])
 178  	k[3] = bucket
 179  	binary.BigEndian.PutUint32(k[4:], gen)
 180  	return k
 181  }
 182  
 183  // MndKey builds: mnd | gen(4)
 184  func MndKey(gen uint32) []byte {
 185  	k := make([]byte, 3+4)
 186  	copy(k, PrefixMnd[:])
 187  	binary.BigEndian.PutUint32(k[3:], gen)
 188  	return k
 189  }
 190  
 191  // EwmKey builds: ewm | gen(4)
 192  func EwmKey(gen uint32) []byte {
 193  	k := make([]byte, 3+4)
 194  	copy(k, PrefixEwm[:])
 195  	binary.BigEndian.PutUint32(k[3:], gen)
 196  	return k
 197  }
 198  
 199  // AdrKey builds: adr | gen(4)
 200  func AdrKey(gen uint32) []byte {
 201  	k := make([]byte, 3+4)
 202  	copy(k, PrefixAdr[:])
 203  	binary.BigEndian.PutUint32(k[3:], gen)
 204  	return k
 205  }
 206  
 207  // FscKey builds: fsc | file_hash(8)
 208  func FscKey(fileHash [8]byte) []byte {
 209  	k := make([]byte, 3+8)
 210  	copy(k, PrefixFsc[:])
 211  	copy(k[3:], fileHash[:])
 212  	return k
 213  }
 214  
 215  // WlkKey builds: wlk (singleton key, no suffix)
 216  func WlkKey() []byte {
 217  	return PrefixWlk[:]
 218  }
 219  
 220  // OrcKey builds: orc (singleton key — always the latest oracle state).
 221  func OrcKey() []byte {
 222  	return PrefixOrc[:]
 223  }
 224  
 225  // OhxKey builds: ohx | seq(4) | gen(4)
 226  func OhxKey(seq, gen uint32) []byte {
 227  	k := make([]byte, 3+4+4)
 228  	copy(k, PrefixOhx[:])
 229  	binary.BigEndian.PutUint32(k[3:], seq)
 230  	binary.BigEndian.PutUint32(k[7:], gen)
 231  	return k
 232  }
 233  
 234  // OsrKey builds: osr | seq(4) | directive_hash(8)
 235  func OsrKey(seq uint32, hash [8]byte) []byte {
 236  	k := make([]byte, 3+4+8)
 237  	copy(k, PrefixOsr[:])
 238  	binary.BigEndian.PutUint32(k[3:], seq)
 239  	copy(k[7:], hash[:])
 240  	return k
 241  }
 242  
 243  // --- Recognition key builders ---
 244  
 245  // PrfKey builds: prf | gen(4) — profile snapshot for a generation.
 246  func PrfKey(gen uint32) []byte {
 247  	k := make([]byte, 3+4)
 248  	copy(k, PrefixPrf[:])
 249  	binary.BigEndian.PutUint32(k[3:], gen)
 250  	return k
 251  }
 252  
 253  // MdlKey builds: mdl | name_hash(8) — model fingerprint spore.
 254  func MdlKey(nameHash [8]byte) []byte {
 255  	k := make([]byte, 3+8)
 256  	copy(k, PrefixMdl[:])
 257  	copy(k[3:], nameHash[:])
 258  	return k
 259  }
 260  
 261  // CvgKey builds: cvg | gen(4) — convergence state for a generation.
 262  func CvgKey(gen uint32) []byte {
 263  	k := make([]byte, 3+4)
 264  	copy(k, PrefixCvg[:])
 265  	binary.BigEndian.PutUint32(k[3:], gen)
 266  	return k
 267  }
 268  
 269  // DecodeOhx extracts seq and gen from an ohx-prefixed key.
 270  func DecodeOhx(key []byte) (seq, gen uint32) {
 271  	if len(key) < 11 {
 272  		return
 273  	}
 274  	seq = binary.BigEndian.Uint32(key[3:7])
 275  	gen = binary.BigEndian.Uint32(key[7:11])
 276  	return
 277  }
 278  
 279  // --- Key decoders ---
 280  
 281  // DecodeGen extracts generation from a gen-prefixed key.
 282  func DecodeGen(key []byte) uint32 {
 283  	if len(key) < 7 {
 284  		return 0
 285  	}
 286  	return binary.BigEndian.Uint32(key[3:7])
 287  }
 288  
 289  // DecodeTyp extracts tag_hash, count, gen from a typ-prefixed key.
 290  func DecodeTyp(key []byte) (tagHash [8]byte, count uint32, gen uint32) {
 291  	if len(key) < 19 {
 292  		return
 293  	}
 294  	copy(tagHash[:], key[3:11])
 295  	count = binary.BigEndian.Uint32(key[11:15])
 296  	gen = binary.BigEndian.Uint32(key[15:19])
 297  	return
 298  }
 299  
 300  // DecodeBnd extracts tag_hash, gen, site_id from a bnd-prefixed key.
 301  func DecodeBnd(key []byte) (tagHash [8]byte, gen uint32, siteID uint32) {
 302  	if len(key) < 19 {
 303  		return
 304  	}
 305  	copy(tagHash[:], key[3:11])
 306  	gen = binary.BigEndian.Uint32(key[11:15])
 307  	siteID = binary.BigEndian.Uint32(key[15:19])
 308  	return
 309  }
 310  
 311  // DecodeMis extracts tag_hash, gen, count from a mis-prefixed key.
 312  func DecodeMis(key []byte) (tagHash [8]byte, gen uint32, count uint32) {
 313  	if len(key) < 19 {
 314  		return
 315  	}
 316  	copy(tagHash[:], key[3:11])
 317  	gen = binary.BigEndian.Uint32(key[11:15])
 318  	count = binary.BigEndian.Uint32(key[15:19])
 319  	return
 320  }
 321  
 322  // DecodeFit extracts dimension and gen from a fit-prefixed key.
 323  func DecodeFit(key []byte) (dim byte, gen uint32) {
 324  	if len(key) < 8 {
 325  		return
 326  	}
 327  	dim = key[3]
 328  	gen = binary.BigEndian.Uint32(key[4:8])
 329  	return
 330  }
 331  
 332  // DecodeHlt extracts gen from a hlt-prefixed key.
 333  func DecodeHlt(key []byte) uint32 {
 334  	if len(key) < 7 {
 335  		return 0
 336  	}
 337  	return binary.BigEndian.Uint32(key[3:7])
 338  }
 339  
 340  // DecodeHex extracts operation and gen from a hex-prefixed key.
 341  func DecodeHex(key []byte) (op byte, gen uint32) {
 342  	if len(key) < 8 {
 343  		return
 344  	}
 345  	op = key[3]
 346  	gen = binary.BigEndian.Uint32(key[4:8])
 347  	return
 348  }
 349  
 350  // --- Value encoders/decoders ---
 351  
 352  // EncodeFitValue encodes a numerator/denominator pair.
 353  func EncodeFitValue(num, denom int64) []byte {
 354  	v := make([]byte, 16)
 355  	binary.BigEndian.PutUint64(v[0:], uint64(num))
 356  	binary.BigEndian.PutUint64(v[8:], uint64(denom))
 357  	return v
 358  }
 359  
 360  // DecodeFitValue decodes a numerator/denominator pair.
 361  func DecodeFitValue(v []byte) (num, denom int64) {
 362  	if len(v) < 16 {
 363  		return 0, 1
 364  	}
 365  	num = int64(binary.BigEndian.Uint64(v[0:]))
 366  	denom = int64(binary.BigEndian.Uint64(v[8:]))
 367  	if denom == 0 {
 368  		denom = 1
 369  	}
 370  	return
 371  }
 372  
 373  // EncodeHltValue encodes health snapshot.
 374  func EncodeHltValue(occupied, total uint32, avgLockInNum, avgLockInDenom int64) []byte {
 375  	v := make([]byte, 4+4+8+8)
 376  	binary.BigEndian.PutUint32(v[0:], occupied)
 377  	binary.BigEndian.PutUint32(v[4:], total)
 378  	binary.BigEndian.PutUint64(v[8:], uint64(avgLockInNum))
 379  	binary.BigEndian.PutUint64(v[16:], uint64(avgLockInDenom))
 380  	return v
 381  }
 382  
 383  // DecodeHltValue decodes health snapshot.
 384  func DecodeHltValue(v []byte) (occupied, total uint32, avgLockInNum, avgLockInDenom int64) {
 385  	if len(v) < 24 {
 386  		return 0, 0, 0, 1
 387  	}
 388  	occupied = binary.BigEndian.Uint32(v[0:])
 389  	total = binary.BigEndian.Uint32(v[4:])
 390  	avgLockInNum = int64(binary.BigEndian.Uint64(v[8:]))
 391  	avgLockInDenom = int64(binary.BigEndian.Uint64(v[16:]))
 392  	if avgLockInDenom == 0 {
 393  		avgLockInDenom = 1
 394  	}
 395  	return
 396  }
 397  
 398  // EncodeConValue encodes connectivity as fixed-point (num/denom).
 399  func EncodeConValue(num, denom int64) []byte {
 400  	v := make([]byte, 16)
 401  	binary.BigEndian.PutUint64(v[0:], uint64(num))
 402  	binary.BigEndian.PutUint64(v[8:], uint64(denom))
 403  	return v
 404  }
 405  
 406  // DecodeConValue decodes connectivity fixed-point.
 407  func DecodeConValue(v []byte) (num, denom int64) {
 408  	return DecodeFitValue(v) // same encoding
 409  }
 410  
 411  // EncodeU32Value encodes a single uint32 (for hex/lck counts).
 412  func EncodeU32Value(n uint32) []byte {
 413  	v := make([]byte, 4)
 414  	binary.BigEndian.PutUint32(v, n)
 415  	return v
 416  }
 417  
 418  // DecodeU32Value decodes a single uint32.
 419  func DecodeU32Value(v []byte) uint32 {
 420  	if len(v) < 4 {
 421  		return 0
 422  	}
 423  	return binary.BigEndian.Uint32(v)
 424  }
 425  
 426  // EncodeAdrValue encodes 4 ADSR phase counts: [attack, decay, sustain, release].
 427  func EncodeAdrValue(counts [4]uint32) []byte {
 428  	v := make([]byte, 16)
 429  	for i := range 4 {
 430  		binary.BigEndian.PutUint32(v[i*4:], counts[i])
 431  	}
 432  	return v
 433  }
 434  
 435  // DecodeAdrValue decodes 4 ADSR phase counts.
 436  func DecodeAdrValue(v []byte) [4]uint32 {
 437  	var counts [4]uint32
 438  	if len(v) < 16 {
 439  		return counts
 440  	}
 441  	for i := range 4 {
 442  		counts[i] = binary.BigEndian.Uint32(v[i*4:])
 443  	}
 444  	return counts
 445  }
 446  
 447  // PrefixEnd returns the key that is one past the end of all keys
 448  // with the given prefix. Used as the upper bound for range scans.
 449  func PrefixEnd(prefix []byte) []byte {
 450  	end := make([]byte, len(prefix))
 451  	copy(end, prefix)
 452  	for i := len(end) - 1; i >= 0; i-- {
 453  		end[i]++
 454  		if end[i] != 0 {
 455  			return end
 456  		}
 457  	}
 458  	return nil // overflow: prefix was all 0xFF
 459  }
 460