1use crate::format::{
21 CmfError, CmfHeader, SelectionDescriptor, SkillRecord, TensorEntry, TensorSpec, features,
22};
23use crate::hash::hash64;
24use crate::types::{LayerType, ModelArch, TensorDtype};
25use serde::{Deserialize, Serialize};
26use std::borrow::Cow;
27use std::collections::{BTreeSet, HashMap};
28
29pub const GENOME_STATUSES: &[&str] = &["pre_chat", "sealed", "candidate", "rejected"];
31pub const SKILL_STATUSES: &[&str] = &["quarantine", "active", "stale_regate", "retired"];
33pub const SEGMENT_KINDS: &[&str] = &["genome", "base", "skill"];
35pub const METRIC_MSE_UNIT: &str = "mse_unit";
37pub const BACKBONE_CLASS_ID: &str = "@backbone";
39pub const RESERVED_SKILL_IDS: &[&str] = &["backbone", "none", "auto"];
44
45pub mod skill_kind {
47 pub const FFN_REPLACE: &str = "ffn_replace";
50 pub const EXPERT_APPEND: &str = "expert_append";
57 pub const LOOKUP: &str = "lookup";
65 pub const IMPLEMENTED: &[&str] = &[FFN_REPLACE, EXPERT_APPEND, LOOKUP];
67 pub const RESERVED: &[&str] = &["anchor_sinks", "mask_only", "fcd_vector"];
71}
72
73pub mod state_switch {
75 pub const TRANSPARENT: &str = "transparent";
78 pub const SEQUENCE_START: &str = "sequence_start";
80 pub const ALL: &[&str] = &[TRANSPARENT, SEQUENCE_START];
82}
83
84#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
88pub struct GenomeInfo {
89 pub id: String,
92 pub generation: u32,
94 pub status: String,
96 #[serde(default)]
100 pub trunk_hash: String,
101 pub encoding: String,
103 #[serde(default)]
107 pub master_trunk_hash: String,
108 #[serde(default, skip_serializing_if = "Option::is_none")]
109 pub parent: Option<GenomeParent>,
110 #[serde(default, skip_serializing_if = "Option::is_none")]
112 pub reference: Option<serde_json::Value>,
113 #[serde(default, skip_serializing_if = "Option::is_none")]
121 pub moe_experts: Option<usize>,
122}
123
124impl GenomeInfo {
125 pub fn birth(
128 id: impl Into<String>,
129 status: impl Into<String>,
130 encoding: impl Into<String>,
131 ) -> Self {
132 Self {
133 id: id.into(),
134 generation: 0,
135 status: status.into(),
136 trunk_hash: String::new(),
137 encoding: encoding.into(),
138 master_trunk_hash: String::new(),
139 parent: None,
140 reference: None,
141 moe_experts: None,
142 }
143 }
144}
145
146#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
147pub struct GenomeParent {
148 pub id: String,
149 pub generation: u32,
150 pub master_trunk_hash: String,
151}
152
153#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
157pub struct LineageEvent {
158 pub seq: u32,
159 pub event: String,
160 pub ts: String,
162 #[serde(default)]
163 pub detail: serde_json::Value,
164}
165
166impl LineageEvent {
167 pub fn now(seq: u32, event: impl Into<String>, detail: serde_json::Value) -> Self {
169 Self {
170 seq,
171 event: event.into(),
172 ts: utc_now_rfc3339(),
173 detail,
174 }
175 }
176}
177
178#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
182pub struct Segment {
183 pub kind: String,
185 pub id: String,
186 pub data_start: u64,
187 pub data_end: u64,
188}
189
190#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
194pub struct SkillOverride {
195 pub name: String,
197 pub base_hash: String,
201}
202
203#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
205pub struct SkillBound {
206 pub genome_id: String,
207 pub generation: u32,
208 pub master_trunk_hash: String,
209}
210
211#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
213pub struct StateEffect {
214 pub first_affected_layer: usize,
215 pub switch: String,
217 pub state_bytes_added: u64,
219}
220
221pub fn layer_type_is_stateful(t: LayerType) -> bool {
224 match t {
225 LayerType::FullAttention
226 | LayerType::SlidingAttention
227 | LayerType::LinearAttention
228 | LayerType::ShortConv
229 | LayerType::Kda
230 | LayerType::BoundedAttention => true,
231 }
232}
233
234pub fn ffn_replace_state_effect(arch: &ModelArch, layers: &[usize]) -> StateEffect {
241 let first = layers.iter().copied().min().unwrap_or(0);
242 let later_stateful = arch.num_loops > 1
243 || arch
244 .layer_types
245 .iter()
246 .enumerate()
247 .any(|(j, t)| j > first && layer_type_is_stateful(*t));
248 StateEffect {
249 first_affected_layer: first,
250 switch: if later_stateful {
251 state_switch::SEQUENCE_START
252 } else {
253 state_switch::TRANSPARENT
254 }
255 .into(),
256 state_bytes_added: 0,
257 }
258}
259
260#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
268pub struct ExpertAppend {
269 pub count: usize,
271 pub shell_quantile: f32,
275 pub rank: usize,
279}
280
281pub mod expert_leaf {
285 pub const GATE: &str = "gate_proj.weight";
286 pub const UP: &str = "up_proj.weight";
287 pub const DOWN: &str = "down_proj.weight";
288 pub const MU: &str = "desc.mu";
290 pub const U: &str = "desc.u";
293 pub const BIAS: &str = "desc.bias";
297 pub const SHELL: &str = "desc.shell";
300 pub const ALL: &[&str] = &[GATE, UP, DOWN, MU, U, BIAS, SHELL];
302}
303
304pub fn expert_tensor_name(layer: usize, expert: usize, leaf: &str) -> String {
308 format!("model.layers.{layer}.mlp.experts.{expert}.{leaf}")
309}
310
311pub fn expert_append_tensor_name(id: &str, layer: usize, expert: usize, leaf: &str) -> String {
313 format!("skill.{id}.{}", expert_tensor_name(layer, expert, leaf))
314}
315
316pub fn moe_layers(tensors: &[TensorEntry]) -> Vec<usize> {
320 let mut out: Vec<usize> = tensors
321 .iter()
322 .filter_map(|t| {
323 let l = layer_of(&t.name)?;
324 (t.name == expert_tensor_name(l, 0, expert_leaf::GATE)).then_some(l)
325 })
326 .collect();
327 out.sort_unstable();
328 out.dedup();
329 out
330}
331
332pub fn genome_moe_experts(header: &CmfHeader) -> Result<usize, CmfError> {
338 let g = header
339 .genome
340 .as_ref()
341 .ok_or_else(|| perr("expert_append: the file has no genome".into()))?;
342 let moe = header
343 .arch
344 .moe
345 .as_ref()
346 .filter(|m| m.router_resonance)
347 .ok_or_else(|| {
348 perr(format!(
349 "genome '{}': expert_append needs a resonance-routed MoE trunk \
350 (arch.moe.router_resonance); a gated MoE fixes its expert count in the gate",
351 g.id
352 ))
353 })?;
354 Ok(g.moe_experts.unwrap_or(moe.num_experts))
355}
356
357pub fn trunk_expert_rank(
363 header: &CmfHeader,
364 tensors: &[TensorEntry],
365 layer: usize,
366) -> Result<usize, CmfError> {
367 let by_name: HashMap<&str, &TensorEntry> =
368 tensors.iter().map(|t| (t.name.as_str(), t)).collect();
369 trunk_expert_rank_in(header, &by_name, layer)
370}
371
372fn trunk_expert_rank_in(
373 header: &CmfHeader,
374 by_name: &HashMap<&str, &TensorEntry>,
375 layer: usize,
376) -> Result<usize, CmfError> {
377 let trunk = |leaf: &str| {
378 by_name
379 .get(expert_tensor_name(layer, 0, leaf).as_str())
380 .copied()
381 .filter(|t| is_trunk_tensor(&t.name))
382 };
383 if trunk(expert_leaf::GATE).is_none() {
384 return Err(perr(format!(
385 "layer {layer} is not an MoE layer of the trunk (no '{}')",
386 expert_tensor_name(layer, 0, expert_leaf::GATE)
387 )));
388 }
389 if trunk(expert_leaf::MU).is_none() {
390 return Err(perr(format!(
391 "layer {layer}: the trunk has no per-expert descriptors ('{}'); an \
392 expert_append record needs the per-expert form, not the stacked mlp.desc.*",
393 expert_tensor_name(layer, 0, expert_leaf::MU)
394 )));
395 }
396 let Some(u) = trunk(expert_leaf::U) else {
397 return Ok(0);
398 };
399 let hidden = header.arch.hidden_size.max(1);
400 let n = u.n_elems();
401 if n == 0 || n % hidden != 0 {
402 return Err(perr(format!(
403 "'{}': {n} elements is not a multiple of hidden {hidden}",
404 u.name
405 )));
406 }
407 Ok(n / hidden)
408}
409
410fn expert_chain_before(header: &CmfHeader, at: usize, layer: usize) -> (usize, Option<&str>) {
413 let mut n = 0usize;
414 let mut retired = None;
415 for s in header.skills.iter().take(at) {
416 if s.kind.as_deref() != Some(skill_kind::EXPERT_APPEND) || !s.layers.contains(&layer) {
417 continue;
418 }
419 n += s.experts.as_ref().map(|e| e.count).unwrap_or(0);
420 if retired.is_none() && s.status.as_deref() == Some("retired") {
421 retired = Some(s.id.as_str());
422 }
423 }
424 (n, retired)
425}
426
427pub fn expert_append_base(header: &CmfHeader, at: usize, layer: usize) -> Result<usize, CmfError> {
441 let e0 = genome_moe_experts(header)?;
442 let (n, retired) = expert_chain_before(header, at, layer);
443 if let Some(r) = retired {
444 return Err(perr(format!(
445 "expert_append chain at layer {layer} is broken: record '{r}' before position {at} \
446 is retired — retire records from the tail of the chain (the last appended first)"
447 )));
448 }
449 Ok(e0 + n)
450}
451
452#[derive(Debug, Clone, PartialEq, Eq)]
454pub struct ExpertTensorSpec {
455 pub name: String,
457 pub shape: Vec<usize>,
458 pub layer: usize,
459 pub expert: usize,
461 pub leaf: &'static str,
463}
464
465pub fn expert_append_layout(
480 header: &CmfHeader,
481 tensors: &[TensorEntry],
482 at: usize,
483 record: &SkillRecord,
484) -> Result<Vec<ExpertTensorSpec>, CmfError> {
485 let by_name: HashMap<&str, &TensorEntry> =
486 tensors.iter().map(|t| (t.name.as_str(), t)).collect();
487 expert_append_layout_in(header, &by_name, at, record, false)
488}
489
490fn expert_append_layout_in(
494 header: &CmfHeader,
495 by_name: &HashMap<&str, &TensorEntry>,
496 at: usize,
497 record: &SkillRecord,
498 retired_self: bool,
499) -> Result<Vec<ExpertTensorSpec>, CmfError> {
500 let id = &record.id;
501 let e0 = genome_moe_experts(header).map_err(|e| perr(format!("skill '{id}': {e}")))?;
502 let ea = record
503 .experts
504 .as_ref()
505 .ok_or_else(|| perr(format!("skill '{id}': expert_append record has no `experts`")))?;
506 if ea.count == 0 {
507 return Err(perr(format!(
508 "skill '{id}': experts.count must be ≥ 1"
509 )));
510 }
511 if !(ea.shell_quantile.is_finite() && (0.0..=1.0).contains(&ea.shell_quantile)) {
512 return Err(perr(format!(
513 "skill '{id}': experts.shell_quantile {} must be finite and in [0, 1]",
514 ea.shell_quantile
515 )));
516 }
517 if record.layers.is_empty() {
518 return Err(perr(format!(
519 "skill '{id}': expert_append record grows no layers (`layers` is empty)"
520 )));
521 }
522 let distinct: BTreeSet<usize> = record.layers.iter().copied().collect();
523 if distinct.len() != record.layers.len() {
524 return Err(perr(format!(
525 "skill '{id}': duplicate layer in {:?}",
526 record.layers
527 )));
528 }
529 let hidden = header.arch.hidden_size;
530 let mut out = Vec::with_capacity(distinct.len() * ea.count * expert_leaf::ALL.len());
531 for &l in &distinct {
532 if l >= header.arch.num_layers {
533 return Err(perr(format!(
534 "skill '{id}': layer {l} of {} layers",
535 header.arch.num_layers
536 )));
537 }
538 let rank = trunk_expert_rank_in(header, by_name, l)
539 .map_err(|e| perr(format!("skill '{id}': {e}")))?;
540 if rank != ea.rank {
541 return Err(perr(format!(
542 "skill '{id}': experts.rank {} != the trunk expert 0's desc.u rank {rank} at \
543 layer {l}",
544 ea.rank
545 )));
546 }
547 let (n_before, retired) = expert_chain_before(header, at, l);
548 if let (Some(r), false) = (retired, retired_self) {
549 return Err(perr(format!(
550 "skill '{id}': expert_append chain at layer {l} is broken — the earlier record \
551 '{r}' is retired while this one is live; retire records from the tail of the \
552 chain (the last appended first)"
553 )));
554 }
555 let base = e0 + n_before;
556 let trunk_shape = |leaf: &str| -> Vec<usize> {
557 by_name
558 .get(expert_tensor_name(l, 0, leaf).as_str())
559 .map(|t| t.shape.clone())
560 .unwrap_or_default()
561 };
562 for leaf in [expert_leaf::GATE, expert_leaf::UP, expert_leaf::DOWN] {
563 if trunk_shape(leaf).is_empty() {
564 return Err(perr(format!(
565 "skill '{id}': the trunk has no '{}'",
566 expert_tensor_name(l, 0, leaf)
567 )));
568 }
569 }
570 for k in 0..ea.count {
571 let e = base + k;
572 let mut push = |leaf: &'static str, shape: Vec<usize>| {
573 out.push(ExpertTensorSpec {
574 name: expert_append_tensor_name(id, l, e, leaf),
575 shape,
576 layer: l,
577 expert: e,
578 leaf,
579 })
580 };
581 push(expert_leaf::GATE, trunk_shape(expert_leaf::GATE));
582 push(expert_leaf::UP, trunk_shape(expert_leaf::UP));
583 push(expert_leaf::DOWN, trunk_shape(expert_leaf::DOWN));
584 push(expert_leaf::MU, vec![hidden]);
585 if rank > 0 {
586 push(expert_leaf::U, trunk_shape(expert_leaf::U));
587 }
588 push(expert_leaf::BIAS, vec![1]);
589 push(expert_leaf::SHELL, vec![1]);
590 }
591 }
592 Ok(out)
593}
594
595pub fn expert_append_state_effect(layers: &[usize]) -> StateEffect {
599 StateEffect {
600 first_affected_layer: layers.iter().copied().min().unwrap_or(0),
601 switch: state_switch::SEQUENCE_START.into(),
602 state_bytes_added: 0,
603 }
604}
605
606pub fn f32_le_head(bytes: &[u8]) -> Option<f32> {
608 bytes
609 .get(..4)
610 .map(|b| f32::from_le_bytes([b[0], b[1], b[2], b[3]]))
611}
612
613pub fn validate_expert_append_values(
622 header: &CmfHeader,
623 tensors: &[TensorEntry],
624 mut f32_of: impl FnMut(&TensorEntry) -> Option<f32>,
625) -> Result<(), CmfError> {
626 for s in header
627 .skills
628 .iter()
629 .filter(|s| s.kind.as_deref() == Some(skill_kind::EXPERT_APPEND))
630 {
631 let prefix = format!("skill.{}.", s.id);
632 for t in tensors.iter().filter(|t| t.name.starts_with(&prefix)) {
633 let bias = t.name.ends_with(".desc.bias");
634 let shell = t.name.ends_with(".desc.shell");
635 if !(bias || shell) {
636 continue;
637 }
638 let v = f32_of(t).ok_or_else(|| {
639 perr(format!(
640 "skill '{}': payload of '{}' is not available for the value check",
641 s.id, t.name
642 ))
643 })?;
644 if bias && !v.is_finite() {
645 return Err(perr(format!(
646 "skill '{}': '{}' is {v} — a grown expert's desc.bias must be a finite f32",
647 s.id, t.name
648 )));
649 }
650 if shell && !v.is_finite() {
651 return Err(perr(format!(
652 "skill '{}': '{}' is {v} — desc.shell must be a finite f32 threshold",
653 s.id, t.name
654 )));
655 }
656 }
657 }
658 Ok(())
659}
660
661pub const KEY_NORM_V1: &str = "cmf-key-v1";
669pub const KEY_NORM_V2: &str = "cmf-key-v2";
672pub const KEY_NORM: &str = KEY_NORM_V2;
675pub const LOOKUP_MAX_NGRAM: usize = 4;
680
681#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
688pub struct LookupInfo {
689 pub entries: usize,
691 pub keys: usize,
693 pub key_norm: String,
695 pub langs: Vec<String>,
697 #[serde(default)]
699 pub fields: Vec<String>,
700 #[serde(default, skip_serializing_if = "Option::is_none")]
708 pub policy: Option<String>,
709}
710
711pub mod lookup_policy {
713 pub const ROUTER_AND_KEY: &str = "router_and_key";
715 pub const KEY_FIRST: &str = "key_first";
718 pub const ALL: &[&str] = &[ROUTER_AND_KEY, KEY_FIRST];
720 pub const DEFAULT: &str = ROUTER_AND_KEY;
722}
723
724pub fn unknown_lookup_policies(header: &CmfHeader) -> Vec<(String, String)> {
730 header
731 .skills
732 .iter()
733 .filter(|s| s.kind.as_deref() == Some(skill_kind::LOOKUP))
734 .filter_map(|s| {
735 let p = s.lookup.as_ref()?.policy.as_ref()?;
736 (!lookup_policy::ALL.contains(&p.as_str())).then(|| (s.id.clone(), p.clone()))
737 })
738 .collect()
739}
740
741pub fn check_lookup_policies(header: &CmfHeader) -> Result<(), CmfError> {
746 match unknown_lookup_policies(header).first() {
747 None => Ok(()),
748 Some((id, p)) => Err(perr(format!(
749 "skill '{id}': lookup.policy '{p}' (expected {})",
750 lookup_policy::ALL.join(" | ")
751 ))),
752 }
753}
754
755impl LookupInfo {
756 pub fn policy_label(&self) -> &str {
758 self.policy.as_deref().unwrap_or(lookup_policy::DEFAULT)
759 }
760
761 pub fn slots(&self) -> Option<usize> {
763 self.entries.checked_mul(self.langs.len())
764 }
765
766 pub fn slot(&self, entry: usize, lang: usize) -> Option<usize> {
768 (entry < self.entries && lang < self.langs.len()).then(|| entry * self.langs.len() + lang)
769 }
770}
771
772pub mod lookup_leaf {
774 pub const KEYS_HASH: &str = "lookup.keys.hash";
777 pub const KEYS_ENTRY: &str = "lookup.keys.entry";
779 pub const ENTRIES_OFF: &str = "lookup.entries.off";
782 pub const TEXT: &str = "lookup.text";
785 pub const ALL: &[&str] = &[KEYS_HASH, KEYS_ENTRY, ENTRIES_OFF, TEXT];
787}
788
789pub fn lookup_tensor_name(id: &str, leaf: &str) -> String {
791 format!("skill.{id}.{leaf}")
792}
793
794pub fn normalize_key(s: &str) -> String {
808 use unicode_normalization::UnicodeNormalization;
809 use unicode_normalization::char::{decompose_canonical, is_combining_mark};
810 fn is_format(c: char) -> bool {
812 matches!(
813 c,
814 '\u{00AD}' | '\u{200B}'..='\u{200F}' | '\u{2060}'..='\u{2064}' | '\u{FEFF}'
815 )
816 }
817 fn is_latin_precomposed(c: char) -> bool {
820 matches!(c, '\u{00C0}'..='\u{024F}' | '\u{1E00}'..='\u{1EFF}')
821 }
822 fn emit(out: &mut String, gap: &mut bool, c: char) {
823 for l in c.to_lowercase() {
824 if is_combining_mark(l) {
825 continue;
826 }
827 if l.is_alphanumeric() {
828 if *gap && !out.is_empty() {
829 out.push(' ');
830 }
831 *gap = false;
832 out.push(l);
833 } else {
834 *gap = true;
835 }
836 }
837 }
838 let mut out = String::with_capacity(s.len());
839 let mut gap = false;
840 for c in s.nfc() {
841 if is_combining_mark(c) || is_format(c) {
842 continue;
843 }
844 if is_latin_precomposed(c) {
845 decompose_canonical(c, |d| {
846 if !is_combining_mark(d) {
847 emit(&mut out, &mut gap, d);
848 }
849 });
850 } else {
851 emit(&mut out, &mut gap, c);
852 }
853 }
854 out
855}
856
857pub fn normalized_key_hash(norm: &str) -> u64 {
860 hash64(norm.as_bytes())
861}
862
863pub fn key_hash(key: &str) -> u64 {
865 normalized_key_hash(&normalize_key(key))
866}
867
868pub fn lookup_state_effect() -> StateEffect {
872 StateEffect {
873 first_affected_layer: 0,
874 switch: state_switch::TRANSPARENT.into(),
875 state_bytes_added: 0,
876 }
877}
878
879pub fn read_u64_le(bytes: &[u8]) -> Vec<u64> {
881 bytes
882 .chunks_exact(8)
883 .map(|c| u64::from_le_bytes(c.try_into().unwrap()))
884 .collect()
885}
886
887pub fn read_u32_le(bytes: &[u8]) -> Vec<u32> {
889 bytes
890 .chunks_exact(4)
891 .map(|c| u32::from_le_bytes(c.try_into().unwrap()))
892 .collect()
893}
894
895pub fn lookup_tensors(
904 id: &str,
905 info: &LookupInfo,
906 keys: &[(u64, u32)],
907 slots: &[&str],
908) -> Result<Vec<TensorSpec>, CmfError> {
909 let n_slots = info
910 .slots()
911 .ok_or_else(|| perr(format!("lookup '{id}': entries × langs overflows")))?;
912 if info.entries == 0 || info.langs.is_empty() {
913 return Err(perr(format!(
914 "lookup '{id}': entries {} and langs {:?} must both be non-empty",
915 info.entries, info.langs
916 )));
917 }
918 if keys.is_empty() || keys.len() != info.keys {
919 return Err(perr(format!(
920 "lookup '{id}': {} keys given, lookup.keys says {} (≥ 1)",
921 keys.len(),
922 info.keys
923 )));
924 }
925 if slots.len() != n_slots {
926 return Err(perr(format!(
927 "lookup '{id}': {} slots given, entries {} × langs {} = {n_slots}",
928 slots.len(),
929 info.entries,
930 info.langs.len()
931 )));
932 }
933 let mut sorted: Vec<(u64, u32)> = keys.to_vec();
934 sorted.sort_unstable();
935 for w in sorted.windows(2) {
936 if w[0].0 == w[1].0 {
937 return Err(perr(format!(
938 "lookup '{id}': duplicate key hash {} (entries {} and {})",
939 hex64(w[0].0),
940 w[0].1,
941 w[1].1
942 )));
943 }
944 }
945 for &(h, e) in &sorted {
946 if e as usize >= info.entries {
947 return Err(perr(format!(
948 "lookup '{id}': key {} points at entry {e} of {}",
949 hex64(h),
950 info.entries
951 )));
952 }
953 }
954 let mut text = Vec::new();
955 let mut off = Vec::with_capacity(n_slots + 1);
956 off.push(0u64);
957 for (s, slot) in slots.iter().enumerate() {
958 let v: serde_json::Value = serde_json::from_str(slot)
959 .map_err(|e| perr(format!("lookup '{id}': slot {s} is not JSON: {e}")))?;
960 if !v.is_object() {
961 return Err(perr(format!(
962 "lookup '{id}': slot {s} is not a JSON object"
963 )));
964 }
965 text.extend_from_slice(slot.as_bytes());
966 off.push(text.len() as u64);
967 }
968 let u64s = |v: &[u64]| v.iter().flat_map(|x| x.to_le_bytes()).collect::<Vec<u8>>();
969 let hashes: Vec<u64> = sorted.iter().map(|k| k.0).collect();
970 let entries: Vec<u8> = sorted.iter().flat_map(|k| k.1.to_le_bytes()).collect();
971 Ok(vec![
972 TensorSpec {
973 name: lookup_tensor_name(id, lookup_leaf::KEYS_HASH),
974 dtype: TensorDtype::U64,
975 shape: vec![hashes.len()],
976 data: u64s(&hashes),
977 },
978 TensorSpec {
979 name: lookup_tensor_name(id, lookup_leaf::KEYS_ENTRY),
980 dtype: TensorDtype::U32,
981 shape: vec![sorted.len()],
982 data: entries,
983 },
984 TensorSpec {
985 name: lookup_tensor_name(id, lookup_leaf::ENTRIES_OFF),
986 dtype: TensorDtype::U64,
987 shape: vec![off.len()],
988 data: u64s(&off),
989 },
990 TensorSpec {
991 name: lookup_tensor_name(id, lookup_leaf::TEXT),
992 dtype: TensorDtype::U8,
993 shape: vec![text.len()],
994 data: text,
995 },
996 ])
997}
998
999pub fn validate_lookup_values<'a>(
1013 header: &CmfHeader,
1014 tensors: &[TensorEntry],
1015 deep: bool,
1016 mut bytes_of: impl FnMut(&TensorEntry) -> Option<Cow<'a, [u8]>>,
1017) -> Result<(), CmfError> {
1018 for s in header
1019 .skills
1020 .iter()
1021 .filter(|s| s.kind.as_deref() == Some(skill_kind::LOOKUP))
1022 {
1023 let id = &s.id;
1024 let Some(info) = s.lookup.as_ref() else {
1025 continue; };
1027 let mut get = |leaf: &str| -> Result<Cow<'a, [u8]>, CmfError> {
1028 let name = lookup_tensor_name(id, leaf);
1029 let t = tensors
1030 .iter()
1031 .find(|t| t.name == name)
1032 .ok_or_else(|| perr(format!("skill '{id}': missing tensor '{name}'")))?;
1033 bytes_of(t).ok_or_else(|| {
1034 perr(format!(
1035 "skill '{id}': payload of '{name}' is not available for the value check"
1036 ))
1037 })
1038 };
1039 let hashes = read_u64_le(&get(lookup_leaf::KEYS_HASH)?);
1040 let entries = read_u32_le(&get(lookup_leaf::KEYS_ENTRY)?);
1041 let offs = read_u64_le(&get(lookup_leaf::ENTRIES_OFF)?);
1042 let text = get(lookup_leaf::TEXT)?;
1043 for (i, w) in hashes.windows(2).enumerate() {
1044 if w[1] == w[0] {
1045 return Err(perr(format!(
1046 "skill '{id}': duplicate key hash {} in '{}' (keys {i} and {})",
1047 hex64(w[0]),
1048 lookup_leaf::KEYS_HASH,
1049 i + 1
1050 )));
1051 }
1052 if w[1] < w[0] {
1053 return Err(perr(format!(
1054 "skill '{id}': '{}' is not sorted ascending at key {} ({} after {}) — the \
1055 runtime binary-searches it",
1056 lookup_leaf::KEYS_HASH,
1057 i + 1,
1058 hex64(w[1]),
1059 hex64(w[0])
1060 )));
1061 }
1062 }
1063 for (i, &e) in entries.iter().enumerate() {
1064 if e as usize >= info.entries {
1065 return Err(perr(format!(
1066 "skill '{id}': key {i} points at entry {e} of {} (lookup.entries)",
1067 info.entries
1068 )));
1069 }
1070 }
1071 for (i, w) in offs.windows(2).enumerate() {
1072 if w[1] < w[0] {
1073 return Err(perr(format!(
1074 "skill '{id}': '{}' is not monotone at slot {i} ({} then {})",
1075 lookup_leaf::ENTRIES_OFF,
1076 w[0],
1077 w[1]
1078 )));
1079 }
1080 }
1081 if let Some(&last) = offs.last() {
1082 if last > text.len() as u64 {
1083 return Err(perr(format!(
1084 "skill '{id}': '{}'[{}] = {last} is beyond the text blob ({} bytes)",
1085 lookup_leaf::ENTRIES_OFF,
1086 offs.len() - 1,
1087 text.len()
1088 )));
1089 }
1090 }
1091 let l = info.langs.len().max(1);
1092 let where_ = |slot: usize| {
1093 format!(
1094 "slot {slot} (entry {}, lang '{}')",
1095 slot / l,
1096 info.langs.get(slot % l).map(String::as_str).unwrap_or("?")
1097 )
1098 };
1099 let text_str = std::str::from_utf8(&text).map_err(|e| {
1102 let at = e.valid_up_to() as u64;
1103 let slot = offs.partition_point(|&o| o <= at).saturating_sub(1);
1104 perr(format!("skill '{id}': {} is not UTF-8: {e}", where_(slot)))
1105 })?;
1106 for (slot, w) in offs.windows(2).enumerate() {
1107 let (a, b) = (w[0] as usize, w[1] as usize);
1108 if !text_str.is_char_boundary(a) || !text_str.is_char_boundary(b) {
1109 return Err(perr(format!(
1110 "skill '{id}': {} does not start and end on a UTF-8 character boundary \
1111 ({a}..{b})",
1112 where_(slot)
1113 )));
1114 }
1115 let txt = &text_str[a..b];
1116 let shaped = txt.trim_start().as_bytes().first() == Some(&b'{')
1117 && txt.trim_end().as_bytes().last() == Some(&b'}');
1118 if !shaped {
1119 return Err(perr(format!(
1120 "skill '{id}': {} is not a JSON object",
1121 where_(slot)
1122 )));
1123 }
1124 if deep {
1125 let v: serde_json::Value = serde_json::from_str(txt).map_err(|e| {
1126 perr(format!(
1127 "skill '{id}': {} is not a JSON object: {e}",
1128 where_(slot)
1129 ))
1130 })?;
1131 if !v.is_object() {
1132 return Err(perr(format!(
1133 "skill '{id}': {} is not a JSON object",
1134 where_(slot)
1135 )));
1136 }
1137 }
1138 }
1139 }
1140 Ok(())
1141}
1142
1143impl SkillRecord {
1144 pub fn is_v2(&self) -> bool {
1146 self.kind.is_some()
1147 }
1148
1149 pub fn is_auto_routable(&self) -> bool {
1153 self.is_v2()
1154 && self.selection.is_some()
1155 && self.status.as_deref() == Some("active")
1156 && self
1157 .gate
1158 .as_ref()
1159 .and_then(|g| g.get("status"))
1160 .and_then(|s| s.as_str())
1161 == Some("measured")
1162 }
1163
1164 fn has_v2_fields(&self) -> bool {
1165 !self.overrides.is_empty()
1166 || self.bound.is_some()
1167 || self.state_effect.is_some()
1168 || self.status.is_some()
1169 || self.gate.is_some()
1170 || self.prompt_contract.is_some()
1171 || self.origin.is_some()
1172 || self.experts.is_some()
1173 || self.lookup.is_some()
1174 }
1175}
1176
1177#[derive(Debug, Clone, Serialize, Deserialize)]
1183pub struct RouterPolicy {
1184 pub version: u32,
1186 pub policy: String,
1188 pub granularity: String,
1190 pub phi: PhiSpec,
1192 pub base: SelectionDescriptor,
1195 pub margin: f32,
1197 pub skills_hash: String,
1201 #[serde(default, skip_serializing_if = "Option::is_none")]
1204 pub measured: Option<serde_json::Value>,
1205}
1206
1207#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1212pub struct PhiSpec {
1213 pub layer: usize,
1214 pub pool: String,
1216 pub norm: String,
1218 #[serde(default)]
1219 pub prefix_ids: Vec<u32>,
1220 #[serde(default)]
1221 pub suffix_ids: Vec<u32>,
1222}
1223
1224pub fn is_trunk_tensor(name: &str) -> bool {
1229 !(name.starts_with("skill.") || name.starts_with("route."))
1230}
1231
1232pub fn trunk_hash(header: &CmfHeader, tensors: &[TensorEntry], vocab: Option<&[u8]>) -> u64 {
1259 trunk_hash_exec(header, tensors, vocab, ExecHashes::default())
1260}
1261
1262#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
1266pub struct ExecHashes {
1267 pub masks: Option<u64>,
1268 pub index: Option<u64>,
1269}
1270
1271impl ExecHashes {
1272 pub fn of(masks: Option<&[u8]>, index: Option<&[u8]>) -> Self {
1274 let h = |b: Option<&[u8]>| b.filter(|b| !b.is_empty()).map(hash64);
1275 Self {
1276 masks: h(masks),
1277 index: h(index),
1278 }
1279 }
1280
1281 fn is_empty(&self) -> bool {
1282 self.masks.is_none() && self.index.is_none()
1283 }
1284}
1285
1286pub fn trunk_hash_exec(
1293 header: &CmfHeader,
1294 tensors: &[TensorEntry],
1295 vocab: Option<&[u8]>,
1296 exec: ExecHashes,
1297) -> u64 {
1298 let as_written = |bytes: Vec<u8>| -> serde_json::Value {
1299 serde_json::from_slice(&bytes).expect("serialized JSON parses")
1300 };
1301 let arch = as_written(serde_json::to_vec(&header.arch).expect("ModelArch serializes"));
1302 let tok = as_written(serde_json::to_vec(&header.tokenizer_config).expect("bundle serializes"));
1303 trunk_hash_json_exec(&arch, &tok, tensors, vocab, exec)
1304}
1305
1306pub fn trunk_hash_json(
1309 arch: &serde_json::Value,
1310 tokenizer_config: &serde_json::Value,
1311 tensors: &[TensorEntry],
1312 vocab: Option<&[u8]>,
1313) -> u64 {
1314 trunk_hash_json_exec(arch, tokenizer_config, tensors, vocab, ExecHashes::default())
1315}
1316
1317pub fn trunk_hash_json_exec(
1320 arch: &serde_json::Value,
1321 tokenizer_config: &serde_json::Value,
1322 tensors: &[TensorEntry],
1323 vocab: Option<&[u8]>,
1324 exec: ExecHashes,
1325) -> u64 {
1326 let mut trunk: Vec<&TensorEntry> = tensors
1327 .iter()
1328 .filter(|t| is_trunk_tensor(&t.name))
1329 .collect();
1330 trunk.sort_by(|a, b| a.name.as_bytes().cmp(b.name.as_bytes()));
1331 let mut buf = Vec::with_capacity(trunk.len() * 96 + 4096);
1332 buf.extend_from_slice(b"cmf-trunk-v1\0");
1333 for t in trunk {
1334 buf.extend_from_slice(t.name.as_bytes());
1335 buf.push(0);
1336 buf.push(t.dtype.id());
1337 buf.push(0);
1338 buf.push(t.shape.len() as u8);
1339 for &d in &t.shape {
1340 buf.extend_from_slice(&(d as u64).to_le_bytes());
1341 }
1342 buf.push(0);
1343 buf.extend_from_slice(&t.hash.to_le_bytes());
1344 }
1345 buf.push(0x1e);
1346 buf.extend(canonical_json(arch));
1347 buf.push(0x1e);
1348 buf.extend_from_slice(&vocab.map(hash64).unwrap_or(0).to_le_bytes());
1349 buf.push(0x1e);
1350 buf.extend(canonical_json(tokenizer_config));
1351 if !exec.is_empty() {
1352 buf.push(0x1e);
1353 buf.extend_from_slice(b"exec\0");
1354 for h in [exec.masks, exec.index] {
1355 match h {
1356 Some(v) => {
1357 buf.push(1);
1358 buf.extend_from_slice(&v.to_le_bytes());
1359 }
1360 None => buf.push(0),
1361 }
1362 }
1363 }
1364 hash64(&buf)
1365}
1366
1367pub fn canonical_json(v: &serde_json::Value) -> Vec<u8> {
1372 fn walk(v: &serde_json::Value, out: &mut Vec<u8>) {
1373 match v {
1374 serde_json::Value::Object(m) => {
1375 let mut keys: Vec<&String> = m.keys().collect();
1376 keys.sort_unstable_by(|a, b| a.as_bytes().cmp(b.as_bytes()));
1377 out.push(b'{');
1378 for (i, k) in keys.into_iter().enumerate() {
1379 if i > 0 {
1380 out.push(b',');
1381 }
1382 out.extend(serde_json::to_vec(k).expect("string serializes"));
1383 out.push(b':');
1384 walk(&m[k], out);
1385 }
1386 out.push(b'}');
1387 }
1388 serde_json::Value::Array(a) => {
1389 out.push(b'[');
1390 for (i, x) in a.iter().enumerate() {
1391 if i > 0 {
1392 out.push(b',');
1393 }
1394 walk(x, out);
1395 }
1396 out.push(b']');
1397 }
1398 other => out.extend(serde_json::to_vec(other).expect("scalar serializes")),
1399 }
1400 }
1401 let mut out = Vec::new();
1402 walk(v, &mut out);
1403 out
1404}
1405
1406pub fn hex64(h: u64) -> String {
1408 format!("{h:016x}")
1409}
1410
1411pub fn parse_hex64(s: &str) -> Option<u64> {
1413 if s.is_empty() || s.len() > 16 {
1414 return None;
1415 }
1416 u64::from_str_radix(s, 16).ok()
1417}
1418
1419pub(crate) fn seal_genome(
1425 header: &mut CmfHeader,
1426 tensors: &[TensorEntry],
1427 vocab: Option<&[u8]>,
1428 exec: ExecHashes,
1429) -> Result<(), CmfError> {
1430 let computed = trunk_hash_exec(header, tensors, vocab, exec);
1431 let e0 = header
1434 .arch
1435 .moe
1436 .as_ref()
1437 .filter(|m| m.router_resonance)
1438 .map(|m| m.num_experts);
1439 let Some(g) = header.genome.as_mut() else {
1440 return Ok(());
1441 };
1442 if g.moe_experts.is_none() {
1443 g.moe_experts = e0;
1444 }
1445 if g.trunk_hash.is_empty() {
1446 g.trunk_hash = hex64(computed);
1447 } else {
1448 let stored = parse_hex64(&g.trunk_hash).ok_or_else(|| {
1449 CmfError::Parse(format!(
1450 "genome.trunk_hash '{}' is not a hex hash64",
1451 g.trunk_hash
1452 ))
1453 })?;
1454 if stored != computed {
1455 return Err(CmfError::Parse(format!(
1456 "refusing to write genome '{}': genome.trunk_hash {} != trunk content {} — \
1457 the trunk changed without a new genome (a new id/generation with a lineage \
1458 event, or a requant that rewrites trunk_hash/encoding)",
1459 g.id,
1460 g.trunk_hash,
1461 hex64(computed)
1462 )));
1463 }
1464 }
1465 if g.master_trunk_hash.is_empty() && g.encoding == "f32" {
1466 g.master_trunk_hash = g.trunk_hash.clone();
1467 }
1468 Ok(())
1469}
1470
1471pub const KNOWLEDGE_BITS: u32 = features::GENOME | features::SKILLS_V2 | features::ROUTER_V2;
1475
1476pub fn knowledge_bits(header: &CmfHeader) -> u32 {
1478 let mut bits = 0;
1479 if header.genome.is_some() {
1480 bits |= features::GENOME;
1481 }
1482 if header.skills.iter().any(|s| s.kind.is_some()) {
1483 bits |= features::SKILLS_V2;
1484 }
1485 if header.router.is_some() {
1486 bits |= features::ROUTER_V2;
1487 }
1488 bits
1489}
1490
1491fn perr(msg: String) -> CmfError {
1492 CmfError::Parse(msg)
1493}
1494
1495fn layer_of(name: &str) -> Option<usize> {
1497 let rest = name.strip_prefix("model.layers.")?;
1498 let (li, _) = rest.split_once('.')?;
1499 li.parse().ok()
1500}
1501
1502pub fn validate_knowledge(
1514 header: &CmfHeader,
1515 tensors: &[TensorEntry],
1516 vocab: Option<&[u8]>,
1517 required_features: u32,
1518 data_len: Option<u64>,
1519 raw_trunk_hash: Option<u64>,
1520 exec: ExecHashes,
1521) -> Result<(), CmfError> {
1522 let content = knowledge_bits(header);
1524 for (bit, name, what) in [
1525 (features::GENOME, "GENOME", "genome record"),
1526 (features::SKILLS_V2, "SKILLS_V2", "v2 skill record (kind)"),
1527 (features::ROUTER_V2, "ROUTER_V2", "router policy"),
1528 ] {
1529 let declared = content & bit != 0;
1530 let set = required_features & bit != 0;
1531 if declared != set {
1532 return Err(perr(format!(
1533 "{what} ({}) and {name} feature bit ({}) disagree",
1534 if declared { "present" } else { "absent" },
1535 if set { "set" } else { "clear" }
1536 )));
1537 }
1538 }
1539 for s in &header.skills {
1541 if s.kind.is_none() && s.has_v2_fields() {
1542 return Err(perr(format!(
1543 "skill '{}': v2 fields (overrides/bound/state_effect/status/gate/\
1544 prompt_contract/origin/experts/lookup) on a record without `kind`",
1545 s.id
1546 )));
1547 }
1548 }
1549 let new_file = content != 0 || !header.segments.is_empty() || !header.lineage.is_empty();
1550 if !new_file {
1551 return Ok(());
1552 }
1553
1554 if let Some(g) = &header.genome {
1556 if header.shard.is_some() {
1557 return Err(perr(
1558 "a genome file cannot be sharded (the trunk hash covers one directory)".into(),
1559 ));
1560 }
1561 if g.id.is_empty() {
1562 return Err(perr("genome.id is empty".into()));
1563 }
1564 if !GENOME_STATUSES.contains(&g.status.as_str()) {
1565 return Err(perr(format!(
1566 "genome.status '{}' is not one of {GENOME_STATUSES:?}",
1567 g.status
1568 )));
1569 }
1570 if g.encoding.is_empty() {
1571 return Err(perr("genome.encoding is empty".into()));
1572 }
1573 if vocab.is_none_or(|v| v.is_empty()) {
1577 return Err(perr(format!(
1578 "genome '{}': a genome file must embed its tokenizer (VOCAB section) — the \
1579 trunk hash binds it; a sidecar tokenizer.json is not part of the genome",
1580 g.id
1581 )));
1582 }
1583 if header
1587 .provenance
1588 .as_ref()
1589 .and_then(|p| p.get("o1_attn"))
1590 .is_some()
1591 {
1592 return Err(perr(format!(
1593 "genome '{}': provenance.o1_attn is refused on a genome file — the trunk's \
1594 attention operator is part of the genome (arch), not a provenance hint",
1595 g.id
1596 )));
1597 }
1598 let stored = parse_hex64(&g.trunk_hash).ok_or_else(|| {
1599 perr(format!(
1600 "genome.trunk_hash '{}' is not a hex hash64",
1601 g.trunk_hash
1602 ))
1603 })?;
1604 let master = parse_hex64(&g.master_trunk_hash).ok_or_else(|| {
1605 perr(format!(
1606 "genome.master_trunk_hash '{}' is not a hex hash64",
1607 g.master_trunk_hash
1608 ))
1609 })?;
1610 if g.encoding == "f32" && master != stored {
1611 return Err(perr(format!(
1612 "genome.encoding is f32 but master_trunk_hash {} != trunk_hash {}",
1613 g.master_trunk_hash, g.trunk_hash
1614 )));
1615 }
1616 if let Some(n) = g.moe_experts {
1619 match &header.arch.moe {
1620 Some(m) if m.num_experts == n => {}
1621 Some(m) => {
1622 return Err(perr(format!(
1623 "genome '{}': moe_experts {n} != arch.moe.num_experts {}",
1624 g.id, m.num_experts
1625 )));
1626 }
1627 None => {
1628 return Err(perr(format!(
1629 "genome '{}': moe_experts {n} on an arch without a MoE block",
1630 g.id
1631 )));
1632 }
1633 }
1634 }
1635 let computed =
1636 raw_trunk_hash.unwrap_or_else(|| trunk_hash_exec(header, tensors, vocab, exec));
1637 if computed != stored {
1638 return Err(perr(format!(
1639 "trunk_hash mismatch: the genome's bytes changed without a new genome \
1640 (lineage) — genome '{}' gen {} declares {}, the directory hashes to {}",
1641 g.id,
1642 g.generation,
1643 g.trunk_hash,
1644 hex64(computed)
1645 )));
1646 }
1647 }
1648
1649 for w in header.lineage.windows(2) {
1651 if w[1].seq <= w[0].seq {
1652 return Err(perr(format!(
1653 "lineage seq must strictly increase ({} then {})",
1654 w[0].seq, w[1].seq
1655 )));
1656 }
1657 }
1658 for e in &header.lineage {
1659 if e.event.is_empty() {
1660 return Err(perr(format!("lineage event #{} has an empty name", e.seq)));
1661 }
1662 }
1663
1664 for s in &header.segments {
1666 if !SEGMENT_KINDS.contains(&s.kind.as_str()) {
1667 return Err(perr(format!(
1668 "segment kind '{}' is not one of {SEGMENT_KINDS:?}",
1669 s.kind
1670 )));
1671 }
1672 let over = data_len.is_some_and(|dl| s.data_end > dl);
1673 if s.data_start > s.data_end || over {
1674 return Err(perr(format!(
1675 "segment {}:{} [{}, {}) is outside the data section",
1676 s.kind, s.id, s.data_start, s.data_end
1677 )));
1678 }
1679 }
1680
1681 let by_name: HashMap<&str, &TensorEntry> =
1683 tensors.iter().map(|t| (t.name.as_str(), t)).collect();
1684 let mut ids = BTreeSet::new();
1685 for (at, s) in header.skills.iter().enumerate() {
1686 if !ids.insert(s.id.as_str()) {
1687 return Err(perr(format!("duplicate skill id '{}'", s.id)));
1688 }
1689 if s.id == BACKBONE_CLASS_ID {
1690 return Err(perr(format!(
1691 "skill id '{BACKBONE_CLASS_ID}' is reserved for the backbone class"
1692 )));
1693 }
1694 if s.kind.is_some() {
1695 validate_skill_v2(header, at, s, tensors, &by_name)?;
1696 }
1697 }
1698 for t in tensors {
1700 if let Some(rest) = t.name.strip_prefix("skill.") {
1701 let owned = header.skills.iter().any(|s| {
1702 rest.strip_prefix(s.id.as_str())
1703 .is_some_and(|r| r.starts_with('.'))
1704 });
1705 if !owned {
1706 return Err(perr(format!(
1707 "tensor '{}' belongs to no skill record",
1708 t.name
1709 )));
1710 }
1711 }
1712 }
1713
1714 if let Some(r) = &header.router {
1716 validate_router(header, r)?;
1717 }
1718 Ok(())
1719}
1720
1721fn validate_skill_v2(
1722 header: &CmfHeader,
1723 at: usize,
1724 s: &SkillRecord,
1725 tensors: &[TensorEntry],
1726 by_name: &HashMap<&str, &TensorEntry>,
1727) -> Result<(), CmfError> {
1728 let id = &s.id;
1729 if id.is_empty() || id.contains('.') {
1730 return Err(perr(format!(
1731 "skill '{id}': a v2 skill id must be non-empty and contain no '.' \
1732 (it prefixes its tensors: skill.{{id}}.X)"
1733 )));
1734 }
1735 if RESERVED_SKILL_IDS.contains(&id.as_str()) {
1736 return Err(perr(format!(
1737 "skill '{id}': the id is reserved ({RESERVED_SKILL_IDS:?} name the backbone / the \
1738 automatic decision in --skill, --route and route reports)"
1739 )));
1740 }
1741 let kind = s.kind.as_deref().unwrap_or_default();
1742 if skill_kind::RESERVED.contains(&kind) {
1743 return Err(perr(format!(
1744 "skill '{id}': kind '{kind}' is reserved and not implemented by this reader"
1745 )));
1746 }
1747 if !skill_kind::IMPLEMENTED.contains(&kind) {
1748 return Err(perr(format!("skill '{id}': unknown kind '{kind}'")));
1749 }
1750 if let Some(st) = &s.status {
1751 if !SKILL_STATUSES.contains(&st.as_str()) {
1752 return Err(perr(format!(
1753 "skill '{id}': status '{st}' is not one of {SKILL_STATUSES:?}"
1754 )));
1755 }
1756 }
1757 let bound = s
1759 .bound
1760 .as_ref()
1761 .ok_or_else(|| perr(format!("skill '{id}': v2 record has no `bound`")))?;
1762 let g = header.genome.as_ref().ok_or_else(|| {
1763 perr(format!(
1764 "skill '{id}': v2 record in a file without a genome"
1765 ))
1766 })?;
1767 if bound.genome_id != g.id {
1768 return Err(perr(format!(
1769 "skill '{id}': bound.genome_id '{}' != genome.id '{}'",
1770 bound.genome_id, g.id
1771 )));
1772 }
1773 if bound.generation != g.generation {
1774 return Err(perr(format!(
1775 "skill '{id}': bound.generation {} != genome.generation {}",
1776 bound.generation, g.generation
1777 )));
1778 }
1779 let bm = parse_hex64(&bound.master_trunk_hash);
1780 if bm.is_none() || bm != parse_hex64(&g.master_trunk_hash) {
1781 return Err(perr(format!(
1782 "skill '{id}': bound.master_trunk_hash {} != genome.master_trunk_hash {}",
1783 bound.master_trunk_hash, g.master_trunk_hash
1784 )));
1785 }
1786 match kind {
1787 skill_kind::EXPERT_APPEND => validate_expert_append(header, at, s, tensors, by_name),
1788 skill_kind::LOOKUP => validate_lookup(s, tensors, by_name),
1789 _ => validate_ffn_replace(header, s, tensors, by_name),
1790 }
1791}
1792
1793fn validate_lookup(
1800 s: &SkillRecord,
1801 tensors: &[TensorEntry],
1802 by_name: &HashMap<&str, &TensorEntry>,
1803) -> Result<(), CmfError> {
1804 let id = &s.id;
1805 let info = s
1806 .lookup
1807 .as_ref()
1808 .ok_or_else(|| perr(format!("skill '{id}': lookup record has no `lookup`")))?;
1809 if s.experts.is_some() {
1810 return Err(perr(format!(
1811 "skill '{id}': `experts` belongs to an expert_append record, not to lookup"
1812 )));
1813 }
1814 if !s.overrides.is_empty() {
1815 return Err(perr(format!(
1816 "skill '{id}': a lookup record replaces nothing — `overrides` must be empty"
1817 )));
1818 }
1819 if !s.layers.is_empty() {
1820 return Err(perr(format!(
1821 "skill '{id}': a lookup record touches no layer — `layers` must be empty (is {:?})",
1822 s.layers
1823 )));
1824 }
1825 if info.key_norm == KEY_NORM_V1 {
1826 return Err(perr(format!(
1827 "skill '{id}': lookup.key_norm '{KEY_NORM_V1}' is the pre-release rule — rebuild \
1828 the table with `cortiq lookup-build` (this reader knows {KEY_NORM})"
1829 )));
1830 }
1831 if info.key_norm != KEY_NORM {
1832 return Err(perr(format!(
1833 "skill '{id}': lookup.key_norm '{}' (this reader knows {KEY_NORM})",
1834 info.key_norm
1835 )));
1836 }
1837 if info.entries == 0 {
1844 return Err(perr(format!("skill '{id}': lookup.entries must be ≥ 1")));
1845 }
1846 if info.keys == 0 {
1847 return Err(perr(format!("skill '{id}': lookup.keys must be ≥ 1")));
1848 }
1849 if info.langs.is_empty() {
1850 return Err(perr(format!("skill '{id}': lookup.langs is empty")));
1851 }
1852 for (what, list) in [("langs", &info.langs), ("fields", &info.fields)] {
1853 let mut seen = BTreeSet::new();
1854 for x in list {
1855 if x.is_empty() {
1856 return Err(perr(format!(
1857 "skill '{id}': lookup.{what} has an empty name"
1858 )));
1859 }
1860 if !seen.insert(x.as_str()) {
1861 return Err(perr(format!(
1862 "skill '{id}': duplicate '{x}' in lookup.{what}"
1863 )));
1864 }
1865 }
1866 }
1867 let n_off = info
1868 .slots()
1869 .and_then(|n| n.checked_add(1))
1870 .ok_or_else(|| perr(format!("skill '{id}': lookup.entries × langs overflows")))?;
1871 let prefix = format!("skill.{id}.");
1872 for t in tensors.iter().filter(|t| t.name.starts_with(&prefix)) {
1873 if !lookup_leaf::ALL.contains(&&t.name[prefix.len()..]) {
1874 return Err(perr(format!(
1875 "skill '{id}': tensor '{}' is not part of a lookup record (expected exactly \
1876 {prefix}{{{}}})",
1877 t.name,
1878 lookup_leaf::ALL.join(", ")
1879 )));
1880 }
1881 }
1882 let want = [
1883 (lookup_leaf::KEYS_HASH, TensorDtype::U64, Some((info.keys, "lookup.keys"))),
1884 (lookup_leaf::KEYS_ENTRY, TensorDtype::U32, Some((info.keys, "lookup.keys"))),
1885 (
1886 lookup_leaf::ENTRIES_OFF,
1887 TensorDtype::U64,
1888 Some((n_off, "lookup.entries × langs + 1")),
1889 ),
1890 (lookup_leaf::TEXT, TensorDtype::U8, None),
1891 ];
1892 for (leaf, dtype, len) in want {
1893 let name = lookup_tensor_name(id, leaf);
1894 let Some(t) = by_name.get(name.as_str()) else {
1895 return Err(perr(format!("skill '{id}': missing tensor '{name}'")));
1896 };
1897 if t.dtype != dtype {
1898 return Err(perr(format!(
1899 "skill '{id}': '{name}' must be {} (is {})",
1900 dtype.name(),
1901 t.dtype.name()
1902 )));
1903 }
1904 if t.shape.len() != 1 {
1905 return Err(perr(format!(
1906 "skill '{id}': '{name}' must be 1-D (shape {:?})",
1907 t.shape
1908 )));
1909 }
1910 if let Some((n, why)) = len {
1911 if t.shape[0] != n {
1912 return Err(perr(format!(
1913 "skill '{id}': '{name}' shape {:?} != [{n}] ({why})",
1914 t.shape
1915 )));
1916 }
1917 }
1918 }
1919 let se = s
1920 .state_effect
1921 .as_ref()
1922 .ok_or_else(|| perr(format!("skill '{id}': v2 record has no `state_effect`")))?;
1923 let want = lookup_state_effect();
1924 if *se != want {
1925 return Err(perr(format!(
1926 "skill '{id}': state_effect {{first_affected_layer {}, switch '{}', \
1927 state_bytes_added {}}} — a lookup record never touches the network's state: \
1928 first_affected_layer 0, switch '{}', state_bytes_added 0",
1929 se.first_affected_layer, se.switch, se.state_bytes_added, want.switch
1930 )));
1931 }
1932 Ok(())
1933}
1934
1935fn validate_expert_append(
1941 header: &CmfHeader,
1942 at: usize,
1943 s: &SkillRecord,
1944 tensors: &[TensorEntry],
1945 by_name: &HashMap<&str, &TensorEntry>,
1946) -> Result<(), CmfError> {
1947 let id = &s.id;
1948 if s.lookup.is_some() {
1949 return Err(perr(format!(
1950 "skill '{id}': `lookup` belongs to a lookup record, not to expert_append"
1951 )));
1952 }
1953 if !s.overrides.is_empty() {
1954 return Err(perr(format!(
1955 "skill '{id}': an expert_append record replaces nothing — `overrides` must be empty"
1956 )));
1957 }
1958 if s.selection.is_some() {
1959 return Err(perr(format!(
1960 "skill '{id}': an expert_append record carries no `selection` — its experts are \
1961 chosen per token by the layer's resonance router, never per request"
1962 )));
1963 }
1964 let retired = s.status.as_deref() == Some("retired");
1965 let plan = expert_append_layout_in(header, by_name, at, s, retired)?;
1966 let expected: HashMap<&str, &ExpertTensorSpec> =
1967 plan.iter().map(|p| (p.name.as_str(), p)).collect();
1968 let prefix = format!("skill.{id}.");
1969 for t in tensors.iter().filter(|t| t.name.starts_with(&prefix)) {
1970 let Some(p) = expected.get(t.name.as_str()) else {
1971 return Err(perr(format!(
1972 "skill '{id}': tensor '{}' is not part of the expert_append layout (layers {:?}, \
1973 count {})",
1974 t.name,
1975 s.layers,
1976 s.experts.as_ref().map(|e| e.count).unwrap_or(0)
1977 )));
1978 };
1979 if t.shape != p.shape {
1980 return Err(perr(format!(
1981 "skill '{id}': '{}' shape {:?} != {:?} (the trunk's expert 0 of layer {})",
1982 t.name, t.shape, p.shape, p.layer
1983 )));
1984 }
1985 if matches!(p.leaf, expert_leaf::BIAS | expert_leaf::SHELL) && t.dtype != TensorDtype::F32
1986 {
1987 return Err(perr(format!(
1988 "skill '{id}': '{}' must be f32 (is {:?})",
1989 t.name, t.dtype
1990 )));
1991 }
1992 }
1993 for p in &plan {
1994 if !by_name.contains_key(p.name.as_str()) {
1995 return Err(perr(format!(
1996 "skill '{id}': missing tensor '{}' (layer {}, expert {})",
1997 p.name, p.layer, p.expert
1998 )));
1999 }
2000 }
2001 let se = s
2002 .state_effect
2003 .as_ref()
2004 .ok_or_else(|| perr(format!("skill '{id}': v2 record has no `state_effect`")))?;
2005 let computed = expert_append_state_effect(&s.layers);
2006 if se.first_affected_layer != computed.first_affected_layer {
2007 return Err(perr(format!(
2008 "skill '{id}': state_effect.first_affected_layer {} != min(layers) {}",
2009 se.first_affected_layer, computed.first_affected_layer
2010 )));
2011 }
2012 if se.switch != computed.switch {
2013 return Err(perr(format!(
2014 "skill '{id}': state_effect.switch '{}' — grown experts are part of the organism, \
2015 the record's switch is '{}'",
2016 se.switch, computed.switch
2017 )));
2018 }
2019 if se.state_bytes_added != 0 {
2020 return Err(perr(format!(
2021 "skill '{id}': state_effect.state_bytes_added {} — an expert_append record adds \
2022 no per-sequence state",
2023 se.state_bytes_added
2024 )));
2025 }
2026 Ok(())
2027}
2028
2029fn validate_ffn_replace(
2031 header: &CmfHeader,
2032 s: &SkillRecord,
2033 tensors: &[TensorEntry],
2034 by_name: &HashMap<&str, &TensorEntry>,
2035) -> Result<(), CmfError> {
2036 let id = &s.id;
2037 let g = header.genome.as_ref().expect("checked by the caller");
2038 if s.experts.is_some() {
2039 return Err(perr(format!(
2040 "skill '{id}': `experts` belongs to an expert_append record, not to ffn_replace"
2041 )));
2042 }
2043 if s.lookup.is_some() {
2044 return Err(perr(format!(
2045 "skill '{id}': `lookup` belongs to a lookup record, not to ffn_replace"
2046 )));
2047 }
2048 let prefix = format!("skill.{id}.");
2049 let mut seen = BTreeSet::new();
2050 for o in &s.overrides {
2051 if !seen.insert(o.name.as_str()) {
2052 return Err(perr(format!(
2053 "skill '{id}': duplicate override '{}'",
2054 o.name
2055 )));
2056 }
2057 }
2058 let mut layers_named = BTreeSet::new();
2059 let mut n_tensors = 0usize;
2060 for t in tensors.iter().filter(|t| t.name.starts_with(&prefix)) {
2061 n_tensors += 1;
2062 let x = &t.name[prefix.len()..];
2063 let Some(o) = s.overrides.iter().find(|o| o.name == x) else {
2064 return Err(perr(format!(
2065 "skill '{id}': tensor '{}' has no override entry",
2066 t.name
2067 )));
2068 };
2069 let li =
2070 layer_of(x).filter(|&l| x[format!("model.layers.{l}.").len()..].starts_with("mlp."));
2071 let Some(li) = li else {
2072 return Err(perr(format!(
2073 "skill '{id}': ffn_replace tensor '{}' is not an FFN tensor (model.layers.N.mlp.*)",
2074 t.name
2075 )));
2076 };
2077 if li >= header.arch.num_layers {
2078 return Err(perr(format!(
2079 "skill '{id}': '{}' names layer {li} of {}",
2080 t.name, header.arch.num_layers
2081 )));
2082 }
2083 layers_named.insert(li);
2084 let Some(base) = by_name.get(x).copied().filter(|b| is_trunk_tensor(&b.name)) else {
2085 return Err(perr(format!(
2086 "skill '{id}': override '{x}' replaces no trunk tensor"
2087 )));
2088 };
2089 if base.shape != t.shape {
2090 return Err(perr(format!(
2091 "skill '{id}': '{}' shape {:?} != trunk '{x}' shape {:?}",
2092 t.name, t.shape, base.shape
2093 )));
2094 }
2095 let bh = parse_hex64(&o.base_hash).ok_or_else(|| {
2096 perr(format!(
2097 "skill '{id}': override '{x}' base_hash '{}' is not a hex hash64",
2098 o.base_hash
2099 ))
2100 })?;
2101 if g.encoding == "f32" && bh != base.hash {
2102 return Err(perr(format!(
2103 "skill '{id}': override '{x}' base_hash {} != trunk entry hash {} \
2104 (the skill was trained against other trunk bytes)",
2105 o.base_hash,
2106 hex64(base.hash)
2107 )));
2108 }
2109 }
2110 for o in &s.overrides {
2111 if by_name
2112 .get(format!("{prefix}{}", o.name).as_str())
2113 .is_none()
2114 {
2115 return Err(perr(format!(
2116 "skill '{id}': override '{}' has no tensor '{prefix}{}'",
2117 o.name, o.name
2118 )));
2119 }
2120 }
2121 if n_tensors == 0 {
2122 return Err(perr(format!(
2123 "skill '{id}': ffn_replace record carries no tensors"
2124 )));
2125 }
2126 let declared: BTreeSet<usize> = s.layers.iter().copied().collect();
2127 if declared != layers_named || declared.len() != s.layers.len() {
2128 return Err(perr(format!(
2129 "skill '{id}': layers {:?} != layers named by its tensors {:?}",
2130 s.layers, layers_named
2131 )));
2132 }
2133 let se = s
2134 .state_effect
2135 .as_ref()
2136 .ok_or_else(|| perr(format!("skill '{id}': v2 record has no `state_effect`")))?;
2137 let first = *layers_named.iter().next().unwrap();
2138 if se.first_affected_layer != first {
2139 return Err(perr(format!(
2140 "skill '{id}': state_effect.first_affected_layer {} != min(layers) {first}",
2141 se.first_affected_layer
2142 )));
2143 }
2144 let rank = |sw: &str| state_switch::ALL.iter().position(|v| *v == sw);
2145 let Some(claimed) = rank(&se.switch) else {
2146 return Err(perr(format!(
2147 "skill '{id}': state_effect.switch '{}' is not one of {:?}",
2148 se.switch,
2149 state_switch::ALL
2150 )));
2151 };
2152 let computed = ffn_replace_state_effect(&header.arch, &s.layers);
2153 if claimed < rank(&computed.switch).unwrap() {
2154 return Err(perr(format!(
2155 "skill '{id}': state_effect.switch '{}' is more permissive than the layer schedule \
2156 allows ('{}')",
2157 se.switch, computed.switch
2158 )));
2159 }
2160 Ok(())
2161}
2162
2163fn validate_router(header: &CmfHeader, r: &RouterPolicy) -> Result<(), CmfError> {
2164 if r.version != 2 {
2165 return Err(perr(format!(
2166 "router.version {} (this reader knows 2)",
2167 r.version
2168 )));
2169 }
2170 if r.policy != "backbone_gated" {
2171 return Err(perr(format!(
2172 "router.policy '{}' (known: backbone_gated)",
2173 r.policy
2174 )));
2175 }
2176 if r.granularity != "request" {
2177 return Err(perr(format!(
2178 "router.granularity '{}' (known: request)",
2179 r.granularity
2180 )));
2181 }
2182 if r.phi.pool != "span_mean" || r.phi.norm != "unit" {
2183 return Err(perr(format!(
2184 "router.phi pool/norm '{}'/'{}' (known: span_mean/unit)",
2185 r.phi.pool, r.phi.norm
2186 )));
2187 }
2188 if r.phi.layer >= header.arch.num_layers {
2189 return Err(perr(format!(
2190 "router.phi.layer {} of {} layers",
2191 r.phi.layer, header.arch.num_layers
2192 )));
2193 }
2194 if !(r.margin.is_finite() && r.margin >= 0.0) {
2195 return Err(perr(format!(
2196 "router.margin {} must be finite and ≥ 0",
2197 r.margin
2198 )));
2199 }
2200 if parse_hex64(&r.skills_hash).is_none() {
2201 return Err(perr(format!(
2202 "router.skills_hash '{}' is not a hex hash64",
2203 r.skills_hash
2204 )));
2205 }
2206 let check_desc = |who: &str, d: &SelectionDescriptor| -> Result<(), CmfError> {
2207 if d.metric != METRIC_MSE_UNIT {
2208 return Err(perr(format!(
2209 "{who}: selection.metric '{}' (router v2 requires {METRIC_MSE_UNIT})",
2210 d.metric
2211 )));
2212 }
2213 if d.phi_layer != r.phi.layer {
2214 return Err(perr(format!(
2215 "{who}: selection.phi_layer {} != router.phi.layer {}",
2216 d.phi_layer, r.phi.layer
2217 )));
2218 }
2219 Ok(())
2220 };
2221 check_desc("router.base", &r.base)?;
2222 for s in header.skills.iter().filter(|s| s.is_v2()) {
2223 if let Some(sel) = &s.selection {
2224 check_desc(&format!("skill '{}'", s.id), sel)?;
2225 if let Some(&lmin) = s.layers.iter().min() {
2226 if r.phi.layer >= lmin {
2227 return Err(perr(format!(
2228 "skill '{}': router.phi.layer {} must be < min(layers) {lmin} \
2229 (φ must not depend on the active skill)",
2230 s.id, r.phi.layer
2231 )));
2232 }
2233 }
2234 }
2235 }
2236 Ok(())
2237}
2238
2239pub fn utc_now_rfc3339() -> String {
2243 let secs = std::time::SystemTime::now()
2244 .duration_since(std::time::UNIX_EPOCH)
2245 .map(|d| d.as_secs() as i64)
2246 .unwrap_or(0);
2247 let (days, sod) = (secs.div_euclid(86_400), secs.rem_euclid(86_400));
2248 let z = days + 719_468;
2250 let era = z.div_euclid(146_097);
2251 let doe = z - era * 146_097;
2252 let yoe = (doe - doe / 1460 + doe / 36_524 - doe / 146_096) / 365;
2253 let doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
2254 let mp = (5 * doy + 2) / 153;
2255 let d = doy - (153 * mp + 2) / 5 + 1;
2256 let m = if mp < 10 { mp + 3 } else { mp - 9 };
2257 let y = yoe + era * 400 + i64::from(m <= 2);
2258 format!(
2259 "{y:04}-{m:02}-{d:02}T{:02}:{:02}:{:02}Z",
2260 sod / 3600,
2261 (sod / 60) % 60,
2262 sod % 60
2263 )
2264}